diff --git a/Makefile b/Makefile index 5ebe2db19..df64e7ed0 100644 --- a/Makefile +++ b/Makefile @@ -7,22 +7,29 @@ library = work # Top level module to compile top_level = core_tb test_top_level = core_tb +# test targets tests = alu scoreboard fifo mem_arbiter store_queue -# path to agents -agents = tb/agents/fu_if/fu_if.sv tb/agents/fu_if/fu_if_agent_pkg.sv \ - include/ariane_pkg.svh tb/agents/scoreboard_if/scoreboard_if_agent_pkg.sv tb/common/eth_tb_pkg.sv \ - tb/agents/mem_if/mem_if_agent_pkg.sv +# UVM agents +agents = include/ariane_pkg.svh $(wildcard tb/agents/*/*.sv) tb/common/eth_tb_pkg.sv +# path to interfaces +interfaces = $(wildcard include/*.svh) +# UVM environments +envs = $(wildcard tb/env/*/*.sv) +# UVM Sequences +sequences = $(wildcard tb/sequences/*/*.sv) +# Test packages +test_pkg = tb/test/alu/alu_lib_pkg.sv + +src2obj = $(addsuffix /_primary.dat, $(addprefix $(library)/, $(basename $(notdir $(1))))) -interfaces = include/debug_if.svh include/mem_if.svh tb/agents/fifo_if/fifo_if.sv \ - tb/agents/store_queue_if/store_queue_if.sv tb/agents/scoreboard_if/scoreboard_if.sv # this list contains the standalone components -src = alu.sv tb/sequences/alu/alu_sequence_pkg.sv tb/env/alu/alu_env_pkg.sv tb/test/alu/alu_lib_pkg.sv \ - ptw.sv tlb.sv store_queue.sv \ - if_stage.sv compressed_decoder.sv fetch_fifo.sv commit_stage.sv prefetch_buffer.sv \ - mmu.sv lsu.sv fifo.sv tb/fifo_tb.sv mem_arbiter.sv \ - scoreboard.sv issue_read_operands.sv decoder.sv id_stage.sv util/cluster_clock_gating.sv regfile.sv ex_stage.sv ariane.sv +src = alu.sv if_stage.sv compressed_decoder.sv mem_arbiter.sv decoder.sv \ + fetch_fifo.sv commit_stage.sv prefetch_buffer.sv regfile.sv \ + ptw.sv tlb.sv store_queue.sv mmu.sv lsu.sv fifo.sv ex_stage.sv \ + scoreboard.sv issue_read_operands.sv id_stage.sv util/cluster_clock_gating.sv \ + ariane.sv -tb = tb/alu_tb.sv tb/mem_arbiter_tb.sv tb/core_tb.sv tb/scoreboard_tb.sv tb/store_queue_tb.sv +tbs = tb/alu_tb.sv tb/mem_arbiter_tb.sv tb/core_tb.sv tb/scoreboard_tb.sv tb/store_queue_tb.sv tb/fifo_tb.sv # Search here for include files (e.g.: non-standalone components) incdir = ./includes @@ -35,21 +42,28 @@ compile_flag = +cover=bcfst+/dut # Iterate over all include directories and write them with +incdir+ prefixed # +incdir+ works for Verilator and QuestaSim list_incdir = $(foreach dir, ${incdir}, +incdir+$(dir)) +# create library if not exists -# Build the TB and module using QuestaSim -build: +$(library): # Create the library vlib${questa_version} ${library} - # Suppress message that always_latch may not be checked thoroughly bu Questa. - # Compile agents - vlog${questa_version} ${compile_flag} -incr ${agents} ${list_incdir} -suppress 2583 - # Compile interfaces - vlog${questa_version} ${compile_flag} -incr ${interfaces} ${list_incdir} -suppress 2583 + +# Build the TB and module using QuestaSim +build: $(library) build-agents build-interfaces + # Suppress message that always_latch may not be checked thoroughly by QuestaSim. + # Compile agents, interfaces and environments + vlog${questa_version} ${compile_flag} -incr ${envs} ${sequences} ${test_pkg} ${list_incdir} -suppress 2583 # Compile source files - vlog${questa_version} ${compile_flag} -incr ${src} ${tb} ${list_incdir} -suppress 2583 + vlog${questa_version} ${compile_flag} -incr ${src} ${tbs} ${list_incdir} -suppress 2583 # Optimize top level vopt${questa_version} ${compile_flag} ${test_top_level} -o ${test_top_level}_optimized +acc -check_synthesis +build-agents: ${agents} + vlog${questa_version} ${compile_flag} -incr ${agents} ${list_incdir} -suppress 2583 + +build-interfaces: ${interfaces} + vlog${questa_version} ${compile_flag} -incr ${interfaces} ${list_incdir} -suppress 2583 + # Run the specified test case sim: # vsim${questa_version} ${top_level}_optimized -c -do "run -a" diff --git a/tb/agents/mem_if/mem_if_agent.svh b/tb/agents/mem_if/mem_if_agent.svh new file mode 100644 index 000000000..882b879ca --- /dev/null +++ b/tb/agents/mem_if/mem_if_agent.svh @@ -0,0 +1,57 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: Main agent object mem_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 mem_if_agent extends uvm_component; + // UVM Factory Registration Macro + `uvm_component_utils(mem_if_agent) + //------------------------------------------ + // Data Members + //------------------------------------------ + mem_if_agent_config m_cfg; + //------------------------------------------ + // Component Members + //------------------------------------------ + uvm_analysis_port #(mem_if_seq_item) ap; + mem_if_driver m_driver; + mem_if_monitor m_monitor; + mem_if_sequencer m_sequencer; + //------------------------------------------ + // Methods + //------------------------------------------ + // Standard UVM Methods: + function new(string name = "mem_if_agent", uvm_component parent = null); + super.new(name, parent); + endfunction : new + + function void build_phase(uvm_phase phase); + if (!uvm_config_db #(mem_if_agent_config)::get(this, "", "mem_if_agent_config", m_cfg) ) + `uvm_fatal("CONFIG_LOAD", "Cannot get() configuration mem_if_agent_config from uvm_config_db. Have you set() it?") + + m_driver = mem_if_driver::type_id::create("m_driver", this); + m_sequencer = mem_if_sequencer::type_id::create("m_sequencer", this); + m_monitor = mem_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 : mem_if_agent diff --git a/tb/agents/mem_if/mem_if_agent_config.svh b/tb/agents/mem_if/mem_if_agent_config.svh new file mode 100644 index 000000000..444b5cd5e --- /dev/null +++ b/tb/agents/mem_if/mem_if_agent_config.svh @@ -0,0 +1,41 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: Agent configuration object mem_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 mem_if_agent_config extends uvm_object; + + // UVM Factory Registration Macro + `uvm_object_utils(mem_if_agent_config) + + //------------------------------------------ + // Data Members + //------------------------------------------ + // Virtual Interface + virtual mem_if fu; + // Is this a master or a slave interface + mem_if_config mem_if_config; + // configure the path to the memory file from which to serve all read requests + string mem_file; + // Is the agent active or passive + uvm_active_passive_enum active = UVM_ACTIVE; + + // Standard UVM Methods: + function new(string name = "mem_if_agent_config"); + super.new(name); + endfunction : new + +endclass : mem_if_agent_config + + + diff --git a/tb/agents/mem_if/mem_if_agent_pkg.sv b/tb/agents/mem_if/mem_if_agent_pkg.sv new file mode 100644 index 000000000..71278c2e6 --- /dev/null +++ b/tb/agents/mem_if/mem_if_agent_pkg.sv @@ -0,0 +1,45 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: mem_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 mem_if_agent_pkg; + typedef enum { + SLAVE, MASTER + } mem_if_config; + // Mode of request either read or write + typedef enum { + READ, WRITE + } mode_t; + + // UVM Import + import uvm_pkg::*; + `include "uvm_macros.svh" + + // Sequence item to model transactions + `include "mem_if_seq_item.svh" + // Agent configuration object + `include "mem_if_agent_config.svh" + // Driver + `include "mem_if_driver.svh" + // Coverage monitor + // `include "mem_if_coverage_monitor.svh" + // Monitor that includes analysis port + `include "mem_if_monitor.svh" + // Sequencer + `include "mem_if_sequencer.svh" + // Main agent + `include "mem_if_agent.svh" + // Sequence + `include "mem_if_sequence.svh" +endpackage: mem_if_agent_pkg \ No newline at end of file diff --git a/tb/agents/mem_if/mem_if_driver.svh b/tb/agents/mem_if/mem_if_driver.svh new file mode 100644 index 000000000..193365153 --- /dev/null +++ b/tb/agents/mem_if/mem_if_driver.svh @@ -0,0 +1,127 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: Driver for interface mem_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 mem_if_driver extends uvm_driver #(mem_if_seq_item); + + // UVM Factory Registration Macro + `uvm_component_utils(mem_if_driver) + + // Virtual Interface + virtual mem_if fu; + + //--------------------- + // Data Members + //--------------------- + mem_if_agent_config m_cfg; + + // Standard UVM Methods: + function new(string name = "mem_if_driver", uvm_component parent = null); + super.new(name, parent); + endfunction + + task run_phase(uvm_phase phase); + mem_if_seq_item cmd; + + // this driver is configured as a SLAVE + if (m_cfg.mem_if_config == SLAVE) begin + // we serve all requests from the memory file we store in our configuration object + // -------------- + // Slave Port + // -------------- + logic [7:0] imem [400]; + logic [63:0] address [$]; + logic [63:0] addr; + logic slave_data_gnt; + // grant process is combinatorial + fork + slave_gnt: begin + forever begin + slave_data_gnt = 1'b0; + fu.data_gnt = slave_data_gnt; + wait (fu.data_req); + // randomize grant delay + repeat ($urandom_range(0,4)) @(fu.mck); + slave_data_gnt = 1'b1; + fu.data_gnt = slave_data_gnt; + wait (~fu.data_req); + end + end + slave_serve: begin + fu.mck.data_rdata <= 32'b0; + // apply stimuli for instruction interface + forever begin + @(fu.mck) + fu.mck.data_rvalid <= 1'b0; + fork + 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 + end + imem_write: begin + + end + join_none + 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 + // -------------- + // Master Port + // -------------- + // request a read + // initial statements, sane resets + fu.sck.data_req <= 1'b0; + fu.sck.address <= 64'b0; + fu.sck.data_be <= 7'b0; + fu.sck.data_we <= 1'b0; + fu.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 + 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 + fu.sck.data_req <= 1'b0; + seq_item_port.item_done(); + end + endtask : run_phase + + function void build_phase(uvm_phase phase); + if (!uvm_config_db #(mem_if_agent_config)::get(this, "", "mem_if_agent_config", m_cfg) ) + `uvm_fatal("CONFIG_LOAD", "Cannot get() configuration mem_if_agent_config from uvm_config_db. Have you set() it?") + + fu = m_cfg.fu; + endfunction: build_phase +endclass : mem_if_driver diff --git a/tb/agents/mem_if/mem_if_monitor.svh b/tb/agents/mem_if/mem_if_monitor.svh new file mode 100644 index 000000000..af31c09f6 --- /dev/null +++ b/tb/agents/mem_if/mem_if_monitor.svh @@ -0,0 +1,68 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: mem_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 mem_if_monitor extends uvm_component; + + // UVM Factory Registration Macro + `uvm_component_utils(mem_if_monitor) + + // analysis port + uvm_analysis_port #(mem_if_seq_item) m_ap; + + // Virtual Interface + virtual mem_if fu; + + //--------------------- + // Data Members + //--------------------- + mem_if_agent_config m_cfg; + + // Standard UVM Methods: + function new(string name = "mem_if_driver", uvm_component parent = null); + super.new(name, parent); + endfunction + + function void build_phase(uvm_phase phase); + if (!uvm_config_db #(mem_if_agent_config)::get(this, "", "mem_if_agent_config", m_cfg) ) + `uvm_fatal("CONFIG_LOAD", "Cannot get() configuration mem_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); + + mem_if_seq_item cmd = mem_if_seq_item::type_id::create("cmd"); + mem_if_seq_item cloned_item; + + // Monitor + // we should also distinguish between slave and master here + forever begin + @(fu.pck iff fu.pck.data_rvalid); + `uvm_info("MEM IF MONITOR", "Got rvalid", UVM_MEDIUM); + end + + $cast(cloned_item, cmd.clone()); + m_ap.write(cloned_item); + + endtask : run_phase +endclass : mem_if_monitor diff --git a/tb/agents/mem_if/mem_if_seq_item.svh b/tb/agents/mem_if/mem_if_seq_item.svh new file mode 100644 index 000000000..92f5f1b90 --- /dev/null +++ b/tb/agents/mem_if/mem_if_seq_item.svh @@ -0,0 +1,99 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: mem_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 mem_if_seq_item extends uvm_sequence_item; + + // UVM Factory Registration Macro + `uvm_object_utils(mem_if_seq_item) + + //------------------------------------------ + // Data Members (Outputs rand, inputs non-rand) + //------------------------------------------ + rand logic [63:0] address; + rand logic [63:0] data; + rand logic [7:0] be; + rand int grantDelay; + mode_t mode; + + //------------------------------------------ + // Methods + //------------------------------------------ + + // Standard UVM Methods: + function new(string name = "mem_if_seq_item"); + super.new(name); + endfunction + + function void do_copy(uvm_object rhs); + mem_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.: + address = rhs_.address; + data = rhs_.data; + be = rhs_.be; + mode = rhs_.mode; + endfunction:do_copy + + function bit do_compare(uvm_object rhs, uvm_comparer comparer); + mem_if_seq_item rhs_; + + if(!$cast(rhs_, rhs)) begin + `uvm_error("do_copy", "cast of rhs object failed") + return 0; + end + + return super.do_compare(rhs, comparer) + && address == rhs_.address + && data == rhs_.data + && be == rhs_.be + && mode == rhs_.mode; + + endfunction:do_compare + + function string convert2string(); + string s; + + $sformat(s, "%s\n", super.convert2string()); + $sformat(s, "%s\n Mode: %s\n Address: %0h \nData: %0h \nBE: %0h \n", s, mode.name, address, data, be); + 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: + `uvm_record_field("Mode", mode) + `uvm_record_field("Address", address) + `uvm_record_field("Data", data) + `uvm_record_field("BE", be) + endfunction:do_record + +endclass : mem_if_seq_item diff --git a/tb/agents/mem_if/mem_if_sequence.svh b/tb/agents/mem_if/mem_if_sequence.svh new file mode 100644 index 000000000..2e18ac6a9 --- /dev/null +++ b/tb/agents/mem_if/mem_if_sequence.svh @@ -0,0 +1,53 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: mem_if sequence consisting of mem_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 mem_if_sequence extends uvm_sequence #(mem_if_seq_item); + + // UVM Factory Registration Macro + `uvm_object_utils(mem_if_sequence) + + //----------------------------------------------- + // Data Members (Outputs rand, inputs non-rand) + //----------------------------------------------- + + + //------------------------------------------ + // Constraints + //------------------------------------------ + + + + //------------------------------------------ + // Methods + //------------------------------------------ + + // Standard UVM Methods: + function new(string name = "mem_if_sequence"); + super.new(name); + endfunction + + task body; + mem_if_seq_item req; + + begin + req = mem_if_seq_item::type_id::create("req"); + start_item(req); + assert(req.randomize()); + finish_item(req); + end + endtask:body + +endclass : mem_if_sequence \ No newline at end of file diff --git a/tb/agents/mem_if/mem_if_sequencer.svh b/tb/agents/mem_if/mem_if_sequencer.svh new file mode 100644 index 000000000..d096b8cdc --- /dev/null +++ b/tb/agents/mem_if/mem_if_sequencer.svh @@ -0,0 +1,29 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: mem_if Sequencer for mem_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 mem_if_sequencer extends uvm_sequencer #(mem_if_seq_item); + + // UVM Factory Registration Macro + `uvm_component_utils(mem_if_sequencer) + + // Standard UVM Methods: + function new(string name="mem_if_sequencer", uvm_component parent = null); + super.new(name, parent); + endfunction + +endclass: mem_if_sequencer + + diff --git a/tb/env/mem_arbiter/mem_arbiter_env.svh b/tb/env/mem_arbiter/mem_arbiter_env.svh new file mode 100644 index 000000000..a04c4581c --- /dev/null +++ b/tb/env/mem_arbiter/mem_arbiter_env.svh @@ -0,0 +1,56 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: Environment which instantiates the agent and all environment +// related components such as a scoreboard etc. +// 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 mem_arbiter_env extends uvm_env; + + // UVM Factory Registration Macro + `uvm_component_utils(mem_arbiter_env) + + //------------------------------------------ + // Data Members + //------------------------------------------ + mem_if_agent m_mem_if_agent; + mem_if_sequencer m_mem_if_sequencer; + mem_arbiter_env_config m_cfg; + //------------------------------------------ + // Methods + //------------------------------------------ + + // Standard UVM Methods: + function new(string name = "mem_arbiter_env", uvm_component parent = null); + super.new(name, parent); + endfunction + + function void build_phase(uvm_phase phase); + if (!uvm_config_db #(mem_arbiter_env_config)::get(this, "", "mem_arbiter_env_config", m_cfg)) + `uvm_fatal("CONFIG_LOAD", "Cannot get() configuration mem_arbiter_env_config from uvm_config_db. Have you set() it?") + // Conditional instantiation goes here + + // Create agent configuration + uvm_config_db #(mem_if_agent_config)::set(this, "m_mem_if_agent*", + "mem_if_agent_config", + m_cfg.m_mem_if_agent_config); + m_mem_if_agent = mem_if_agent::type_id::create("m_mem_if_agent", this); + + // Get sequencer + m_mem_if_sequencer = mem_if_sequencer::type_id::create("m_mem_if_sequencer", this); + + endfunction:build_phase + + function void connect_phase(uvm_phase phase); + m_mem_if_sequencer = m_mem_if_agent.m_sequencer; + endfunction: connect_phase +endclass : mem_arbiter_env diff --git a/tb/env/mem_arbiter/mem_arbiter_env_config.svh b/tb/env/mem_arbiter/mem_arbiter_env_config.svh new file mode 100644 index 000000000..aa2f4004f --- /dev/null +++ b/tb/env/mem_arbiter/mem_arbiter_env_config.svh @@ -0,0 +1,29 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: mem_arbiter 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 mem_arbiter_env_config extends uvm_object; + + // UVM Factory Registration Macro + `uvm_object_utils(mem_arbiter_env_config) + + // a functional unit master interface + virtual mem_if m_mem_if; + + // an agent config + + mem_if_agent_config m_mem_if_agent_config; + +endclass : mem_arbiter_env_config diff --git a/tb/env/mem_arbiter/mem_arbiter_env_pkg.sv b/tb/env/mem_arbiter/mem_arbiter_env_pkg.sv new file mode 100644 index 000000000..e6de0f75e --- /dev/null +++ b/tb/env/mem_arbiter/mem_arbiter_env_pkg.sv @@ -0,0 +1,26 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: mem_arbiter package +// 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 mem_arbiter_env_pkg; + // Standard UVM import & include: + import uvm_pkg::*; + `include "uvm_macros.svh" + // Testbench related imports + import mem_if_agent_pkg::*; + // Includes for the config for the environment + `include "mem_arbiter_env_config.svh" + // Includes the environment + `include "mem_arbiter_env.svh" +endpackage diff --git a/tb/test/mem_arbiter/mem_arbiter_lib_pkg.sv b/tb/test/mem_arbiter/mem_arbiter_lib_pkg.sv new file mode 100644 index 000000000..cb4333fa9 --- /dev/null +++ b/tb/test/mem_arbiter/mem_arbiter_lib_pkg.sv @@ -0,0 +1,41 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: Main test package contains all necessary packages +// +// 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 mem_arbiter_lib_pkg; + // Standard UVM import & include: + import uvm_pkg::*; + `include "uvm_macros.svh" + // Import the memory interface agent + import mem_if_agent_pkg::*; + // ------------------------------------------------ + // Environment which will be instantiated + // ------------------------------------------------ + import mem_arbiter_env_pkg::*; + // ---------------- + // Sequence Package + // ---------------- + import mem_arbiter_sequence_pkg::*; + // Test based includes like base test class and specializations of it + // ---------------- + // Base test class + // ---------------- + `include "mem_arbiter_test_base.svh" + // ------------------- + // Child test classes + // ------------------- + `include "mem_arbiter_test.svh" + +endpackage diff --git a/tb/test/mem_arbiter/mem_arbiter_sequence_pkg.sv b/tb/test/mem_arbiter/mem_arbiter_sequence_pkg.sv new file mode 100644 index 000000000..c1dddec16 --- /dev/null +++ b/tb/test/mem_arbiter/mem_arbiter_sequence_pkg.sv @@ -0,0 +1,26 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: mem_arbiter sequence package +// +// 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 mem_arbiter_sequence_pkg; + + +import mem_if_agent_pkg::*; +import uvm_pkg::*; + +`include "uvm_macros.svh" +// Include your sequences here e.g.: +// `include "fibonacci_sequence.svh" +endpackage diff --git a/tb/test/mem_arbiter/mem_arbiter_test.svh b/tb/test/mem_arbiter/mem_arbiter_test.svh new file mode 100644 index 000000000..2a0393a3a --- /dev/null +++ b/tb/test/mem_arbiter/mem_arbiter_test.svh @@ -0,0 +1,50 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: mem_arbiter main test class +// +// 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 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; + //------------------------------------------ + // Methods + //------------------------------------------ + + // Standard UVM Methods: + function new(string name = "mem_arbiter_test", uvm_component parent = null); + super.new(name, parent); + endfunction + + function void build_phase(uvm_phase phase); + super.build_phase(phase); + endfunction + + task run_phase(uvm_phase phase); + phase.raise_objection(this, "mem_arbiter_test"); + //fibonacci_sequence fibonacci; + super.run_phase(phase); + + // mem_arbiter = new("mem_arbiter"); + // TODO: Start sequence here + // mem_arbiter.start(sequencer_h); + // Testlogic goes here + #100ns; + + phase.drop_objection(this, "mem_arbiter_test"); + endtask + + +endclass : mem_arbiter_test diff --git a/tb/test/mem_arbiter/mem_arbiter_test_base.svh b/tb/test/mem_arbiter/mem_arbiter_test_base.svh new file mode 100644 index 000000000..af1dfb4cf --- /dev/null +++ b/tb/test/mem_arbiter/mem_arbiter_test_base.svh @@ -0,0 +1,82 @@ +// Author: Florian Zaruba, ETH Zurich +// Date: 30.04.2017 +// Description: mem_arbiter base test class +// +// 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 mem_arbiter_test_base extends uvm_test; + + // UVM Factory Registration Macro + `uvm_component_utils(mem_arbiter_test_base) + + //------------------------------------------ + // Data Members + //------------------------------------------ + + //------------------------------------------ + // Component Members + //------------------------------------------ + // environment configuration + mem_arbiter_env_config m_env_cfg; + // environment + mem_arbiter_env m_env; + mem_if_sequencer sequencer_h; + + // reset_sequence reset; + // --------------------- + // Agent configuration + // --------------------- + // functional unit interface + mem_if_agent_config m_cfg; + + //------------------------------------------ + // Methods + //------------------------------------------ + // Standard UVM Methods: + function new(string name = "mem_arbiter_test_base", uvm_component parent = null); + super.new(name, parent); + endfunction + + // Build the environment, get all configurations + // Use the factory pattern in order to facilitate UVM functionality + function void build_phase(uvm_phase phase); + // create environment + m_env_cfg = mem_arbiter_env_config::type_id::create("m_env_cfg"); + + // create agent configurations and assign interfaces + // create agent memory master configuration + m_cfg = mem_if_agent_config::type_id::create("m_cfg"); + m_env_cfg.m_mem_if_agent_config = m_cfg; + // Get Virtual Interfaces + // get master interface DB + if (!uvm_config_db #(virtual mem_if)::get(this, "", "mem_if", m_cfg.fu)) + `uvm_fatal("VIF CONFIG", "Cannot get() interface mem_if from uvm_config_db. Have you set() it?") + m_env_cfg.m_mem_if = m_cfg.fu; + + + // create environment + uvm_config_db #(mem_arbiter_env_config)::set(this, "*", "mem_arbiter_env_config", m_env_cfg); + m_env = mem_arbiter_env::type_id::create("m_env", this); + + endfunction + + function void end_of_elaboration_phase(uvm_phase phase); + sequencer_h = m_env.m_mem_if_sequencer; + endfunction + + task run_phase(uvm_phase phase); + // reset = new("reset"); + // reset.start(sequencer_h); + endtask + +endclass : mem_arbiter_test_base \ No newline at end of file