개발 편의성을 위한 소소한 Tips/04 질의 응답 정리

[Verilog HDL Q/A. 010] always @ (*) 에 대해서..

반응형

해당 내용을 많이 헷갈려하시는 것 같아서 정리합니다. 

결론은 Combinational Logic 이고, 문법을 정확하게 이해가 사용하신다면, Latch 를 만들일도, ASIC 이 불가능 할 일도 없습니다.

11년차인 저와, 저보다 훨씬 오래된 경력을 갖고 계신 분도 사용하고 계십니다.

 

always@ 안에 기술되는 Type 은 reg 여야 합니다. (port 는 예외)

이 말은 reg 라고 전부 F/F 이 아닙니다.

always 의 level sensitive 로 사용하느냐 (combinational Logic), Clock Edge Sensitive 로 사용하느냐 (Sequential Logic) 에 따라서 갈립니다.

 

다음은 유사한 질문을 갖고 계시는 분들의 질의 응답입니다.

 

Q1. 조합회로의 두가지 코딩 스타일중 어떤게 더 좋은 스타일인가요??

조합회로 강의에서 alway문과 assign을 사용한 두가지 스타일을 보여주셨는데요 제가 본 블로그에서 always문을 사용하여 조합회로를 코딩하면 래치가 생성될 가능성이 있다며 그런 코딩스타일을 정말 신랄하게 비판하더라구요 .. 선생님은 조합회로 설계시 어떤 코딩 스타일을 쓰는게 더 좋다고 생각하시는지 궁금합니다 !

 

A1.

안녕하세요 :)

사실 저 질문을 몇번 받긴했는데, 인프런에서는 처음이네요 ㅎ

결론은 좋은 스타일은, 두 코딩 스타일의 회로가 동일하다면 가독성이 좋은 쪽으로 선택하세요. 현업에 가시면 코딩가이드가 있긴합니다...만? 완벽하게 지키시는 분들이 있을지는 의문입니다. 우선은 동작하는 설계에 집중하시고, 현업에 오시면 그때 다듬으셔도 늦지 않다 생각해요.

그리고 명확하게 문법을 알고 있다면, always 문을 사용해도 됩니다. (저는 잘 쓰고 있고, 저 문법으로 많은 양산 제품을 만들었어요.) 어설프게? 알고있다면, 최악을 피하기 위해서 안쓰셔도 됩니다.

https://stackoverflow.com/questions/6009998/verilog-always-block-using-symbol
여기의 답변이 저의 생각하고 일치합니다.

 

 

Q2. FSM 관련 질문 좀 드리겠습니다!

안녕하세요! 좋은 강의 늘 감사드립니다 !!

 

FSM always @(*) 구문에서 

처음에 n_state = S_IDLE; 로 초기화 구문을 넣어주는거랑 default문을 추가해서 n_state = S_IDLE을 넣어주는거랑 완전히 같은 역할을 한다고 생각하면 될까요? 혹시 그렇다면 전자로 코딩 하시는 이유를 알 수 있을까요??

 

그리고 Verilog에서 저런식으로 특정 상수로 값을 초기화해도 합성 과정에서 별 문제 없이 잘 합성이 되나요 ?? 조합회로라 상관 없을 것 같다는 생각이 들었는데 순차회로의 경우에는 저런식으로 초기화 구문을 사용하면 합성이 되는지 안되는지도 궁금합니다!!

 

A2.

안녕하세요 :)

처음에 n_state = S_IDLE; 로 초기화 구문을 넣어주는거랑 default문을 추가해서 n_state = S_IDLE을 넣어주는거랑 완전히 같은 역할을 한다고 생각하면 될까요? 혹시 그렇다면 전자로 코딩 하시는 이유를 알 수 있을까요??

 -> Tool 마다 다를 수 있기때문에 완전히 란 단어는 사용하지는 않겠습니다. 하지만 저는 같은 역할을 한다! 라고 알고 있습니다. 코딩 스타일일 뿐입니다. 저는 전자의 코딩 스타일(초기화)을 선호하구요. 실수로 default 를 빼먹을 수 있기 때문입니다. default 가 없으면 원치않는 Latch 를 만듭니다.

그리고 Verilog에서 저런식으로 특정 상수로 값을 초기화해도 합성 과정에서 별 문제 없이 잘 합성이 되나요 ?? 조합회로라 상관 없을 것 같다는 생각이 들었는데 순차회로의 경우에는 저런식으로 초기화 구문을 사용하면 합성이 되는지 안되는지도 궁금합니다!!

-> 잘 합성 됩니다. (FPGA 강의에서 해당 코드를 적극 사용하고 있어요!)

FSM always @(*)  는 순차회로가 아닌 조합회로 입니다.

* 는 모든 입력이 포함된 것을 의미하므로 모든 입력을 쓰는 것과 같습니다. * 기호를 사용하면 입력이 변경될 때마다 항상 변경되는 것이기 때문에, 모듈이 순차가 아닌 조합 회로를 기술할 때 유용합니다.

순차회로 F/F 은 초기화 + default 를 넣으실 필요가 없습니다. 왜냐하면, F/F 소자 자체가 유지한다가 기본 개념으로 존재하기 때문이구요. 즉, full condition 문을 작성하지 않으셔도 아무 문제가 없습니다. 오히려 초기화를 reset 이 아닌 저렇게 blocking assign 으로 하면... 그건 문제가 될 것 같네요.

 

즐공하세요 :)

 

Q3. Latch 방지를 위한 n_state 의 default 값 정의

안녕하세요 좋은 강의 감사드립니다.

강의 7분 40초경에 n_state 값이 assign 되어 있지 않기 때문에 2bit 11 신호가 들어오면 latch 가 발생하기 때문에 꼭 default 값을 assign 해 줘야 한다고 말씀 하셨는데요. 왜 그런지 설명 좀 더 부연 설명 가능 하실까요? latch 가 안 좋은것은 알겠는데 왜 latch가 발생 되는지 궁금합니다. case 에 없는 상황이니 그냥 머신이 작동하지 않을 것 같은데요..

그리고 한 가지더요, always block 2번째 3번째는 always block 한개로 같이 기술 될 수 있나요? 같은 combinational logic 이고 stimulus도 같으니 가능할 것도 같아서요. 만약 가능하다면 어쩐식으로 기술이 될 수 있을 까요? 그리고 always block 두개로 코드를 만드신 이유가 있을까요?

질문이 너무 많았네요^^ 그럼 시간 되실때 답변 부탁 드리겠습니다.

 

A3. Latch 관련 답변.

원론적인 질문이 가장 어려운 것 같습니다.. 만 아는 범위 내에서 답변을 드리겠습니다.

먼저 Latch 와 F/F 은 저장 소자라는 공통점을 가집니다.

그렇다면, Latch 와 F/F 의 차이를 한번 보겠습니다.

Latch 는 Level sensitive 로 입력신호를 바로 저장 + 출력합니다.

F/F 은 Clock Edge 기반의 동작으로 Clock 신호가 인가될 때 저장 + 출력 합니다. (동기화 입니다.)

여기서 Latch 를 만들면 안된다 라고 말씀드린 이유는.

설계독학에서 뿐만아니라, 현업에 가셔서 설계하실 Digital 로직은 Synchronous (동기식) 동작이기 때문입니다. (Latch 를 일부러 사용하는 Case 도 있다고 합니다. 11년 동안 Latch 를 일부러 만든적은 없었습니다.)

동기 회로를 설계하는데, Latch 소자가 중간에 들어있다면, 이는 Timing 관점에서 문제를 야기합니다. (Timing 관점은 석사 공부가 필요합니다.)

말씀드리고 하자는 내용의 결론은 동기식 회로 설계에서 Level Sensitive 저장 소자를 사용하지 말자입니다. 사용시, Timing 의 문제가 발생합니다. (로직이 오동작 할 수 있습니다.)

아주 다행인건, 현업에 가시면 이런 Latch 가 발생하는 코드들을 잡아주는 Tool 들이 있다는 것이니, 크게 겁먹지 마시고 열심히 설계하시면 됩니다. (Synopsys 사의 spyglass 라는 툴을 썼었습니다.) 

더 자세히 알고 싶으시다면, 다음 링크를 참고 부탁드릴께요.

https://electronics.stackexchange.com/questions/38645/why-are-inferred-latches-bad

 

 

Q4. 

FSM으로 uart 설계중이었는데 그 보통 state 컨트롤시 always(*) 조합회로로 컨트롤을 하는데 이거에 대한 글을 쓴 블로그를 보았는데요.

 

진짜 always(*)문 안에 레지스터를 쓰게되면 실제 양산시에 큰 문제가 생기나요?
갑자기 궁금해서 여쭤봅니다.

https://m.blog.naver.com/PostView.nhn?blogId=godinus123&logNo=221552331215&proxyReferer=https:%2F%2Fwww.google.com%2F

이 블로그구요. "Note4"에 언급되어있습니다.

 

A4.

예전에 어떤 학생도 이분 글로 물어보던데.. 음..
개인적으로 그렇게 동의하는 글은 아니에요. 다 틀렸다는 아닌데.. 공격적인 말투하고.. 본인말이 무조건 맞다 식의 문장이 조금 걸릴 뿐.. (다 맞지 않지만요)
저희 회사 사장님 및 선배들.. 다 망했겠네요..ㅎ 저도 이번생의 설계 엔지니어는 망했군요.. ㅠㅠ

always(*) 문 이 문법은 쓰세요. Verilog 2001 정식 문법입니다.. 왜 그걸 이렇게 표현했는지.. 이거 Combinational Logic 입니다......

저분 글에 반박하면
<저분 글 발췌>
always@(*)
어떤 양아치가 이런 문장을 책에 처음 썼는지 모르겠으나 이 후로 나온 책들이 모두 이런 문장을 사용했다. 이 문장은 일단 컴비네이셔널 로직을 register 로 선언하게 된다. register 로 선언되면 메모리가 된다. 컴비네이셔널 로직에 플립플롭이나 래치가 되면 시그날 처리가 애매해 진다.

reg 로 선언했다고 해서 전부 register 아니구요. 경우에 따라서 Combinational Logic 으로 만들어집니다. (이 한줄이면 충분해요.)

어떤 양아치 == IEEE

<저분 댓글>
당연히 reg 로 선언해서 컴비네이셔널 로직으로 합성이 가능하죠. 그런데 그게 경우에 따라 레지스터가 될수도 있잖아요. 컴비네이셔널 로직을 설계하는데 만에하나 레지스터나 래치같은 형태로 합성되면 회로에 재앙이 발생합니다.
코딩 스타일로 충분히 막을 수 있는 재앙을 왜 잘못될 확률이 있는 방식으로 설계하냐는 말이죠.

경우에 따라서.. 가 어떤 경우인지는 모르겠는데, 문법을 정확하게 모르면 안쓰는 것이 좋다 의 뉘앙스로는 공감합니다.
하지만 저는 써요 :)

 

즐공하세요 :)

 

반응형