mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-24 06:07:19 -04:00
Implement monitor of dcache interface, test passing
This commit is contained in:
parent
c1269588c4
commit
b2ad6f058e
3 changed files with 84 additions and 25 deletions
|
@ -73,16 +73,17 @@ class dcache_if_driver extends uvm_driver #(dcache_if_seq_item);
|
|||
if (m_vif.pck.data_gnt && m_vif.mck.data_req) begin
|
||||
// push the low portion of the address a.k.a. the index
|
||||
address_index.push_back(m_vif.mck.address_index);
|
||||
lock.get(1);
|
||||
// wait a couple of cycles, but at least one
|
||||
@(m_vif.mck);
|
||||
// in this cycle the tag is ready
|
||||
address_tag.push_back(m_vif.mck.address_tag);
|
||||
lock.get(1);
|
||||
// randomize rvalid here
|
||||
repeat ($urandom_range(0,2)) @(m_vif.mck);
|
||||
repeat ($urandom_range(1,2)) @(m_vif.mck);
|
||||
m_vif.mck.data_rvalid <= 1'b1;
|
||||
// compose the address
|
||||
address_out = {address_tag.pop_front(), address_index.pop_front()};
|
||||
m_vif.mck.data_rdata <= address_out;
|
||||
// put back the lock
|
||||
lock.put(1);
|
||||
end else
|
||||
|
@ -114,30 +115,30 @@ class dcache_if_driver extends uvm_driver #(dcache_if_seq_item);
|
|||
m_vif.sck.data_wdata <= 64'b0;
|
||||
// request read or write
|
||||
// we don't care about results at this point
|
||||
forever begin
|
||||
seq_item_port.get_next_item(cmd);
|
||||
// do begin
|
||||
m_vif.sck.data_req <= 1'b1;
|
||||
m_vif.sck.address_index <= cmd.address[11:0];
|
||||
m_vif.sck.data_be <= cmd.be;
|
||||
m_vif.sck.data_we <= (cmd.mode == READ) ? 1'b0 : 1'b1;
|
||||
m_vif.sck.data_wdata <= cmd.data;
|
||||
fork
|
||||
forever begin
|
||||
seq_item_port.get_next_item(cmd);
|
||||
// do begin
|
||||
m_vif.sck.data_req <= 1'b1;
|
||||
m_vif.sck.address_index <= cmd.address[11:0];
|
||||
m_vif.sck.data_be <= cmd.be;
|
||||
m_vif.sck.data_we <= (cmd.mode == READ) ? 1'b0 : 1'b1;
|
||||
m_vif.sck.data_wdata <= cmd.data;
|
||||
|
||||
@(m_vif.sck iff m_vif.sck.data_gnt);
|
||||
m_vif.sck.address_tag <= cmd.address[43:12];
|
||||
m_vif.sck.tag_valid <= 1'b1;
|
||||
m_vif.sck.data_req <= 1'b0;
|
||||
@(m_vif.sck iff m_vif.sck.data_gnt);
|
||||
m_vif.sck.address_tag <= cmd.address[43:12];
|
||||
m_vif.sck.data_req <= 1'b0;
|
||||
// delay the next request
|
||||
repeat (cmd.requestDelay) @(m_vif.sck);
|
||||
|
||||
// delay the next request
|
||||
// if there is delay, wait one clock cycle and set the tag valid back to zero
|
||||
if (cmd.requestDelay != 0) begin
|
||||
@(m_vif.sck);
|
||||
m_vif.sck.tag_valid <= 1'b0;
|
||||
seq_item_port.item_done();
|
||||
end
|
||||
repeat (cmd.requestDelay-1) @(m_vif.sck);
|
||||
|
||||
seq_item_port.item_done();
|
||||
end
|
||||
forever begin
|
||||
@(m_vif.sck);
|
||||
m_vif.sck.tag_valid <= m_vif.sck.data_gnt;
|
||||
end
|
||||
join_none
|
||||
end
|
||||
|
||||
seq_item_port.get_next_item(cmd);
|
||||
|
|
|
@ -26,6 +26,9 @@ class dcache_if_monitor extends uvm_component;
|
|||
// Virtual Interface
|
||||
virtual dcache_if m_vif;
|
||||
|
||||
mailbox address_mbx;
|
||||
mailbox data_mbx;
|
||||
|
||||
//---------------------
|
||||
// Data Members
|
||||
//---------------------
|
||||
|
@ -41,6 +44,8 @@ class dcache_if_monitor extends uvm_component;
|
|||
`uvm_fatal("CONFIG_LOAD", "Cannot get() configuration dcache_if_agent_config from uvm_config_db. Have you set() it?")
|
||||
|
||||
m_ap = new("m_ap", this);
|
||||
address_mbx = new();
|
||||
data_mbx = new();
|
||||
|
||||
endfunction: build_phase
|
||||
|
||||
|
@ -51,12 +56,63 @@ class dcache_if_monitor extends uvm_component;
|
|||
|
||||
task run_phase(uvm_phase phase);
|
||||
|
||||
string if_type = this.get_full_name();//(m_cfg.dcache_if_config inside {SLAVE, SLAVE_REPLAY, SLAVE_NO_RANDOM}) ? "[SLAVE]" : "[MASTER]";
|
||||
logic [11:0] address_index [$];
|
||||
logic [44:0] address;
|
||||
logic[7:0] be [$];
|
||||
|
||||
dcache_if_seq_item cmd = dcache_if_seq_item::type_id::create("cmd");
|
||||
dcache_if_seq_item cloned_item;
|
||||
// Monitor process
|
||||
fork
|
||||
// 1. Thread
|
||||
// detect a request
|
||||
req: begin
|
||||
forever begin
|
||||
@(m_vif.pck iff (m_vif.pck.data_gnt && m_vif.pck.data_req));
|
||||
// save tag and byte enable
|
||||
// $display("%s: %t, Putting index: %0h", if_type, $time(), m_vif.pck.address_index);
|
||||
address_index.push_back(m_vif.pck.address_index);
|
||||
be.push_back(m_vif.pck.data_be);
|
||||
end
|
||||
end
|
||||
|
||||
// 2. Thread
|
||||
// detect a valid tag and save it
|
||||
tag_valid: begin
|
||||
forever begin
|
||||
@(m_vif.pck iff m_vif.pck.tag_valid);
|
||||
// save tag for later use
|
||||
address_mbx.put({m_vif.pck.address_tag, address_index.pop_front()});
|
||||
|
||||
// $display("%s: %t, Putting Tag %0h, Queue Size: %d", if_type, $time(), m_vif.pck.address_tag, address_mbx.num());
|
||||
end
|
||||
end
|
||||
|
||||
// 3. thread wait for valid data
|
||||
read_valid: begin
|
||||
forever begin
|
||||
@(m_vif.pck iff m_vif.pck.data_rvalid);
|
||||
data_mbx.put(m_vif.pck.data_rdata);
|
||||
end
|
||||
end
|
||||
|
||||
respsonese_gen: begin
|
||||
forever begin
|
||||
dcache_if_seq_item cloned_item;
|
||||
|
||||
// blocking get, wait for both to be ready
|
||||
data_mbx.get(cmd.data);
|
||||
address_mbx.get(cmd.address);
|
||||
cmd.be = be.pop_front();
|
||||
// $display("%s: %t, Popping %0h from MBX", if_type, $time(), cmd.address);
|
||||
// was this from a master or slave agent monitor?
|
||||
cmd.isSlaveAnswer = (m_cfg.dcache_if_config inside {SLAVE, SLAVE_REPLAY, SLAVE_NO_RANDOM}) ? 1'b1 : 1'b0;
|
||||
$cast(cloned_item, cmd.clone());
|
||||
m_ap.write(cloned_item);
|
||||
end
|
||||
end
|
||||
join_any
|
||||
|
||||
$cast(cloned_item, cmd.clone());
|
||||
m_ap.write(cloned_item);
|
||||
|
||||
endtask : run_phase
|
||||
endclass : dcache_if_monitor
|
||||
|
|
|
@ -38,6 +38,8 @@ class mem_arbiter_scoreboard extends uvm_scoreboard;
|
|||
if (~seq_item.isSlaveAnswer) begin
|
||||
if (seq_item.address !== seq_item.data) begin
|
||||
`uvm_error( "DCache Arbiter Scoreboard", $sformatf("Got: %0h Expected: %0h", seq_item.address, seq_item.data) )
|
||||
end else begin
|
||||
// `uvm_info( "DCache Arbiter Scoreboard", $sformatf("Got: %0h Expected: %0h", seq_item.address, seq_item.data), UVM_LOW)
|
||||
end
|
||||
master_answer_cnt++;
|
||||
end else begin
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue