mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-24 06:07:19 -04:00
✅ Add store queue test, flush missing
This commit is contained in:
parent
26cf604ee0
commit
6131b1b7c8
4 changed files with 75 additions and 41 deletions
2
Makefile
2
Makefile
|
@ -57,7 +57,7 @@ $(tests):
|
|||
# Optimize top level
|
||||
vopt${questa_version} ${compile_flag} $@_tb -o $@_tb_optimized +acc -check_synthesis
|
||||
# vsim${questa_version} $@_tb_optimized
|
||||
# vsim${questa_version} -c +UVM_TESTNAME=$@_test -coverage -do "coverage save -onexit $@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]" $@_tb_optimized
|
||||
vsim${questa_version} -c +UVM_TESTNAME=$@_test -coverage -do "coverage save -onexit $@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]" $@_tb_optimized
|
||||
# User Verilator to lint the target
|
||||
lint:
|
||||
verilator ${src} --lint-only \
|
||||
|
|
|
@ -82,7 +82,7 @@ module store_queue (
|
|||
// if we got a grant this implies that the value was not speculative anymore and that we
|
||||
// do not need to save the values anymore since the memory already processed them
|
||||
automatic logic ready = ~commit_queue_q.valid | data_gnt_i;
|
||||
ready_o = ready;
|
||||
ready_o = ready & ~flush_i;
|
||||
|
||||
commit_queue_n = commit_queue_q;
|
||||
|
||||
|
|
|
@ -63,25 +63,47 @@ module store_queue_tb;
|
|||
end
|
||||
|
||||
// combinatorial signals
|
||||
assign store_queue.flush = 1'b0;
|
||||
assign store_queue.store_valid = store_valid & store_queue.ready;
|
||||
assign slave.data_gnt = slave_data_gnt;
|
||||
|
||||
// simulator stopper, this is suboptimal better go for coverage
|
||||
initial begin
|
||||
#10000000ns
|
||||
#1000000ns
|
||||
$stop;
|
||||
end
|
||||
|
||||
program testbench (mem_if slave, store_queue_if store_queue);
|
||||
// data to store
|
||||
class store_data;
|
||||
rand logic [63:0] address;
|
||||
rand logic [63:0] data;
|
||||
rand logic [7:0] be;
|
||||
|
||||
function new (logic [63:0] address, logic [63:0] data, logic [7:0] be);
|
||||
this.address = address;
|
||||
this.data = data;
|
||||
this.be = be;
|
||||
endfunction : new
|
||||
|
||||
function string convert2string();
|
||||
string s;
|
||||
$sformat(s, "Address: %0h, Data: %0h, BE: %0h", address, data, be);
|
||||
return s;
|
||||
endfunction : convert2string
|
||||
|
||||
function bit do_compare(store_data rhs);
|
||||
|
||||
if (rhs.address == address && rhs.data == data && rhs.be == be)
|
||||
return 1;
|
||||
else return 0;
|
||||
|
||||
endfunction : do_compare
|
||||
|
||||
endclass : store_data
|
||||
|
||||
store_data data = new();
|
||||
store_data data = new(64'b0, 64'b0, 8'b0);
|
||||
semaphore sem = new(1);
|
||||
logic flush;
|
||||
// ----------
|
||||
// Driver
|
||||
// ----------
|
||||
|
@ -98,22 +120,23 @@ module store_queue_tb;
|
|||
|
||||
forever begin
|
||||
@(store_queue.mck);
|
||||
store_queue.mck.commit <= 1'b0;
|
||||
if (store_queue.mck.ready) begin
|
||||
store_queue.mck.store_paddr <= 64'h1;
|
||||
store_valid <= 1'b1;
|
||||
// get some randomized data
|
||||
void'(data.randomize());
|
||||
store_queue.mck.store_data <= data.data;
|
||||
store_queue.mck.store_be <= data.be;
|
||||
store_queue.mck.store_paddr <= data.address;
|
||||
store_queue.mck.store_data <= data.data;
|
||||
store_queue.mck.store_be <= data.be;
|
||||
store_valid <= 1'b1;
|
||||
|
||||
// commit a couple of cycles later
|
||||
fork
|
||||
commit_block: begin
|
||||
sem.get(1);
|
||||
@(store_queue.mck);
|
||||
@(store_queue.mck);
|
||||
@(store_queue.mck)
|
||||
wait(~flush);
|
||||
store_queue.mck.commit <= 1'b1;
|
||||
@(store_queue.mck)
|
||||
store_queue.mck.commit <= 1'b0;
|
||||
sem.put(1);
|
||||
end
|
||||
join_none
|
||||
|
@ -123,10 +146,6 @@ module store_queue_tb;
|
|||
end
|
||||
end
|
||||
|
||||
end
|
||||
// commit part
|
||||
initial begin
|
||||
|
||||
end
|
||||
|
||||
// grant process
|
||||
|
@ -152,13 +171,51 @@ module store_queue_tb;
|
|||
end
|
||||
end
|
||||
|
||||
// random flush signal
|
||||
initial begin
|
||||
flush = 1'b0;
|
||||
store_queue.mck.flush <= 0;
|
||||
forever begin
|
||||
repeat (20) @(store_queue.mck);
|
||||
// TODO: Implement Flush test, needs some more test logic
|
||||
store_queue.mck.flush <= 0;
|
||||
flush = 1'b1;
|
||||
repeat (4) @(store_queue.mck);
|
||||
store_queue.mck.flush <= 0;
|
||||
flush = 1'b0;
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
// -------------------
|
||||
// Monitor && Checker
|
||||
// -------------------
|
||||
|
||||
store_data request_data_queue [$];
|
||||
store_data tmp;
|
||||
store_data result;
|
||||
// check that all requested stores got through
|
||||
// therefore put them in a queue when requested from the LSU and check them on the
|
||||
// memory interface output
|
||||
initial begin
|
||||
forever begin
|
||||
@(store_queue.pck iff store_queue.pck.store_valid)
|
||||
tmp = new(store_queue.pck.store_paddr, store_queue.pck.store_data, store_queue.pck.store_be);
|
||||
request_data_queue.push_back(tmp);
|
||||
// $display("[LSU] Got: %s", tmp.convert2string());
|
||||
end
|
||||
end
|
||||
// check here what we actually got on the memory interface
|
||||
initial begin
|
||||
automatic store_data queue_data;
|
||||
|
||||
forever begin
|
||||
@(slave.pck iff slave.pck.data_req & slave.pck.data_gnt)
|
||||
result = new(slave.pck.address, slave.pck.data_wdata, slave.pck.data_be);
|
||||
// $display("[MEM] Got: %s", result.convert2string());
|
||||
// pop from queue and check if this was indeed requested
|
||||
queue_data = request_data_queue.pop_front();
|
||||
assert(queue_data.do_compare(result)) else $error("Mismatch: Expected %s, Got: %s", queue_data.convert2string() , result.convert2string());
|
||||
end
|
||||
end
|
||||
|
||||
endprogram
|
||||
|
|
|
@ -1,29 +1,6 @@
|
|||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate /store_queue_tb/dut/clk_i
|
||||
add wave -noupdate /store_queue_tb/dut/rst_ni
|
||||
add wave -noupdate /store_queue_tb/dut/flush_i
|
||||
add wave -noupdate /store_queue_tb/dut/paddr_o
|
||||
add wave -noupdate /store_queue_tb/dut/data_o
|
||||
add wave -noupdate /store_queue_tb/dut/valid_o
|
||||
add wave -noupdate /store_queue_tb/dut/be_o
|
||||
add wave -noupdate /store_queue_tb/dut/commit_i
|
||||
add wave -noupdate /store_queue_tb/dut/ready_o
|
||||
add wave -noupdate /store_queue_tb/dut/valid_i
|
||||
add wave -noupdate /store_queue_tb/dut/paddr_i
|
||||
add wave -noupdate /store_queue_tb/dut/data_i
|
||||
add wave -noupdate /store_queue_tb/dut/be_i
|
||||
add wave -noupdate /store_queue_tb/dut/address_o
|
||||
add wave -noupdate /store_queue_tb/dut/data_wdata_o
|
||||
add wave -noupdate /store_queue_tb/dut/data_req_o
|
||||
add wave -noupdate /store_queue_tb/dut/data_we_o
|
||||
add wave -noupdate /store_queue_tb/dut/data_be_o
|
||||
add wave -noupdate /store_queue_tb/dut/data_gnt_i
|
||||
add wave -noupdate /store_queue_tb/dut/data_rvalid_i
|
||||
add wave -noupdate /store_queue_tb/dut/CS
|
||||
add wave -noupdate /store_queue_tb/dut/NS
|
||||
add wave -noupdate /store_queue_tb/dut/commit_queue_n
|
||||
add wave -noupdate /store_queue_tb/dut/commit_queue_q
|
||||
add wave -noupdate /store_queue_tb/dut/*
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {0 ns} 0}
|
||||
quietly wave cursor active 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue