본문 바로가기
digital logic/knowlege

blocking vs non-blocking assignment(feat. race condition)

by 파란하늘코더 2020. 10. 19.
반응형

RTL 설계를 하다 보면 내가 원하는 설계 block을 설계하는 일도 있지만, 

 

해당 block을 구현하기 위해 testbench를 따로 구현해야 하는 일도 있다.

 

신입 때는 아무 생각 없이 선배들이 전달해준 testbench를 기반으로 수정하여 사용했지만,

 

시간이 지날수록 내가 설계를 직접 해야 하는 일이 생겼었다.

 

그래서 verilog로 설계하던 것을 최근에 systemverilog로도 해보고 하다 보니 

 

blocking, non-blocking으로 인해 결과 값이 제대로 나오지 않는 문제들이 simulator마다 다르게 발생하는 것을 경험했다.

 

따라서 오늘은 이 부분에 대해 까먹지 않을수 있도록 정리를 해놓으려고 한다.

 

---------------------------------------------------------------------------------------

 

우선 blocking assignment와 non-blocking assignment에 대해 정리를 해보면

 

단어에서 나오는 뉘앙스처럼 막는것과 막지 않는 것으로 이해를 하면 된다.

 

예시와 같이 설명을 하면 아래와 같이 

 

코드가 구현이 되어있을때를 보면, 예를 들어 초기값이 a = 1, b = 2, c = 3이라고 하면

 

blocking assignment는 a = b = c = 2

 

non-blocking assignment는 a = b = 2, c = 1로 바뀌어 있을 것이다.

 

원리를 설명하면 blocking assignment는 해당 process가 처리되고 있을 때는 다음 line으로 넘어가지 않는다

(즉, 다른 line으로 넘어가는 것을 막는다)

 

반대로 non-blocking assignment는 모든 line이 동시에 처리가 되는 구문이다

 

실제 업무에서 sequential logic을 구현할 때는 non-blocking assignment로 설계를 진행하고,

 

combinational logic을 구현할 때는 blocking assignment로 설계를 한다.

 

그리고 combinational logic을 설계할 때는 race condition이 생기지 않도록 주의를 해야 한다.

 

race condition이란 단어를 직역하면 경쟁상태이고, 의미적으로 해석하면

 

verilog simulator가 signal들을 계산 및 예측하는 데 있어 우선순위를 어디에 먼저 두어야 할지 모르는 상황을 말하는 것이다.

 

예를 들어 아래와 같은 코드에서는 어떻게 동작을 할지 아무도 모르게 된다

 

위와 같은 코드는 clk rising edge에서 구문을 동작시키는 순서에 따라 최종 결과가 달라지게 된다.

 

따라서 위의 코드는 아래와 같이 목적에 맞도록 수정을 하여야 한다.

왼쪽의 경우 최종 결과가 a = b = c 가 될 것이고, 

 

오른쪽의 경우 b = a(이전 값), a = c 가 될 것이다.

-----------------------------------------------------------------------------------------

위의 설명에서 simulator들이 어떤 식으로 계산 및 예측을 하는지 살펴보면 아래와 같이 돌아간다

 

verilog simulator는 time이 진행되면서 특정 시점에서 위의 process들을 진행을 한다

 

차례대로 active event queue -> nonblocking update queue -> postponed queue 이렇게 진행하는데

 

blocking assignment의 경우 순서가 없이 마구잡이로 먼저 선언이 되기 때문에 위의 예제가 예측이 되지 않는 것이다.

 

그리고 flow를 자세히 살펴보면 non-blocking과 blocking에 대해 변수를 log로 저장하고 싶을 때 

 

update 되는 시점이 다르기 때문에 각각에 맞는 system function을 사용하여야 한다.($display, $monitor, $strobe)

 

또한 non-blocking의 경우 RHS의 값을 계산한 이후에 LHS값을 업데이트하는 queue가 다르기 때문에 

 

$display 함수를 쓰게 될 경우 원하는 결과를 얻지 못한다.

 

이번 포스팅하면서 드는 생각이 담음 포스팅은 coding guideline을 정리해놔야겠다는 생각이 든다.

'digital logic > knowlege' 카테고리의 다른 글

관성지연, 전달지연  (0) 2020.10.20
signed arithmetic  (0) 2020.10.16
Clock gating  (0) 2020.10.14
CDC(Clock domain crossing)  (3) 2020.10.13

댓글