SystemVerilog Test Environment |
---|
![]() |
- The
program
block
- testbench code 적는 공간
- entry point for testbench execution =
main()
함수랑 같은 의미- The
interface
- testbench랑 DUT 연결 메커니즘
- named bundle of wires
- 생략 가능
- Driving DUT Signals
- device driver 를 통해 DUT signals 들이 driven 됨
- Sampling DUT Signals
- device monitor 로 DUT signals 들이 samplied 됨
initial
block 만 사용 가능함SystemVerilog Containers |
---|
![]() |
clocking
blocks)initial
/always
blocks)interface simple_bus(input bit clk);
logic req, gnt;
logic [7:0] addr;
wire [7:0] data;
logic [1:0] mode;
logic start, rdy;
endinterface
module cpu(simple_bus sb);
...
endmodule
module top;
logic clk = 0;
always #10 clk = !clk;
simple_bus sb(clk);
test t1(sb);
cpu c1(sb);
endmodule
clocking
BlocksSynchronous Timing |
---|
![]() |
Just for testbench : Emulate the launch and capture flops at IO of DUT
clocking cb @(posedge clk); default input #1ns output #1ns; output reset_n; output din; output frame_n; output valid_n; input dout; input busy_n; input valido_n; input frameo_n; endclocking: cb
TB 입장에서 input은 DUT의 output delay = setup time, 안쓰면 SAMPLE이 default
output은 DUT의 input delay = clk2q, 안쓰면 DRIVE가 default
modport
interface router_io(input bit clock);
logic reset_n;
...
clocking cb @ (posedge clock);
default input #1ns output #1ns;
output reset_n;
output valid_n;
...
endclocking
modport DUT(input reset_n, input din, output dout, ...);
modport TB(clocking cb, output reset_n);
endinterface: router_io
module router(
router_io.DUT dut_io,
input logic clk);
...
endmodule: router
program automatic test(router_io.TB rtr_io);
initial begin
rtr_io.reset_n = 1'b0;
rtr_io.cb.reset_n <= 1'b1;
rtr_io.cb.valid_n <= ~('b0);
end
endprogram: test
time slot |
---|
![]() |
Assertion and testbench events can trigger design evaluations
- Preponed : Sample signals before any changes (#1step)
- Active : Design simulation (module), including NBA
- Observed : Assertions evaluated after design executes
- Reactive : Testbench activity (program)
- Postponed : Read Only phase
rtr_io.cb.din[3] <= var_a; // legal
rtr_io.cb.din[3] = var_a; // error
rtr_io.cb.dout[3] >= var_a; // error
all_data = rtr_io.cb.dout; // legal
frm_out = rtr_io.frameo_n[7]; // error
$display("din = %b\n", rtr_io.cb.din); // error
if(rtr_io.cb.din[3] == 1'b0) begin ... end // error
if (rtr_io.cb.frameo_n[7] !== 1'b0)
@(rtr_io.cb iff(rtr_io.cb.frameo_n[7] === 1'b0));
wait (rtr_io.cb.frameo_n[7] === 1'b0);
wait (rtr_io.cb.frameo_n[7] !== 1'b0);
@(rtr_io.cb iff(rtr_io.cb.frameo_n[7] === 1'b0));
@(negedge rtr_io.cb.frameo_n[7]);
initial begin: proc_user_args
int user_seed;
if ($value$plusargs("ntb_random_seed=%d", user_seed))
$display("User seed is %d", user_seed);
else
$display("Using default seed");
end: proc_user_args
> ./simv +ntb_random_seed=100
$value$plusargs()
사용해서+argument
받을 수 있음