diff --git a/tb/agents/lsu_if/lsu_if.sv b/tb/agents/lsu_if/lsu_if.sv new file mode 100644 index 000000000..d7752abab --- /dev/null +++ b/tb/agents/lsu_if/lsu_if.sv @@ -0,0 +1,57 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 02.05.2017 +// Description: LSU interface +// +// +// Copyright (C) 2017 ETH Zurich, University of Bologna +// All rights reserved. + +// Guard statement proposed by "Easier UVM" (doulos) +`ifndef LSU_IF_SV +`define LSU_IF_SV +import ariane_pkg::*; + +interface lsu_if #( + parameter int OPERAND_SIZE = 64 + ) + ( + input clk + ); + + fu_op operator; // FU operation + wire [OPERAND_SIZE-1:0] operand_a; // Operand A + wire [OPERAND_SIZE-1:0] operand_b; // Operand B + wire [OPERAND_SIZE-1:0] imm; // Operand B + wire [OPERAND_SIZE-1:0] result; // Result + wire [TRANS_ID_BITS-1:0] lsu_trans_id_id; // transaction id from ID + wire [TRANS_ID_BITS-1:0] lsu_trans_id_wb; // transaction id to WB + // LSU control signals + wire commit; + wire source_valid; // Source operands are valid + wire result_valid; // Result is valid, ready to accept new request + wire ready; // Sink is ready + // exceptions + exception exception; + + // FU interface configured as master + clocking mck @(posedge clk); + output operator, operand_a, operand_b, imm, source_valid, commit, lsu_trans_id_id; + input result, lsu_trans_id_wb, result_valid, ready, exception; + endclocking + // FU interface configured as slave + clocking sck @(posedge clk); + input operator, operand_a, operand_b, imm, source_valid, commit, lsu_trans_id_id; + output result, lsu_trans_id_wb, result_valid, ready, exception; + endclocking + // FU interface configured in passive mode + clocking pck @(posedge clk); + input operator, operand_a, operand_b, imm, source_valid, commit, lsu_trans_id_id, + result, lsu_trans_id_wb, result_valid, ready, exception ; + endclocking + + modport master (clocking mck); + modport slave (clocking sck); + modport passive (clocking pck); + +endinterface +`endif diff --git a/tb/agents/lsu_if/lsu_if_agent.svh b/tb/agents/lsu_if/lsu_if_agent.svh new file mode 100644 index 000000000..74a305995 --- /dev/null +++ b/tb/agents/lsu_if/lsu_if_agent.svh @@ -0,0 +1,57 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 02.05.2017 +// Description: Main agent object lsu_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 lsu_if_agent extends uvm_component; + // UVM Factory Registration Macro + `uvm_component_utils(lsu_if_agent) + //------------------------------------------ + // Data Members + //------------------------------------------ + lsu_if_agent_config m_cfg; + //------------------------------------------ + // Component Members + //------------------------------------------ + uvm_analysis_port #(lsu_if_seq_item) ap; + lsu_if_driver m_driver; + lsu_if_monitor m_monitor; + lsu_if_sequencer m_sequencer; + //------------------------------------------ + // Methods + //------------------------------------------ + // Standard UVM Methods: + function new(string name = "lsu_if_agent", uvm_component parent = null); + super.new(name, parent); + endfunction : new + + function void build_phase(uvm_phase phase); + if (!uvm_config_db #(lsu_if_agent_config)::get(this, "", "lsu_if_agent_config", m_cfg) ) + `uvm_fatal("CONFIG_LOAD", "Cannot get() configuration lsu_if_agent_config from uvm_config_db. Have you set() it?") + + m_driver = lsu_if_driver::type_id::create("m_driver", this); + m_sequencer = lsu_if_sequencer::type_id::create("m_sequencer", this); + m_monitor = lsu_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 : lsu_if_agent diff --git a/tb/agents/lsu_if/lsu_if_agent_config.svh b/tb/agents/lsu_if/lsu_if_agent_config.svh new file mode 100644 index 000000000..1527d0e85 --- /dev/null +++ b/tb/agents/lsu_if/lsu_if_agent_config.svh @@ -0,0 +1,37 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 02.05.2017 +// Description: Agent configuration object lsu_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 lsu_if_agent_config extends uvm_object; + + // UVM Factory Registration Macro + `uvm_object_utils(lsu_if_agent_config) + + // Virtual Interface + virtual lsu_if fu; + //------------------------------------------ + // Data Members + //------------------------------------------ + // Is the agent active or passive + uvm_active_passive_enum active = UVM_ACTIVE; + + // Standard UVM Methods: + function new(string name = "lsu_if_agent_config"); + super.new(name); + endfunction : new + +endclass : lsu_if_agent_config + + + diff --git a/tb/agents/lsu_if/lsu_if_agent_pkg.sv b/tb/agents/lsu_if/lsu_if_agent_pkg.sv new file mode 100644 index 000000000..ff26b15d2 --- /dev/null +++ b/tb/agents/lsu_if/lsu_if_agent_pkg.sv @@ -0,0 +1,37 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 02.05.2017 +// Description: lsu_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 lsu_if_agent_pkg; + // UVM Import + import uvm_pkg::*; + `include "uvm_macros.svh" + + // Sequence item to model transactions + `include "lsu_if_seq_item.svh" + // Agent configuration object + `include "lsu_if_agent_config.svh" + // Driver + `include "lsu_if_driver.svh" + // Coverage monitor + // `include "lsu_if_coverage_monitor.svh" + // Monitor that includes analysis port + `include "lsu_if_monitor.svh" + // Sequencer + `include "lsu_if_sequencer.svh" + // Main agent + `include "lsu_if_agent.svh" + // Sequence + `include "lsu_if_sequence.svh" +endpackage: lsu_if_agent_pkg \ No newline at end of file diff --git a/tb/agents/lsu_if/lsu_if_driver.svh b/tb/agents/lsu_if/lsu_if_driver.svh new file mode 100644 index 000000000..a4ac6f01b --- /dev/null +++ b/tb/agents/lsu_if/lsu_if_driver.svh @@ -0,0 +1,47 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 02.05.2017 +// Description: Driver for interface lsu_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 lsu_if_driver extends uvm_driver #(lsu_if_seq_item); + + // UVM Factory Registration Macro + `uvm_component_utils(lsu_if_driver) + + // Virtual Interface + virtual lsu_if fu; + + //--------------------- + // Data Members + //--------------------- + lsu_if_agent_config m_cfg; + + // Standard UVM Methods: + function new(string name = "lsu_if_driver", uvm_component parent = null); + super.new(name, parent); + endfunction + + task run_phase(uvm_phase phase); + lsu_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 #(lsu_if_agent_config)::get(this, "", "lsu_if_agent_config", m_cfg) ) + `uvm_fatal("CONFIG_LOAD", "Cannot get() configuration lsu_if_agent_config from uvm_config_db. Have you set() it?") + + fu = m_cfg.fu; + endfunction: build_phase +endclass : lsu_if_driver diff --git a/tb/agents/lsu_if/lsu_if_monitor.svh b/tb/agents/lsu_if/lsu_if_monitor.svh new file mode 100644 index 000000000..efbc1cd8b --- /dev/null +++ b/tb/agents/lsu_if/lsu_if_monitor.svh @@ -0,0 +1,62 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 02.05.2017 +// Description: lsu_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 lsu_if_monitor extends uvm_component; + + // UVM Factory Registration Macro + `uvm_component_utils(lsu_if_monitor) + + // analysis port + uvm_analysis_port #(lsu_if_seq_item) m_ap; + + // Virtual Interface + virtual lsu_if fu; + + //--------------------- + // Data Members + //--------------------- + lsu_if_agent_config m_cfg; + + // Standard UVM Methods: + function new(string name = "lsu_if_driver", uvm_component parent = null); + super.new(name, parent); + endfunction + + function void build_phase(uvm_phase phase); + if (!uvm_config_db #(lsu_if_agent_config)::get(this, "", "lsu_if_agent_config", m_cfg) ) + `uvm_fatal("CONFIG_LOAD", "Cannot get() configuration lsu_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 + fu = m_cfg.fu; + endfunction + + task run_phase(uvm_phase phase); + + lsu_if_seq_item cmd = lsu_if_seq_item::type_id::create("cmd"); + lsu_if_seq_item cloned_item; + + + $cast(cloned_item, cmd.clone()); + m_ap.write(cloned_item); + + endtask : run_phase +endclass : lsu_if_monitor diff --git a/tb/agents/lsu_if/lsu_if_seq_item.svh b/tb/agents/lsu_if/lsu_if_seq_item.svh new file mode 100644 index 000000000..e27a29d34 --- /dev/null +++ b/tb/agents/lsu_if/lsu_if_seq_item.svh @@ -0,0 +1,89 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 02.05.2017 +// Description: lsu_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 lsu_if_seq_item extends uvm_sequence_item; + + // UVM Factory Registration Macro + `uvm_object_utils(lsu_if_seq_item) + + //------------------------------------------ + // Data Members (Outputs rand, inputs non-rand) + //------------------------------------------ + // TODO: set data members + + //------------------------------------------ + // Methods + //------------------------------------------ + + // Standard UVM Methods: + function new(string name = "lsu_if_seq_item"); + super.new(name); + endfunction + + function void do_copy(uvm_object rhs); + lsu_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); + lsu_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 : lsu_if_seq_item diff --git a/tb/agents/lsu_if/lsu_if_sequence.svh b/tb/agents/lsu_if/lsu_if_sequence.svh new file mode 100644 index 000000000..69bbce585 --- /dev/null +++ b/tb/agents/lsu_if/lsu_if_sequence.svh @@ -0,0 +1,53 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 02.05.2017 +// Description: lsu_if sequence consisting of lsu_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 lsu_if_sequence extends uvm_sequence #(lsu_if_seq_item); + + // UVM Factory Registration Macro + `uvm_object_utils(lsu_if_sequence) + + //----------------------------------------------- + // Data Members (Outputs rand, inputs non-rand) + //----------------------------------------------- + + + //------------------------------------------ + // Constraints + //------------------------------------------ + + + + //------------------------------------------ + // Methods + //------------------------------------------ + + // Standard UVM Methods: + function new(string name = "lsu_if_sequence"); + super.new(name); + endfunction + + task body; + lsu_if_seq_item req; + + begin + req = lsu_if_seq_item::type_id::create("req"); + start_item(req); + assert(req.randomize()); + finish_item(req); + end + endtask:body + +endclass : lsu_if_sequence \ No newline at end of file diff --git a/tb/agents/lsu_if/lsu_if_sequencer.svh b/tb/agents/lsu_if/lsu_if_sequencer.svh new file mode 100644 index 000000000..7144d1e18 --- /dev/null +++ b/tb/agents/lsu_if/lsu_if_sequencer.svh @@ -0,0 +1,29 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 02.05.2017 +// Description: lsu_if Sequencer for lsu_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 lsu_if_sequencer extends uvm_sequencer #(lsu_if_seq_item); + + // UVM Factory Registration Macro + `uvm_component_utils(lsu_if_sequencer) + + // Standard UVM Methods: + function new(string name="lsu_if_sequencer", uvm_component parent = null); + super.new(name, parent); + endfunction + +endclass: lsu_if_sequencer + + diff --git a/tb/lsu_tb.sv b/tb/lsu_tb.sv index bfb635788..957fe7e5b 100644 --- a/tb/lsu_tb.sv +++ b/tb/lsu_tb.sv @@ -29,38 +29,41 @@ module lsu_tb; mem_if slave(clk); mem_if instr_if(clk); + lsu_if lsu(clk); lsu dut ( - .clk_i ( clk ), - .rst_ni ( rst_ni ), - .flush_i ( 1'b0 ), - .operator_i ( ), - .operand_a_i ( ), - .operand_b_i ( ), - .imm_i ( ), - .lsu_ready_o ( ), - .lsu_valid_i ( ), - .lsu_trans_id_i ( ), - .lsu_trans_id_o ( ), - .lsu_result_o ( ), - .lsu_valid_o ( ), - .commit_i ( ), + .clk_i ( clk ), + .rst_ni ( rst_ni ), + .flush_i ( 1'b0 ), + .operator_i ( lsu.operator ), + .operand_a_i ( lsu.operand_a ), + .operand_b_i ( lsu.operand_b ), + .imm_i ( lsu.imm ), + .lsu_ready_o ( lsu.ready ), + .lsu_valid_i ( lsu.source_valid ), + .lsu_trans_id_i ( lsu.lsu_trans_id_id ), + .lsu_trans_id_o ( lsu.lsu_trans_id_wb ), + .lsu_result_o ( lsu.result ), + .lsu_valid_o ( lsu.result_valid ), + .commit_i ( lsu.commit ), + // we are currently no testing the PTW and MMU .enable_translation_i ( 1'b0 ), - .fetch_req_i ( ), + .fetch_req_i ( 1'b0 ), .fetch_gnt_o ( ), .fetch_valid_o ( ), .fetch_err_o ( ), - .fetch_vaddr_i ( ), + .fetch_vaddr_i ( 64'b0 ), .fetch_rdata_o ( ), - .priv_lvl_i ( ), - .flag_pum_i ( ), - .flag_mxr_i ( ), - .pd_ppn_i ( ), - .asid_i ( ), - .flush_tlb_i ( ), - .instr_if ( instr_if ), - .data_if ( slave ), - .lsu_exception_o ( ) + .priv_lvl_i ( PRIV_LVL_M ), + .flag_pum_i ( 1'b0 ), + .flag_mxr_i ( 1'b0 ), + .pd_ppn_i ( 38'b0 ), + .asid_i ( 1'b0 ), + .flush_tlb_i ( 1'b0 ), + + .instr_if ( instr_if ), + .data_if ( slave ), + .lsu_exception_o ( lsu.exception ) ); initial begin @@ -74,10 +77,11 @@ module lsu_tb; #10ns clk = ~clk; end - program testbench (mem_if slave); + program testbench (mem_if slave, lsu_if lsu); initial begin // register the memory interface uvm_config_db #(virtual mem_if)::set(null, "uvm_test_top", "mem_if", slave); + uvm_config_db #(virtual lsu_if)::set(null, "uvm_test_top", "lsu_if", lsu); // print the topology uvm_top.enable_print_topology = 1; @@ -86,5 +90,5 @@ module lsu_tb; end endprogram - testbench tb (slave); + testbench tb (slave, lsu); endmodule \ No newline at end of file