From 1b343e7b11a853e53d4b9cb9c6ab493e0ed3343b Mon Sep 17 00:00:00 2001 From: Florian Zaruba Date: Mon, 1 May 2017 12:28:55 +0200 Subject: [PATCH] :bug: Fix combinatorial access in driver --- Makefile | 2 +- tb/agents/mem_if/mem_if_driver.svh | 54 +++++++++++-------- tb/agents/mem_if/mem_if_seq_item.svh | 5 +- tb/test/mem_arbiter/mem_arbiter_sequence.svh | 24 +++++++++ .../mem_arbiter/mem_arbiter_sequence_pkg.sv | 2 +- tb/test/mem_arbiter/mem_arbiter_test.svh | 22 +++++--- 6 files changed, 76 insertions(+), 33 deletions(-) create mode 100755 tb/test/mem_arbiter/mem_arbiter_sequence.svh diff --git a/Makefile b/Makefile index d4a5fa5e6..3180f89d5 100644 --- a/Makefile +++ b/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 \ diff --git a/tb/agents/mem_if/mem_if_driver.svh b/tb/agents/mem_if/mem_if_driver.svh index 7f80fad39..f0403fa12 100644 --- a/tb/agents/mem_if/mem_if_driver.svh +++ b/tb/agents/mem_if/mem_if_driver.svh @@ -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 diff --git a/tb/agents/mem_if/mem_if_seq_item.svh b/tb/agents/mem_if/mem_if_seq_item.svh index 92f5f1b90..b2dd50b99 100644 --- a/tb/agents/mem_if/mem_if_seq_item.svh +++ b/tb/agents/mem_if/mem_if_seq_item.svh @@ -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 //------------------------------------------ diff --git a/tb/test/mem_arbiter/mem_arbiter_sequence.svh b/tb/test/mem_arbiter/mem_arbiter_sequence.svh new file mode 100755 index 000000000..0f7a39577 --- /dev/null +++ b/tb/test/mem_arbiter/mem_arbiter_sequence.svh @@ -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 diff --git a/tb/test/mem_arbiter/mem_arbiter_sequence_pkg.sv b/tb/test/mem_arbiter/mem_arbiter_sequence_pkg.sv index c1dddec16..9c1ff28c4 100644 --- a/tb/test/mem_arbiter/mem_arbiter_sequence_pkg.sv +++ b/tb/test/mem_arbiter/mem_arbiter_sequence_pkg.sv @@ -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 diff --git a/tb/test/mem_arbiter/mem_arbiter_test.svh b/tb/test/mem_arbiter/mem_arbiter_test.svh index 2a0393a3a..1fa87f4a4 100644 --- a/tb/test/mem_arbiter/mem_arbiter_test.svh +++ b/tb/test/mem_arbiter/mem_arbiter_test.svh @@ -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