mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 21:57:11 -04:00
🐛 Fix combinatorial access in driver
This commit is contained in:
parent
97a9336ad8
commit
1b343e7b11
6 changed files with 76 additions and 33 deletions
2
Makefile
2
Makefile
|
@ -71,7 +71,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} +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 \
|
||||
|
|
|
@ -50,12 +50,15 @@ class mem_if_driver extends uvm_driver #(mem_if_seq_item);
|
|||
forever begin
|
||||
slave_data_gnt = 1'b0;
|
||||
fu.data_gnt_driver = slave_data_gnt;
|
||||
// wait until we got a valid request
|
||||
wait (fu.data_req);
|
||||
// randomize grant delay
|
||||
repeat ($urandom_range(0,4)) @(fu.mck);
|
||||
// randomize grant delay - the grant may come in the same clock cycle
|
||||
repeat ($urandom_range(0,3)) @(fu.mck);
|
||||
// now set the grant to one
|
||||
slave_data_gnt = 1'b1;
|
||||
fu.data_gnt_driver = slave_data_gnt;
|
||||
wait (~fu.data_req);
|
||||
@(fu.mck);
|
||||
// do we have another request?
|
||||
end
|
||||
end
|
||||
slave_serve: begin
|
||||
|
@ -65,20 +68,22 @@ class mem_if_driver extends uvm_driver #(mem_if_seq_item);
|
|||
@(fu.mck)
|
||||
fu.mck.data_rvalid <= 1'b0;
|
||||
fork
|
||||
// replay interface
|
||||
imem_read: begin
|
||||
@(fu.mck);
|
||||
if (slave_data_gnt) begin
|
||||
// $display("Time: %t, Pushing", $time);
|
||||
address.push_back(fu.mck.address);
|
||||
if (address.size() != 0) begin
|
||||
// we an wait a couple of cycles here
|
||||
repeat (3) @(fu.mck);
|
||||
fu.mck.data_rvalid <= 1'b1;
|
||||
addr = address.pop_front();
|
||||
fu.mck.data_rdata <= addr;
|
||||
end else
|
||||
fu.mck.data_rvalid <= 1'b0;
|
||||
end
|
||||
// $display("Time: %t, Pushing", $time);
|
||||
address.push_back(fu.mck.address);
|
||||
if (address.size() != 0) begin
|
||||
// we an wait a couple of cycles here
|
||||
// but at least one
|
||||
repeat ($urandom_range(1,3)) @(fu.mck);
|
||||
fu.mck.data_rvalid <= 1'b1;
|
||||
addr = address.pop_front();
|
||||
fu.mck.data_rdata <= addr;
|
||||
end else
|
||||
fu.mck.data_rvalid <= 1'b0;
|
||||
end
|
||||
end
|
||||
imem_write: begin
|
||||
|
||||
|
@ -87,6 +92,7 @@ class mem_if_driver extends uvm_driver #(mem_if_seq_item);
|
|||
end
|
||||
end
|
||||
join_none
|
||||
|
||||
// although no other option exist lets be specific about its purpose
|
||||
// this is a master interface
|
||||
end else if (m_cfg.mem_if_config == MASTER) begin
|
||||
|
@ -104,17 +110,19 @@ class mem_if_driver extends uvm_driver #(mem_if_seq_item);
|
|||
// we don't care about results at this point
|
||||
forever begin
|
||||
seq_item_port.get_next_item(cmd);
|
||||
do begin
|
||||
fu.sck.data_req <= 1'b1;
|
||||
fu.sck.address <= cmd.address;
|
||||
fu.sck.data_be <= cmd.be;
|
||||
fu.sck.data_we <= (cmd.mode == READ) ? 1'b0 : 1'b1;
|
||||
fu.sck.data_wdata <= cmd.data;
|
||||
@(fu.sck);
|
||||
end while (~fu.data_gnt);
|
||||
end
|
||||
do begin
|
||||
fu.sck.data_req <= 1'b1;
|
||||
fu.sck.address <= cmd.address;
|
||||
fu.sck.data_be <= cmd.be;
|
||||
fu.sck.data_we <= (cmd.mode == READ) ? 1'b0 : 1'b1;
|
||||
fu.sck.data_wdata <= cmd.data;
|
||||
@(fu.sck);
|
||||
end while (~fu.sck.data_gnt);
|
||||
fu.sck.data_req <= 1'b0;
|
||||
// delay the next request
|
||||
repeat(cmd.requestDelay) @(fu.sck);
|
||||
seq_item_port.item_done();
|
||||
end
|
||||
end
|
||||
endtask : run_phase
|
||||
|
||||
|
|
|
@ -25,9 +25,12 @@ class mem_if_seq_item extends uvm_sequence_item;
|
|||
rand logic [63:0] address;
|
||||
rand logic [63:0] data;
|
||||
rand logic [7:0] be;
|
||||
rand int grantDelay;
|
||||
rand int requestDelay;
|
||||
mode_t mode;
|
||||
|
||||
constraint delay_bounds {
|
||||
requestDelay inside {[0:10]};
|
||||
}
|
||||
//------------------------------------------
|
||||
// Methods
|
||||
//------------------------------------------
|
||||
|
|
24
tb/test/mem_arbiter/mem_arbiter_sequence.svh
Executable file
24
tb/test/mem_arbiter/mem_arbiter_sequence.svh
Executable file
|
@ -0,0 +1,24 @@
|
|||
class mem_arbiter_sequence extends mem_if_sequence;
|
||||
|
||||
`uvm_object_utils(mem_arbiter_sequence);
|
||||
|
||||
function new(string name = "mem_arbiter_sequence");
|
||||
super.new(name);
|
||||
endfunction : new
|
||||
|
||||
task body();
|
||||
mem_if_seq_item command;
|
||||
|
||||
command = mem_if_seq_item::type_id::create("command");
|
||||
`uvm_info("Mem Arbiter Sequence", "Starting mem_arbiter sequence", UVM_LOW)
|
||||
|
||||
for(int i = 0; i <= 100; i++) begin
|
||||
start_item(command);
|
||||
|
||||
void'(command.randomize());
|
||||
|
||||
finish_item(command);
|
||||
end
|
||||
`uvm_info("Mem Arbiter Sequence", "Finished mem_arbiter sequence", UVM_LOW)
|
||||
endtask : body
|
||||
endclass : mem_arbiter_sequence
|
|
@ -22,5 +22,5 @@ import uvm_pkg::*;
|
|||
|
||||
`include "uvm_macros.svh"
|
||||
// Include your sequences here e.g.:
|
||||
// `include "fibonacci_sequence.svh"
|
||||
`include "mem_arbiter_sequence.svh"
|
||||
endpackage
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
class mem_arbiter_test extends mem_arbiter_test_base;
|
||||
// UVM Factory Registration Macro
|
||||
`uvm_component_utils(mem_arbiter_test)
|
||||
// TODO: declare sequence here
|
||||
// mem_arbiter_sequence mem_arbiter;
|
||||
mem_arbiter_sequence mem_arbiter_sequences[3];
|
||||
//------------------------------------------
|
||||
// Methods
|
||||
//------------------------------------------
|
||||
|
@ -32,17 +31,26 @@ class mem_arbiter_test extends mem_arbiter_test_base;
|
|||
super.build_phase(phase);
|
||||
endfunction
|
||||
|
||||
// start the sequencer with number sequencer
|
||||
task start_sequence(int sequencer);
|
||||
mem_arbiter_sequences[sequencer] = new({"mem_arbiter_sequences", sequencer});
|
||||
mem_arbiter_sequences[sequencer].start(sequencer_h[sequencer]);
|
||||
endtask
|
||||
|
||||
task run_phase(uvm_phase phase);
|
||||
phase.raise_objection(this, "mem_arbiter_test");
|
||||
#200ns;
|
||||
//fibonacci_sequence fibonacci;
|
||||
super.run_phase(phase);
|
||||
|
||||
// mem_arbiter = new("mem_arbiter");
|
||||
// TODO: Start sequence here
|
||||
// mem_arbiter.start(sequencer_h);
|
||||
// fork three sequencers and wait for all of them to finish
|
||||
// until dropping the objection again
|
||||
fork
|
||||
start_sequence(0);
|
||||
start_sequence(1);
|
||||
start_sequence(2);
|
||||
join
|
||||
// Testlogic goes here
|
||||
#100ns;
|
||||
|
||||
phase.drop_objection(this, "mem_arbiter_test");
|
||||
endtask
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue