Verilog / System Veilog / VHDL에서 Blocking 와 Non-Blocking의 개념은 매우 중요하니, 잘 이해하시고 활용하시면 좋겠습니다.
Ⅰ. Blocking
- Blocking assignment 는 verilog/sytem verilog 기준 "="로 쓰며, procedural block 내에서 순차적으로 실행된다.
- 하지만 prarallel 하게 실행되는 경우, 차례대로 수행됨
- Hardware 관점에서 생각을 해보면, Blocking 개념은 Combination logic을 설계할 때 사용하게 됩니다.
+ ADDER와 같은 Logic은 Clock에 관계없이 바로 출력이 되어야 겠지요?
ⅰ. Simulation 1
- 예제를 참고하여 간단한 simulation 진행.
module sverilog_blocking_1();
reg [7:0] a, b, c, d, e;
initial begin
a = 8'hAA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
b = 8'hD0;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c = 8'h10;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
d = 8'hBB;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
e = 8'h33;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
- 결과는 아래 참고하세요!
# run 1000ns
[0] a=0xaa b=0xxx c=0xxx
[0] a=0xaa b=0xd0 c=0xxx
[0] a=0xaa b=0xd0 c=0x10
[0] d=0xbb e=0xxx
[0] d=0xbb e=0x33
ⅱ. Simulation 2
- 예제를 참고하여 간단한 simulation 진행.
module sverilog_blocking_2();
reg [7:0] a, b, c, d, e;
initial begin
a = 8'hAA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
#10 b = 8'hD0;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c = 8'h10;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
#5 d = 8'hBB;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
#5 e = 8'h33;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
- 결과는 아래 참고하세요!
# run 1000ns
[0] a=0xaa b=0xxx c=0xxx
[5000] d=0xbb e=0xxx
[10000] a=0xaa b=0xd0 c=0xxx
[10000] a=0xaa b=0xd0 c=0x10
[10000] d=0xbb e=0x33
앞의 두 예제의 차이를 아시겠나요??
첫 번째 예제에서는 두 개의 initial block이 병렬적으로 이루어지는 것이며, initial blcok 내부에서는 순차적으로 code가 실행되면서 즉각 실행하게 됩니다.
두 번째 예제에서는 약간의 delay를 주었기 때문에 initial block 이 병렬적을 동작하지만 내부에서는 순차적으로 code가 실행되는 것을 볼 수 있습니다.
Ⅰ. Non-blocking
- Non-blocking assignment는 verilog/sytem verilog 기준 "<="로 쓰며, statement들의 실행이 blocking 없이 스케쥴링되어 짐
+ 위의 말을 쉽게 설명을 드리면, Code가 순차적으로 실행되는 것이 아니라 일단 Code가 내려가면서 어떻게 실행을 할지를 스케줄링하면서 time-stemp가 충족하게 되면(ex. clock triggerd) 실행되는 것을 의미합니다.
+ 이렇게 설명해도 어려우니 예제를 보고 이해하시면 편할 것 같습니다.
- Hardware 관점에서 생각을 해보면, Non-blocking 개념은 Sequential logic을 설계할 때 사용하게 됩니다.
+ 대표적으로 clock의 positive edge에서 register에 값이 저장하는 case죠
ⅰ. Simulation 1
- 예제를 참고하여 간단한 simulation 진행.
module sverilog_nonblocking_1();
reg [7:0] a, b, c, d, e;
initial begin
a <= 8'hAA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
b <= 8'hD0;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c <= 8'h10;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
d <= 8'hBB;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
e <= 8'h33;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
- 결과는 아래 참고하세요!
# run 1000ns
[0] a=0xxx b=0xxx c=0xxx
[5000] d=0xxx e=0xxx
[10000] a=0xaa b=0xxx c=0xxx
[10000] a=0xaa b=0xxx c=0xxx
[10000] d=0xbb e=0xxx
ⅱ. Simulation 2
- 예제를 참고하여 간단한 simulation 진행.
module sverilog_nonblocking_1();
reg [7:0] a, b, c, d, e;
initial begin
a <= 8'hAA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
#10 b <= 8'hD0;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c <= 8'h10;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
#5 d <= 8'hBB;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
#5 e <= 8'h33;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
- 결과는 아래 참고하세요!
# run 1000ns
[0] a=0xaa b=0xxx c=0xxx
[5000] d=0xbb e=0xxx
[10000] a=0xaa b=0xd0 c=0xxx
[10000] a=0xaa b=0xd0 c=0x10
[10000] d=0xbb e=0x33
첫 번째 예제에서는 모두 unknown 값이 나왔지요? 그 이유는 "<=" 오른쪽의 값이 왼쪽으로 변수로 대입이 되기 위해서는 특정한 time-stemp, 즉 event와 같은 조건이 필요한데 스케쥴링만 되었고 특정 time-stemp가 없어서 값을 할당 못하여서 unknown 값이 나온 것입니다.
두 번째 예제에서는 "#10" "#5"와 같은 time-stemp가 존재하기 때문에 값이 할당되어 display로 출력되는 것입니다.
'Digital Hardware Design > System verilog' 카테고리의 다른 글
Control-Case (0) | 2022.10.24 |
---|---|
Control - condition (0) | 2022.10.11 |
Control - loop (0) | 2022.10.09 |
Data type(3) (0) | 2022.10.09 |
data type(2) (0) | 2022.10.03 |
댓글