해결된 질문
작성
·
124
·
수정됨
1
안녕하세요 맛비님
강의 잘 듣고 있는 도중에 always 블럭으로 combination logic을 기술하는 경우 제가 명확하게 알고 있는지 궁금합니다.
always로 코드를 작성 할 때, 그 안에 내부 변수는 reg로 사용하고, 이 reg변수는 register,latch(보통의 경우 의도하지 않은), combination logic을 만들 때 사용되는 것으로 알고 있습니다.
저는 always 블럭을 사용할 때, 의도하지 않은 latch가 발생하는 것을 완전히 피하고 싶습니다.
그래서 코드 작성 스타일을 이렇게 하면 좋을지 궁금합니다.
/*output combination 2*/
reg done; //this is not a register, it is just combination logic circuit
reg running; //this is not a register, Do not confuse
reg idle; //this is not a register, you must not make latch
always@(*)begin
done = 0;
running = 0;
idle = 0;
case(c_state)
S_IDLE : idle = 1;
S_RUN : running = 1;
S_DONE : done = 1
default : begin
done = 0;
running = 0;
idle = 0;
end
endcase
end
default에 그 외적인 정의되지 않은 동작에 대해 처리하도록 작성하거나
case문을 시작하기 전에 각각 초기값을 작성해두면 되는 것으로 알고 있습니다.
하지만 이놈의...chatGPT는 초기값도 작성하고 default문을 둘 다 작성 안하면 latch가 발생할 가능성이 있다고 해서... 이 점이 궁금합니다.
사실 위의 코드처럼 작성하면 정말로 latch가 생길 여지가 없어 보입니다만...
아시다시피 번거로움이라는 이슈로...
아 그리고 질문이 하나 더 있습니다.
fsm_counter부분에서 state로 동작을 제어한다는 개념을 반복해서 공부하고 있습니다.
assign o_done = done;
assign o_running = running;
assign o_idle = idle;
reg [31:0] r_cnt_num; //this is register to capture input value
always @(posedge clk or negedge reset_n) begin
if(!reset_n)begin
r_cnt_num <= 0;
end
else if(i_run) begin
r_cnt_num <= i_cnt_num;
end
else if(o_running) begin
r_cnt_num <= r_cnt_num;
end
else if(o_done) begin
r_cnt_num <= 0;
end
end
reg [31:0] r_cnt_core;
assign is_done = o_running&&(r_cnt_core == r_cnt_num -1);
/*counter core part*/
always@(posedge clk or negedge reset_n) begin
if(!reset_n)begin
r_cnt_core <=0;
end
else if(o_idle)begin
r_cnt_core<=0;
end
else if(o_running)begin
r_cnt_core <= r_cnt_core + 1;
end
else if(is_done)begin
r_cnt_core <=0;
end
end
이 부분은 위에 질문 코드 바로 뒤에 이어지는 코드입니다.
바로 위의 블럭에서 첫번째 capture register를 기술하는 부분에서
run state일 때도 register가 어떻게 동작해야하는지 꼭 기술해야할까요?
이 부분은 맛비님 코드에서 작성되어있지는 않던데, 제가 생각하기에는...
run state일 때 register의 동작이 어떻게 될지 예상이 안가서 직접 작성해주는게 좋아보이는데..
어떻게 생각하시나요?
두번째 always블럭 또한 같은 맥락으로 idle상태일 때 core 내부에 있는 register의 동작도 기술해주는 것이 필수적일까요?
위의 코드는 수업에 다루신 코드를 제가 schematic을 보고 다시 작성한 코드입니다.
저의 질문은 여기까지입니다.
감사합니다.
답변 2
0
안녕하세요 🙂
먼저 다음 코드는 FSM 이 아닙니다. (next state 가 없습니다)
제 생각에는 reg 로 선언되어 있는 모든 변수들이 always 문 안에서 무조건, 값을 가짐으로 (초기값 0 을 assign 해주셨기 때문에) latch 는 발생되지 않을 것으로 생각됩니다.
default 문을 작성하는 것이 코딩스타일 관점에서 좋고요.
현재 이 초기화 값 때문에, 항상 값을 가지게 됩니다. (빨간 네모박스) 이는 설계하시는 로직에 문제가 없다면 latch 가 발생하지 않습니다. 저도 latch 를 방지하기 위해 즐겨쓰는 코딩 스타일 입니다.
==============================================
아 그리고 질문이 하나 더 있습니다.
fsm_counter부분에서 state로 동작을 제어한다는 개념을 반복해서 공부하고 있습니다.
질문을 정확하게 이해를 못해서, 이 부분만 따로 정리해주시면, 이해해보고 답변드릴께요 🙂
0
안녕하세요, 인프런 AI 인턴입니다. 매드닭강정님.
Verilog 코드 작성 시, 항상 올바른 조건을 제공하여 불필요한 latch 발생을 피하는 것이 중요합니다. 말씀하신 것처럼 초기 값을 지정하는 것과 default 문을 사용하는 방법이 있습니다.
기본적으로, Verilog에서 combinational logic을 다룰 때, 모든 신호에 대해 모든 가능한 조건을 다루지 않는다면 의도치 않은 latch가 발생할 수 있습니다. 귀하의 코드에서 초기값을 설정하고 default 구문을 추가하는 방식은 매우 좋은 습관입니다.
아래는 귀하의 이해를 돕기 위해 유사한 상황에서의 해결책을 다룬 기존 답변들입니다:
FSM case문 default 와 latch 관련 질문있습니다.
fsm 에서 next state 계산하는 always 블록 관련 질문 드립니다.
말씀하신 내용처럼, 초기값을 설정하고 default 문을 추가하는 방식은 latch를 예방하기에 충분하다 하겠습니다. 하지만, 여전히 모든 조건을 정확하게 다루는 것이 중요하기 때문에 조심스럽게 접근할 필요가 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.