verilog
차단 할당 문은 =
을 사용하여 할당됩니다. 절차 블록에서 차례로 실행됩니다. 그러나 이것이 병렬 블록에서 실행되는 명령문의 실행을 방해하지는 않습니다.
module tb;
reg [7:0] a, b, c, d, e;
initial begin
a = 8'hDA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
b = 8'hF1;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c = 8'h30;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
d = 8'hAA;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
e = 8'h55;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
두 개의 initial
이 있습니다. 시뮬레이션이 시작될 때 병렬로 실행되는 블록. 명령문은 각 블록에서 순차적으로 실행되며 두 블록은 모두 0ns에 종료됩니다. 보다 구체적으로, 변수 a 가 먼저 할당되고 그 다음에 display 문이 오고 그 다음에 다른 모든 문이 옵니다. 이것은 변수 b 및 c 첫 번째 표시 문에서 8'hxx입니다. 이것은 변수 b 때문입니다. 및 c 첫 번째 $display
일 때 할당이 아직 실행되지 않았습니다. 라고 합니다.
ncsim> run [0] a=0xda b=0xx c=0xx [0] a=0xda b=0xf1 c=0xx [0] a=0xda b=0xf1 c=0x30 [0] d=0xaa e=0xx [0] d=0xaa e=0x55 ncsim: *W,RNQUIE: Simulation is complete.
다음 예에서는 동일한 명령문 세트에 몇 가지 지연을 추가하여 작동 방식을 확인합니다.
module tb;
reg [7:0] a, b, c, d, e;
initial begin
a = 8'hDA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
#10 b = 8'hF1;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c = 8'h30;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
#5 d = 8'hAA;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
#5 e = 8'h55;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
시뮬레이션 로그 ncsim> run [0] a=0xda b=0xx c=0xx [5] d=0xaa e=0xx [10] a=0xda b=0xf1 c=0xx [10] a=0xda b=0xf1 c=0x30 [10] d=0xaa e=0x55 ncsim: *W,RNQUIE: Simulation is complete.
비차단 할당을 사용하면 다음 명령문의 실행을 차단하지 않고 할당을 예약할 수 있으며 <=
으로 지정됩니다. 상징. 동일한 기호가 식에서 관계 연산자로 사용되고 비차단 할당 컨텍스트에서 할당 연산자로 사용된다는 점은 흥미롭습니다. 위의 첫 번째 예를 들면 모든 =
을 교체하십시오. 비차단 할당 연산자 <=
가 있는 기호 , 출력에 약간의 차이가 있음을 알 수 있습니다.
module tb;
reg [7:0] a, b, c, d, e;
initial begin
a <= 8'hDA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
b <= 8'hF1;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c <= 8'h30;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
d <= 8'hAA;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
e <= 8'h55;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
모든 $display
인쇄된 명령문 'h'x
. 이 동작의 이유는 비차단 할당이 실행되는 방식에 있습니다. 특정 시간 단계의 모든 비차단 명령문의 RHS가 캡처되고 다음 명령문으로 이동합니다. 캡처된 RHS 값은 시간 단계가 끝날 때만 LHS 변수에 할당됩니다.
ncsim> run [0] a=0xx b=0xx c=0xx [0] a=0xx b=0xx c=0xx [0] a=0xx b=0xx c=0xx [0] d=0xx e=0xx [0] d=0xx e=0xx ncsim: *W,RNQUIE: Simulation is complete.
따라서 위 예제의 실행 흐름을 분해하면 아래와 같은 결과를 얻을 수 있습니다.
|__ Spawn Block1: initial | |___ Time #0ns : a <= 8'DA, is non-blocking so note value of RHS (8'hDA) and execute next step | |___ Time #0ns : $display() is blocking, so execute this statement: But a hasn't received new values so a=8'hx | |___ Time #0ns : b <= 8'F1, is non-blocking so note value of RHS (8'hF1) and execute next step | |___ Time #0ns : $display() is blocking, so execute this statement. But b hasn't received new values so b=8'hx | |___ Time #0ns : c <= 8'30, is non-blocking so note value of RHS (8'h30) and execute next step | |___ Time #0ns : $display() is blocking, so execute this statement. But c hasn't received new values so c=8'hx | |___ End of time-step and initial block, assign captured values into variables a, b, c | |__ Spawn Block2: initial | |___ Time #0ns : d <= 8'AA, is non-blocking so note value of RHS (8'hAA) and execute next step | |___ Time #0ns : $display() is blocking, so execute this statement: But d hasn't received new values so d=8'hx | |___ Time #0ns : e <= 8'55, is non-blocking so note value of RHS (8'h55) and execute next step | |___ Time #0ns : $display() is blocking, so execute this statement. But e hasn't received new values so e=8'hx | |___ End of time-step and initial block, assign captured values into variables d and e | |__ End of simulation at #0ns
다음으로 두 번째 예를 사용하여 모든 차단 문을 비차단으로 바꿔봅시다.
module tb;
reg [7:0] a, b, c, d, e;
initial begin
a <= 8'hDA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
#10 b <= 8'hF1;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c <= 8'h30;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
#5 d <= 8'hAA;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
#5 e <= 8'h55;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
출력물이 이전에 얻은 것과 다른 것을 다시 한 번 확인할 수 있습니다.
시뮬레이션 로그ncsim> run [0] a=0xx b=0xx c=0xx [5] d=0xx e=0xx [10] a=0xda b=0xx c=0xx [10] a=0xda b=0xx c=0xx [10] d=0xaa e=0xx ncsim: *W,RNQUIE: Simulation is complete.
실행 흐름을 분석하면 아래와 같은 결과를 얻을 수 있습니다.
|__ Spawn Block1 at #0ns: initial | |___ Time #0ns : a <= 8'DA, is non-blocking so note value of RHS (8'hDA) and execute next step | |___ Time #0ns : $display() is blocking, so execute this statement: But a hasn't received new values so a=8'hx | |___ End of time-step : Assign captured value to variable a, and a is now 8'hDA | |___ Wait until time advances by 10 time-units to #10ns | | |___ Time #10ns : b <= 8'F1, is non-blocking so note value of RHS (8'hF1) and execute next step | |___ Time #10ns : $display() is blocking, so execute this statement. But b hasn't received new values so b=8'hx | |___ Time #10ns : c <= 8'30, is non-blocking so note value of RHS (8'h30) and execute next step | |___ Time #10ns : $display() is blocking, so execute this statement. But c hasn't received new values so c=8'hx | |___ End of time-step and initial block, assign captured values into variables b, c | |__ Spawn Block2 at #0ns: initial | |___ Wait until time advances by 5 time-units to #5ns | | |___ Time #5ns : d <= 8'AA, is non-blocking so note value of RHS (8'hAA) and execute next step | |___ Time #5ns : $display() is blocking, so execute this statement: But d hasn't received new values so d=8'hx | |___ End of time-step : Assign captured value to variable d, and d is now 8'hAA | |___ Wait until time advances by 5 time-units to #5ns | | |___ Time #10ns : e <= 8'55, is non-blocking so note value of RHS (8'h55) and execute next step | |___ Time #10ns : $display() is blocking, so execute this statement. But e hasn't received new values so e=8'hx | |___ End of time-step and initial block, assign captured values to variable e, and e is now 8'h55 | |__ End of simulation at #10ns
verilog
Verilog는 하드웨어 설명 언어이며 설계자가 RTL 설계를 시뮬레이션하여 논리 게이트로 변환할 필요가 없습니다. 시뮬레이션이 필요한 이유는 무엇입니까? 시뮬레이션은 RTL 코드가 의도한 대로 동작하는지 확인하기 위해 다른 시간에 다른 입력 자극을 설계에 적용하는 기술입니다. 기본적으로 시뮬레이션은 설계의 견고성을 검증하기 위해 잘 따라야 하는 기술입니다. 또한 가공된 칩이 실제 세계에서 사용되는 방식과 다양한 입력에 반응하는 방식과 유사합니다. 예를 들어, 위의 디자인은 출력 pe 보여진 바와 같이. 시뮬레이션을 통해
디자인 module pr_en ( input [7:0] a, input [7:0] b, input [7:0] c, input [7:0] d, input [1:0] sel, output reg [7:0] out); always @ (a or b or c or d or sel) begin if (sel == 2b00) out <= a; else if