본문 바로가기

SoC

[Verilog] Blocking VS Non-blocking 차이 블로킹과 논블로킹

Verilog에서 blockingnon-blocking 할당은 둘 다 레지스터 값을 변경하는 데 사용됩니다. 하지만, 이 둘은 다른 작업을 수행하며, 이를 이해하기 위해서는 Verilog에서 작성된 코드의 시뮬레이션 단계에서 일어나는 동작 순서에 대한 이해가 필요합니다.

 

blocking 할당은 = 기호를 사용하여 값을 할당합니다.

 

 

이 할당은 현재 할당 문장이 완료된 후 다음 문장이 실행되기 전에 완료됩니다.

즉, 이전 할당 문장이 완료되기 전에 다음 문장이 실행되지 않습니다. 이러한 특징으로, blocking 할당은 순차적인 동작을 수행하는 경우에 유용합니다.

 

예를 들어, 아래 코드에서 blocking 할당 연산자를 사용하여 ab의 값을 순차적으로 변경합니다.

 

module example(
  input clk,
  input reset,
  output reg [7:0] data_out
);

  reg [7:0] a, b;
  
  always @(posedge clk) begin
    if (reset) begin
      a <= 8'b0;
      b <= 8'hFF;
    end else begin
      a = b;
      b = a + 1;
    end
  end
  
  assign data_out = a;
  
endmodule

reset이 '1" 일때 a 와 b는 각각 '0' '255' 로 초기화 됩니다. 

이후에 always에서 'blocking' 연산자 '=' 로 a 레지스터에 b 값을 할당하고, b 레지스터에 a+1 값을 할당합니다.

이 때, 이전 할당문이 완료되어야 다음 할당문이 실행되므로, a 레지스터에는 항상 이전의 b 값을 유지하고, b 레지스터에는 이전 a+1의 값을 유지합니다.

 

non-blocking 할당은 <= 기호를 사용하여 값을 할당합니다. 이 할당은 다음 문장이 실행되기 전에 완료됩니다. 즉, 현재 할당문이 완료되지 않은 상태에서 다음 문장이 실행됩니다. 이러한 특징으로, non-blocking 할당은 병렬적인 동작을 수행하는 경우에 유용합니다.

 

예를 들어, 아래 코드에서 non-blocking 할당 연산자를 사용하여 ab의 값을 병렬적으로 변경합니다.

module example(input clk, input reset, output reg [3:0] count);

always @(posedge clk or posedge reset) begin
  if (reset) begin
    count <= 4'b0000;
  end else begin
    count <= count + 1;
  end
end

endmodule

위의 예시에서 count 레지스터는 non-blocking assignment을 사용하여 값을 업데이트하고 있습니다. count 레지스터의 이전 값과 1을 더한 값을 새로운 값으로 업데이트하기 때문에, 이는 Verilog에서 흔한 시퀀셜 논리 회로 동작입니다.