mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 21:57:11 -04:00
Converging mem arbiter tb to a UVM TB
This commit is contained in:
parent
f0455a09cf
commit
9472444bdf
2 changed files with 14 additions and 198 deletions
4
Makefile
4
Makefile
|
@ -18,9 +18,7 @@ envs = $(wildcard tb/env/*/*.sv)
|
|||
# UVM Sequences
|
||||
sequences = $(wildcard tb/sequences/*/*.sv)
|
||||
# Test packages
|
||||
test_pkg = tb/test/alu/alu_lib_pkg.sv
|
||||
|
||||
src2obj = $(addsuffix /_primary.dat, $(addprefix $(library)/, $(basename $(notdir $(1)))))
|
||||
test_pkg =tb/test/mem_arbiter/mem_arbiter_sequence_pkg.sv $(wildcard tb/test/*/*.sv)
|
||||
|
||||
# this list contains the standalone components
|
||||
src = alu.sv if_stage.sv compressed_decoder.sv mem_arbiter.sv decoder.sv \
|
||||
|
|
|
@ -19,11 +19,12 @@
|
|||
//
|
||||
|
||||
module mem_arbiter_tb;
|
||||
logic rst_ni, clk;
|
||||
logic end_test;
|
||||
|
||||
logic flush_ready_o;
|
||||
logic slave_data_gnt, slave_data_req;
|
||||
import uvm_pkg::*;
|
||||
// import the main test class
|
||||
import mem_arbiter_lib_pkg::*;
|
||||
|
||||
logic rst_ni, clk;
|
||||
|
||||
mem_if master[3](clk);
|
||||
mem_if slave(clk);
|
||||
|
@ -63,199 +64,16 @@ module mem_arbiter_tb;
|
|||
#10ns clk = ~clk;
|
||||
end
|
||||
|
||||
initial begin
|
||||
end_test = 1'b0;
|
||||
|
||||
#1000000ns;
|
||||
|
||||
end_test = 1'b1;
|
||||
|
||||
end
|
||||
|
||||
|
||||
assign slave.data_gnt = slave_data_gnt;
|
||||
|
||||
program testbench (mem_if master[3], mem_if slave, input flush_ready);
|
||||
// --------------
|
||||
// Slave Port
|
||||
// --------------
|
||||
logic [7:0] imem [400];
|
||||
logic [63:0] address [$];
|
||||
logic [63:0] addr;
|
||||
// grant process
|
||||
program testbench (mem_if master[3], mem_if slave);
|
||||
initial begin
|
||||
|
||||
forever begin
|
||||
slave_data_gnt = 1'b0;
|
||||
wait (slave.data_req);
|
||||
// randomize grant delay
|
||||
repeat ($urandom_range(0,4)) @(slave.mck);
|
||||
slave_data_gnt = 1'b1;
|
||||
wait (~slave.data_req);
|
||||
end
|
||||
end
|
||||
// instruction memory
|
||||
initial begin
|
||||
slave.mck.data_rdata <= 32'b0;
|
||||
// apply stimuli for instruction interface
|
||||
forever begin
|
||||
@(slave.mck)
|
||||
slave.mck.data_rvalid <= 1'b0;
|
||||
fork
|
||||
imem_read: begin
|
||||
@(slave.mck);
|
||||
if (slave_data_gnt) begin
|
||||
// $display("Time: %t, Pushing", $time);
|
||||
address.push_back(slave.mck.address);
|
||||
if (address.size() != 0) begin
|
||||
// we an wait a couple of cycles here
|
||||
repeat (3) @(slave.mck);
|
||||
slave.mck.data_rvalid <= 1'b1;
|
||||
addr = address.pop_front();
|
||||
slave.mck.data_rdata <= addr;
|
||||
end else
|
||||
slave.mck.data_rvalid <= 1'b0;
|
||||
end
|
||||
end
|
||||
imem_write: begin
|
||||
|
||||
end
|
||||
join_none
|
||||
end
|
||||
end
|
||||
|
||||
// --------------
|
||||
// Master Ports
|
||||
// --------------
|
||||
// request a read
|
||||
initial begin
|
||||
// initial statements, sane resets
|
||||
master[0].sck.data_req <= 1'b0;
|
||||
master[0].sck.address <= 64'b0;
|
||||
master[0].sck.data_be <= 7'b0;
|
||||
master[0].sck.data_we <= 1'b0;
|
||||
master[0].sck.data_wdata <= 64'b0;
|
||||
|
||||
master[1].sck.data_req <= 1'b0;
|
||||
master[1].sck.address <= 64'b0;
|
||||
master[1].sck.data_be <= 7'b0;
|
||||
master[1].sck.data_we <= 1'b0;
|
||||
master[1].sck.data_wdata <= 64'b0;
|
||||
|
||||
master[2].sck.data_req <= 1'b0;
|
||||
master[2].sck.address <= 64'b0;
|
||||
master[2].sck.data_be <= 7'b0;
|
||||
master[2].sck.data_we <= 1'b0;
|
||||
master[2].sck.data_wdata <= 64'b0;
|
||||
|
||||
wait (rst_ni);
|
||||
|
||||
forever begin
|
||||
if (end_test)
|
||||
break;
|
||||
fork
|
||||
master0: begin
|
||||
// read request master 0
|
||||
do begin
|
||||
master[0].sck.data_req <= 1'b1;
|
||||
master[0].sck.address <= 64'b1;
|
||||
master[0].sck.data_be <= 7'b1011;
|
||||
master[0].sck.data_we <= 1'b0;
|
||||
master[0].sck.data_wdata <= 64'b0;
|
||||
|
||||
@(master[0].sck);
|
||||
end while (~master[0].data_gnt);
|
||||
master[0].sck.data_req <= 1'b0;
|
||||
// randomize response
|
||||
repeat ($urandom_range(0,10)) @(master[0].sck);
|
||||
end
|
||||
master1: begin
|
||||
// read request master 1
|
||||
do begin
|
||||
master[1].sck.data_req <= 1'b1;
|
||||
master[1].sck.address <= 64'h8;
|
||||
master[1].sck.data_be <= 7'b1011;
|
||||
master[1].sck.data_we <= 1'b0;
|
||||
master[1].sck.data_wdata <= 64'b0;
|
||||
|
||||
@(master[1].sck);
|
||||
end while (~master[1].data_gnt);
|
||||
master[1].sck.data_req <= 1'b0;
|
||||
// randomize response
|
||||
repeat ($urandom_range(0,10)) @(master[1].sck);
|
||||
end
|
||||
master2: begin
|
||||
// read request master 2
|
||||
do begin
|
||||
master[2].sck.data_req <= 1'b1;
|
||||
master[2].sck.address <= 64'hF;
|
||||
master[2].sck.data_be <= 7'b1011;
|
||||
master[2].sck.data_we <= 1'b0;
|
||||
master[2].sck.data_wdata <= 64'b0;
|
||||
|
||||
@(master[2].sck);
|
||||
end while (~master[2].data_gnt);
|
||||
master[2].sck.data_req <= 1'b0;
|
||||
// randomize response
|
||||
repeat ($urandom_range(0,10)) @(master[2].sck);
|
||||
end
|
||||
join_any
|
||||
end
|
||||
end
|
||||
|
||||
// ----------------------
|
||||
// Monitor & Scoreboard
|
||||
// ----------------------
|
||||
|
||||
initial begin
|
||||
|
||||
automatic int slave_count = 0;
|
||||
automatic int master_count [3] = {0, 0, 0};
|
||||
|
||||
fork
|
||||
slave_scoreboard: begin
|
||||
forever begin
|
||||
@(slave.pck iff slave.pck.data_rvalid);
|
||||
slave_count++;
|
||||
end
|
||||
end
|
||||
|
||||
master0_scoreboard: begin
|
||||
forever begin
|
||||
@(master[0].pck iff master[0].pck.data_rvalid);
|
||||
master_count[0]++;
|
||||
assert (master[0].pck.data_rdata == 64'h1) else $error("Mismatch @%t, expected: %0h got: %0h", $time, 64'h1, master[0].pck.data_rdata);
|
||||
end
|
||||
end
|
||||
|
||||
master1_scoreboard: begin
|
||||
forever begin
|
||||
@(master[1].pck iff master[1].pck.data_rvalid);
|
||||
master_count[1]++;
|
||||
assert (master[1].pck.data_rdata == 64'h8) else $error("Mismatch @%t, expected: %0h got: %0h", $time, 64'h8, master[1].pck.data_rdata);
|
||||
end
|
||||
end
|
||||
|
||||
master2_scoreboard: begin
|
||||
forever begin
|
||||
@(master[2].pck iff master[2].pck.data_rvalid);
|
||||
master_count[2]++;
|
||||
assert (master[2].pck.data_rdata == 64'hF) else $error("Mismatch @%t, expected: %0h got: %0h", $time, 64'hF, master[2].pck.data_rdata);
|
||||
end
|
||||
end
|
||||
|
||||
control_block: begin
|
||||
// Wait here for the end of test signal
|
||||
wait(end_test);
|
||||
// wait an additional time to be sure that all results got propagated
|
||||
wait(flush_ready);
|
||||
// check the result count
|
||||
assert(slave_count === master_count[0] + master_count[1] + master_count[2]) else $error("Mismatch in expected result count!");
|
||||
$stop;
|
||||
end
|
||||
join
|
||||
// register the ALU interface
|
||||
uvm_config_db #(virtual fu_if)::set(null, "uvm_test_top", "mem_if", slave);
|
||||
// print the topology
|
||||
uvm_top.enable_print_topology = 1;
|
||||
// Start UVM test
|
||||
run_test();
|
||||
end
|
||||
endprogram
|
||||
|
||||
testbench tb (master, slave, flush_ready_o);
|
||||
testbench tb (master, slave);
|
||||
endmodule
|
Loading…
Add table
Add a link
Reference in a new issue