From 91a887da478247dd2af72415d92334d08b1d6d84 Mon Sep 17 00:00:00 2001 From: Florian Zaruba Date: Mon, 29 May 2017 14:46:32 +0200 Subject: [PATCH] Add dcache interface as an agent --- tb/agents/dcache_if/dcache_if.sv | 64 +++++++++++++ tb/agents/dcache_if/dcache_if_agent.svh | 57 ++++++++++++ .../dcache_if/dcache_if_agent_config.svh | 37 ++++++++ tb/agents/dcache_if/dcache_if_agent_pkg.sv | 37 ++++++++ tb/agents/dcache_if/dcache_if_driver.svh | 47 ++++++++++ tb/agents/dcache_if/dcache_if_monitor.svh | 62 +++++++++++++ tb/agents/dcache_if/dcache_if_seq_item.svh | 89 +++++++++++++++++++ tb/agents/dcache_if/dcache_if_sequence.svh | 53 +++++++++++ tb/agents/dcache_if/dcache_if_sequencer.svh | 29 ++++++ tb/mem_arbiter_tb.sv | 40 +++++---- 10 files changed, 498 insertions(+), 17 deletions(-) create mode 100755 tb/agents/dcache_if/dcache_if.sv create mode 100644 tb/agents/dcache_if/dcache_if_agent.svh create mode 100644 tb/agents/dcache_if/dcache_if_agent_config.svh create mode 100644 tb/agents/dcache_if/dcache_if_agent_pkg.sv create mode 100644 tb/agents/dcache_if/dcache_if_driver.svh create mode 100644 tb/agents/dcache_if/dcache_if_monitor.svh create mode 100644 tb/agents/dcache_if/dcache_if_seq_item.svh create mode 100644 tb/agents/dcache_if/dcache_if_sequence.svh create mode 100644 tb/agents/dcache_if/dcache_if_sequencer.svh diff --git a/tb/agents/dcache_if/dcache_if.sv b/tb/agents/dcache_if/dcache_if.sv new file mode 100755 index 000000000..6e2a8eda1 --- /dev/null +++ b/tb/agents/dcache_if/dcache_if.sv @@ -0,0 +1,64 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 29.05.2017 +// Description: DCache interface +// +// Copyright (C) 2017 ETH Zurich, University of Bologna +// All rights reserved. +// +// This code is under development and not yet released to the public. +// Until it is released, the code is under the copyright of ETH Zurich and +// the University of Bologna, and may contain confidential and/or unpublished +// work. Any reuse/redistribution is strictly forbidden without written +// permission from ETH Zurich. +// +// Bug fixes and contributions will eventually be released under the +// SolderPad open hardware license in the context of the PULP platform +// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the +// University of Bologna. +// +// Guard statement proposed by "Easier UVM" (doulos) +`ifndef DCACHE_IF_SV +`define DCACHE_IF_SV +interface dcache_if + ( + input clk + ); + wire [11:0] address_index; // Index portion of address + wire [43:0] address_tag; // Tag portion of the address + wire [63:0] data_wdata; // Data to be written + wire data_req; // Requests read data + wire data_gnt; // Request has been granted, signals can be changed as + // soon as request has been granted + wire kill_req; // Request to kill the previous request + wire tag_valid; // The tag (or kill request) is valid + wire data_rvalid; // Read data is valid + wire [63:0] data_rdata; // Read data + wire data_we; // Write enable + wire [7:0] data_be; // Byte enable + + clocking mck @(posedge clk); + input address_index, address_tag, data_wdata, data_we, data_req, kill_req, tag_valid, data_be; + output data_rvalid, data_rdata, data_gnt; + endclocking + + // Memory interface configured as slave + clocking sck @(posedge clk); + output address_index, address_tag, data_wdata, data_we, data_req, kill_req, tag_valid, data_be; + input data_rvalid, data_rdata, data_gnt; + endclocking + + clocking pck @(posedge clk); + // default input #1ns output #1ns; + input address_index, address_tag, data_wdata, data_req, data_we, data_be, kill_req, tag_valid, + data_gnt, data_rvalid, data_rdata; + endclocking + + modport master ( + clocking mck + ); + modport slave ( + clocking sck + ); +endinterface + +`endif \ No newline at end of file diff --git a/tb/agents/dcache_if/dcache_if_agent.svh b/tb/agents/dcache_if/dcache_if_agent.svh new file mode 100644 index 000000000..c16f280a8 --- /dev/null +++ b/tb/agents/dcache_if/dcache_if_agent.svh @@ -0,0 +1,57 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 29.05.2017 +// Description: Main agent object dcache_if. Builds and instantiates the appropriate +// subcomponents like the monitor, driver etc. all based on the +// agent configuration object. +// Copyright (C) 2017 ETH Zurich, University of Bologna +// All rights reserved. +// This code is under development and not yet released to the public. +// Until it is released, the code is under the copyright of ETH Zurich and +// the University of Bologna, and may contain confidential and/or unpublished +// work. Any reuse/redistribution is strictly forbidden without written +// permission from ETH Zurich. +// Bug fixes and contributions will eventually be released under the +// SolderPad open hardware license in the context of the PULP platform +// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the +// University of Bologna. + +class dcache_if_agent extends uvm_component; + // UVM Factory Registration Macro + `uvm_component_utils(dcache_if_agent) + //------------------------------------------ + // Data Members + //------------------------------------------ + dcache_if_agent_config m_cfg; + //------------------------------------------ + // Component Members + //------------------------------------------ + uvm_analysis_port #(dcache_if_seq_item) ap; + dcache_if_driver m_driver; + dcache_if_monitor m_monitor; + dcache_if_sequencer m_sequencer; + //------------------------------------------ + // Methods + //------------------------------------------ + // Standard UVM Methods: + function new(string name = "dcache_if_agent", uvm_component parent = null); + super.new(name, parent); + endfunction : new + + function void build_phase(uvm_phase phase); + if (!uvm_config_db #(dcache_if_agent_config)::get(this, "", "dcache_if_agent_config", m_cfg) ) + `uvm_fatal("CONFIG_LOAD", "Cannot get() configuration dcache_if_agent_config from uvm_config_db. Have you set() it?") + + m_driver = dcache_if_driver::type_id::create("m_driver", this); + m_sequencer = dcache_if_sequencer::type_id::create("m_sequencer", this); + m_monitor = dcache_if_monitor::type_id::create("m_monitor", this); + endfunction : build_phase + + function void connect_phase(uvm_phase phase); + + m_driver.seq_item_port.connect(m_sequencer.seq_item_export); + // m_monitor.ap.connect(m_cov_monitor.analysis_port) + m_driver.m_cfg = m_cfg; + m_monitor.m_cfg = m_cfg; + + endfunction: connect_phase +endclass : dcache_if_agent diff --git a/tb/agents/dcache_if/dcache_if_agent_config.svh b/tb/agents/dcache_if/dcache_if_agent_config.svh new file mode 100644 index 000000000..eab281056 --- /dev/null +++ b/tb/agents/dcache_if/dcache_if_agent_config.svh @@ -0,0 +1,37 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 29.05.2017 +// Description: Agent configuration object dcache_if +// Copyright (C) 2017 ETH Zurich, University of Bologna +// All rights reserved. +// This code is under development and not yet released to the public. +// Until it is released, the code is under the copyright of ETH Zurich and +// the University of Bologna, and may contain confidential and/or unpublished +// work. Any reuse/redistribution is strictly forbidden without written +// permission from ETH Zurich. +// Bug fixes and contributions will eventually be released under the +// SolderPad open hardware license in the context of the PULP platform +// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the +// University of Bologna. + +class dcache_if_agent_config extends uvm_object; + + // UVM Factory Registration Macro + `uvm_object_utils(dcache_if_agent_config) + + // Virtual Interface + virtual dcache_if m_vif; + //------------------------------------------ + // Data Members + //------------------------------------------ + // Is the agent active or passive + uvm_active_passive_enum active = UVM_ACTIVE; + + // Standard UVM Methods: + function new(string name = "dcache_if_agent_config"); + super.new(name); + endfunction : new + +endclass : dcache_if_agent_config + + + diff --git a/tb/agents/dcache_if/dcache_if_agent_pkg.sv b/tb/agents/dcache_if/dcache_if_agent_pkg.sv new file mode 100644 index 000000000..d5084bf7f --- /dev/null +++ b/tb/agents/dcache_if/dcache_if_agent_pkg.sv @@ -0,0 +1,37 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 29.05.2017 +// Description: dcache_if_agent package - compile unit +// Copyright (C) 2017 ETH Zurich, University of Bologna +// All rights reserved. +// This code is under development and not yet released to the public. +// Until it is released, the code is under the copyright of ETH Zurich and +// the University of Bologna, and may contain confidential and/or unpublished +// work. Any reuse/redistribution is strictly forbidden without written +// permission from ETH Zurich. +// Bug fixes and contributions will eventually be released under the +// SolderPad open hardware license in the context of the PULP platform +// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the +// University of Bologna. + +package dcache_if_agent_pkg; + // UVM Import + import uvm_pkg::*; + `include "uvm_macros.svh" + + // Sequence item to model transactions + `include "dcache_if_seq_item.svh" + // Agent configuration object + `include "dcache_if_agent_config.svh" + // Driver + `include "dcache_if_driver.svh" + // Coverage monitor + // `include "dcache_if_coverage_monitor.svh" + // Monitor that includes analysis port + `include "dcache_if_monitor.svh" + // Sequencer + `include "dcache_if_sequencer.svh" + // Main agent + `include "dcache_if_agent.svh" + // Sequence + `include "dcache_if_sequence.svh" +endpackage: dcache_if_agent_pkg \ No newline at end of file diff --git a/tb/agents/dcache_if/dcache_if_driver.svh b/tb/agents/dcache_if/dcache_if_driver.svh new file mode 100644 index 000000000..61ed4f4ce --- /dev/null +++ b/tb/agents/dcache_if/dcache_if_driver.svh @@ -0,0 +1,47 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 29.05.2017 +// Description: Driver for interface dcache_if +// Copyright (C) 2017 ETH Zurich, University of Bologna +// All rights reserved. +// This code is under development and not yet released to the public. +// Until it is released, the code is under the copyright of ETH Zurich and +// the University of Bologna, and may contain confidential and/or unpublished +// work. Any reuse/redistribution is strictly forbidden without written +// permission from ETH Zurich. +// Bug fixes and contributions will eventually be released under the +// SolderPad open hardware license in the context of the PULP platform +// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the +// University of Bologna. + +class dcache_if_driver extends uvm_driver #(dcache_if_seq_item); + + // UVM Factory Registration Macro + `uvm_component_utils(dcache_if_driver) + + // Virtual Interface + virtual dcache_if m_vif; + + //--------------------- + // Data Members + //--------------------- + dcache_if_agent_config m_cfg; + + // Standard UVM Methods: + function new(string name = "dcache_if_driver", uvm_component parent = null); + super.new(name, parent); + endfunction + + task run_phase(uvm_phase phase); + dcache_if_seq_item cmd; + seq_item_port.get_next_item(cmd); + + seq_item_port.item_done(); + endtask : run_phase + + function void build_phase(uvm_phase phase); + if (!uvm_config_db #(dcache_if_agent_config)::get(this, "", "dcache_if_agent_config", m_cfg) ) + `uvm_fatal("CONFIG_LOAD", "Cannot get() configuration dcache_if_agent_config from uvm_config_db. Have you set() it?") + + m_vif = m_cfg.m_vif; + endfunction: build_phase +endclass : dcache_if_driver diff --git a/tb/agents/dcache_if/dcache_if_monitor.svh b/tb/agents/dcache_if/dcache_if_monitor.svh new file mode 100644 index 000000000..a10ed659c --- /dev/null +++ b/tb/agents/dcache_if/dcache_if_monitor.svh @@ -0,0 +1,62 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 29.05.2017 +// Description: dcache_if Monitor, monitors the DUT's pins and writes out +// appropriate sequence items as defined for this particular dut +// +// Copyright (C) 2017 ETH Zurich, University of Bologna +// All rights reserved. +// This code is under development and not yet released to the public. +// Until it is released, the code is under the copyright of ETH Zurich and +// the University of Bologna, and may contain confidential and/or unpublished +// work. Any reuse/redistribution is strictly forbidden without written +// permission from ETH Zurich. +// Bug fixes and contributions will eventually be released under the +// SolderPad open hardware license in the context of the PULP platform +// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the +// University of Bologna. + +class dcache_if_monitor extends uvm_component; + + // UVM Factory Registration Macro + `uvm_component_utils(dcache_if_monitor) + + // analysis port + uvm_analysis_port #(dcache_if_seq_item) m_ap; + + // Virtual Interface + virtual dcache_if m_vif; + + //--------------------- + // Data Members + //--------------------- + dcache_if_agent_config m_cfg; + + // Standard UVM Methods: + function new(string name = "dcache_if_driver", uvm_component parent = null); + super.new(name, parent); + endfunction + + function void build_phase(uvm_phase phase); + if (!uvm_config_db #(dcache_if_agent_config)::get(this, "", "dcache_if_agent_config", m_cfg) ) + `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); + + endfunction: build_phase + + function void connect_phase(uvm_phase phase); + // connect virtual interface + m_vif = m_cfg.m_vif; + endfunction + + task run_phase(uvm_phase phase); + + dcache_if_seq_item cmd = dcache_if_seq_item::type_id::create("cmd"); + dcache_if_seq_item cloned_item; + + + $cast(cloned_item, cmd.clone()); + m_ap.write(cloned_item); + + endtask : run_phase +endclass : dcache_if_monitor diff --git a/tb/agents/dcache_if/dcache_if_seq_item.svh b/tb/agents/dcache_if/dcache_if_seq_item.svh new file mode 100644 index 000000000..484df8f3f --- /dev/null +++ b/tb/agents/dcache_if/dcache_if_seq_item.svh @@ -0,0 +1,89 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 29.05.2017 +// Description: dcache_if Sequence item +// +// Copyright (C) 2017 ETH Zurich, University of Bologna +// All rights reserved. +// This code is under development and not yet released to the public. +// Until it is released, the code is under the copyright of ETH Zurich and +// the University of Bologna, and may contain confidential and/or unpublished +// work. Any reuse/redistribution is strictly forbidden without written +// permission from ETH Zurich. +// Bug fixes and contributions will eventually be released under the +// SolderPad open hardware license in the context of the PULP platform +// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the +// University of Bologna. + +class dcache_if_seq_item extends uvm_sequence_item; + + // UVM Factory Registration Macro + `uvm_object_utils(dcache_if_seq_item) + + //------------------------------------------ + // Data Members (Outputs rand, inputs non-rand) + //------------------------------------------ + // TODO: set data members + + //------------------------------------------ + // Methods + //------------------------------------------ + + // Standard UVM Methods: + function new(string name = "dcache_if_seq_item"); + super.new(name); + endfunction + + function void do_copy(uvm_object rhs); + dcache_if_seq_item rhs_; + + if(!$cast(rhs_, rhs)) begin + `uvm_fatal("do_copy", "cast of rhs object failed") + end + super.do_copy(rhs); + // Copy over data members: + // e.g.: + // operator = rhs_.operator; + + endfunction:do_copy + + function bit do_compare(uvm_object rhs, uvm_comparer comparer); + dcache_if_seq_item rhs_; + + if(!$cast(rhs_, rhs)) begin + `uvm_error("do_copy", "cast of rhs object failed") + return 0; + end + // TODO + return super.do_compare(rhs, comparer); // && operator == rhs_.operator + + endfunction:do_compare + + function string convert2string(); + string s; + + $sformat(s, "%s\n", super.convert2string()); + // Convert to string function reusing s: + // TODO + // $sformat(s, "%s\n operator\n", s, operator); + return s; + + endfunction:convert2string + + function void do_print(uvm_printer printer); + if(printer.knobs.sprint == 0) begin + $display(convert2string()); + end + else begin + printer.m_string = convert2string(); + end + endfunction:do_print + + function void do_record(uvm_recorder recorder); + super.do_record(recorder); + + // Use the record macros to record the item fields: + // TODO + // `uvm_record_field("operator", operator) + endfunction:do_record + +endclass : dcache_if_seq_item diff --git a/tb/agents/dcache_if/dcache_if_sequence.svh b/tb/agents/dcache_if/dcache_if_sequence.svh new file mode 100644 index 000000000..7b506c16a --- /dev/null +++ b/tb/agents/dcache_if/dcache_if_sequence.svh @@ -0,0 +1,53 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 29.05.2017 +// Description: dcache_if sequence consisting of dcache_if_sequence_items +// +// Copyright (C) 2017 ETH Zurich, University of Bologna +// All rights reserved. +// This code is under development and not yet released to the public. +// Until it is released, the code is under the copyright of ETH Zurich and +// the University of Bologna, and may contain confidential and/or unpublished +// work. Any reuse/redistribution is strictly forbidden without written +// permission from ETH Zurich. +// Bug fixes and contributions will eventually be released under the +// SolderPad open hardware license in the context of the PULP platform +// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the +// University of Bologna. + +class dcache_if_sequence extends uvm_sequence #(dcache_if_seq_item); + + // UVM Factory Registration Macro + `uvm_object_utils(dcache_if_sequence) + + //----------------------------------------------- + // Data Members (Outputs rand, inputs non-rand) + //----------------------------------------------- + + + //------------------------------------------ + // Constraints + //------------------------------------------ + + + + //------------------------------------------ + // Methods + //------------------------------------------ + + // Standard UVM Methods: + function new(string name = "dcache_if_sequence"); + super.new(name); + endfunction + + task body; + dcache_if_seq_item req; + + begin + req = dcache_if_seq_item::type_id::create("req"); + start_item(req); + assert(req.randomize()); + finish_item(req); + end + endtask:body + +endclass : dcache_if_sequence \ No newline at end of file diff --git a/tb/agents/dcache_if/dcache_if_sequencer.svh b/tb/agents/dcache_if/dcache_if_sequencer.svh new file mode 100644 index 000000000..1e4eab3e9 --- /dev/null +++ b/tb/agents/dcache_if/dcache_if_sequencer.svh @@ -0,0 +1,29 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 29.05.2017 +// Description: dcache_if Sequencer for dcache_if_sequence_item +// +// Copyright (C) 2017 ETH Zurich, University of Bologna +// All rights reserved. +// This code is under development and not yet released to the public. +// Until it is released, the code is under the copyright of ETH Zurich and +// the University of Bologna, and may contain confidential and/or unpublished +// work. Any reuse/redistribution is strictly forbidden without written +// permission from ETH Zurich. +// Bug fixes and contributions will eventually be released under the +// SolderPad open hardware license in the context of the PULP platform +// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the +// University of Bologna. + +class dcache_if_sequencer extends uvm_sequencer #(dcache_if_seq_item); + + // UVM Factory Registration Macro + `uvm_component_utils(dcache_if_sequencer) + + // Standard UVM Methods: + function new(string name="dcache_if_sequencer", uvm_component parent = null); + super.new(name, parent); + endfunction + +endclass: dcache_if_sequencer + + diff --git a/tb/mem_arbiter_tb.sv b/tb/mem_arbiter_tb.sv index f6c48c681..654514d2b 100644 --- a/tb/mem_arbiter_tb.sv +++ b/tb/mem_arbiter_tb.sv @@ -26,8 +26,8 @@ module mem_arbiter_tb; logic rst_ni, clk; - mem_if master[3](clk); - mem_if slave(clk); + dcache_if master[3](clk); + dcache_if slave(clk); // super hack in assigning the wire a value // we need to keep all interface signals as wire as // the simulator does not now if this interface will be used @@ -42,23 +42,29 @@ module mem_arbiter_tb; .rst_ni ( rst_ni ), .flush_i ( 1'b0 ), - .address_index_o ( slave.address ), + .address_index_o ( slave.address_index ), + .address_tag_o ( slave.address_tag ), .data_wdata_o ( slave.data_wdata ), .data_req_o ( slave.data_req ), .data_we_o ( slave.data_we ), .data_be_o ( slave.data_be ), + .tag_valid_o ( slave.tag_valid ), + .kill_req_o ( slave.kill_req ), .data_gnt_i ( slave.data_req & slave.data_gnt ), .data_rvalid_i ( slave.data_rvalid ), .data_rdata_i ( slave.data_rdata ), - .address_index_i ( {master[2].address, master[1].address, master[0].address} ), - .data_wdata_i ( {master[2].data_wdata, master[1].data_wdata, master[0].data_wdata} ), - .data_req_i ( {master[2].data_req, master[1].data_req, master[0].data_req} ), - .data_we_i ( {master[2].data_we, master[1].data_we, master[0].data_we} ), - .data_be_i ( {master[2].data_be, master[1].data_be, master[0].data_be} ), - .data_gnt_o ( {master[2].data_gnt, master[1].data_gnt, master[0].data_gnt} ), - .data_rvalid_o ( {master[2].data_rvalid, master[1].data_rvalid, master[0].data_rvalid} ), - .data_rdata_o ( {master[2].data_rdata, master[1].data_rdata, master[0].data_rdata} ) + .address_index_i ( {master[2].address_index, master[1].address_index, master[0].address_index} ), + .address_tag_i ( {master[2].address_tag, master[1].address_tag, master[0].address_tag} ), + .data_wdata_i ( {master[2].data_wdata, master[1].data_wdata, master[0].data_wdata} ), + .data_req_i ( {master[2].data_req, master[1].data_req, master[0].data_req} ), + .data_we_i ( {master[2].data_we, master[1].data_we, master[0].data_we} ), + .data_be_i ( {master[2].data_be, master[1].data_be, master[0].data_be} ), + .tag_valid_i ( {master[2].tag_valid, master[1].tag_valid, master[0].tag_valid} ), + .kill_req_i ( {master[2].kill_req, master[1].kill_req, master[0].kill_req} ), + .data_gnt_o ( {master[2].data_gnt, master[1].data_gnt, master[0].data_gnt} ), + .data_rvalid_o ( {master[2].data_rvalid, master[1].data_rvalid, master[0].data_rvalid} ), + .data_rdata_o ( {master[2].data_rdata, master[1].data_rdata, master[0].data_rdata} ) ); initial begin @@ -72,17 +78,17 @@ module mem_arbiter_tb; #10ns clk = ~clk; end - program testbench (mem_if master[3], mem_if slave); + program testbench (dcache_if master[3], dcache_if slave); initial begin // register the memory interface - uvm_config_db #(virtual mem_if)::set(null, "uvm_test_top", "mem_if_slave", slave); - uvm_config_db #(virtual mem_if)::set(null, "uvm_test_top", "mem_if_master0", master[0]); - uvm_config_db #(virtual mem_if)::set(null, "uvm_test_top", "mem_if_master1", master[1]); - uvm_config_db #(virtual mem_if)::set(null, "uvm_test_top", "mem_if_master2", master[2]); + // uvm_config_db #(virtual mem_if)::set(null, "uvm_test_top", "mem_if_slave", slave); + // uvm_config_db #(virtual mem_if)::set(null, "uvm_test_top", "mem_if_master0", master[0]); + // uvm_config_db #(virtual mem_if)::set(null, "uvm_test_top", "mem_if_master1", master[1]); + // uvm_config_db #(virtual mem_if)::set(null, "uvm_test_top", "mem_if_master2", master[2]); // print the topology uvm_top.enable_print_topology = 1; // Start UVM test - run_test(); + // run_test(); end endprogram