🐛 Fix combinatorial access in driver

This commit is contained in:
Florian Zaruba 2017-05-01 12:28:55 +02:00
parent 97a9336ad8
commit 1b343e7b11
6 changed files with 76 additions and 33 deletions

View file

@ -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 \

View file

@ -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

View file

@ -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
//------------------------------------------

View 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

View file

@ -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

View file

@ -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