작성
·
2.3K
1
always문을 사용하실 때 어떤 기준으로 always문을 나누시는지 궁금합니다.
가령 예를 들면 올려주신 chapter_11에 있는 count 코드를 보면 always 문 2개를 사용해서 모듈을 구성하셨고
그밖에 강의를 보면 다양하게 always문을 나누시는데
같은 동작을 하는 모듈을 always문 하나로 만들 수 있을텐데 나누시는 기준이 어떤건지 궁금합니다.
그리고 작성한 verilog 코드의 가독성을 높히기 위한 팁이나 관련 추천 서적이나 참고 자료가 있으실까요!
제가 이 부분에 대해서 부족한게 많아서 알려주신다면 앞으로 설계를 할 때 도움이 많이 될 것 같습니다.
감사합니다.
답변 1
1
안녕하세요 :)
cnt 와 cnt_always 를 나눈 것에 대한 질문으로 이해를 했습니다.
always 문의 내부 변수를 나누고 합치는 기준.
always 문 안의 condition (if else 의 조건) 이 동일하다면 하나로 묶으셔도 괜찮습니다.
하지만 지금 cnt 와 cnt_always 의 if else 조건을 보시면 (32 line vs 43,46 line) 서로 다른 조건이기 때문에, 나누어서 사용하였습니다.
지금 예제에서는 합쳐서 HDL 기술은 가능하겠지만, 불필요한 로직이 발생할 것 같아요.
코드의 가독성이나 tip 이라.. 면? (저도 잘 지키진 않지만)
http://www.ime.cas.cn/icac/learning/learning_3/201907/P020190716574161163126.pdf
여기서, 다음 부분을 참고하시면 됩니다.
즐공하세요 :)
HDL 은 HW 를 생성하는 언어입니다.
즉, 불필요한 로직은 생성할 수 있어서, always 를 분리 시킨거에요.
always 문의 개수에 대한 제약은 없습니다.
문법책과 구글링을 봐도 도저히 잘 모르겠다... 싶으면 분리하시는 것을 권장드립니다.
다음 링크 참고부탁드립니다. (질문과는 관련없는 blocking assign case 이지만, 설계인생에서 도움이 되시라고.. 이해시키기 어렵네요. ㅠ 설계를 많이 하시다 보면 감이 오십니다. )
if~else 3개 case3개가 필요한 모듈이라면 always는 6개 필요하다 라고 이해하면 될까요?
3개, 3개 안에 사용되는 변수들이 각각 다른 조건이라면 나눠서 사용합니다.
즉, 1 변수 1 always 문이 되어야 합니다.
reg A 라는 녀석을 두개의 always 문에 assign 되도록 하면 안됩니다.
이 이야기는 다음 링크를 참고하시면 도움이 됩니다. 혹시나 참고하시라고
예) 예를 위한 의사 코드입니다.
reg A, B;
////// Case 1
always @(posedge clk) begin
A <= 0;
end
always @(posedge clk) begin
B <= 0;
A <= 0; // 위에 non-blocking assign 이 있음으로 사용 비권장.
end
////// Case 2
always @(posedge clk) begin
A <= 0;
end
always @(posedge clk) begin
if (A == 0) // 사용가능
B <= 0;
end
이 룰을 지키셔서, 여쭤보신 질문의 답을 직접 내보시면 됩니다.
그리고 중간중간 스텝 단계에 맞는 assign을 먼저 위에 넣은건 가독성을 위해서 인가요?
네, 맞습니다. 바꾸셔도 됩니다. (설계자 마음대로)
즐공하세요 :)
ps, 문법이나 코딩룰은 책과 구글링을 참고 부탁드려요.
회사마다 룰이 다 다릅니다. 그래서 답변드리기 애매해요. 이해부탁드립니다. :)
더 찾아보았구요
https://stackoverflow.com/questions/61690027/assigning-multiple-if-statements-in-a-sequential-always-block
여기 보시면,
// 다음 case 는 괜찮습니다... 만, 굳이.. 이렇게 ... 저는 쓰고싶진않아요. (if, if 로 independent condition)
always @(posedge clk) begin
if (rst) begin
a <= 0;
b <= 0;
end else begin
if (condition_one) a <= 1;
if (condition_two) b <= 1;
end
end
// 다음 case 는 비권장 쓸때없는 로직생성. (if, else로 dependent condition)
always @(posedge clk) begin
if (rst) begin
a <= 0;
b <= 0;
end else begin
if (condition_one) a <= 1;
if else (condition_two) b <= 1;
end
결론은 앞서 적었지만,
문법 설명이 가장… 힘들 ㅠㅠ
즐공하세요 :)
너무 중구난방 해서, 정리합니다. (이걸 글로 쓸줄이야... ㅎㅎ)
맛비의 always 문을 나누는 기준 (정해드립니다.)
1. 한 변수에 여러 always 문 assign 을 해야한다면? (합치세요. 가장 주의해야함)
2. if else 의 condition 이 indepentent 하다면 always 문을 합쳐도 동일한 로직을 만드나, 맛비는 추천하지 않는다. (합쳐도 되는데, 나누세요)
3. if else 의 condition 이 depentent 하다면? (나누세요)
4. 너무 복잡해서 가독성이 떨어진다. (가독성이 좋은 쪽으로 합치던 나누세요.)
5. 맛비가 무슨말을 하는지 모르겠다. 그러면 1번 case 만 주의하시고 일단 나누세요.
즐공하세요 :)
답변 감사합니다! 그럼 서로 다른조건의 if~else 가 5개가 필요한 모듈이 있다면 always문을 5개로 해서 만드는건가요? 이게 설계 할 때 있어서 불필요한 로직을 방지하는 방법이여서 그렇게 하는건가요?
if~else 3개 case3개가 필요한 모듈이라면 always는 6개 필요하다 라고 이해하면 될까요?
말씀해주신 내용을 특정 기능을 하는 애들을 나눠서 always문으로 만들었다 라고 이해 했거든요
chapter_20에 있는 simple_bram에 있는거로 예를 들면
c_state를 초기화하고 값을 주는 기능의 always 하나
각 state의 상태를 변화시키는 기능을 담당하는 모든 신호를 받는(*) always하나
num_cnt 에 값을 넣는 기능을 담당할 always하나
addr_cnt를 담당할 always하나
r_valid를 담당할 always하나 이렇게 이해하면 될까요?
그리고 중간중간 스텝 단계에 맞는 assign을 먼저 위에 넣은건 가독성을 위해서 인가요?
다시 한번 좋은 강의와 답변에 감사드립니다.