블로킹 할당 vs 논블로킹 할당: 평가 타이밍·순서·사용 위치 비교
둘 다 Verilog always 블록 안에서 쓰는 할당이지만, 좌변이 바뀌는 타이밍이 다릅니다. 블로킹 할당(=)은 그 줄을 실행한 시점에 좌변을 갱신하며, 다음 줄에서는 새 값이 쓰입니다. 논블로킹 할당(<=)은 같은 타이밍의 모든 우변을 먼저 평가한 뒤 좌변을 한꺼번에 갱신합니다. 클럭으로 동작하는 순차 회로에는 <=, 조합 회로의 always에는 =를 쓰는 것이 기본 가이드라인입니다.
| 비교 항목 | 블로킹 할당(=) | 논블로킹 할당(<=) |
|---|---|---|
| 작성법 | a = b; | a <= b; |
| 좌변을 갱신하는 타이밍 | 그 줄을 실행할 때 즉시 갱신합니다 | 같은 타이밍의 우변을 모두 평가한 뒤 한꺼번에 갱신합니다 |
| 다음 줄에서 보이는 값 | 갱신 후의 새 값 | 갱신 전의 이전 값 |
| 기술 순서에 대한 의존성 | 있음. 줄 순서를 바꾸면 결과가 달라집니다 | 거의 없음. 단, 같은 변수에 두 번 할당하면 나중 할당이 남습니다 |
| 대응하는 회로 동작 | 위에서부터 차례로 중간값을 계산해 나가는 조합 회로 | 클럭 에지에서 일제히 값을 받아들이는 플립플롭 |
| 주로 쓰는 위치 | 조합 회로의 always @(*), 테스트벤치의 절차 | 클럭으로 동작하는 순차 회로의 always @(posedge clk) |
| 2단 시프트 레지스터(클럭으로 동작하는 블록) | q1 = d; q2 = q1;에서는 q2에도 같은 에지에서 d가 들어가 1단만 지연됩니다 | q1 <= d; q2 <= q1;에서는 q2에 에지 이전의 q1이 들어가 2단이 됩니다 |
| 값 교환(클럭으로 동작하는 블록) | a = b; b = a;에서는 a와 b가 같은 값이 됩니다 | a <= b; b <= a;에서는 a와 b가 서로 바뀝니다 |
| 여러 always 블록 사이 | 같은 에지에서 동작하는 블록끼리 실행 순서에 따라 결과가 달라지는 레이스가 생기기 쉽습니다 | 우변 평가가 먼저 갖춰지므로 레이스가 잘 생기지 않습니다 |
| 잘못 사용했을 때 | 순차 회로에 쓰면 결과가 블록 실행 순서에 좌우되어, 합성된 회로와 동작이 어긋날 수 있습니다 | 조합 회로에 쓰면 중간값이 이전 값인 채로 읽혀, 시뮬레이션이 합성된 회로와 어긋나거나 불필요하게 재실행됩니다 |
수치는 대략적인 자릿수 기준이며, 공정 세대와 제품에 따라 달라져요.