mirror of
https://github.com/verilator/verilator.git
synced 2025-01-21 05:44:03 +00:00
137 lines
2.9 KiB
Systemverilog
137 lines
2.9 KiB
Systemverilog
// Copyright 2003 by Wilson Snyder. This program is free software; you
|
|
// can redistribute it and/or modify it under the terms of either the GNU
|
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
|
// Version 2.0.
|
|
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
|
// Create stimulus and Drive the interface
|
|
class DriverStim;
|
|
protected virtual example_if v_if;
|
|
|
|
task run();
|
|
bit[7:0] x;
|
|
bit[7:0] y;
|
|
|
|
v_if.reset();
|
|
forever begin
|
|
x++;
|
|
y++;
|
|
|
|
$display("[DriverStim] initiating calculation, x: %8b y: %8b", x, y);
|
|
v_if.initiate_calculation(x, y);
|
|
end
|
|
endtask: run
|
|
|
|
function void bind_if(virtual example_if v_if);
|
|
this.v_if = v_if;
|
|
endfunction: bind_if
|
|
endclass: DriverStim
|
|
// Monitor returns from interface and check them
|
|
class MonitorCheck;
|
|
localparam NUM_TXNS = 10;
|
|
protected virtual example_if v_if;
|
|
|
|
task run();
|
|
logic[8:0] result;
|
|
int txns_received = 0;
|
|
|
|
forever begin
|
|
v_if.wait_for_result(result);
|
|
$display(
|
|
"[MonitorCheck] (%d) result %7b carry_out %1b",
|
|
txns_received, result[7:0], result[8]
|
|
);
|
|
if(++txns_received == NUM_TXNS) begin
|
|
$write("*-* All Finished *-*\n");
|
|
$finish();
|
|
end
|
|
end
|
|
endtask: run
|
|
|
|
function void bind_if(virtual example_if v_if);
|
|
this.v_if = v_if;
|
|
endfunction: bind_if
|
|
endclass: MonitorCheck
|
|
|
|
module example(
|
|
input logic clk,
|
|
input logic rstn,
|
|
input logic[7:0] x,
|
|
input logic[7:0] y,
|
|
output logic[8:0] z
|
|
);
|
|
|
|
// 8 bit full adder
|
|
always_ff @(posedge clk)
|
|
if(!rstn) z <= '0;
|
|
else z <= x + y;
|
|
endmodule: example
|
|
// interfaces with the DUT
|
|
|
|
interface example_if();
|
|
localparam CLK_FREQ_MHz = 400;
|
|
localparam CLK_PERIOD = 1/((CLK_FREQ_MHz * 1e6) * (1e-12));
|
|
|
|
logic clk;
|
|
logic rstn;
|
|
logic[7:0] x;
|
|
logic[7:0] y;
|
|
logic[8:0] z;
|
|
|
|
initial begin: clk_gen
|
|
forever #(CLK_PERIOD/2) clk = !clk;
|
|
end: clk_gen
|
|
|
|
task reset();
|
|
$display("reset called");
|
|
rstn = 0;
|
|
@(posedge clk);
|
|
$display("clock tick");
|
|
rstn = 1;
|
|
@(posedge clk);
|
|
endtask: reset
|
|
|
|
event calc_clkd;
|
|
task initiate_calculation(
|
|
input logic[7:0] x_in,
|
|
input logic[7:0] y_in
|
|
);
|
|
|
|
x = x_in;
|
|
y = y_in;
|
|
@(posedge clk);
|
|
->calc_clkd;
|
|
endtask: initiate_calculation
|
|
|
|
task wait_for_result(output logic[8:0] result);
|
|
@(calc_clkd);
|
|
result = z;
|
|
endtask: wait_for_result
|
|
endinterface: example_if
|
|
|
|
module t(/*AUTOARG*/);
|
|
|
|
example_if example_if_inst();
|
|
|
|
example DUT(
|
|
.clk (example_if_inst.clk),
|
|
.rstn(example_if_inst.rstn),
|
|
.x (example_if_inst.x),
|
|
.y (example_if_inst.y),
|
|
.z (example_if_inst.z)
|
|
);
|
|
|
|
|
|
initial begin: main
|
|
DriverStim driverStim = new();
|
|
MonitorCheck monitorCheck = new();
|
|
|
|
driverStim.bind_if(example_if_inst);
|
|
monitorCheck.bind_if(example_if_inst);
|
|
|
|
fork
|
|
driverStim.run();
|
|
monitorCheck.run();
|
|
join_none
|
|
end: main
|
|
endmodule: t
|