OpenCores
URL https://opencores.org/ocsvn/openhmc/openhmc/trunk

Subversion Repositories openhmc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 6 to Rev 7
    Reverse comparison

Rev 6 → Rev 7

/openhmc/trunk/openHMC/sim/tb/bfm/build/compile_ius_openhmc_behavioral_bfm.f
0,0 → 1,64
#
# .--------------. .----------------. .------------.
# | .------------. | .--------------. | .----------. |
# | | ____ ____ | | | ____ ____ | | | ______ | |
# | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
# ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
# / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
# (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
# \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
# | | | | | | | | | | | |
# |_| | '------------' | '--------------' | '----------' |
# '--------------' '----------------' '------------'
#
# openHMC - An Open Source Hybrid Memory Cube Controller
# (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
# www.ziti.uni-heidelberg.de
# B6, 26
# 68159 Mannheim
# Germany
#
# Contact: openhmc@ziti.uni-heidelberg.de
# http://ra.ziti.uni-heidelberg.de/openhmc
#
# This source file is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This source file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this source file. If not, see <http://www.gnu.org/licenses/>.
#
#
 
#Leave untouched
+define+HMC_REQUESTER_IS_ACTIVE=0
+define+HMC_RESPONDER_IS_ACTIVE=0
+define+SIMULATION=1
 
###Include Sources
#Behavioral serializer and routing models
${OPENHMC_SIM}/tb/bfm/src/behavioral/deserializer.v
${OPENHMC_SIM}/tb/bfm/src/behavioral/serializer.v
${OPENHMC_SIM}/tb/bfm/src/behavioral/routing.v
 
#openHMC controller
-f ${OPENHMC_PATH}/rtl/hmc_controller/hmc_controller_top.f
+incdir+${OPENHMC_PATH}/rtl/include/
 
#Micron BFM model
-f ${OPENHMC_SIM}/bfm/hmc_bfm.f
 
#Include Register File and controller header
+incdir+${OPENHMC_SIM}/tb/bfm/src/rgm/openhmc/
+incdir+${OPENHMC_SIM}/tb/bfm/src/targets/
 
#Source top TB and DUT
-f ${OPENHMC_SIM}/tb/bfm/build/compile_tb_openhmc.f
${OPENHMC_SIM}/tb/bfm/src/tb_top_bfm.sv
${OPENHMC_SIM}/tb/bfm/src/targets/dut_openhmc_behavioral_bfm.sv
/openhmc/trunk/openHMC/sim/tb/bfm/build/compile_tb_openhmc.f
0,0 → 1,82
#
# .--------------. .----------------. .------------.
# | .------------. | .--------------. | .----------. |
# | | ____ ____ | | | ____ ____ | | | ______ | |
# | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
# ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
# / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
# (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
# \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
# | | | | | | | | | | | |
# |_| | '------------' | '--------------' | '----------' |
# '--------------' '----------------' '------------'
#
# openHMC - An Open Source Hybrid Memory Cube Controller
# (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
# www.ziti.uni-heidelberg.de
# B6, 26
# 68159 Mannheim
# Germany
#
# Contact: openhmc@ziti.uni-heidelberg.de
# http://ra.ziti.uni-heidelberg.de/openhmc
#
# This source file is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This source file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this source file. If not, see <http://www.gnu.org/licenses/>.
#
#
 
+define+RFS_DATA_WIDTH=64
+define+RFS_VC107_1HMC_8LANE_TOP_RF_AWIDTH=5
+define+RFS_VC107_1HMC_8LANE_TOP_RF_RWIDTH=64
+define+RFS_VC107_1HMC_8LANE_TOP_RF_WWIDTH=64
+define+RFS_HMC_CONTROLLER_RF_AWIDTH=4
+define+RFS_HMC_CONTROLLER_RF_RWIDTH=64
+define+RFS_HMC_CONTROLLER_RF_WWIDTH=64
 
+incdir+${OPENHMC_SIM}/tb/bfm/src
+incdir+${OPENHMC_SIM}/tb/bfm/testlib
+incdir+${OPENHMC_SIM}/UVC/axi4_stream/sv
+incdir+${OPENHMC_SIM}/UVC/cag_rgm/sv
+incdir+${OPENHMC_SIM}/UVC/hmc_module/sv
+incdir+${OPENHMC_SIM}/UVC/hmc_base_types/sv
 
 
-64bit
-access +rwc
 
-linedebug
 
-uvm
 
-sv
-q
 
-ncerror CUVWSI
-ncerror CUVWSP
-ncerror CUVMPW
-ncerror CUVUKP
-ncerror RTSDAD
-ncerror OBINRG
-ncerror BNDMEM
-ncerror FUNTSK
-ncerror CSINFI
-ncerror RECOME
-nowarn CUVIHR
+UVM_NO_RELNOTES
 
-timescale 100ps/10ps
 
### DUT-specific files
 
-top tb_top
/openhmc/trunk/openHMC/sim/tb/bfm/build/ncsim.tcl
0,0 → 1,14
database -open waves -into waves.shm -default
 
probe -create tb_top.dut_I -depth all -tasks -functions -all -database waves
probe -create tb_top.dut_I.hmc_controller_instance.hmc_rx_link_I -all -database waves -memories
probe -create tb_top.dut_I.hmc_controller_instance.hmc_tx_link_I -all -database waves -memories
 
probe -create tb_top.axi4_hmc_req_if -all -database waves
probe -create tb_top.axi4_hmc_rsp_if -all -database waves
 
set assert_output_stop_level failed
set assert_report_incompletes 0
 
run
 
/openhmc/trunk/openHMC/sim/tb/bfm/testlib/hmc_check_seq.sv
0,0 → 1,121
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef HMC_CHECK_SEQ
`define HMC_CHECK_SEQ
 
`include "config.h"
 
class hmc_check_seq extends hmc_base_seq;
 
function new(string name="hmc_check_seq");
super.new(name);
endfunction : new
 
`uvm_object_utils(hmc_check_seq)
`uvm_declare_p_sequencer(hmc_vseqr)
 
int timer;
 
task body();
reg_hmc_controller_rf_status_general_c status;
reg_hmc_controller_rf_sent_np_c sent_np;
reg_hmc_controller_rf_rcvd_rsp_c rcvd_rsp;
 
`uvm_info(get_type_name(), "Running Check Sequence", UVM_NONE)
 
timer = 0;
 
$cast(status,p_sequencer.rf_seqr_hmc.get_by_name("status_general"));
status.set_check_on_read(1'b0);
 
$cast(sent_np,p_sequencer.rf_seqr_hmc.get_by_name("sent_np"));
sent_np.set_check_on_read(1'b0);
 
$cast(rcvd_rsp,p_sequencer.rf_seqr_hmc.get_by_name("rcvd_rsp"));
rcvd_rsp.set_check_on_read(1'b0);
 
p_sequencer.rf_seqr_hmc.read_reg(status);
p_sequencer.rf_seqr_hmc.read_reg(sent_np);
p_sequencer.rf_seqr_hmc.read_reg(rcvd_rsp);
 
#1us;
 
while( ((sent_np.fields.cnt_ != rcvd_rsp.fields.cnt_) ||
(status.fields.hmc_tokens_remaining_ != `HMC_TOKENS) ||
(status.fields.rx_tokens_remaining_ != `RX_TOKENS))
&&
(timer < 200)) begin
#1us;
p_sequencer.rf_seqr_hmc.read_reg(status);
p_sequencer.rf_seqr_hmc.read_reg(sent_np);
p_sequencer.rf_seqr_hmc.read_reg(rcvd_rsp);
`uvm_info(get_type_name(),$psprintf("RX token count in TX_LINK = %0d, should be %0d", status.fields.rx_tokens_remaining_, `RX_TOKENS),UVM_LOW)
`uvm_info(get_type_name(),$psprintf("HMC token count in TX_LINK = %0d, should be %0d", status.fields.hmc_tokens_remaining_, `HMC_TOKENS),UVM_LOW)
`uvm_info(get_type_name(),$psprintf("sent = %0d non-posted packets, received %0d responses", sent_np.fields.cnt_, rcvd_rsp.fields.cnt_),UVM_LOW)
timer++;
end
#1us;
 
p_sequencer.rf_seqr_hmc.read_reg(status);
p_sequencer.rf_seqr_hmc.read_reg(sent_np);
p_sequencer.rf_seqr_hmc.read_reg(rcvd_rsp);
 
#1us;
 
//-- ***REPORTS***
//-- Report Packet Counts
if(sent_np.fields.cnt_ != rcvd_rsp.fields.cnt_) begin
`uvm_info(get_type_name(),$psprintf("Counted: %0d NP Requests, %0d Responses", sent_np.fields.cnt_, rcvd_rsp.fields.cnt_), UVM_LOW)
end
 
if(status.fields.hmc_tokens_remaining_ != `HMC_TOKENS) begin
`uvm_fatal(get_type_name(),$psprintf("Responder token count in TX_LINK = %0d, should be %0d", status.fields.hmc_tokens_remaining_, `HMC_TOKENS))
end
 
//-- Report Tokens in RX Link
if(status.fields.rx_tokens_remaining_ != `RX_TOKENS) begin
`uvm_fatal(get_type_name(),$psprintf("Requester token count in TX_LINK = %0d, should be %0d", status.fields.rx_tokens_remaining_, `RX_TOKENS))
end
 
endtask : body
 
endclass : hmc_check_seq
 
`endif // HMC_CHECK_SEQ
/openhmc/trunk/openHMC/sim/tb/bfm/testlib/hmc_base_test.sv
0,0 → 1,126
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef hmc_BASE_TEST_SV
`define hmc_BASE_TEST_SV
 
class hmc_base_test extends uvm_test;
 
hmc_tb hmc_tb0;
axi4_stream_config axi4_req_config;
axi4_stream_config axi4_rsp_config;
 
uvm_table_printer printer;
 
function new(string name="hmc_base_test", uvm_component parent=null);
super.new(name,parent);
endfunction : new
 
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
 
//-- create config
//-- AXI4 request config
axi4_req_config = axi4_stream_config::type_id::create("axi4_req_config", this);
axi4_req_config.master_active = UVM_ACTIVE;
axi4_req_config.slave_active = UVM_PASSIVE;
 
uvm_report_info(get_type_name(), $psprintf("Setting the axi4_req config:\n"), UVM_LOW);
uvm_config_db#(axi4_stream_config)::set(this, "hmc_tb0", "axi4_req_config", axi4_req_config);
//-- AXI4 response config
axi4_rsp_config = axi4_stream_config::type_id::create("axi4_rsp_config", this);
axi4_rsp_config.master_active = UVM_PASSIVE;
axi4_rsp_config.slave_active = UVM_ACTIVE;
 
uvm_report_info(get_type_name(), $psprintf("Setting the axi4_rsp config:\n"), UVM_LOW);
uvm_config_db#(axi4_stream_config)::set(this, "hmc_tb0", "axi4_rsp_config", axi4_rsp_config);
 
set_config_int("*", "recording_detail", UVM_FULL);
//-- create the testbench
hmc_tb0 = hmc_tb#()::type_id::create("hmc_tb0", this);
 
printer = new();
printer.knobs.depth = 5;
 
endfunction : build_phase
 
function void end_of_elaboration_phase(uvm_phase phase);
super.end_of_elaboration_phase(phase);
 
uvm_report_info(get_type_name(), $psprintf("Printing the test topology :\n%s", this.sprint(printer)), UVM_HIGH);
 
endfunction : end_of_elaboration_phase
 
 
virtual task run_phase(uvm_phase phase);
phase.phase_done.set_drain_time(this, 10us);
endtask : run_phase
 
//function void report_phase(uvm_phase phase);
// report_summarize();
//endfunction : report_phase
 
endclass : hmc_base_test
 
 
class hmc_base_seq extends uvm_sequence;
 
function new(string name="hmc_base_seq");
super.new(name);
endfunction : new
 
`uvm_object_utils(hmc_base_seq)
`uvm_declare_p_sequencer(hmc_vseqr)
 
virtual task pre_body();
if(starting_phase != null)
starting_phase.raise_objection(this);
endtask : pre_body
 
virtual task post_body();
if(starting_phase != null)
starting_phase.drop_objection(this);
endtask : post_body
 
endclass : hmc_base_seq
 
`endif // hmc_BASE_TEST_SV
/openhmc/trunk/openHMC/sim/tb/bfm/testlib/simple_test/simple_test.sv
0,0 → 1,73
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
//
// simple_test test
//
//
 
`ifndef simple_test_SV
`define simple_test_SV
 
class simple_test extends hmc_base_test;
 
`uvm_component_utils(simple_test)
 
 
function new(string name = "simple_test", uvm_component parent = null);
super.new(name,parent);
endfunction : new
 
 
virtual function void build_phase(uvm_phase phase);
 
uvm_config_db#(uvm_object_wrapper)::set(this,"hmc_tb0.v_seqr.run_phase","default_sequence",simple_test_seq::type_id::get());
 
super.build_phase(phase);
 
endfunction : build_phase
task run_phase(uvm_phase phase);
phase.phase_done.set_drain_time(this, 1us);
endtask : run_phase
 
endclass : simple_test
 
`endif // simple_test_SV
/openhmc/trunk/openHMC/sim/tb/bfm/testlib/simple_test/simple_test_seq.sv
0,0 → 1,92
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
//
//
// simple_test sequence
//
//
 
`ifndef simple_test_SEQ_SV
`define simple_test_SEQ_SV
 
`include "config.h"
 
class simple_test_seq extends hmc_base_seq;
 
function new(string name="simple_test_seq");
super.new(name);
endfunction : new
 
hmc_init_seq init;
hmc_check_seq check;
 
`uvm_object_utils(simple_test_seq)
`uvm_declare_p_sequencer(hmc_vseqr)
 
hmc_2_axi4_sequence #(.DATA_BYTES(`AXI4BYTES), .TUSER_WIDTH(`AXI4BYTES)) requests;
int np_tag;
rand bit hmc_command_np;
rand int flit_count;
 
virtual task body();
 
`uvm_info(get_type_name(), "starting simple_test_seq", UVM_NONE)
 
//-- write your test here
 
#1us;
`uvm_do(init)
#1us;
 
 
`uvm_create_on(requests, p_sequencer.axi4_req_seqr) //-- create a new sequence item 'requests' on sequencer
requests.num_packets = `NUM_PACKETS; //-- HMC packets to send
requests.max_pkts_per_cycle = `FPW; //-- Set the maximum number of complete packets per AXI4 cycle
`uvm_rand_send(requests) //-- randomize and send the parametrize sequence item
 
#1us;
`uvm_info(get_type_name(), "simple_test_seq done", UVM_NONE)
`uvm_do(check)
 
endtask : body
 
endclass : simple_test_seq
 
`endif // simple_test_SEQ_SV
/openhmc/trunk/openHMC/sim/tb/bfm/testlib/hmc_init_seq.sv
0,0 → 1,121
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef HMC_INIT_SEQ
`define HMC_INIT_SEQ
 
`include "config.h"
 
class hmc_init_seq extends hmc_base_seq;
 
// hmc_link_config link_config;
 
function new(string name="hmc_init_seq");
super.new(name);
endfunction : new
 
`uvm_object_utils(hmc_init_seq)
`uvm_declare_p_sequencer(hmc_vseqr)
 
bit phy_ready = 1'b0;
bit link_up = 1'b0;
int timeout = 0;
 
task body();
//-- configure the HMC controller
reg_hmc_controller_rf_control_c control;
reg_hmc_controller_rf_status_general_c status;
 
`uvm_info(get_type_name(), "Running init sequence", UVM_NONE)
 
$cast(control,p_sequencer.rf_seqr_hmc.get_by_name("control"));
control.set_check_on_read(1'b0);
p_sequencer.rf_seqr_hmc.read_reg(control);
 
control.fields.first_cube_ID_ = `HMC_CUBID;
control.fields.rx_token_count_ = `RX_TOKENS;
control.fields.scrambler_disable_ = 0;
control.fields.bit_slip_time_ = 72;
control.fields.set_hmc_sleep_ = 0;
control.fields.run_length_enable_ = 1;
 
p_sequencer.rf_seqr_hmc.write_reg(control);
 
//-- Wait until the PHY is ready
$cast(status,p_sequencer.rf_seqr_hmc.get_by_name("status_general"));
status.set_check_on_read(1'b0);
while (phy_ready == 1'b0)
begin
#3us;
p_sequencer.rf_seqr_hmc.read_reg(status);
phy_ready = status.fields.phy_ready_;
`uvm_info(get_type_name(), "Waiting for the phy to get ready", UVM_NONE)
end
`uvm_info(get_type_name(), "Phy is ready", UVM_NONE)
 
//-- Set Reset and Init Continue;
control.fields.p_rst_n_ = 1;
control.fields.hmc_init_cont_set_ = 1;
p_sequencer.rf_seqr_hmc.write_reg(control);
 
//-- Poll on link_up to make sure that it comes up.
while (link_up == 1'b0)
begin
if (timeout == 8000) //-- Try Resetting it.
begin
`uvm_info(get_type_name(), "The link didn't come up... Resetting it.", UVM_NONE)
control.fields.p_rst_n_ = 0;
p_sequencer.rf_seqr_hmc.write_reg(control);
#30us;
control.fields.p_rst_n_ = 1;
p_sequencer.rf_seqr_hmc.write_reg(control);
timeout = 0;
end
#4ns;
p_sequencer.rf_seqr_hmc.read_reg(status);
link_up = status.fields.link_up_;
timeout = timeout + 1;
end
 
endtask : body
 
endclass : hmc_init_seq
 
`endif // HMC_INIT_SEQ
/openhmc/trunk/openHMC/sim/tb/bfm/testlib/test_lib.sv
0,0 → 1,52
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
//-- the base test
`include "hmc_base_test.sv"
 
//-- the init sequence
`include "hmc_init_seq.sv"
 
//-- check registers after test ends
`include "hmc_check_seq.sv"
 
//-- the tests
`include "simple_test/simple_test_seq.sv"
`include "simple_test/simple_test.sv"
 
/openhmc/trunk/openHMC/sim/tb/bfm/src/tag_handler.sv
0,0 → 1,185
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
//
// tag handler
//
//
 
`ifndef TAG_HANDLER_SV
`define TAG_HANDLER_SV
 
class tag_handler extends uvm_component;
 
int tag_count = 512; //-- tags available at the beginning
bit tags_in_use[]; //-- bitmap of current used tags
//bit tag_used[]; //-- mitmap of used tags
int tag_fifo[$];
int transaction_count;
int max_tags_in_use;
int num_tags_in_use;
int used_tag;
 
event tag_avail_event;
covergroup tags_used_cg;
TAGS_USED : coverpoint used_tag{
bins valid_tags [] = {[0:tag_count]};
bins illegal_tags = {[tag_count+1:$]};
}
endgroup
 
`uvm_analysis_imp_decl(_hmc_rsp)
uvm_analysis_imp_hmc_rsp #(hmc_packet, tag_handler) hmc_rsp_port;
 
`uvm_component_utils_begin(tag_handler)
`uvm_field_int(tag_count, UVM_DEFAULT)
`uvm_component_utils_end
 
function new ( string name="tag_handler", uvm_component parent );
super.new(name, parent);
tags_used_cg = new();
endfunction : new
function void build_phase(uvm_phase phase);
hmc_rsp_port = new("hmc_rsp_port",this);
tags_in_use = new [tag_count];
// tag_used = new [num_tags];
// foreach (tag_used[i]) begin
// tag_used[i] = 0;
// end
 
max_tags_in_use = 0;
transaction_count = 0;
reset();
endfunction : build_phase
 
function void reset();
foreach (tags_in_use[i]) begin
tags_in_use[i] =0;
end
 
num_tags_in_use = 0;
tag_fifo = {};
for (int i=0; i< tag_count; i++)
tag_fifo.push_back(tag_count-1-i);
endfunction : reset
 
task get_tag(ref int tag );
//-- wait until at least 1 tag available
if (tag_fifo.size() == 0) begin
`uvm_info(get_type_name(), $psprintf("get_tag: no tags available...waiting"), UVM_HIGH)
@(tag_avail_event);
`uvm_info(get_type_name(), $psprintf("get_tag: one tag is now available"), UVM_HIGH)
end
//-- flag tag as used
tag = tag_fifo.pop_front();
tags_in_use[tag] = 1'b1;
// tag_used[tag] = 1'b1;
used_tag = tag;
tags_used_cg.sample();
num_tags_in_use++;
if (num_tags_in_use > max_tags_in_use)
max_tags_in_use = num_tags_in_use;
endtask : get_tag
task try_get_tag(ref int tag );
//-- wait until at least 1 tag available
if (tag_fifo.size() == 0) begin
`uvm_info(get_type_name(), $psprintf("get_tag: no tags available...returning NULL"), UVM_HIGH)
tag = -1;
end else begin
//-- flag tag as used
tag = tag_fifo.pop_front();
tags_in_use[tag] = 1'b1;
// tag_used[tag] = 1'b1;
used_tag = tag;
tags_used_cg.sample();
num_tags_in_use++;
if (num_tags_in_use > max_tags_in_use)
max_tags_in_use = num_tags_in_use;
end
endtask : try_get_tag
 
function void release_tag(input int tag);
if (!tags_in_use[tag])
`uvm_fatal(get_type_name(), $psprintf("release_tag: tag (%0d) not in use!", tag))
//-- release tag
tags_in_use[tag] = 1'b0;
num_tags_in_use--;
transaction_count++;
tag_fifo.push_back(tag);
 
//-- signal that tag is available
-> tag_avail_event;
endfunction : release_tag
 
function void write_hmc_rsp(input hmc_packet packet);
release_tag(packet.tag);
endfunction : write_hmc_rsp
 
function void idle_check();
if (num_tags_in_use > 0)
for (int i=0; i<tag_count; i++)
if (tags_in_use[i])
`uvm_fatal(get_type_name(), $psprintf("%0d tags still in use, first one is %0d!", num_tags_in_use, i))
if (tag_fifo.size() != tag_count)
`uvm_fatal(get_type_name(), $psprintf("tag FIFO should have num_tags (%0d) entries it has %0d!", tag_count, tag_fifo.size()))
endfunction : idle_check
 
function void check_phase(uvm_phase phase);
idle_check();
endfunction : check_phase
 
function void report_phase(uvm_phase phase);
`uvm_info(get_type_name(),$psprintf("max_tags_in_use %0d, transaction_count %0d", max_tags_in_use, transaction_count), UVM_LOW)
endfunction : report_phase
 
endclass : tag_handler
 
`endif // TAG_HANDLER_SV
/openhmc/trunk/openHMC/sim/tb/bfm/src/tb_top_bfm.sv
0,0 → 1,139
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`include "axi4_stream_pkg.sv"
`include "hmc_module_pkg.sv"
`include "cag_rgm_rfs_if.sv"
 
`timescale 100ps/10ps
 
module tb_top ();
 
import uvm_pkg::*;
 
//-- include the UVCs
import axi4_stream_pkg::*;
import hmc_module_pkg::*;
import hmc_base_types_pkg::*;
 
`include "cag_rgm.svh"
 
`ifdef X16
`include "register_file_model_16x.sv"
`else
`include "register_file_model_8x.sv"
`endif
 
`include "hmc_packet.sv"
`include "hmc_req_packet.sv"
`include "hmc_2_axi4_sequencer.sv"
`include "hmc_2_axi4_sequence.sv"
`include "tag_handler.sv"
 
`include "hmc_vseqr.sv"
`include "axi4_stream_hmc_monitor.sv"
`include "bfm_2_hmc_monitor.sv"
 
`include "hmc_tb.sv"
 
`include "test_lib.sv"
 
logic res_n, clk_user, clk_hmc_refclk;
 
//-- instantiate the interfaces
axi4_stream_if #(
.DATA_BYTES(`AXI4BYTES),
.TUSER_WIDTH(`AXI4BYTES)
) axi4_hmc_req_if(
.ACLK(clk_user),
.ARESET_N(res_n)
);
 
axi4_stream_if #(
.DATA_BYTES(`AXI4BYTES),
.TUSER_WIDTH(`AXI4BYTES)
) axi4_hmc_rsp_if(
.ACLK(clk_user),
.ARESET_N(res_n)
);
 
cag_rgm_rfs_if #(
.ADDR_WIDTH(`RFS_HMC_CONTROLLER_RF_AWIDTH),
.READ_DATA_WIDTH(`RFS_HMC_CONTROLLER_RF_RWIDTH),
.WRITE_DATA_WIDTH(`RFS_HMC_CONTROLLER_RF_WWIDTH)
) rfs_hmc_if();
 
dut dut_I (
.clk_user(clk_user),
.clk_hmc_refclk(clk_hmc_refclk),
.res_n(res_n),
 
.axi4_req(axi4_hmc_req_if),
.axi4_rsp(axi4_hmc_rsp_if),
 
.rfs_hmc(rfs_hmc_if)
);
 
initial begin
 
uvm_config_db#(virtual axi4_stream_if #(.DATA_BYTES(`AXI4BYTES), .TUSER_WIDTH(`AXI4BYTES)))::set(null, "uvm_test_top.hmc_tb0.axi4_req", "vif", axi4_hmc_req_if);
uvm_config_db#(virtual axi4_stream_if #(.DATA_BYTES(`AXI4BYTES), .TUSER_WIDTH(`AXI4BYTES)))::set(null, "uvm_test_top.hmc_tb0.axi4_rsp", "vif", axi4_hmc_rsp_if);
//-- connect the BFM monitors with the Module UVC BFM to HMC Packet monitors
uvm_config_db#(pkt_analysis_port#())::set(null,"uvm_test_top.hmc_tb0.hmc_module.hmc_req_mon","mb_pkt",dut_I.hmc_bfm0.hmc_flit_top.mb_rsp_pkt[0]);
uvm_config_db#(pkt_analysis_port#())::set(null,"uvm_test_top.hmc_tb0.hmc_module.hmc_rsp_mon","mb_pkt",dut_I.hmc_bfm0.hmc_flit_top.mb_req_pkt[0]);
run_test();
end
 
initial begin
clk_user <= 1'b1;
clk_hmc_refclk <= 1'b1;
res_n <= 1'b0;
#5001ns res_n <= 1'b1;
end
 
//-- 312.5MHz user Clock, keep it at least 312.5MHz so that it is >= clk_hmc in any configuration
always #1.6ns clk_user <= ~clk_user;
 
//-- 125 MHz
always #4ns clk_hmc_refclk <= ~clk_hmc_refclk;
 
endmodule : tb_top
/openhmc/trunk/openHMC/sim/tb/bfm/src/hmc_tb.sv
0,0 → 1,190
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef hmc_TB_SV
`define hmc_TB_SV
 
class hmc_tb #( parameter AXI4_DATA_BYTES=`AXI4BYTES, parameter AXI4_TUSER_WIDTH=`AXI4BYTES) extends uvm_env;
//-- UVCs
 
axi4_stream_env #(
.DATA_BYTES(AXI4_DATA_BYTES),
.TUSER_WIDTH(AXI4_TUSER_WIDTH)
) axi4_req;
 
axi4_stream_env #(
.DATA_BYTES(AXI4_DATA_BYTES),
.TUSER_WIDTH(AXI4_TUSER_WIDTH)
) axi4_rsp;
 
hmc_module_env hmc_module;
 
axi4_stream_config axi4_rsp_config;
axi4_stream_config axi4_req_config;
 
cag_rgm_rfs_env #(
.ADDR_WIDTH(`RFS_HMC_CONTROLLER_RF_AWIDTH),
.READ_DATA_WIDTH(`RFS_HMC_CONTROLLER_RF_RWIDTH),
.WRITE_DATA_WIDTH(`RFS_HMC_CONTROLLER_RF_WWIDTH)
) rfs_hmc_I;
 
rf_hmc_controller_rf_c rf_model_hmc;
 
hmc_vseqr v_seqr;
 
int i = 2;
 
`uvm_component_param_utils(hmc_tb #(.AXI4_DATA_BYTES(AXI4_DATA_BYTES), .AXI4_TUSER_WIDTH(AXI4_TUSER_WIDTH) ))
 
function new (string name="hmc_tb", uvm_component parent=null);
super.new(name,parent);
endfunction : new
 
virtual function void build_phase(uvm_phase phase);
//-- factory overrides
 
set_inst_override_by_type("axi4_req.master.sequencer",
axi4_stream_master_sequencer #( .DATA_BYTES(AXI4_DATA_BYTES), .TUSER_WIDTH(AXI4_TUSER_WIDTH)
)::get_type(),
hmc_2_axi4_sequencer #( .DATA_BYTES(AXI4_DATA_BYTES),
.TUSER_WIDTH(AXI4_TUSER_WIDTH)
)::get_type()
);
 
set_inst_override_by_type("hmc_module.axi4_req_mon",
hmc_module_mon::get_type(),
axi4_stream_hmc_monitor #( .DATA_BYTES(AXI4_DATA_BYTES),
.TUSER_WIDTH(AXI4_TUSER_WIDTH))::get_type()
);
set_inst_override_by_type("hmc_module.axi4_rsp_mon",
hmc_module_mon::get_type(),
axi4_stream_hmc_monitor #( .DATA_BYTES(AXI4_DATA_BYTES),
.TUSER_WIDTH(AXI4_TUSER_WIDTH))::get_type()
);
set_inst_override_by_type("hmc_module.hmc_req_mon",hmc_module_mon::get_type(),bfm_2_hmc_mon::get_type());
set_inst_override_by_type("hmc_module.hmc_rsp_mon",hmc_module_mon::get_type(),bfm_2_hmc_mon::get_type());
super.build_phase(phase);
 
 
//-- deploy configuration
if (!uvm_config_db#(axi4_stream_config)::get(this, "", "axi4_req_config", axi4_req_config)) begin
uvm_report_fatal(get_type_name(), $psprintf("axi4_config not set via config_db"));
end else begin
uvm_config_db#(axi4_stream_config)::set(this, "axi4_req", "axi4_stream_cfg", axi4_req_config);
end
 
if (!uvm_config_db#(axi4_stream_config)::get(this, "", "axi4_rsp_config", axi4_rsp_config)) begin
uvm_report_fatal(get_type_name(), $psprintf("axi4_config not set via config_db"));
end else begin
uvm_config_db#(axi4_stream_config)::set(this, "axi4_rsp", "axi4_stream_cfg", axi4_rsp_config);
end
 
 
//-- create instances
axi4_req = axi4_stream_env #(.DATA_BYTES(AXI4_DATA_BYTES),.TUSER_WIDTH(AXI4_TUSER_WIDTH))::type_id::create("axi4_req",this);
axi4_rsp = axi4_stream_env #(.DATA_BYTES(AXI4_DATA_BYTES),.TUSER_WIDTH(AXI4_TUSER_WIDTH))::type_id::create("axi4_rsp",this);
 
hmc_module = hmc_module_env::type_id::create("hmc_module",this);
 
rfs_hmc_I = cag_rgm_rfs_env #(.ADDR_WIDTH(`RFS_HMC_CONTROLLER_RF_AWIDTH), .READ_DATA_WIDTH(`RFS_HMC_CONTROLLER_RF_RWIDTH),.WRITE_DATA_WIDTH(`RFS_HMC_CONTROLLER_RF_WWIDTH))::type_id::create("rfs_hmc_I", this);
rf_model_hmc = rf_hmc_controller_rf_c::type_id::create("rf_model_hmc",this);
 
v_seqr = hmc_vseqr::type_id::create("v_seqr", this);
 
endfunction : build_phase
 
function void connect_phase(uvm_phase phase);
 
hmc_2_axi4_sequencer #(.DATA_BYTES(AXI4_DATA_BYTES),.TUSER_WIDTH(AXI4_TUSER_WIDTH)) axi4_req_seqr;
axi4_stream_hmc_monitor #(.DATA_BYTES(AXI4_DATA_BYTES), .TUSER_WIDTH(AXI4_TUSER_WIDTH) ) axi4_hmc_req_mon;
axi4_stream_hmc_monitor #(.DATA_BYTES(AXI4_DATA_BYTES), .TUSER_WIDTH(AXI4_TUSER_WIDTH) ) axi4_hmc_rsp_mon;
bfm_2_hmc_mon hmc_rsp_mon;
bfm_2_hmc_mon hmc_req_mon;
 
super.connect_phase(phase);
rfs_hmc_I.assign_vi(tb_top.rfs_hmc_if);
rfs_hmc_I.set_rf(rf_model_hmc);
 
//-- cast sequencer
if ( !$cast(axi4_req_seqr, axi4_req.master.sequencer))
`uvm_fatal(get_type_name(), $psprintf("error in seqr cast"));
//-- cast AXI4 to HMC pkt monitors
if ( !$cast(axi4_hmc_req_mon, hmc_module.axi4_req_mon))
`uvm_fatal(get_type_name(), $psprintf("error in axi4_req_mon cast"));
if ( !$cast(axi4_hmc_rsp_mon, hmc_module.axi4_rsp_mon))
`uvm_fatal(get_type_name(), $psprintf("error in axi4_rsp_mon cast"));
//-- cast BFM to HMC pkt monitors
if ( !$cast(hmc_req_mon, hmc_module.hmc_req_mon))
`uvm_fatal(get_type_name(), $psprintf("error in hmc_req_mon cast"));
if ( !$cast(hmc_rsp_mon, hmc_module.hmc_rsp_mon))
`uvm_fatal(get_type_name(), $psprintf("error in hmc_rsp_mon scast"));
axi4_req.master.sequencer = axi4_req_seqr;
//-- connect the AXI4 UVC UVM analysis ports to the corresponding Module UVC monitors
axi4_req.monitor.item_collected_port.connect(axi4_hmc_req_mon.axi4_port);
axi4_rsp.monitor.item_collected_port.connect(axi4_hmc_rsp_mon.axi4_port);
//-- connect the AXi4 to HMC pkt response monitor to the tag handler
axi4_hmc_rsp_mon.item_collected_port.connect(axi4_req_seqr.handler.hmc_rsp_port);
//-- virtual sequencer
v_seqr.axi4_req_seqr = axi4_req_seqr;
v_seqr.rf_seqr_hmc = rfs_hmc_I.sequencer;
endfunction : connect_phase
 
endclass : hmc_tb
 
`endif // hmc_TB_SV
/openhmc/trunk/openHMC/sim/tb/bfm/src/rgm/openhmc/register_file_model_16x.sv
0,0 → 1,541
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
// HMC controller status
//
class reg_hmc_controller_rf_16x_status_general_c extends cag_rgm_register;
 
typedef struct packed {
bit [15:0] lane_polarity_reversed_;
bit [5:0] rsvd_status_general_3_;
bit [9:0] rx_tokens_remaining_;
bit [5:0] rsvd_status_general_2_;
bit [9:0] hmc_tokens_remaining_;
bit [6:0] rsvd_status_general_1_;
bit [0:0] phy_ready_;
bit [3:0] rsvd_status_general_0_;
bit [0:0] lanes_reversed_;
bit [0:0] sleep_mode_;
bit [0:0] link_training_;
bit [0:0] link_up_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_16x_status_general_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_16x_status_general_c");
super.new(name);
this.name = name;
set_address('h0);
endfunction : new
 
endclass : reg_hmc_controller_rf_16x_status_general_c
 
//
// HMC controller initialization status
//
class reg_hmc_controller_rf_16x_status_init_c extends cag_rgm_register;
 
typedef struct packed {
bit [0:0] hmc_init_TS1_;
bit [1:0] tx_init_status_;
bit [0:0] all_descramblers_aligned_;
bit [15:0] descrambler_aligned_;
bit [15:0] descrambler_part_aligned_;
bit [15:0] lane_descramblers_locked_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_16x_status_init_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_16x_status_init_c");
super.new(name);
this.name = name;
set_address('h8);
endfunction : new
 
endclass : reg_hmc_controller_rf_16x_status_init_c
 
//
// HMC controller control
//
class reg_hmc_controller_rf_16x_control_c extends cag_rgm_register;
 
typedef struct packed {
bit [7:0] bit_slip_time_;
bit [2:0] rsvd_control_3_;
bit [4:0] irtry_to_send_;
bit [2:0] rsvd_control_2_;
bit [4:0] irtry_received_threshold_;
bit [5:0] rsvd_control_1_;
bit [9:0] rx_token_count_;
bit [6:0] rsvd_control_0_;
bit [0:0] debug_dont_send_tret_;
bit [2:0] first_cube_ID_;
bit [0:0] run_length_enable_;
bit [0:0] scrambler_disable_;
bit [0:0] set_hmc_sleep_;
bit [0:0] hmc_init_cont_set_;
bit [0:0] p_rst_n_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_16x_control_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_16x_control_c");
super.new(name);
this.name = name;
set_address('h10);
endfunction : new
 
endclass : reg_hmc_controller_rf_16x_control_c
 
//
// Count of packets that had data errors but valid flow information
//
class reg_hmc_controller_rf_16x_poisoned_packets_c extends cag_rgm_register;
 
typedef struct packed {
bit [63:0] cnt_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_16x_poisoned_packets_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_16x_poisoned_packets_c");
super.new(name);
this.name = name;
set_address('h18);
endfunction : new
 
endclass : reg_hmc_controller_rf_16x_poisoned_packets_c
 
//
// Nonposted requests sent to the HMC
//
class reg_hmc_controller_rf_16x_sent_np_c extends cag_rgm_register;
 
typedef struct packed {
bit [63:0] cnt_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_16x_sent_np_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_16x_sent_np_c");
super.new(name);
this.name = name;
set_address('h20);
endfunction : new
 
endclass : reg_hmc_controller_rf_16x_sent_np_c
 
//
// Posted requests sent to the HMC
//
class reg_hmc_controller_rf_16x_sent_p_c extends cag_rgm_register;
 
typedef struct packed {
bit [63:0] cnt_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_16x_sent_p_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_16x_sent_p_c");
super.new(name);
this.name = name;
set_address('h28);
endfunction : new
 
endclass : reg_hmc_controller_rf_16x_sent_p_c
 
//
// Read requests sent to the HMC
//
class reg_hmc_controller_rf_16x_sent_r_c extends cag_rgm_register;
 
typedef struct packed {
bit [63:0] cnt_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_16x_sent_r_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_16x_sent_r_c");
super.new(name);
this.name = name;
set_address('h30);
endfunction : new
 
endclass : reg_hmc_controller_rf_16x_sent_r_c
 
//
// Responses received from the HMC
//
class reg_hmc_controller_rf_16x_rcvd_rsp_c extends cag_rgm_register;
 
typedef struct packed {
bit [63:0] cnt_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_16x_rcvd_rsp_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_16x_rcvd_rsp_c");
super.new(name);
this.name = name;
set_address('h38);
endfunction : new
 
endclass : reg_hmc_controller_rf_16x_rcvd_rsp_c
 
//
// Reset performance counters
//
class reg_hmc_controller_rf_16x_counter_reset_c extends cag_rgm_register;
 
typedef struct packed {
bit rreinit_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_16x_counter_reset_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_16x_counter_reset_c");
super.new(name);
this.name = name;
set_address('h40);
endfunction : new
 
endclass : reg_hmc_controller_rf_16x_counter_reset_c
 
//
// Count of re-transmit requests (seq num and bit errors)
//
class reg_hmc_controller_rf_16x_link_retries_c extends cag_rgm_register;
 
typedef struct packed {
bit [31:0] count_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_16x_link_retries_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_16x_link_retries_c");
super.new(name);
this.name = name;
set_address('h48);
endfunction : new
 
endclass : reg_hmc_controller_rf_16x_link_retries_c
 
//
// The number of bit_flips forced by the run length limiter
//
class reg_hmc_controller_rf_16x_run_length_bit_flip_c extends cag_rgm_register;
 
typedef struct packed {
bit [31:0] count_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_16x_run_length_bit_flip_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_16x_run_length_bit_flip_c");
super.new(name);
this.name = name;
set_address('h50);
endfunction : new
 
endclass : reg_hmc_controller_rf_16x_run_length_bit_flip_c
 
class rf_hmc_controller_rf_16x_c extends cag_rgm_register_file;
 
rand reg_hmc_controller_rf_16x_status_general_c status_general;
rand reg_hmc_controller_rf_16x_status_init_c status_init;
rand reg_hmc_controller_rf_16x_control_c control;
rand reg_hmc_controller_rf_16x_poisoned_packets_c poisoned_packets;
rand reg_hmc_controller_rf_16x_sent_np_c sent_np;
rand reg_hmc_controller_rf_16x_sent_p_c sent_p;
rand reg_hmc_controller_rf_16x_sent_r_c sent_r;
rand reg_hmc_controller_rf_16x_rcvd_rsp_c rcvd_rsp;
rand reg_hmc_controller_rf_16x_counter_reset_c counter_reset;
rand reg_hmc_controller_rf_16x_link_retries_c link_retries;
rand reg_hmc_controller_rf_16x_run_length_bit_flip_c run_length_bit_flip;
 
`uvm_object_utils(rf_hmc_controller_rf_16x_c)
 
function new(string name="rf_hmc_controller_rf_16x_c");
super.new(name);
this.name = name;
set_address('h0);
status_general = reg_hmc_controller_rf_16x_status_general_c::type_id::create("status_general");
status_general.set_address('h0);
add_register(status_general);
status_init = reg_hmc_controller_rf_16x_status_init_c::type_id::create("status_init");
status_init.set_address('h8);
add_register(status_init);
control = reg_hmc_controller_rf_16x_control_c::type_id::create("control");
control.set_address('h10);
add_register(control);
poisoned_packets = reg_hmc_controller_rf_16x_poisoned_packets_c::type_id::create("poisoned_packets");
poisoned_packets.set_address('h18);
add_register(poisoned_packets);
sent_np = reg_hmc_controller_rf_16x_sent_np_c::type_id::create("sent_np");
sent_np.set_address('h20);
add_register(sent_np);
sent_p = reg_hmc_controller_rf_16x_sent_p_c::type_id::create("sent_p");
sent_p.set_address('h28);
add_register(sent_p);
sent_r = reg_hmc_controller_rf_16x_sent_r_c::type_id::create("sent_r");
sent_r.set_address('h30);
add_register(sent_r);
rcvd_rsp = reg_hmc_controller_rf_16x_rcvd_rsp_c::type_id::create("rcvd_rsp");
rcvd_rsp.set_address('h38);
add_register(rcvd_rsp);
counter_reset = reg_hmc_controller_rf_16x_counter_reset_c::type_id::create("counter_reset");
counter_reset.set_address('h40);
add_register(counter_reset);
link_retries = reg_hmc_controller_rf_16x_link_retries_c::type_id::create("link_retries");
link_retries.set_address('h48);
add_register(link_retries);
run_length_bit_flip = reg_hmc_controller_rf_16x_run_length_bit_flip_c::type_id::create("run_length_bit_flip");
run_length_bit_flip.set_address('h50);
add_register(run_length_bit_flip);
endfunction : new
 
endclass : rf_hmc_controller_rf_16x_c
 
//
// Pattern Generator Control Register
//
class reg_pattern_gen_rf_control_c extends cag_rgm_register;
 
typedef struct packed {
bit [2:0] cubID_size_;
bit [2:0] first_cube_ID_;
bit [0:0] hmc_gen_running_;
bit [0:0] hmc_gen_enable_;
bit [6:0] hmc_gen_read_ratio_;
bit [3:0] hmc_gen_write_size_;
bit [3:0] hmc_gen_read_size_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_pattern_gen_rf_control_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_pattern_gen_rf_control_c");
super.new(name);
this.name = name;
set_address('h80);
endfunction : new
 
endclass : reg_pattern_gen_rf_control_c
 
//
// dummy
//
class reg_pattern_gen_rf_dummy_c extends cag_rgm_register;
 
typedef struct packed {
bit [3:0] dummy_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_pattern_gen_rf_dummy_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_pattern_gen_rf_dummy_c");
super.new(name);
this.name = name;
set_address('h88);
endfunction : new
 
endclass : reg_pattern_gen_rf_dummy_c
 
class rf_pattern_gen_rf_c extends cag_rgm_register_file;
 
rand reg_pattern_gen_rf_control_c control;
rand reg_pattern_gen_rf_dummy_c dummy;
 
`uvm_object_utils(rf_pattern_gen_rf_c)
 
function new(string name="rf_pattern_gen_rf_c");
super.new(name);
this.name = name;
set_address('h80);
control = reg_pattern_gen_rf_control_c::type_id::create("control");
control.set_address('h80);
add_register(control);
dummy = reg_pattern_gen_rf_dummy_c::type_id::create("dummy");
dummy.set_address('h88);
add_register(dummy);
endfunction : new
 
endclass : rf_pattern_gen_rf_c
 
//
// General Reset controlable via i2c
//
class reg_res_rf_control_c extends cag_rgm_register;
 
typedef struct packed {
bit [0:0] res_n_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_res_rf_control_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_res_rf_control_c");
super.new(name);
this.name = name;
set_address('h90);
endfunction : new
 
endclass : reg_res_rf_control_c
 
//
// dummy
//
class reg_res_rf_dummy_c extends cag_rgm_register;
 
typedef struct packed {
bit [0:0] dummy_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_res_rf_dummy_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_res_rf_dummy_c");
super.new(name);
this.name = name;
set_address('h98);
endfunction : new
 
endclass : reg_res_rf_dummy_c
 
class rf_res_rf_c extends cag_rgm_register_file;
 
rand reg_res_rf_control_c control;
rand reg_res_rf_dummy_c dummy;
 
`uvm_object_utils(rf_res_rf_c)
 
function new(string name="rf_res_rf_c");
super.new(name);
this.name = name;
set_address('h90);
control = reg_res_rf_control_c::type_id::create("control");
control.set_address('h90);
add_register(control);
dummy = reg_res_rf_dummy_c::type_id::create("dummy");
dummy.set_address('h98);
add_register(dummy);
endfunction : new
 
endclass : rf_res_rf_c
 
class rf_vc107_1hmc_16lane_top_rf_c extends cag_rgm_register_file;
 
rand rf_hmc_controller_rf_16x_c hmc_controller_rf_16x;
rand rf_pattern_gen_rf_c pattern_gen_rf;
rand rf_res_rf_c res_rf;
 
`uvm_object_utils(rf_vc107_1hmc_16lane_top_rf_c)
 
function new(string name="rf_vc107_1hmc_16lane_top_rf_c");
super.new(name);
this.name = name;
set_address('h0);
hmc_controller_rf_16x = rf_hmc_controller_rf_16x_c::type_id::create("hmc_controller_rf_16x");
add_register_file(hmc_controller_rf_16x);
pattern_gen_rf = rf_pattern_gen_rf_c::type_id::create("pattern_gen_rf");
add_register_file(pattern_gen_rf);
res_rf = rf_res_rf_c::type_id::create("res_rf");
add_register_file(res_rf);
endfunction : new
 
endclass : rf_vc107_1hmc_16lane_top_rf_c
 
/openhmc/trunk/openHMC/sim/tb/bfm/src/rgm/openhmc/register_file_model_8x.sv
0,0 → 1,614
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
// HMC controller status
//
class reg_hmc_controller_rf_status_general_c extends cag_rgm_register;
 
typedef struct packed {
bit [7:0] lane_polarity_reversed_;
bit [5:0] rsvd_status_general_3_;
bit [9:0] rx_tokens_remaining_;
bit [5:0] rsvd_status_general_2_;
bit [9:0] hmc_tokens_remaining_;
bit [6:0] rsvd_status_general_1_;
bit [0:0] phy_ready_;
bit [3:0] rsvd_status_general_0_;
bit [0:0] lanes_reversed_;
bit [0:0] sleep_mode_;
bit [0:0] link_training_;
bit [0:0] link_up_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_status_general_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_status_general_c");
super.new(name);
this.name = name;
set_address('h0);
endfunction : new
 
endclass : reg_hmc_controller_rf_status_general_c
 
//
// HMC controller initialization status
//
class reg_hmc_controller_rf_status_init_c extends cag_rgm_register;
 
typedef struct packed {
bit [0:0] hmc_init_TS1_;
bit [1:0] tx_init_status_;
bit [0:0] all_descramblers_aligned_;
bit [7:0] descrambler_aligned_;
bit [7:0] descrambler_part_aligned_;
bit [7:0] lane_descramblers_locked_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_status_init_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_status_init_c");
super.new(name);
this.name = name;
set_address('h8);
endfunction : new
 
endclass : reg_hmc_controller_rf_status_init_c
 
//
// HMC controller control
//
class reg_hmc_controller_rf_control_c extends cag_rgm_register;
 
typedef struct packed {
bit [7:0] bit_slip_time_;
bit [2:0] rsvd_control_3_;
bit [4:0] irtry_to_send_;
bit [2:0] rsvd_control_2_;
bit [4:0] irtry_received_threshold_;
bit [5:0] rsvd_control_1_;
bit [9:0] rx_token_count_;
bit [6:0] rsvd_control_0_;
bit [0:0] debug_dont_send_tret_;
bit [2:0] first_cube_ID_;
bit [0:0] run_length_enable_;
bit [0:0] scrambler_disable_;
bit [0:0] set_hmc_sleep_;
bit [0:0] hmc_init_cont_set_;
bit [0:0] p_rst_n_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_control_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_control_c");
super.new(name);
this.name = name;
set_address('h10);
endfunction : new
 
endclass : reg_hmc_controller_rf_control_c
 
//
// Count of packets that had data errors but valid flow information
//
class reg_hmc_controller_rf_poisoned_packets_c extends cag_rgm_register;
 
typedef struct packed {
bit [63:0] cnt_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_poisoned_packets_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_poisoned_packets_c");
super.new(name);
this.name = name;
set_address('h18);
endfunction : new
 
endclass : reg_hmc_controller_rf_poisoned_packets_c
 
//
// Nonposted requests sent to the HMC
//
class reg_hmc_controller_rf_sent_np_c extends cag_rgm_register;
 
typedef struct packed {
bit [63:0] cnt_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_sent_np_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_sent_np_c");
super.new(name);
this.name = name;
set_address('h20);
endfunction : new
 
endclass : reg_hmc_controller_rf_sent_np_c
 
//
// Posted requests sent to the HMC
//
class reg_hmc_controller_rf_sent_p_c extends cag_rgm_register;
 
typedef struct packed {
bit [63:0] cnt_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_sent_p_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_sent_p_c");
super.new(name);
this.name = name;
set_address('h28);
endfunction : new
 
endclass : reg_hmc_controller_rf_sent_p_c
 
//
// Read requests sent to the HMC
//
class reg_hmc_controller_rf_sent_r_c extends cag_rgm_register;
 
typedef struct packed {
bit [63:0] cnt_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_sent_r_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_sent_r_c");
super.new(name);
this.name = name;
set_address('h30);
endfunction : new
 
endclass : reg_hmc_controller_rf_sent_r_c
 
//
// Responses received from the HMC
//
class reg_hmc_controller_rf_rcvd_rsp_c extends cag_rgm_register;
 
typedef struct packed {
bit [63:0] cnt_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_rcvd_rsp_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_rcvd_rsp_c");
super.new(name);
this.name = name;
set_address('h38);
endfunction : new
 
endclass : reg_hmc_controller_rf_rcvd_rsp_c
 
//
// Reset performance counters
//
class reg_hmc_controller_rf_counter_reset_c extends cag_rgm_register;
 
typedef struct packed {
bit rreinit_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_counter_reset_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_counter_reset_c");
super.new(name);
this.name = name;
set_address('h40);
endfunction : new
 
endclass : reg_hmc_controller_rf_counter_reset_c
 
//
// Count of re-transmit requests (seq num and bit errors)
//
class reg_hmc_controller_rf_link_retries_c extends cag_rgm_register;
 
typedef struct packed {
bit [31:0] count_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_link_retries_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_link_retries_c");
super.new(name);
this.name = name;
set_address('h48);
endfunction : new
 
endclass : reg_hmc_controller_rf_link_retries_c
 
//
// The number of bit_flips forced by the run length limiter
//
class reg_hmc_controller_rf_run_length_bit_flip_c extends cag_rgm_register;
 
typedef struct packed {
bit [31:0] count_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_hmc_controller_rf_run_length_bit_flip_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_hmc_controller_rf_run_length_bit_flip_c");
super.new(name);
this.name = name;
set_address('h50);
endfunction : new
 
endclass : reg_hmc_controller_rf_run_length_bit_flip_c
 
class rf_hmc_controller_rf_c extends cag_rgm_register_file;
 
rand reg_hmc_controller_rf_status_general_c status_general;
rand reg_hmc_controller_rf_status_init_c status_init;
rand reg_hmc_controller_rf_control_c control;
rand reg_hmc_controller_rf_poisoned_packets_c poisoned_packets;
rand reg_hmc_controller_rf_sent_np_c sent_np;
rand reg_hmc_controller_rf_sent_p_c sent_p;
rand reg_hmc_controller_rf_sent_r_c sent_r;
rand reg_hmc_controller_rf_rcvd_rsp_c rcvd_rsp;
rand reg_hmc_controller_rf_counter_reset_c counter_reset;
rand reg_hmc_controller_rf_link_retries_c link_retries;
rand reg_hmc_controller_rf_run_length_bit_flip_c run_length_bit_flip;
 
`uvm_object_utils(rf_hmc_controller_rf_c)
 
function new(string name="rf_hmc_controller_rf_c");
super.new(name);
this.name = name;
set_address('h0);
status_general = reg_hmc_controller_rf_status_general_c::type_id::create("status_general");
status_general.set_address('h0);
add_register(status_general);
status_init = reg_hmc_controller_rf_status_init_c::type_id::create("status_init");
status_init.set_address('h8);
add_register(status_init);
control = reg_hmc_controller_rf_control_c::type_id::create("control");
control.set_address('h10);
add_register(control);
poisoned_packets = reg_hmc_controller_rf_poisoned_packets_c::type_id::create("poisoned_packets");
poisoned_packets.set_address('h18);
add_register(poisoned_packets);
sent_np = reg_hmc_controller_rf_sent_np_c::type_id::create("sent_np");
sent_np.set_address('h20);
add_register(sent_np);
sent_p = reg_hmc_controller_rf_sent_p_c::type_id::create("sent_p");
sent_p.set_address('h28);
add_register(sent_p);
sent_r = reg_hmc_controller_rf_sent_r_c::type_id::create("sent_r");
sent_r.set_address('h30);
add_register(sent_r);
rcvd_rsp = reg_hmc_controller_rf_rcvd_rsp_c::type_id::create("rcvd_rsp");
rcvd_rsp.set_address('h38);
add_register(rcvd_rsp);
counter_reset = reg_hmc_controller_rf_counter_reset_c::type_id::create("counter_reset");
counter_reset.set_address('h40);
add_register(counter_reset);
link_retries = reg_hmc_controller_rf_link_retries_c::type_id::create("link_retries");
link_retries.set_address('h48);
add_register(link_retries);
run_length_bit_flip = reg_hmc_controller_rf_run_length_bit_flip_c::type_id::create("run_length_bit_flip");
run_length_bit_flip.set_address('h50);
add_register(run_length_bit_flip);
endfunction : new
 
endclass : rf_hmc_controller_rf_c
 
//
// Pattern Generator Control Register
//
class reg_pattern_gen_rf_control_c extends cag_rgm_register;
 
typedef struct packed {
bit [2:0] cubID_size_;
bit [2:0] first_cube_ID_;
bit [0:0] hmc_gen_running_;
bit [0:0] hmc_gen_enable_;
bit [6:0] hmc_gen_read_ratio_;
bit [3:0] hmc_gen_write_size_;
bit [3:0] hmc_gen_read_size_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_pattern_gen_rf_control_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_pattern_gen_rf_control_c");
super.new(name);
this.name = name;
set_address('h80);
endfunction : new
 
endclass : reg_pattern_gen_rf_control_c
 
//
// dummy
//
class reg_pattern_gen_rf_dummy_c extends cag_rgm_register;
 
typedef struct packed {
bit [3:0] dummy_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_pattern_gen_rf_dummy_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_pattern_gen_rf_dummy_c");
super.new(name);
this.name = name;
set_address('h88);
endfunction : new
 
endclass : reg_pattern_gen_rf_dummy_c
 
class rf_pattern_gen_rf_c extends cag_rgm_register_file;
 
rand reg_pattern_gen_rf_control_c control;
rand reg_pattern_gen_rf_dummy_c dummy;
 
`uvm_object_utils(rf_pattern_gen_rf_c)
 
function new(string name="rf_pattern_gen_rf_c");
super.new(name);
this.name = name;
set_address('h80);
control = reg_pattern_gen_rf_control_c::type_id::create("control");
control.set_address('h80);
add_register(control);
dummy = reg_pattern_gen_rf_dummy_c::type_id::create("dummy");
dummy.set_address('h88);
add_register(dummy);
endfunction : new
 
endclass : rf_pattern_gen_rf_c
 
//
// General Reset controlable via i2c
//
class reg_res_rf_control_c extends cag_rgm_register;
 
typedef struct packed {
bit [0:0] res_n_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_res_rf_control_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_res_rf_control_c");
super.new(name);
this.name = name;
set_address('h90);
endfunction : new
 
endclass : reg_res_rf_control_c
 
//
// dummy
//
class reg_res_rf_dummy_c extends cag_rgm_register;
 
typedef struct packed {
bit [0:0] dummy_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_res_rf_dummy_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_res_rf_dummy_c");
super.new(name);
this.name = name;
set_address('h98);
endfunction : new
 
endclass : reg_res_rf_dummy_c
 
class rf_res_rf_c extends cag_rgm_register_file;
 
rand reg_res_rf_control_c control;
rand reg_res_rf_dummy_c dummy;
 
`uvm_object_utils(rf_res_rf_c)
 
function new(string name="rf_res_rf_c");
super.new(name);
this.name = name;
set_address('h90);
control = reg_res_rf_control_c::type_id::create("control");
control.set_address('h90);
add_register(control);
dummy = reg_res_rf_dummy_c::type_id::create("dummy");
dummy.set_address('h98);
add_register(dummy);
endfunction : new
 
endclass : rf_res_rf_c
 
//
// General Reset controlable via i2c
//
class reg_phy_rf_control_c extends cag_rgm_register;
 
typedef struct packed {
bit [0:0] lpm_en_;
bit [0:0] rx_res_n_;
bit [0:0] tx_res_n_;
bit [0:0] res_n_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_phy_rf_control_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_phy_rf_control_c");
super.new(name);
this.name = name;
set_address('ha0);
endfunction : new
 
endclass : reg_phy_rf_control_c
 
//
// status
//
class reg_phy_rf_status_c extends cag_rgm_register;
 
typedef struct packed {
bit [7:0] cdr_locked_;
} pkd_flds_s;
 
`cag_rgm_register_fields(pkd_flds_s)
 
`uvm_object_utils_begin(reg_phy_rf_status_c)
`uvm_field_int(fields,UVM_ALL_ON)
`uvm_object_utils_end
 
function new(string name="reg_phy_rf_status_c");
super.new(name);
this.name = name;
set_address('ha8);
endfunction : new
 
endclass : reg_phy_rf_status_c
 
class rf_phy_rf_c extends cag_rgm_register_file;
 
rand reg_phy_rf_control_c control;
rand reg_phy_rf_status_c status;
 
`uvm_object_utils(rf_phy_rf_c)
 
function new(string name="rf_phy_rf_c");
super.new(name);
this.name = name;
set_address('ha0);
control = reg_phy_rf_control_c::type_id::create("control");
control.set_address('ha0);
add_register(control);
status = reg_phy_rf_status_c::type_id::create("status");
status.set_address('ha8);
add_register(status);
endfunction : new
 
endclass : rf_phy_rf_c
 
class rf_vc107_1hmc_8lane_top_rf_c extends cag_rgm_register_file;
 
rand rf_hmc_controller_rf_c hmc_controller_rf;
rand rf_pattern_gen_rf_c pattern_gen_rf;
rand rf_res_rf_c res_rf;
rand rf_phy_rf_c phy_rf;
 
`uvm_object_utils(rf_vc107_1hmc_8lane_top_rf_c)
 
function new(string name="rf_vc107_1hmc_8lane_top_rf_c");
super.new(name);
this.name = name;
set_address('h0);
hmc_controller_rf = rf_hmc_controller_rf_c::type_id::create("hmc_controller_rf");
add_register_file(hmc_controller_rf);
pattern_gen_rf = rf_pattern_gen_rf_c::type_id::create("pattern_gen_rf");
add_register_file(pattern_gen_rf);
res_rf = rf_res_rf_c::type_id::create("res_rf");
add_register_file(res_rf);
phy_rf = rf_phy_rf_c::type_id::create("phy_rf");
add_register_file(phy_rf);
endfunction : new
 
endclass : rf_vc107_1hmc_8lane_top_rf_c
 
/openhmc/trunk/openHMC/sim/tb/bfm/src/targets/config.h
0,0 → 1,42
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`define RX_TOKENS 100
`define HMC_TOKENS 100
`define HMC_CUBID 0
/openhmc/trunk/openHMC/sim/tb/bfm/src/targets/dut_openhmc_behavioral_bfm.sv
0,0 → 1,394
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`default_nettype none
`timescale 100ps/10ps
 
 
`include "config.h"
 
 
module dut #(
//*************************Don't touch! Control the design in config.h and with arguments when executing run.sh
parameter LOG_NUM_LANES = `LOG_NUM_LANES,
parameter NUM_LANES = 2**LOG_NUM_LANES,
parameter LOG_FPW = `LOG_FPW,
parameter FPW = `FPW,
parameter DWIDTH = 128*FPW,
parameter NUM_DATA_BYTES = 16*FPW,
parameter LANE_WIDTH = DWIDTH / NUM_LANES
//*************************
)
(
//AXI4 user clock
input wire clk_user,
//125MHz reference clock
input wire clk_hmc_refclk,
//Global reset
input wire res_n,
 
//AXI4 interface ports
axi4_stream_if axi4_req,
axi4_stream_if axi4_rsp,
 
//Register File interface
cag_rgm_rfs_if rfs_hmc
);
 
//----------------------------- Configuration and Debug
bit disable_lane_delays = 1;
bit disable_lane_polarity = 1;
bit disable_scramblers = 0;
//Lane Reversal
localparam LANE_REVERSAL_TX = 0;
localparam LANE_REVERSAL_RX = 0;
 
//Lane delays
localparam LOG_DELAY = 5;
typedef bit [LOG_DELAY-1:0] delay_t;
delay_t [NUM_LANES-1:0] delays_Rx;
delay_t [NUM_LANES-1:0] delays_Tx;
//Polarity
bit [NUM_LANES-1:0] polarity_Rx;
 
//----------------------------- Wiring openHMC controller
wire [DWIDTH-1:0] to_serializers;
wire [DWIDTH-1:0] from_deserializers;
wire [NUM_LANES-1:0] bit_slip;
bit P_RST_N;
 
// Wire the HMC BFM model
wire LxRXPS; // HMC input
wire LxTXPS; // HMC output
wire FERR_N; // HMC output
wire hmc_refclkp;
wire hmc_refclkn;
wire [16-1:0] LxRXP;
wire [16-1:0] LxRXN;
wire [16-1:0] LxTXP;
wire [16-1:0] LxTXN;
 
//----------------------------- Signal Routing from SerDes to HMC
wire [NUM_LANES-1:0] serial_Rx;
wire [NUM_LANES-1:0] serial_Rx_routed;
wire [NUM_LANES-1:0] serial_Txn;
wire [NUM_LANES-1:0] serial_Txp;
wire [NUM_LANES-1:0] serial_Tx_routed;
 
assign LxRXP = {serial_Tx_routed};
assign LxRXN = ~LxRXP;
assign serial_Rx = LxTXP[NUM_LANES-1:0];
 
//----------------------------- Define the Clocks
bit clk_10G;
bit clk_hmc;
assign hmc_refclkp = clk_hmc_refclk;
assign hmc_refclkn = ~hmc_refclkp;
 
//----------------------------- Attach the Register File System interface
assign rfs_hmc_if.clk = clk_hmc;
assign rfs_hmc_if.res_n = res_n;
 
//----------------------------- Randomize configuration and Load HMC Link Config
int n = 0;
initial begin
var cls_link_cfg link_cfg; // declare configuration object
 
//Randomize lane delays, polarity, and reversal
repeat(NUM_LANES) begin
delays_Rx[n] = disable_lane_delays ? 0 : $urandom_range(0,8);
delays_Tx[n] = disable_lane_delays ? 0 : $urandom_range(0,8);
polarity_Rx[n] = disable_lane_polarity ? 0 : $urandom_range(0,1);
n++;
end
 
#(5us);
 
//Create a new HMC link config
link_cfg = new();
 
link_cfg.cfg_cid = `HMC_CUBID;
link_cfg.cfg_lane_auto_correct = 1;
link_cfg.cfg_rsp_open_loop = 0;
 
// These are set to match the design
link_cfg.cfg_rx_clk_ratio = 40;
link_cfg.cfg_half_link_mode_rx = (NUM_LANES==8);
 
link_cfg.cfg_tx_clk_ratio = 40;
link_cfg.cfg_half_link_mode_tx = (NUM_LANES==8);
 
link_cfg.cfg_descram_enb = !disable_scramblers;
link_cfg.cfg_scram_enb = !disable_scramblers;
 
link_cfg.cfg_tokens = `HMC_TOKENS;
link_cfg.cfg_init_retry_rxcnt = 16;
link_cfg.cfg_init_retry_txcnt = 16;
 
//***Enable Errors - Dont touch
//link_cfg.cfg_rsp_dln = 5;
//link_cfg.cfg_rsp_lng = 5;
//link_cfg.cfg_rsp_crc = 5;
//link_cfg.cfg_rsp_seq = 5;
//link_cfg.cfg_rsp_poison= 5;
//
 
link_cfg.cfg_retry_enb = 1;
 
if(!disable_scramblers)
link_cfg.cfg_tx_rl_lim = 85;
 
tb_top.dut_I.hmc_bfm0.set_config(link_cfg,0);
//link_cfg.display(); //uncomment for full link configuration output
 
$display("***** HMC BFM CONFIGURATION IS COMPLETE *****");
end
 
//----------------------------- Generate Clocks
generate
begin : clocking_gen
initial clk_10G = 1'b1;
always #0.05ns clk_10G = ~clk_10G;
 
initial clk_hmc = 1'bZ;
always begin
if (clk_hmc == 1'bZ )
begin
@(posedge clk_hmc_refclk);
clk_hmc = 1'b1;
end
//Clock frequency depends on the link-width and datapath-width. Lane speed is fixed to 10Gbit
case(FPW)
2: begin
if(NUM_LANES==8)
#1.6ns clk_hmc = !clk_hmc;
else begin
$display("*******************************************************");
$display("***** Sorry - This configuration is not supported *****");
$display("***** Please use FPW=2 only with 8 lanes *****");
$display("*******************************************************");
$finish;
end
end
4: begin
if(NUM_LANES==8)
#3.2ns clk_hmc = !clk_hmc;
else
#1.6ns clk_hmc = !clk_hmc;
end
6: begin
if(NUM_LANES==8)
#4.8ns clk_hmc = !clk_hmc;
else
#2.4ns clk_hmc = !clk_hmc;
end
8: begin
if(NUM_LANES==8)
#6.4ns clk_hmc = !clk_hmc;
else
#3.2ns clk_hmc = !clk_hmc;
end
endcase
end
end
endgenerate
 
//----------------------------- Signal Routing
genvar lane;
generate
for (lane=0; lane<NUM_LANES; lane++) begin : delay_lanes_gen
routing #(
.LOG_DELAY(LOG_DELAY)
) routing_Tx (
.clk(clk_10G),
.data_in(serial_Txp[lane]),
.delay_in(delays_Tx[lane]),
.polarity_reverse_in(1'b0),
.data_out(serial_Tx_routed[(LANE_REVERSAL_TX ? NUM_LANES-1-lane : lane)])
);
routing #(
.LOG_DELAY(LOG_DELAY)
) routing_Rx (
.clk(clk_10G),
.data_in(serial_Rx[lane]),
.delay_in(delays_Rx[lane]),
.polarity_reverse_in(polarity_Rx[lane]),
.data_out(serial_Rx_routed[(LANE_REVERSAL_RX ? NUM_LANES-1-lane : lane)])
);
end
endgenerate
 
//----------------------------- Behavioral SerDes
generate
begin : serializers_gen
assign serial_Txn = ~serial_Txp;
 
for (lane=0; lane<NUM_LANES; lane++) begin : behavioral_gen
serializer #(
.DWIDTH(LANE_WIDTH)
) serializer_I (
.clk(clk_hmc),
.fast_clk(clk_10G),
.data_in(to_serializers[lane*LANE_WIDTH+LANE_WIDTH-1:lane*LANE_WIDTH]),
.data_out(serial_Txp[lane])
);
deserializer #(
.DWIDTH(LANE_WIDTH)
) deserializer_I (
.clk(clk_hmc),
.fast_clk(clk_10G),
.bit_slip(bit_slip[lane]),
.data_in(serial_Rx_routed[lane]),
.data_out(from_deserializers[lane*LANE_WIDTH+LANE_WIDTH-1:lane*LANE_WIDTH])
);
end
end
endgenerate
 
//=====================================================================================================
//-----------------------------------------------------------------------------------------------------
//---------INSTANTIATIONS HERE-------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//=====================================================================================================
hmc_controller_top #(
.DWIDTH(DWIDTH),
.LOG_FPW(LOG_FPW),
.FPW(FPW),
.LOG_NUM_LANES(LOG_NUM_LANES),
.NUM_LANES(NUM_LANES),
.NUM_DATA_BYTES(NUM_DATA_BYTES)
)
hmc_controller_instance
(
 
//----------------------------------
//----SYSTEM INTERFACES
//----------------------------------
.clk_user(clk_user),
.clk_hmc(clk_hmc),
.res_n_user(res_n),
.res_n_hmc(res_n),
 
//----------------------------------
//----Connect HMC Controller
//----------------------------------
//to TX
.s_axis_tx_TVALID(axi4_req.TVALID),
.s_axis_tx_TREADY(axi4_req.TREADY),
.s_axis_tx_TDATA(axi4_req.TDATA),
.s_axis_tx_TUSER(axi4_req.TUSER),
//from RX
.m_axis_rx_TVALID(axi4_rsp.TVALID),
.m_axis_rx_TREADY(axi4_rsp.TREADY),
.m_axis_rx_TDATA(axi4_rsp.TDATA),
.m_axis_rx_TUSER(axi4_rsp.TUSER),
 
//----------------------------------
//----Connect Physical Link
//----------------------------------
.phy_data_tx_link2phy(to_serializers),
.phy_data_rx_phy2link(from_deserializers),
.phy_bit_slip(bit_slip),
.phy_ready(res_n),
 
//----------------------------------
//----Connect HMC
//----------------------------------
.P_RST_N(P_RST_N),
.hmc_LxRXPS(LxRXPS),
.hmc_LxTXPS(LxTXPS),
.FERR_N(FERR_N),
 
//----------------------------------
//----Connect RF
//----------------------------------
.rf_address(rfs_hmc.address),
.rf_read_data(rfs_hmc.read_data),
.rf_invalid_address(rfs_hmc.invalid_address),
.rf_access_complete(rfs_hmc.access_done),
.rf_read_en(rfs_hmc.ren),
.rf_write_en(rfs_hmc.wen),
.rf_write_data(rfs_hmc.write_data)
 
);
 
 
//********************************************************************************
// From MICRON's hmc_bfm_tb.sv
//******************************************
//BFM
hmc_bfm #(
.num_links_c (1)
)
hmc_bfm0 (
.LxRXP (LxRXP),
.LxRXN (LxRXN),
.LxTXP (LxTXP),
.LxTXN (LxTXN),
.LxRXPS (LxRXPS),
.LxTXPS (LxTXPS),
.FERR_N (FERR_N),
 
.REFCLKP (hmc_refclkp),
.REFCLKN (hmc_refclkn),
.REFCLKSEL (1'b0),
.P_RST_N (P_RST_N),
 
.TRST_N (1'b0),
.TCK (1'b0),
.TMS (1'b0),
.TDI (1'b0),
.TDO (),
 
.SCL (1'b0),
.SDA (),
 
.CUB (3'b0),
.REFCLK_BOOT (2'b0),
 
.EXTRESTP (),
.EXTRESTN (),
.EXTRESBP (),
.EXTRESBN ()
);
 
endmodule : dut
 
`default_nettype wire
 
/openhmc/trunk/openHMC/sim/tb/bfm/src/bfm_2_hmc_monitor.sv
0,0 → 1,126
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef BFM_2_HMC
`define BFM_2_HMC
class bfm_2_hmc_mon extends hmc_module_mon;
 
pkt_analysis_port#() mb_pkt;
cls_pkt pkt;
hmc_packet hmc_pkt;
bit bitstream[];
int phit_size = 64;
bit [64:0] header; //-- phit size
bit [64:0] tail ; //-- phit size
int data_phit_count;
int flit_size = 128;
`uvm_component_utils(bfm_2_hmc_mon)
function new ( string name="bfm_2_hmc_mon", uvm_component parent );
super.new(name, parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(uvm_config_db#(pkt_analysis_port#())::get(this, "", "mb_pkt",mb_pkt) ) begin
end else
`uvm_fatal(get_type_name(),"pkt_analysis_port#() is not set")
endfunction : build_phase
task run();
`uvm_info(get_type_name(),$psprintf("starting BFM_2_HMC converter"), UVM_MEDIUM)
forever begin
mb_pkt.get(pkt);
 
header = pkt.get_header();
tail = pkt.get_tail();
data_phit_count = pkt.data.size(); //-- 7 flits->14 phits --> 14-2 =12 data_phits
bitstream = new [2*phit_size + data_phit_count*phit_size];
//-- generate Bitstream
if (header >64'b0) begin
for (int b = 0; b < 64; b++) begin //-- read header to bitmap
bitstream[b]=header[b];
end
if (data_phit_count > 0)
for (int phit = 0; phit < data_phit_count; phit++) //-- read data to bitmap
for (int b = 0; b < phit_size; b++)
bitstream[(phit + 1) * phit_size + b] = pkt.data[phit][b];
for (int b = 0; b < 64; b++) begin //-- read tail to bitmap
bitstream[(data_phit_count+1)*phit_size+b]=tail[b];
end
//-- create hmc packet
hmc_pkt = hmc_packet::type_id::create("packet", this);
void'(hmc_pkt.unpack(bitstream));
`uvm_info(get_type_name(),$psprintf("Got a BFM Packet: %s",pkt.convert2string()), UVM_HIGH)
//-- write to HMC Monitor / Scoreboard
if (hmc_pkt.get_command_type() == HMC_FLOW_TYPE )begin //-- do not write if Flow Control Packet
`uvm_info(get_type_name(),$psprintf("receiving non request/response packet"), UVM_HIGH)
`uvm_info(get_type_name(),$psprintf("hmc_packet: \n%s", hmc_pkt.sprint()), UVM_HIGH)
end else begin
`uvm_info(get_type_name(),$psprintf("commiting translated packet"), UVM_MEDIUM)
`uvm_info(get_type_name(),$psprintf("hmc_packet: \n%s", hmc_pkt.sprint()), UVM_HIGH)
item_collected_port.write(hmc_pkt);
end
end
end
endtask
 
endclass
 
 
`endif
/openhmc/trunk/openHMC/sim/tb/bfm/src/behavioral/deserializer.v
0,0 → 1,99
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
`timescale 100ps/100ps
 
module deserializer #(
parameter LOG_DWIDTH=7,
parameter DWIDTH=64
)
(
input wire clk,
input wire fast_clk,
input wire bit_slip,
input wire data_in,
output reg [DWIDTH-1:0] data_out
);
 
reg [DWIDTH-1:0] tmp_buffer;
reg [DWIDTH-1:0] buffer;
reg [DWIDTH-1:0] buffer2;
reg [DWIDTH-1:0] buffer3;
reg [LOG_DWIDTH-1:0] curr_bit = 'h0;
reg bit_slip_done = 1'b0;
reg [8:0] bit_slip_cnt=9'h0;
 
// SEQUENTIAL PROCESS
always @ (posedge fast_clk)
begin
if (!bit_slip || bit_slip_done) begin
if(curr_bit == DWIDTH-1) begin
curr_bit <= 0;
end else begin
curr_bit <= curr_bit + 1;
end
end
 
if (bit_slip && !bit_slip_done)
bit_slip_done = 1'b1;
 
if (bit_slip_done && !bit_slip)
bit_slip_done = 1'b0;
 
tmp_buffer[curr_bit] <= data_in;
if (|curr_bit == 1'b0)
buffer <= tmp_buffer;
end
 
always @ (posedge clk)
begin
buffer2 <= buffer;
buffer3 <= buffer2;
 
if (bit_slip)
bit_slip_cnt = bit_slip_cnt + 1;
if (bit_slip_cnt < 63)
data_out <= buffer3;
else if (bit_slip_cnt < 127)
data_out <= buffer2;
else if (bit_slip_cnt < 191)
data_out <= buffer;
end
 
endmodule
 
/openhmc/trunk/openHMC/sim/tb/bfm/src/behavioral/routing.v
0,0 → 1,64
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`timescale 100ps/100ps
 
module routing #(
parameter LOG_DELAY=6
)
(
input wire clk,
input wire data_in,
input wire [LOG_DELAY-1:0] delay_in,
input wire polarity_reverse_in,
output wire data_out
);
 
reg [2**(LOG_DELAY+1)-1:0] wire_delay;
 
// SEQUENTIAL PROCESS
always @ (posedge clk)
begin
wire_delay <= {wire_delay[2**(LOG_DELAY+1)-2:0], data_in^polarity_reverse_in};
end
 
assign data_out = wire_delay[delay_in+2**LOG_DELAY];
 
endmodule
 
/openhmc/trunk/openHMC/sim/tb/bfm/src/behavioral/serializer.v
0,0 → 1,75
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`timescale 100ps/100ps
 
module serializer #(
parameter LOG_DWIDTH=7,
parameter DWIDTH=64
)
(
input wire clk,
input wire fast_clk,
input wire [DWIDTH-1:0] data_in,
output wire data_out
);
 
reg [DWIDTH-1:0] buffer;
 
// SEQUENTIAL PROCESS
always @ (posedge clk)
begin
buffer <= data_in;
end
 
reg [LOG_DWIDTH-1:0] curr_bit = 'h0;
reg clk_d1;
 
always @ (posedge fast_clk)
begin
curr_bit <= curr_bit + 1;
clk_d1 <= clk;
if (!clk_d1 && clk)
curr_bit <= 0;
end
 
assign data_out = buffer[curr_bit];
 
endmodule
 
/openhmc/trunk/openHMC/sim/tb/bfm/src/hmc_2_axi4_sequence.sv
0,0 → 1,284
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
//
// hmc_2_axi4_sequence
//
//
 
`ifndef HMC_2_AXI4_SEQUENCE_SV
`define HMC_2_AXI4_SEQUENCE_SV
 
class hmc_2_axi4_sequence #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends uvm_sequence #(axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)));
 
int unsigned num_packets = 1; //-- packets to generate
int unsigned max_pkts_per_cycle = 4; //-- maximum packets in single AXI4 cycle
 
rand hmc_req_packet hmc_items[];
hmc_packet hmc_packets_ready[$];
typedef bit [1+1+1+127:0] tail_header_flit_t;
tail_header_flit_t flit_queue[$];
rand int tag = 0;
constraint tag_value_c {
tag >= 0;
tag < 512;
}
 
axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES),.TUSER_WIDTH(TUSER_WIDTH)) axi4_queue[$];
 
`uvm_object_param_utils_begin(hmc_2_axi4_sequence #(.DATA_BYTES(DATA_BYTES),.TUSER_WIDTH(TUSER_WIDTH)))
`uvm_field_int(num_packets, UVM_DEFAULT | UVM_DEC)
`uvm_field_int(max_pkts_per_cycle, UVM_DEFAULT | UVM_DEC)
`uvm_object_utils_end
 
`uvm_declare_p_sequencer(hmc_2_axi4_sequencer #(.DATA_BYTES(DATA_BYTES),.TUSER_WIDTH(TUSER_WIDTH)))
 
function new(string name="hmc_2_axi4_sequence");
super.new(name);
 
endfunction : new
 
function void pre_randomize ();
super.pre_randomize();
 
hmc_items = new[num_packets];
foreach (hmc_items[i]) begin
hmc_items[i] = hmc_req_packet::type_id::create($psprintf("hmc_item[%0d]", i) );
end
 
`uvm_info(get_type_name(),$psprintf("%0d HMC packets generated", num_packets), UVM_LOW)
endfunction : pre_randomize
function void pack_hmc_packet(hmc_packet pkt);
bit bitstream[];
tail_header_flit_t tmp_flit;
 
int unsigned bitcount;
int unsigned packet_count=1;
 
bitcount = pkt.pack(bitstream);
 
pkt_successfully_packed : assert (bitcount > 0);
 
//-- For each FLIT in the packet, add the flit entry
for (int f=0; f<bitcount/128; f++) begin
for (int i=0; i< 128; i++)
tmp_flit[i] = bitstream[f*128+i];
 
tmp_flit[128] = (f==0); //-- Header
 
tmp_flit[129] = (f==bitcount/128-1); //-- Tail
tmp_flit[130] = 1'b1; //-- Flit is valid
 
flit_queue.push_back(tmp_flit);
end
endfunction : pack_hmc_packet
function void hmc_packet_2_axi_cycles();
axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES),.TUSER_WIDTH(TUSER_WIDTH)) axi4_item;
int unsigned FPW = DATA_BYTES/16; //--FPW: desired Data width in Flits (HMC packet length) valid: 4.6.8 databytes= tdata_width /8 fpw = tdata_width /128
int unsigned HEADERS = 1*FPW;
int unsigned TAILS = 2*FPW;
int unsigned VALIDS = 0;
int unsigned pkts_in_cycle = 0; //-- HMC tails inserted in current AXI4 cycle
int unsigned header_in_cycle = 0; //-- HMC headers inserted in current AXI4 cycle
hmc_packet hmc_pkt;
bit first_pkt = 1;
int flit_offset=0; //-- flit offset First flit-> create new axi_item
tail_header_flit_t current_flit;
tail_header_flit_t next_flit;
//-- create empty vc
`uvm_create_on(axi4_item, p_sequencer)
axi4_item.tdata = 0;
axi4_item.tuser = 0;
axi4_item.delay = hmc_packets_ready[0].flit_delay / FPW; // measured in flits
//`uvm_info(get_type_name(),$psprintf("delay for axi4_cycle 0 is %0d", axi4_item.delay), UVM_MEDIUM)
while (hmc_packets_ready.size() >0 ) begin
hmc_pkt = hmc_packets_ready.pop_front();
pack_hmc_packet(hmc_pkt);
//-- write flits 2 axi4_queue
while( flit_queue.size > 0 ) begin //-- flit queue contains flits
current_flit = flit_queue.pop_front();
if (first_pkt) begin
if (current_flit[128]) begin //-- If current flit is header
flit_offset+= hmc_pkt.flit_delay;
end
first_pkt = 0;
end
//-- check if axi4_item is full
if ((flit_offset >= FPW) || pkts_in_cycle == max_pkts_per_cycle ) begin
//-- push full axi item to axi4_queue
`uvm_info(get_type_name(),$psprintf("axi4_item is full (offset = %0d), writing element %0d to queue ", flit_offset, axi4_queue.size()), UVM_MEDIUM)
axi4_queue.push_back(axi4_item);
//-- create new AXI4 cycle
`uvm_create_on(axi4_item, p_sequencer)
axi4_item.tdata = 0;
axi4_item.tuser = 0;
axi4_item.delay = (flit_offset / FPW) -1; //-- flit offset contains also empty flits
if (flit_offset % FPW >0)
axi4_item.delay +=1;
`uvm_info(get_type_name(),$psprintf("HMC Packets in last cycle: %0d, %0d", pkts_in_cycle, header_in_cycle), UVM_HIGH)
pkts_in_cycle = 0; //-- reset HMC packet counter in AXI4 Cycle
header_in_cycle = 0;
`uvm_info(get_type_name(),$psprintf("axi_delay is %0d", axi4_item.delay), UVM_MEDIUM)
//-- reset flit_offset
flit_offset=0;
end
 
//-- write flit to axi4_item
for (int i =0;i<128;i++) begin//write flit to cycle
axi4_item.tdata[(flit_offset*128)+i] = current_flit[i];
end
//-- write valid
axi4_item.tuser[VALIDS +flit_offset] =current_flit[130]; //-- valid[fpw-1:0]
//-- write header
axi4_item.tuser[HEADERS +flit_offset] = current_flit[128]; //-- only 1 if header
//-- write footer
axi4_item.tuser[TAILS +flit_offset] = current_flit[129]; //-- only 1 if tail
if(current_flit[129]) begin
pkts_in_cycle ++;
end
if(current_flit[128]) begin
header_in_cycle ++;
end
//-- debugging output
if(current_flit[128]) begin
`uvm_info(get_type_name(),$psprintf("FLIT is header at pos %d", flit_offset), UVM_MEDIUM)
end
if(current_flit[129]) begin
`uvm_info(get_type_name(),$psprintf("FLIT is tail at pos %d", flit_offset), UVM_MEDIUM)
end
//-- insert empty flits between packets
flit_offset++;
end
end
//-- push last axi4_item to axi4_queue
axi4_queue.push_back(axi4_item);
endfunction : hmc_packet_2_axi_cycles
task body();
axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES),.TUSER_WIDTH(TUSER_WIDTH)) axi4_item;
int working_pos = 0;
`uvm_info(get_type_name(),$psprintf("HMC Packets to send: %0d", hmc_items.size()), UVM_MEDIUM)
 
while (hmc_items.size-1 > working_pos)begin //-- cycle until all hmc_packets have been sent
for (int i = working_pos; i < hmc_items.size(); i++) begin //-- get a tag for each packet
//-- only register an tag if response required!
if (hmc_items[i].get_command_type() == HMC_WRITE_TYPE ||
hmc_items[i].get_command_type() == HMC_MISC_WRITE_TYPE ||
hmc_items[i].get_command_type() == HMC_READ_TYPE ||
hmc_items[i].get_command_type() == HMC_MODE_READ_TYPE)
begin
p_sequencer.handler.try_get_tag(tag);
`uvm_info(get_type_name(),$psprintf("Tag for HMC Packet %0d is: %0d", i, tag), UVM_MEDIUM)
end else begin
tag = 0;
// void'(randomize(tag)); //-- can be used to randomize the tag
`uvm_info(get_type_name(),$psprintf("Tag for HMC Packet Type %0d is: %0d", hmc_items[i].get_command_type(), tag), UVM_HIGH)
end
if (tag >= 0) begin
hmc_items[i].tag = tag;
hmc_packets_ready.push_back(hmc_items[i]);
working_pos = i+1;
end else begin
break; //-- send all already processed AXI4 Cycles if tag_handler can not provide an additional tag
end
end
 
 
if (hmc_packets_ready.size()>0) begin
 
//-- generate axi4_queue
hmc_packet_2_axi_cycles();
 
//-- send axi4_queue
while( axi4_queue.size() > 0 ) begin
`uvm_info(get_type_name(),$psprintf("axi4_queue contains %0d items", axi4_queue.size()), UVM_MEDIUM)
axi4_item = axi4_queue.pop_front();
`uvm_send(axi4_item);
`uvm_info(get_type_name(),$psprintf("\n%s", axi4_item.sprint()), UVM_HIGH)
end
end
end
endtask : body
 
endclass : hmc_2_axi4_sequence
 
`endif // HMC_2_AXI4_SEQUENCE_SV
 
/openhmc/trunk/openHMC/sim/tb/bfm/src/hmc_req_packet.sv
0,0 → 1,78
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
// hmc_req_packet
//
 
// Only requests should be sent to test the controller
// All of the tail fields should be zero
 
`ifndef HMC_REQ_PACKET_SV
`define HMC_REQ_PACKET_SV
 
class hmc_req_packet extends hmc_packet;
`uvm_object_utils(hmc_req_packet)
constraint c_req_command { command >= HMC_WRITE_16 && command <= HMC_READ_128; }
// constraint c_req_command_fix {command >= HMC_POSTED_WRITE_64 && command <= HMC_POSTED_WRITE_64;}
// constraint c_req_command_fix {command >= HMC_WRITE_16 && command <= HMC_WRITE_128;}
constraint c_req_command_fix {
(command >= HMC_WRITE_16 && command <= HMC_WRITE_128)
||
(command >= HMC_POSTED_WRITE_16 && command <= HMC_POSTED_WRITE_128)
||
(command >= HMC_READ_16 && command <= HMC_READ_128)
;}
 
constraint c_zero_tail_fields {
return_token_count == 0;
sequence_number == 0;
forward_retry_pointer == 0;
return_retry_pointer == 0;
packet_crc == 0;
}
 
function new (string name = "hmc_req_packet");
super.new(name);
endfunction : new
 
endclass : hmc_req_packet
 
`endif // HMC_REQ_PACKET_SV
 
/openhmc/trunk/openHMC/sim/tb/bfm/src/hmc_2_axi4_sequencer.sv
0,0 → 1,70
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
//
// hmc_2_axi4_sequencer
//
//
 
`ifndef HMC_2_AXI4_SEQUENCER_SV
`define HMC_2_AXI4_SEQUENCER_SV
 
typedef class hmc_2_axi4_sequence;
 
class hmc_2_axi4_sequencer #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends axi4_stream_master_sequencer #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH));
 
tag_handler handler; //-- a tag handler is used to handle tags of non posted packets
`uvm_component_param_utils_begin(hmc_2_axi4_sequencer #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))
`uvm_field_object(handler, UVM_DEFAULT)
`uvm_component_utils_end
function new (string name = "hmc_2_axi4_sequencer", uvm_component parent);
super.new(name, parent);
endfunction : new
 
function void build_phase(uvm_phase phase);
handler = tag_handler::type_id::create("handler", this);
endfunction : build_phase
endclass : hmc_2_axi4_sequencer
 
`endif // HMC_2_AXI4_SEQUENCER_SV
 
/openhmc/trunk/openHMC/sim/tb/bfm/src/hmc_vseqr.sv
0,0 → 1,60
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef hmc_VIRTUAL_SEQUENCER_SV
`define hmc_VIRTUAL_SEQUENCER_SV
 
class hmc_vseqr extends uvm_sequencer;
 
// hmc_link_config link_config;
 
//-- references to testbench sequencers
cag_rgm_sequencer rf_seqr_hmc;
 
hmc_2_axi4_sequencer #(.DATA_BYTES(`AXI4BYTES),.TUSER_WIDTH(`AXI4BYTES)) axi4_req_seqr;
 
`uvm_component_utils(hmc_vseqr)
 
function new (string name = "hmc_virtual_sequencer", uvm_component parent);
super.new(name, parent);
endfunction : new
 
endclass : hmc_vseqr
 
`endif // hmc_VIRTUAL_SEQUENCER_SV
/openhmc/trunk/openHMC/sim/tb/run/clean_up.sh
0,0 → 1,45
#
# .--------------. .----------------. .------------.
# | .------------. | .--------------. | .----------. |
# | | ____ ____ | | | ____ ____ | | | ______ | |
# | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
# ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
# / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
# (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
# \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
# | | | | | | | | | | | |
# |_| | '------------' | '--------------' | '----------' |
# '--------------' '----------------' '------------'
#
# openHMC - An Open Source Hybrid Memory Cube Controller
# (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
# www.ziti.uni-heidelberg.de
# B6, 26
# 68159 Mannheim
# Germany
#
# Contact: openhmc@ziti.uni-heidelberg.de
# http://ra.ziti.uni-heidelberg.de/openhmc
#
# This source file is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This source file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this source file. If not, see <http://www.gnu.org/licenses/>.
#
#
 
#!/bin/bash
rm -rf waves.shm
rm -rf INCA_libs
rm -rf cov_work
rm -f *.log
rm -f irun.key
rm -rf .simvision
/openhmc/trunk/openHMC/sim/tb/run/run_files/run.sh
0,0 → 1,192
#
# .--------------. .----------------. .------------.
# | .------------. | .--------------. | .----------. |
# | | ____ ____ | | | ____ ____ | | | ______ | |
# | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
# ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
# / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
# (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
# \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
# | | | | | | | | | | | |
# |_| | '------------' | '--------------' | '----------' |
# '--------------' '----------------' '------------'
#
# openHMC - An Open Source Hybrid Memory Cube Controller
# (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
# www.ziti.uni-heidelberg.de
# B6, 26
# 68159 Mannheim
# Germany
#
# Contact: openhmc@ziti.uni-heidelberg.de
# http://ra.ziti.uni-heidelberg.de/openhmc
#
# This source file is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This source file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this source file. If not, see <http://www.gnu.org/licenses/>.
#
#
 
#!/bin/bash
 
function print_help {
printf "Usage: %s: [-c] [-d DUT] [-f FPW] [-g] [-l NUM_LANES] [-p] [-s SEED] -t TEST_NAME\n [-v UVM_VERBOSITY] -?" $(basename $0) >&2
}
 
#-----------------------------------------------------------------
# set defaults
if [ ! $CAG_DUT ]
then
CAG_DUT="default"
fi
 
#-- Controller params
num_lanes="default"
log_num_lanes="3"
fpw="default"
log_fpw="2"
 
do_clean_up=
tflag="0"
dflag="0"
test_name=
verbosity="UVM_LOW"
use_gui=
coverage=""
input_file="-input ${CAG_TB_DIR}/build/ncsim.tcl"
seed=""
num_pkt="default"
num_axi_bytes="64"
 
#-- parse options
while getopts 'cgt:v:d:s:l:f:p:' OPTION
do
case $OPTION in
c) do_clean_up=1
;;
d) export CAG_DUT=${OPTARG}
dflag="1"
;;
f) fpw="${OPTARG}"
;;
g) use_gui="+gui"
;;
l) num_lanes="${OPTARG}"
;;
p) num_pkt="${OPTARG}"
;;
s) seed="+svseed+${OPTARG}"
;;
t) tflag="1"
test_name="$OPTARG"
;;
v) verbosity="$OPTARG"
;;
?) print_help
exit 2
;;
esac
done
shift $(($OPTIND - 1))
 
printf "****************************************************\n"
printf "****************************************************\n"
 
#-- Set up controller
if [ $num_lanes == "default" ]
then
printf "No link-width specified. Defaulting to 8 lanes \n"
else
if [ $num_lanes != "8" -a $num_lanes != "16" ]
then
printf "Unsupported link-width specified. Defaulting to 8 lanes\n"
else
if [ $num_lanes == "16" ]
then
log_num_lanes="4"
export X16
fi
printf "Link width set: $num_lanes lanes\n"
fi
fi
 
if [ $fpw == "default" ]
then
printf "No FPW specified. Defaulting to FPW=4 (512bit datapath)\n"
fpw="4"
else
if [ $fpw != "2" -a $fpw != "4" -a $fpw != "6" -a $fpw != "8" ]
then
printf "Unsupported FPW specified. Defaulting to FPW=4 (512bit datapath)\n"
fpw="4"
else
printf "FPW set: $fpw\n"
case $fpw in
2)
log_fpw="1"
num_axi_bytes="32"
;;
4)
log_fpw="2"
;;
6)
log_fpw="3"
num_axi_bytes="96"
;;
8)
log_fpw="3"
num_axi_bytes="128"
;;
esac
fi
fi
 
#-- check test
if [ "$tflag" == "0" ]
then
printf "Test defaulted to simple_test.\n"
test_name="simple_test"
fi
 
#-- Set up the test
if [ $num_pkt == "default" ]
then
num_pkt="100"
fi
printf "Sending $num_pkt packets. \n"
 
#-- select DUT
if [ "$dflag" == "0" ]
then
printf "DUT is default: ${CAG_DUT}\n"
else
echo "DUT used: ${CAG_DUT}"
fi
CAG_TB_COMPILE_IUS="${CAG_TB_DIR}/build/compile_ius_${CAG_DUT}.f"
 
printf "****************************************************\n"
printf "****************************************************\n"
 
#-- do some clean up
if [ "$do_clean_up" ]
then
echo "Removing old build files..."
${CAG_TB_DIR}/../run/clean_up.sh
fi
 
#-- all other stuff
echo "Starting the verification environment..."
irun ${input_file} \
-f ${CAG_TB_COMPILE_IUS} \
-access +rwc \
${use_gui} "+UVM_TESTNAME=${test_name}" "+UVM_VERBOSITY=${verbosity}" ${seed} \
"-define LOG_NUM_LANES=$log_num_lanes -define FPW=$fpw -define LOG_FPW=$log_fpw -define NUM_PACKETS=$num_pkt -define AXI4BYTES=$num_axi_bytes" $*
/openhmc/trunk/openHMC/sim/tb/run/run.sh
0,0 → 1,77
#
# .--------------. .----------------. .------------.
# | .------------. | .--------------. | .----------. |
# | | ____ ____ | | | ____ ____ | | | ______ | |
# | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
# ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
# / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
# (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
# \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
# | | | | | | | | | | | |
# |_| | '------------' | '--------------' | '----------' |
# '--------------' '----------------' '------------'
#
# openHMC - An Open Source Hybrid Memory Cube Controller
# (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
# www.ziti.uni-heidelberg.de
# B6, 26
# 68159 Mannheim
# Germany
#
# Contact: openhmc@ziti.uni-heidelberg.de
# http://ra.ziti.uni-heidelberg.de/openhmc
#
# This source file is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This source file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this source file. If not, see <http://www.gnu.org/licenses/>.
#
#
 
#!/bin/bash
 
if [ ! $OPENHMC_SIM ]
then
echo "Please export the OPENHMC_SIM first"
exit 1
fi
 
export CAG_TB_DIR=${OPENHMC_SIM}/tb/bfm
export CAG_DUT="openhmc_behavioral_bfm"
 
#-----------------------------------------------------------------
 
echo ""
echo "*"
echo "* .--------------. .----------------. .------------. "
echo "* | .------------. | .--------------. | .----------. |"
echo "* | | ____ ____ | | | ____ ____ | | | ______ | |"
echo "* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |"
echo "* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |"
echo "* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |"
echo "* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ '.___.'\| |"
echo "* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | '._____.'| |"
echo "* | | | | | | | | | | | |"
echo "* |_| | ------------ | '--------------' | '----------' |"
echo "* '--------------' '----------------' '------------' "
echo "*"
echo "*"
echo "* *******************************************************"
echo "* * *"
echo "* * openHMC Verification Environment *"
echo "* * *"
echo "* * *"
echo "* * *"
echo "* *******************************************************"
echo ""
 
${OPENHMC_SIM}/tb/run/run_files/run.sh $*
 
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_base.sv
0,0 → 1,156
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
class cag_rgm_base extends uvm_object;
 
protected CAG_RGM_TYPE m_type = NONE;
protected bit [63:0] address;
protected bit [63:0] offset;
protected int loop = -1;
protected string name;
protected bit check_on_read = 1;
 
`uvm_object_utils_begin(cag_rgm_base)
`uvm_field_int(address, UVM_NOCOMPARE | UVM_NOPACK | UVM_DEFAULT)
`uvm_field_int(offset, UVM_NOCOMPARE | UVM_NOPACK | UVM_DEFAULT)
`uvm_field_int(check_on_read, UVM_NOCOMPARE | UVM_NOPACK | UVM_DEFAULT)
`uvm_field_string(name, UVM_NOCOMPARE | UVM_NOPACK | UVM_DEFAULT)
`uvm_object_utils_end
 
function new(string name="cag_rgm_base");
super.new(name);
endfunction : new
 
function CAG_RGM_TYPE get_rgm_type();
return m_type;
endfunction : get_rgm_type
 
function string get_name();
return name;
endfunction : get_name
 
function void set_name(string name);
this.name = name;
endfunction : set_name
 
virtual function void set_address(bit [63:0] address);
this.address = address;
endfunction : set_address
 
virtual function bit [63:0] get_address();
return address + offset;
endfunction : get_address
 
virtual function int address_match(bit [63:0] address);
if(get_address() == address)
return 1;
else
return -1;
endfunction : address_match
 
function void set_offset(bit [63:0] offset);
this.offset = offset;
endfunction : set_offset
 
function bit [63:0] get_offset();
return offset;
endfunction : get_offset
 
virtual function void set_loop(int loop);
this.loop = loop;
endfunction : set_loop
 
function int get_loop();
return loop;
endfunction : get_loop
 
function void set_check_on_read(bit check_on_read);
this.check_on_read = check_on_read;
endfunction : set_check_on_read
 
function bit get_check_on_read();
return this.check_on_read;
endfunction : get_check_on_read
 
function void set_raw(bit [63:0] data, bit endian = 1);
bit bitstream[];
int bits;
 
bits = pack(bitstream);
if (endian == 1) begin
for(int i = 0, int j = bits-1; i < bits; i++, j--)
bitstream[i] = data[j];
end else begin
for(int i = 0; i < bits; i++)
bitstream[i] = data[i];
end
bits = unpack(bitstream);
 
endfunction : set_raw
 
function bit [63:0] get_raw(bit endian = 1);
uvm_packer packer = new();
int bits;
bit bitstream[];
bit [63:0] data = 0;
 
packer.big_endian = endian;
 
bits = pack(bitstream,packer);
for(int i = 0; i < bits; i++)
data[i] = bitstream[i];
 
return data;
endfunction
 
virtual function void print_rf(string prefix = "");
$display(do_print_rf($psprintf("%stype: %s, name: %s, address: %0h, offset: %0h",prefix,m_type.name,name,address,offset)));
endfunction : print_rf
 
virtual function string do_print_rf(string s = "");
return s;
endfunction : do_print_rf
 
endclass : cag_rgm_base
 
/******************************************************************************
*
* REVISION HISTORY:
*
*******************************************************************************/
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_pkg.sv
0,0 → 1,49
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef CAG_RGM_PKG_SV
`define CAG_RGM_PKG_SV
 
package cag_rgm;
`include "cag_rgm.svh"
endpackage : cag_rgm
 
`endif // CAG_RGM_PKG_SV
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_container.sv
0,0 → 1,137
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
class cag_rgm_container extends cag_rgm_base;
 
protected cag_rgm_base m_registers[$];
protected cag_rgm_base m_ramblocks[$];
`uvm_object_utils(cag_rgm_container)
function new(string name = "cag_rgm_container");
super.new(name);
this.name = name;
this.m_type = CONTAINER;
endfunction : new
function void add_register(cag_rgm_register register, bit set_address = 0);
if(set_address)
register.set_address(address);
m_registers.push_back(register);
endfunction : add_register
function void add_ramblock(cag_rgm_base ramblock, bit set_address = 0);
if(set_address)
ramblock.set_address(address);
m_ramblocks.push_back(ramblock);
endfunction : add_ramblock
virtual function void set_address(bit [63:0] address);
super.set_address(address);
foreach(m_registers[i])
m_registers[i].set_address(address);
foreach(m_ramblocks[i])
m_ramblocks[i].set_address(address);
endfunction : set_address
virtual function void set_loop(int loop);
super.set_loop(loop);
foreach(m_registers[i])
m_registers[i].set_loop(loop);
foreach(m_ramblocks[i])
m_ramblocks[i].set_loop(loop);
endfunction : set_loop
virtual function cag_rgm_base get_by_name(string full_name = "");
foreach(m_registers[i]) begin
if(m_registers[i].get_name() == full_name) begin
return m_registers[i];
end
end
foreach(m_ramblocks[i]) begin
if(m_ramblocks[i].get_name() == full_name) begin
return m_ramblocks[i];
end
end
return null;
endfunction : get_by_name
virtual function cag_rgm_base get_by_address(bit [63:0] address);
foreach(m_registers[i]) begin
if(m_registers[i].address_match(address) != -1) begin
return m_registers[i];
end
end
foreach(m_ramblocks[i]) begin
if(m_ramblocks[i].address_match(address) != -1) begin
return m_ramblocks[i];
end
end
return null;
endfunction : get_by_address
virtual function void print_rf(string prefix = "");
super.print_rf(prefix);
foreach (m_registers[i]) begin
m_registers[i].print_rf({prefix," "});
end
foreach (m_ramblocks[i]) begin
m_ramblocks[i].print_rf({prefix," "});
end
 
endfunction : print_rf
endclass : cag_rgm_container
 
/******************************************************************************
*
* REVISION HISTORY:
*
*******************************************************************************/
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_register_file.sv
0,0 → 1,145
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
class cag_rgm_register_file extends cag_rgm_container;
 
protected cag_rgm_register_file m_register_files[$];
protected cag_rgm_repeat_block m_repeat_blocks[$];
`uvm_object_utils(cag_rgm_register_file)
function new(string name="cag_rgm_register_file");
super.new(name);
this.name = name;
this.m_type = REGISTER_FILE;
endfunction : new
function void add_register_file(cag_rgm_register_file register_file);
m_register_files.push_back(register_file);
endfunction : add_register_file
function void add_repeat_block(cag_rgm_repeat_block repeat_block);
m_repeat_blocks.push_back(repeat_block);
endfunction : add_repeat_block
function cag_rgm_base get_by_name(string full_name = "");
bit check_registers = 1;
cag_rgm_base base;
cag_rgm_register_file m_reg_file;
cag_rgm_repeat_block m_repeat;
string name;
for( int i = 0; i < full_name.len(); i++) begin
if(full_name.getc(i) == ".") begin
name = full_name.substr(0, i-1);
full_name = full_name.substr(i + 1, full_name.len()-1);
check_registers = 0;
break;
end
end
if(check_registers) begin
base = super.get_by_name(full_name);
if(base != null)
return base;
foreach(m_repeat_blocks[i]) begin
if(m_repeat_blocks[i].get_name() == full_name) begin
return m_repeat_blocks[i];
end
end
end else begin
foreach(m_register_files[i]) begin
if(m_register_files[i].get_name() == name) begin
$cast(m_reg_file,m_register_files[i]);
return m_reg_file.get_by_name(full_name);
end
end
foreach(m_repeat_blocks[i]) begin
if(m_repeat_blocks[i].get_name() == name) begin
$cast(m_repeat,m_repeat_blocks[i]);
return m_repeat_blocks[i].get_by_name(full_name);
end
end
end
return null;
endfunction : get_by_name
virtual function cag_rgm_base get_by_address(bit [63:0] address);
// check registers and ram blocks
get_by_address = super.get_by_address(address);
if(get_by_address != null)
return get_by_address;
 
// check sub registerfiles
foreach(m_register_files[i]) begin
get_by_address = m_register_files[i].get_by_address(address);
if(get_by_address != null)
return get_by_address;
end
// check repeat blocks
foreach(m_repeat_blocks[i]) begin
get_by_address = m_repeat_blocks[i].get_by_address(address);
if(get_by_address != null)
return get_by_address;
end
return null;
endfunction : get_by_address
virtual function void print_rf(string prefix = "");
super.print_rf(prefix);
foreach(m_register_files[i])
m_register_files[i].print_rf({prefix," "});
foreach(m_repeat_blocks[i])
m_repeat_blocks[i].print_rf({prefix," "});
endfunction : print_rf
endclass : cag_rgm_register_file
 
/******************************************************************************
*
* REVISION HISTORY:
*
*******************************************************************************/
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_transfer.sv
0,0 → 1,64
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
class cag_rgm_transfer extends uvm_sequence_item;
 
CAG_RGM_TRANSFER_COMMAND command;
bit [63:0] address;
bit [63:0] data;
int unsigned source_tag;
rand int unsigned delay;
bit error;
 
`uvm_object_utils_begin(cag_rgm_transfer)
`uvm_field_enum(CAG_RGM_TRANSFER_COMMAND, command, UVM_ALL_ON)
`uvm_field_int(address, UVM_ALL_ON)
`uvm_field_int(data, UVM_ALL_ON)
`uvm_field_int(source_tag, UVM_ALL_ON)
`uvm_field_int(delay, UVM_ALL_ON)
`uvm_field_int(error, UVM_ALL_ON)
`uvm_object_utils_end
 
constraint c_delay { delay inside {[0:50]}; }
 
function new(string name="cag_rgm_transfer");
super.new(name);
endfunction : new
 
endclass : cag_rgm_transfer
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_register.sv
0,0 → 1,52
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
class cag_rgm_register extends cag_rgm_base;
//T fields;
`uvm_object_utils(cag_rgm_register)
function new(string name="cag_rgm_register");
super.new(name);
this.name = name;
this.m_type = REGISTER;
endfunction : new
endclass : cag_rgm_register
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_defines.svh
0,0 → 1,192
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
typedef enum {
NONE,
CONTAINER,
REPEAT_BLOCK,
REGISTER,
RAM,
REGISTER_FILE
} CAG_RGM_TYPE;
 
typedef enum {
CAG_RGM_UNDEFINED,
CAG_RGM_READ,
CAG_RGM_WRITE,
CAG_RGM_READ_RESPONSE,
CAG_RGM_WRITE_RESPONSE
} CAG_RGM_TRANSFER_COMMAND;
 
typedef enum {
SINGLE,
ALL
} CAG_RGM_MODE;
 
`define cag_rgm_register_fields(T) \
rand T fields;
 
`define cag_rgm_driver_utils_start \
task start_rf(); \
super.start_rf(); \
fork
 
`define cag_rgm_driver_utils_end \
join \
endtask : start_rf
 
`define cag_rgm_driver_field_reg_begin(TYPE,PATH,NAME) \
begin \
TYPE m_reg; \
$cast(m_reg,rf_model.get_by_name(PATH)); \
if( m_reg == null ) \
uvm_report_fatal(get_type_name(),{PATH," not found"});\
forever begin \
wait(!vif.res_n); \
vif.NAME <= {16{1'b0}}; \
@(posedge vif.res_n); \
fork \
@(negedge vif.res_n); \
begin \
forever begin \
@(posedge vif.clk);
 
`define cag_rgm_driver_field_reg_no_reset_begin(TYPE,PATH) \
begin \
TYPE m_reg; \
$cast(m_reg,rf_model.get_by_name(PATH)); \
if( m_reg == null ) \
uvm_report_fatal(get_type_name(),{PATH," not found"});\
forever begin \
wait(!vif.res_n); \
@(posedge vif.res_n); \
fork \
@(negedge vif.res_n); \
begin \
forever begin \
@(posedge vif.clk);
 
`define cag_rgm_driver_field_reg_end \
end \
end \
join_any \
disable fork; \
end \
end
 
`define cag_rgm_driver_reg_ro(TYPE,PATH,NAME,FIELD) \
`cag_rgm_driver_field_reg_begin(TYPE,PATH,NAME) \
vif.NAME <= m_reg.fields.FIELD; \
`cag_rgm_driver_field_reg_end
 
`define cag_rgm_driver_reg_wo(TYPE,PATH,NAME,FIELD) \
`cag_rgm_driver_field_reg_no_reset_begin(TYPE,PATH) \
m_reg.fields.FIELD = vif.NAME``_next; \
`cag_rgm_driver_field_reg_end
 
`define cag_rgm_driver_reg_wo_en(TYPE,PATH,NAME,FIELD) \
`cag_rgm_driver_field_reg_begin(TYPE,PATH,NAME) \
if(vif.NAME``_wen) \
m_reg.fields.FIELD = vif.NAME; \
`cag_rgm_driver_field_reg_end
 
`define cag_rgm_driver_reg_rw(TYPE,PATH,NAME,FIELD) \
`cag_rgm_driver_field_reg_begin(TYPE,PATH,NAME) \
vif.NAME <= m_reg.fields.FIELD; \
m_reg.fields.FIELD = vif.NAME; \
`cag_rgm_driver_field_reg_end
 
`define cag_rgm_driver_reg_rw_en(TYPE,PATH,NAME,FIELD) \
`cag_rgm_driver_field_reg_begin(TYPE,PATH,NAME) \
vif.NAME <= m_reg.fields.FIELD; \
if(vif.NAME``_wen) \
m_reg.fields.FIELD = vif.NAME; \
`cag_rgm_driver_field_reg_end
 
`define cag_rgm_driver_ram_int(TYPE,PATH,NAME,WIDTH) \
begin \
TYPE m_ram; \
bit [WIDTH-1:0] ram_address; \
bit enable = 0; \
$cast(m_ram,rf_model.get_by_name(PATH)); \
if( m_ram == null ) \
uvm_report_fatal(get_type_name(),{PATH," not found"}); \
forever begin \
enable = vif.NAME``_ren; \
if(enable) \
ram_address = vif.NAME``_rf_addr; \
@(posedge vif.clk); \
if(enable) \
vif.NAME``_rdata <= m_ram.get_entry(ram_address); \
->m_ram.write_done; \
end \
end
 
`define cag_rgm_driver_ram_ext(TYPE,PATH,NAME) \
begin \
TYPE m_ram; \
int unsigned entry; \
$cast(m_ram,rf_model.get_by_name(PATH)); \
if( m_ram == null ) \
uvm_report_fatal(get_type_name(),{PATH," not found"}); \
vif.NAME``_rf_wen <= 1'b0; \
vif.NAME``_rf_ren <= 1'b0; \
forever begin \
@(m_ram.read_event or m_ram.write_event); \
@(posedge vif.clk); \
entry = m_ram.entry; \
vif.NAME``_rf_addr <= entry; \
if(m_ram.read_write) begin \
vif.NAME``_rf_wdata <= m_ram.get_entry(entry); \
vif.NAME``_rf_wen <= 1'b1; \
end else begin \
vif.NAME``_rf_ren <= 1'b1; \
end \
@(posedge vif.clk); \
vif.NAME``_rf_wen <= 1'b0; \
while(!vif.NAME``_rf_access_complete) \
@(posedge vif.clk); \
vif.NAME``_rf_wen <= 1'b0; \
vif.NAME``_rf_ren <= 1'b0; \
if(!m_ram.read_write) \
m_ram.set_entry(vif.NAME``_rf_rdata, entry ); \
->m_ram.write_done; \
end \
end
 
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_monitor.sv
0,0 → 1,57
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
`ifndef CAG_RGM_MONITOR_SV
`define CAG_RGM_MONITOR_SV
 
class cag_rgm_monitor extends uvm_monitor;
`uvm_component_utils(cag_rgm_monitor)
uvm_analysis_port#(cag_rgm_transfer) collected_port;
function new(string name="cag_rgm_monitor",uvm_component parent);
super.new(name,parent);
collected_port = new("collected_port",this);
endfunction : new
endclass : cag_rgm_monitor
 
`endif // CAG_RGM_MONITOR_SV
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm.svh
0,0 → 1,71
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef CAG_RGM_SVH
`define CAG_RGM_SVH
 
`include "uvm_macros.svh"
import uvm_pkg::*;
 
`include "cag_rgm_defines.svh"
 
`include "cag_rgm_base.sv"
 
`include "cag_rgm_register.sv"
 
`include "cag_rgm_container.sv"
`include "cag_rgm_repeat_block.sv"
 
`include "cag_rgm_register_file.sv"
 
`include "cag_rgm_transfer.sv"
 
`include "cag_rgm_sequencer.sv"
`include "cag_rgm_sequence.sv"
 
`include "cag_rgm_driver.sv"
 
`include "cag_rgm_rfs_driver.sv"
`include "cag_rgm_rfs_monitor.sv"
`include "cag_rgm_rfs_env.sv"
 
`include "cag_rgm_monitor.sv"
`include "cag_rgm_env.sv"
 
`endif // CAG_RGM_SVH
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_env.sv
0,0 → 1,84
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef CAG_RGM_ENV_SV
`define CAG_RGM_ENV_SV
 
class cag_rgm_env extends uvm_env;
uvm_active_passive_enum is_active = UVM_ACTIVE;
 
`uvm_component_utils_begin(cag_rgm_env)
`uvm_field_enum(uvm_active_passive_enum, is_active, UVM_DEFAULT)
`uvm_component_utils_end
cag_rgm_sequencer sequencer;
cag_rgm_monitor tx_monitor;
cag_rgm_monitor rx_monitor;
function new(string name="cag_rgm_env", uvm_component parent);
super.new(name,parent);
endfunction : new
function void build();
super.build();
if(is_active == UVM_ACTIVE)
sequencer = cag_rgm_sequencer::type_id::create("sequencer",this);
tx_monitor = cag_rgm_monitor::type_id::create("tx_monitor",this);
rx_monitor = cag_rgm_monitor::type_id::create("rx_monitor",this);
endfunction : build
function void connect();
if(is_active == UVM_ACTIVE) begin
rx_monitor.collected_port.connect(sequencer.resp_port);
end
endfunction : connect
function void set_rf(cag_rgm_register_file rf);
if(is_active == UVM_ACTIVE)
sequencer.set_rf(rf);
endfunction : set_rf
endclass : cag_rgm_env
 
`endif // CAG_RGM_ENV_SV
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_sequencer.sv
0,0 → 1,180
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
typedef class cag_rgm_write_sequence;
typedef class cag_rgm_read_sequence;
 
class cag_rgm_sequencer extends uvm_sequencer #(cag_rgm_transfer);
 
`uvm_analysis_imp_decl(_resp)
uvm_analysis_imp_resp #(cag_rgm_transfer,cag_rgm_sequencer) resp_port;
int unsigned source_tag_count = 1;
protected mailbox #(int unsigned) source_tags;
protected cag_rgm_register_file m_rf;
protected cag_rgm_write_sequence write_seq;
protected cag_rgm_read_sequence read_seq;
protected mailbox #(cag_rgm_transfer) responses_mb;
cag_rgm_transfer responses_q[$];
semaphore responses_s;
event new_rsp;
//`uvm_sequencer_utils_begin(cag_rgm_sequencer)
// `uvm_field_int(source_tag_count, UVM_ALL_ON)
//`uvm_sequencer_utils_end
`uvm_component_utils_begin(cag_rgm_sequencer)
`uvm_field_int(source_tag_count, UVM_ALL_ON)
`uvm_component_utils_end
function new(string name = "cag_rgm_sequencer",uvm_component parent);
super.new(name,parent);
//count = 0;
//`uvm_update_sequence_lib
resp_port = new("resp_port",this);
responses_mb = new();
responses_s = new(1);
source_tags = new();
endfunction : new
function void build();
super.build();
for(int unsigned i = 0; i < source_tag_count; i++)
void'(source_tags.try_put(i));
endfunction : build
task run();
cag_rgm_transfer response;
forever begin
responses_mb.get(response);
//uvm_report_info("DEBUG",$psprintf("received rsp with tag %0d",response.source_tag),UVM_NONE);
//$stop;
responses_s.get(1);
responses_q.push_back(response);
->new_rsp;
responses_s.put(1);
//$stop;
end
endtask : run
function void set_rf(cag_rgm_register_file rf);
this.m_rf = rf;
endfunction : set_rf
function void write_resp(input cag_rgm_transfer transfer);
if(transfer.command == CAG_RGM_READ_RESPONSE)
assert(responses_mb.try_put(transfer));
endfunction : write_resp
task get_response(int unsigned source_tag, ref cag_rgm_transfer rsp);
//responses.get(rsp);
//if(rsp.source_tag != source_tag)
// p_sequencer.uvm_report_fatal(get_type_name(),$psprintf("got the wrong source tag: %h",rsp.source_tag));
forever begin
responses_s.get(1);
while(responses_q.size() == 0) begin
responses_s.put(1);
//$stop;
@new_rsp;
//$stop;
responses_s.get(1);
end
foreach(responses_q[i]) begin
//uvm_report_info("DEBUG",$psprintf("foreach tag: %0d",responses_q[i].source_tag),UVM_NONE);
if(responses_q[i].source_tag == source_tag) begin
rsp = responses_q[i];
responses_q.delete(i);
responses_s.put(1);
//$stop;
return;
end
end
responses_s.put(1);
//$stop;
@new_rsp;
end
endtask : get_response
task m_get_source_tag(output int unsigned tag);
source_tags.get(tag);
endtask : m_get_source_tag
task m_release_source_tag(int unsigned tag);
source_tags.put(tag);
endtask : m_release_source_tag
//
// rf access functions
//
function cag_rgm_base get_by_name(string name = "");
return m_rf.get_by_name(name);
endfunction : get_by_name
function cag_rgm_base get_by_address(bit [63:0] address);
return m_rf.get_by_address(address);
endfunction : get_by_address
task write_reg(cag_rgm_base reg_);
write_seq = cag_rgm_write_sequence::type_id::create("write_seq");
write_seq.req_ = reg_;
write_seq.start(this);
endtask : write_reg
task read_reg(cag_rgm_base reg_);
read_seq = cag_rgm_read_sequence::type_id::create("read_seq");
read_seq.req_ = reg_;
read_seq.start(this);
endtask : read_reg
endclass : cag_rgm_sequencer
 
/******************************************************************************
*
* REVISION HISTORY:
*
*******************************************************************************/
 
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_repeat_block.sv
0,0 → 1,117
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
class cag_rgm_repeat_block extends cag_rgm_container;//cag_rgm_base;
 
protected int unsigned loop;
protected bit [63:0] iter_size;
protected cag_rgm_container containers[$];
 
`uvm_object_utils(cag_rgm_repeat_block)
function new(string name = "cag_rgm_repeat_block");
super.new(name);
this.name = name;
this.m_type = REPEAT_BLOCK;
endfunction : new
function void add_container(cag_rgm_container container);
container.set_address(address + (loop*iter_size));
container.set_loop(loop);
this.containers.push_back(container);
loop++;
endfunction : add_container
function void set_iter_size(bit [63:0] iter_size);
this.iter_size = iter_size;
endfunction : set_iter_size
virtual function string do_print_rf(string s = "");
return {s,$psprintf(", loops: %0d, iter_size: %0h",loop,iter_size)};
endfunction : do_print_rf
virtual function void print_rf(string prefix="");
super.print_rf(prefix);
foreach(containers[i])
containers[i].print_rf({prefix," "});
endfunction : print_rf
virtual function cag_rgm_base get_by_name(string full_name = "");
bit check_registers = 1;
string name;
for( int i = 0; i < full_name.len(); i++) begin
if(full_name.getc(i) == ".") begin
name = full_name.substr(0, i-1);
full_name = full_name.substr(i + 1, full_name.len()-1);
check_registers = 0;
break;
end
end
if(check_registers) begin
foreach(containers[i]) begin
if(containers[i].get_name() == full_name) begin
return containers[i];
end
end
end else begin
foreach(containers[i]) begin
if(containers[i].get_name() == name) begin
return containers[i].get_by_name(full_name);
end
end
end
return null;
endfunction : get_by_name
virtual function cag_rgm_base get_by_address(bit [63:0] address);
foreach(containers[i]) begin
get_by_address = containers[i].get_by_address(address);
if( get_by_address != null)
return get_by_address;
end
return null;
endfunction : get_by_address
endclass : cag_rgm_repeat_block
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_driver.sv
0,0 → 1,64
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
class cag_rgm_driver extends uvm_component;
 
protected cag_rgm_register_file rf_model;
`uvm_component_utils(cag_rgm_driver)
function new(string name="cag_rgm_driver", uvm_component parent);
super.new(name,parent);
endfunction : new
function void set_model(cag_rgm_register_file model);
this.rf_model = model;
endfunction : set_model
virtual task start_rf();
endtask : start_rf
virtual task run();
if(rf_model == null)
uvm_report_fatal(get_type_name(),"Register model not set.");
start_rf();
endtask : run
 
endclass : cag_rgm_driver
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_rfs_monitor.sv
0,0 → 1,217
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
//
// cag rgm rfs monitor OVC monitor
//
//
 
`ifndef CAG_RGM_RFS_MONITOR_SV
`define CAG_RGM_RFS_MONITOR_SV
 
class cag_rgm_rfs_monitor #(
parameter ADDR_WIDTH = 6,
parameter READ_DATA_WIDTH = 64,
parameter WRITE_DATA_WIDTH = 64
) extends uvm_monitor;
 
uvm_analysis_port #(cag_rgm_transfer) request_port;
uvm_analysis_port #(cag_rgm_transfer) response_port;
 
virtual cag_rgm_rfs_if #(
.ADDR_WIDTH(ADDR_WIDTH),
.READ_DATA_WIDTH(READ_DATA_WIDTH),
.WRITE_DATA_WIDTH(WRITE_DATA_WIDTH)
) rfs_if;
 
cag_rgm_transfer collected_request;
cag_rgm_transfer collected_response;
 
bit enable_coverage = 1;
bit enable_checks = 1;
 
int cycles_between_req = 0;
int cycles_between_resp = 0;
 
`uvm_component_param_utils_begin(cag_rgm_rfs_monitor #(.ADDR_WIDTH(ADDR_WIDTH), .READ_DATA_WIDTH(READ_DATA_WIDTH), .WRITE_DATA_WIDTH(WRITE_DATA_WIDTH)))
`uvm_field_int(enable_coverage, UVM_ALL_ON)
`uvm_field_int(enable_checks, UVM_ALL_ON)
`uvm_component_utils_end
 
function new ( string name="cag_rgm_rfs_monitor", uvm_component parent );
super.new(name, parent);
request_port = new("request_port", this);
response_port = new("response_port", this);
endfunction : new
 
 
function void assign_vi( virtual interface cag_rgm_rfs_if #(.ADDR_WIDTH(ADDR_WIDTH), .READ_DATA_WIDTH(READ_DATA_WIDTH), .WRITE_DATA_WIDTH(WRITE_DATA_WIDTH)) rfs_if );
this.rfs_if = rfs_if;
endfunction : assign_vi
 
 
task run();
#1;
do_reset();
fork
collect_request_transfers();
collect_response_transfers();
join_none
endtask : run
 
 
task do_reset();
while (rfs_if.res_n == 0)
@( posedge rfs_if.clk );
endtask : do_reset
 
 
task collect_request_transfers();
 
forever
begin
cycles_between_req = 0;
 
// wait for write or read enable
while (!(rfs_if.wen || rfs_if.ren)) begin
cycles_between_req++;
@(posedge rfs_if.clk);
end
 
collected_request = cag_rgm_transfer::type_id::create("collected_request", this);
if(recording_detail == UVM_FULL)
collected_request.enable_recording({get_full_name(),"_request"});
void'(collected_request.begin_tr());
 
if (rfs_if.ren)
collected_request.command = CAG_RGM_READ;
else
collected_request.command = CAG_RGM_WRITE;
 
collected_request.address = {{64-3-ADDR_WIDTH {1'b0}}, rfs_if.address,3'b0};
collected_request.data = rfs_if.write_data;
collected_request.delay = cycles_between_req;
collected_request.error = 1'b0;
 
@(posedge rfs_if.clk);
 
if (enable_checks)
perform_request_checks();
if (enable_coverage)
perform_request_coverage();
 
void'(collected_request.end_tr());
// forward the collected_request to the next higher layer of the verification environment
// collected_request.print();
request_port.write(collected_request);
end
endtask : collect_request_transfers
 
 
task collect_response_transfers();
 
forever begin
cycles_between_resp = 0;
 
while (!(rfs_if.wen || rfs_if.ren)) begin
@(posedge rfs_if.clk);
end
 
collected_response = cag_rgm_transfer::type_id::create("collected_response", this);
 
if(rfs_if.wen)
collected_response.command = CAG_RGM_WRITE_RESPONSE;
else
collected_response.command = CAG_RGM_READ_RESPONSE;
 
// wait for write or read enable
while (!rfs_if.access_done) begin
cycles_between_resp++;
@(posedge rfs_if.clk);
end
 
if(recording_detail == UVM_FULL)
collected_response.enable_recording({get_full_name(),"_response"});
void'(collected_response.begin_tr());
 
collected_response.address = {{64-ADDR_WIDTH {1'b0}}, rfs_if.address}; //-- FIXME? address should be byte aligned? not qw?
collected_response.data = rfs_if.read_data;
collected_response.delay = cycles_between_req;
collected_response.error = rfs_if.invalid_address;
 
@(posedge rfs_if.clk);
 
if (enable_checks)
perform_response_checks();
if (enable_coverage)
perform_response_coverage();
 
void'(collected_response.end_tr());
// forward the collected_response to the next higher layer of the verification environment
// collected_response.print();
response_port.write(collected_response);
end
endtask : collect_response_transfers
 
 
// checks
function void perform_request_checks();
// perform data checks on collected_packet
endfunction : perform_request_checks
 
function void perform_response_checks();
//-- perform data checks on collected_packet
if(collected_response.error)
uvm_report_fatal(get_type_name(),$psprintf("Invalid access to address 0x%0h",collected_response.address));
endfunction : perform_response_checks
 
 
// coverage
function void perform_request_coverage();
// perform coverage on collected_packet
endfunction : perform_request_coverage
 
function void perform_response_coverage();
// perform coverage on collected_packet
endfunction : perform_response_coverage
 
endclass : cag_rgm_rfs_monitor
 
`endif // CAG_RGM_RFS_MONITOR_SV
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_rfs_env.sv
0,0 → 1,99
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef CAG_RGM_RFS_ENV_SV
`define CAG_RGM_RFS_ENV_SV
 
class cag_rgm_rfs_env #(
parameter ADDR_WIDTH = 6,
parameter WRITE_DATA_WIDTH = 64,
parameter READ_DATA_WIDTH = 64
) extends uvm_env;
 
uvm_active_passive_enum is_active = UVM_ACTIVE;
 
cag_rgm_rfs_driver #(.ADDR_WIDTH(ADDR_WIDTH), .READ_DATA_WIDTH(READ_DATA_WIDTH), .WRITE_DATA_WIDTH(WRITE_DATA_WIDTH)) driver;
cag_rgm_rfs_monitor #(.ADDR_WIDTH(ADDR_WIDTH), .READ_DATA_WIDTH(READ_DATA_WIDTH), .WRITE_DATA_WIDTH(WRITE_DATA_WIDTH)) monitor;
 
cag_rgm_sequencer sequencer;
`uvm_component_param_utils_begin(cag_rgm_rfs_env #(.ADDR_WIDTH(ADDR_WIDTH), .READ_DATA_WIDTH(READ_DATA_WIDTH), .WRITE_DATA_WIDTH(WRITE_DATA_WIDTH)))
`uvm_field_enum(uvm_active_passive_enum, is_active, UVM_ALL_ON)
`uvm_component_utils_end
function new(string name="cag_rgm_rfs_env", uvm_component parent);
super.new(name,parent);
endfunction : new
function void build();
super.build();
monitor = cag_rgm_rfs_monitor #(.ADDR_WIDTH(ADDR_WIDTH), .READ_DATA_WIDTH(READ_DATA_WIDTH), .WRITE_DATA_WIDTH(WRITE_DATA_WIDTH))::type_id::create("monitor",this);
if(is_active == UVM_ACTIVE) begin
driver = cag_rgm_rfs_driver #(.ADDR_WIDTH(ADDR_WIDTH), .READ_DATA_WIDTH(READ_DATA_WIDTH), .WRITE_DATA_WIDTH(WRITE_DATA_WIDTH))::type_id::create("driver",this);
sequencer = cag_rgm_sequencer::type_id::create("sequencer",this);
end
endfunction : build
function void connect();
super.connect();
if(is_active == UVM_ACTIVE) begin
driver.seq_item_port.connect(sequencer.seq_item_export);
monitor.response_port.connect(sequencer.resp_port);
end
endfunction : connect
function void assign_vi( virtual interface cag_rgm_rfs_if #(.ADDR_WIDTH(ADDR_WIDTH), .READ_DATA_WIDTH(READ_DATA_WIDTH), .WRITE_DATA_WIDTH(WRITE_DATA_WIDTH)) vif);
monitor.assign_vi(vif);
if(is_active == UVM_ACTIVE)
driver.assign_vi(vif);
endfunction : assign_vi
function void set_rf(cag_rgm_register_file rf);
if(is_active == UVM_ACTIVE)
sequencer.set_rf(rf);
endfunction : set_rf
 
endclass : cag_rgm_rfs_env
 
`endif // CAG_RGM_RFS_ENV_SV
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_rfs_driver.sv
0,0 → 1,136
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
//
// cag rgm rfs driver
//
//
 
`ifndef CAG_RGM_RFS_DRIVER_SV
`define CAG_RGM_RFS_DRIVER_SV
 
class cag_rgm_rfs_driver #(
parameter ADDR_WIDTH = 6,
parameter READ_DATA_WIDTH = 64,
parameter WRITE_DATA_WIDTH = 64
) extends uvm_driver #(cag_rgm_transfer);
 
virtual cag_rgm_rfs_if #(
.ADDR_WIDTH(ADDR_WIDTH),
.READ_DATA_WIDTH(READ_DATA_WIDTH),
.WRITE_DATA_WIDTH(WRITE_DATA_WIDTH)
) rfs_if;
 
cag_rgm_transfer rgm_item;
 
`uvm_component_param_utils(cag_rgm_rfs_driver #(.ADDR_WIDTH(ADDR_WIDTH), .READ_DATA_WIDTH(READ_DATA_WIDTH), .WRITE_DATA_WIDTH(WRITE_DATA_WIDTH)))
 
function new (string name="cag_rgm_rfs_driver", uvm_component parent);
super.new(name, parent);
endfunction : new
 
function void build();
super.build();
endfunction : build
 
function void assign_vi(virtual interface cag_rgm_rfs_if #(.ADDR_WIDTH(ADDR_WIDTH), .READ_DATA_WIDTH(READ_DATA_WIDTH), .WRITE_DATA_WIDTH(WRITE_DATA_WIDTH)) rfs_if);
this.rfs_if = rfs_if;
endfunction : assign_vi
 
task do_reset();
rfs_if.address <= {ADDR_WIDTH {1'b0}};
rfs_if.wen <= 1'b0;
rfs_if.ren <= 1'b0;
rfs_if.write_data <= {WRITE_DATA_WIDTH {1'b0}};
 
while (rfs_if.res_n == 0)
@( posedge rfs_if.clk );
 
endtask : do_reset
 
task run();
#1;
do_reset();
 
forever
begin
if (rfs_if.res_n == 0)
do_reset();
 
seq_item_port.get_next_item(rgm_item);
drive_item();
seq_item_port.item_done();
end
endtask : run
 
 
task drive_item();
 
//uvm_report_info(get_type_name(), $psprintf("start sending rgm_item:\n%s",rgm_item.sprint()));
// Start sending:
@(posedge rfs_if.clk);
 
// Wait until start delay is over
repeat (rgm_item.delay)
@(posedge rfs_if.clk);
 
// start request
rfs_if.address <= rgm_item.address[3+(ADDR_WIDTH-1):3];
rfs_if.write_data <= rgm_item.data;
rfs_if.wen <= (rgm_item.command == CAG_RGM_WRITE);
rfs_if.ren <= (rgm_item.command == CAG_RGM_READ);
 
@(posedge rfs_if.clk);
rfs_if.wen <= 1'b0;
rfs_if.ren <= 1'b0;
 
while (rfs_if.access_done == 0)
@(posedge rfs_if.clk);
 
@(posedge rfs_if.clk);
// end request
rfs_if.address <= {ADDR_WIDTH {1'b0}};
rfs_if.write_data <= {WRITE_DATA_WIDTH {1'b0}};
 
endtask : drive_item
 
endclass : cag_rgm_rfs_driver
 
`endif // CAG_RGM_RFS_DRIVER_SV
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_sequence.sv
0,0 → 1,197
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
class cag_rgm_sequence extends uvm_sequence #(cag_rgm_transfer);
 
//`uvm_sequence_utils(cag_rgm_sequence, cag_rgm_sequencer)
`uvm_object_utils(cag_rgm_sequence)
`uvm_declare_p_sequencer(cag_rgm_sequencer)
 
function new(string name="cag_rgm_sequence");
super.new(name);
endfunction : new
 
virtual task pre_body();
uvm_test_done.raise_objection(p_sequencer);
endtask : pre_body
 
virtual task post_body();
uvm_test_done.drop_objection(p_sequencer);
endtask : post_body
 
function cag_rgm_base get_by_name(string name = "");
return p_sequencer.get_by_name(name);
endfunction : get_by_name
 
task write_reg(cag_rgm_base reg_);
bit bitstream[];
int bits;
cag_rgm_transfer trans;
 
uvm_packer packer = new();
packer.big_endian = 0;
 
bits = reg_.pack(bitstream,packer);
//reg_.print();
 
`uvm_create(trans)
trans.command = CAG_RGM_WRITE;
trans.address = reg_.get_address();
trans.data = 64'd0;
//for(int i = 0 , int j = bits-1; i < bits; i++ ,j--)
// trans.data[i] = bitstream[j];
 
for(int i = 0; i < bits; i++)
trans.data[i] = bitstream[i];
//$display("%b",trans.data);
//uvm_report_info("DEBUG",$psprintf("write; address: %h, data: %h",trans.address,trans.data),UVM_NONE);
 
`uvm_send(trans)
//uvm_report_info("DEBUG",$psprintf("write; address: %h, data: %h done",trans.address,trans.data),UVM_NONE);
endtask : write_reg
 
task read_reg(cag_rgm_base reg_);
int unsigned source_tag;
bit bitstream[];
int bits;
cag_rgm_transfer trans;
cag_rgm_transfer response;
 
uvm_packer packer = new();
packer.big_endian = 0;
 
p_sequencer.m_get_source_tag(source_tag);
//uvm_report_info("DEBUG",$psprintf("using tag: %0d",source_tag),UVM_NONE);
 
bits = reg_.pack(bitstream,packer);
 
`uvm_create(trans)
trans.command = CAG_RGM_READ;
trans.address = reg_.get_address();
trans.source_tag = source_tag;
//uvm_report_info("DEBUG",$psprintf("read; address: %h, data: %h",trans.address,trans.data),UVM_NONE);
`uvm_send(trans)
 
//-- wait for response
//p_sequencer.responses.get(response);
//if(response.source_tag != source_tag)
// p_sequencer.uvm_report_fatal(get_type_name(),$psprintf("got the wrong source tag: %h",response.source_tag));
p_sequencer.get_response(source_tag, response);
for(int i = 0 /*, int j = bits-1*/; i < bits; i++ /*, j--*/)
bitstream[i] = response.data[i];
 
bits = reg_.unpack(bitstream,packer);
 
p_sequencer.m_release_source_tag(source_tag);
//uvm_report_info("DEBUG",$psprintf("read; address: %h, data: %h done",response.address,response.data),UVM_NONE);
endtask : read_reg
 
endclass : cag_rgm_sequence
 
class cag_rgm_write_sequence extends cag_rgm_sequence;
 
rand cag_rgm_base req_;
 
//`uvm_sequence_utils(cag_rgm_write_sequence, cag_rgm_sequencer)
`uvm_object_utils(cag_rgm_write_sequence)
 
function new(string name="cag_rgm_write_sequence");
super.new(name);
endfunction : new
 
task body();
cag_rgm_base m_req_;
//p_sequencer.uvm_report_info(get_type_name(), $psprintf("Write Request:\n%s ",req_.sprint()),UVM_NONE);
$cast(m_req_,req_.clone());
write_reg(m_req_);
req_.copy(m_req_);
endtask : body
 
endclass : cag_rgm_write_sequence
 
class cag_rgm_read_sequence extends cag_rgm_sequence;
 
rand cag_rgm_base req_;
 
`uvm_object_utils(cag_rgm_read_sequence)
 
function new(string name="cag_rgm_read_sequence");
super.new(name);
endfunction : new
 
task body();
cag_rgm_base m_req_;
cag_rgm_base old_reg;
//req_ = cag_rgm_base::type_id::create("m_req");
//req_.copy(req_);
$cast(m_req_,req_.clone());
 
if (m_req_.get_check_on_read() == 1) begin//-- checking is enabled, so make a copy to compare afterwards
$cast(old_reg,m_req_.clone());
end
 
//if (m_req_.get_check_on_read() == 1)
// p_sequencer.uvm_report_info(get_type_name(), $psprintf("Read Request:\n%s\n, Saved:\n%s ",m_req_.sprint(),old_reg.sprint()),UVM_NONE);
read_reg(m_req_);
 
//uvm_report_info(get_type_name(),$psprintf("Compare of:\n%s\n%s",m_req_.sprint(),old_reg.sprint()),UVM_NONE);
 
if (m_req_.get_check_on_read() == 1) begin
 
if (m_req_.compare(old_reg) != 1)
p_sequencer.uvm_report_fatal(get_type_name(),
$psprintf("Compare for check_on_read failed for:\n%s\nShould be:\n%s\nMaybe checking on this register has to be turned off. ",m_req_.sprint(), old_reg.sprint()));
end
req_.copy(m_req_);
endtask : body
 
endclass : cag_rgm_read_sequence
 
/******************************************************************************
*
* REVISION HISTORY:
*
*******************************************************************************/
/openhmc/trunk/openHMC/sim/UVC/cag_rgm/sv/cag_rgm_rfs_if.sv
0,0 → 1,108
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
//
// register file interface
//
//
 
`ifndef CAG_RGM_RFS_IF_SV
`define CAG_RGM_RFS_IF_SV
 
interface cag_rgm_rfs_if #(
parameter ADDR_WIDTH = 6,
parameter WRITE_DATA_WIDTH = 64,
parameter READ_DATA_WIDTH = 64
) ();
 
logic res_n;
logic clk;
 
logic [ADDR_WIDTH-1:0] address;
logic wen;
logic ren;
logic [WRITE_DATA_WIDTH-1:0] write_data;
logic [READ_DATA_WIDTH-1:0] read_data;
logic access_done;
logic invalid_address;
 
property valid_wen;
@(posedge clk) disable iff(!res_n)
wen |-> !$isunknown(address) && !$isunknown(write_data);
endproperty : valid_wen
assert property(valid_wen);
 
 
property valid_ren;
@(posedge clk) disable iff(!res_n)
ren |-> !$isunknown(address);
endproperty : valid_ren
assert property(valid_ren);
 
 
property valid_access_done;
@(posedge clk) disable iff(!res_n)
wen || ren |=> !(wen || ren) [*0:1150] ##1 access_done;
endproperty : valid_access_done
assert property(valid_access_done);
 
access_done_one_clk : assert property(@(posedge clk) disable iff(!res_n) $rose(access_done) |=> !access_done );
 
property invalid_address_on_done_only;
@(posedge clk) disable iff(!res_n)
invalid_address |-> access_done;
endproperty : invalid_address_on_done_only
assert property(invalid_address_on_done_only);
 
property no_simultaneous_read_and_write_on_0;
@(posedge clk) disable iff(!res_n)
ren |-> !wen;
endproperty : no_simultaneous_read_and_write_on_0
assert property(no_simultaneous_read_and_write_on_0);
 
property no_simultaneous_read_and_write_on_1;
@(posedge clk) disable iff(!res_n)
wen |-> !ren;
endproperty : no_simultaneous_read_and_write_on_1
assert property(no_simultaneous_read_and_write_on_1);
 
endinterface : cag_rgm_rfs_if
 
`endif // CAG_RGM_RFS_IF_SV
/openhmc/trunk/openHMC/sim/UVC/axi4_stream/sv/axi4_stream_env.sv
0,0 → 1,101
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef AXI4_STREAM_ENV_SV
`define AXI4_STREAM_ENV_SV
 
class axi4_stream_env #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends uvm_env;
 
virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vif;
axi4_stream_master_agent #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) master;
axi4_stream_slave_agent #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) slave;
 
axi4_stream_monitor #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) monitor;
 
axi4_stream_config axi4_stream_cfg;
 
 
`uvm_component_param_utils_begin(axi4_stream_env #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))
`uvm_field_object(axi4_stream_cfg, UVM_DEFAULT)
`uvm_field_object(master, UVM_DEFAULT)
`uvm_field_object(slave, UVM_DEFAULT)
`uvm_field_object(monitor, UVM_DEFAULT)
`uvm_component_utils_end
function new(string name="axi4_stream_env", uvm_component parent);
super.new(name,parent);
endfunction : new
 
function void build_phase(uvm_phase phase);
super.build_phase(phase);
//-- configure interfaces
if(uvm_config_db#(virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))::get(this, "", "vif",vif) ) begin
uvm_config_db#(virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))::set(this, "monitor","vif",vif);
uvm_config_db#(virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))::set(this, "master" ,"vif",vif);
uvm_config_db#(virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))::set(this, "slave" ,"vif",vif);
end else begin
`uvm_fatal(get_type_name(),"vif is not set")
end
 
if ( uvm_config_db#(axi4_stream_config)::get(this, "" , "axi4_stream_cfg", axi4_stream_cfg)) begin
uvm_config_db#(axi4_stream_config)::set(this, "master" , "axi4_stream_cfg", axi4_stream_cfg); //distributing axi4_stream_cfg to master agent
uvm_config_db#(axi4_stream_config)::set(this, "slave" , "axi4_stream_cfg", axi4_stream_cfg); //distributing axi4_stream_cfg to slave agent
end else begin
uvm_report_fatal(get_type_name(), $psprintf("axi4_stream_cfg not set via config_db"));
end
//-- create
monitor = axi4_stream_monitor #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH))::type_id::create("monitor", this);
master = axi4_stream_master_agent #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH))::type_id::create("master", this);
slave = axi4_stream_slave_agent #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH))::type_id::create("slave", this);
endfunction : build_phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
endfunction : connect_phase
endclass : axi4_stream_env
 
`endif // AXI4_STREAM_ENV_SV
/openhmc/trunk/openHMC/sim/UVC/axi4_stream/sv/axi4_stream_slave_agent.sv
0,0 → 1,81
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef AXI4_STREAM_SLAVE_AGENT_SV
`define AXI4_STREAM_SLAVE_AGENT_SV
 
class axi4_stream_slave_agent #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends uvm_agent;
 
axi4_stream_config axi4_stream_cfg;
virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vif;
 
axi4_stream_slave_driver #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) driver;
 
`uvm_component_param_utils_begin(axi4_stream_slave_agent #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))
`uvm_field_object(axi4_stream_cfg, UVM_DEFAULT)
`uvm_component_utils_end
 
function new(string name="axi4_stream_slave_agent", uvm_component parent);
super.new(name,parent);
endfunction : new
 
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(uvm_config_db#(virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))::get(this, "", "vif",vif) ) begin
uvm_config_db#(virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))::set(this, "driver","vif",vif);
end else begin
`uvm_fatal(get_type_name(),"vif is not set")
end
if (!uvm_config_db#(axi4_stream_config)::get(this, "", "axi4_stream_cfg", axi4_stream_cfg)) begin
uvm_report_fatal(get_type_name(), $psprintf("axi4_stream_cfg not set via config_db"));
end
if(axi4_stream_cfg.slave_active == UVM_ACTIVE)begin
uvm_config_db#(axi4_stream_config)::set(this, "driver", "axi4_stream_cfg", axi4_stream_cfg); // distribute axi4_stream_cfg to driver
driver = axi4_stream_slave_driver#(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH))::type_id::create("driver", this);
end
 
endfunction : build_phase
 
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
endfunction : connect_phase
 
endclass : axi4_stream_slave_agent
 
`endif // AXI4_STREAM_SLAVE_AGENT_SV
/openhmc/trunk/openHMC/sim/UVC/axi4_stream/sv/axi4_stream_master_agent.sv
0,0 → 1,91
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef AXI4_STREAM_MASTER_AGENT_SV
`define AXI4_STREAM_MASTER_AGENT_SV
 
class axi4_stream_master_agent #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends uvm_agent;
 
axi4_stream_config axi4_stream_cfg;
virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vif;
 
axi4_stream_master_driver #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) driver;
axi4_stream_master_sequencer #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) sequencer;
 
`uvm_component_param_utils_begin(axi4_stream_master_agent #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))
`uvm_field_object(axi4_stream_cfg, UVM_DEFAULT)
`uvm_field_object(driver, UVM_DEFAULT)
`uvm_field_object(sequencer, UVM_DEFAULT)
`uvm_component_utils_end
 
function new(string name="axi4_stream_master_agent", uvm_component parent);
super.new(name,parent);
endfunction : new
 
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(uvm_config_db#(virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))::get(this, "", "vif",vif) ) begin
uvm_config_db#(virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))::set(this, "driver","vif",vif);
end else begin
`uvm_fatal(get_type_name(),"vif is not set")
end
if (!uvm_config_db#(axi4_stream_config)::get(this, "", "axi4_stream_cfg", axi4_stream_cfg)) begin
uvm_report_fatal(get_type_name(), $psprintf("axi4_stream_cfg not set via config_db"));
end
if(axi4_stream_cfg.master_active == UVM_ACTIVE)begin
uvm_config_db#(axi4_stream_config)::set(this, "driver", "axi4_stream_cfg", axi4_stream_cfg); // distribute axi4_stream_cfg to driver
driver = axi4_stream_master_driver #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH))::type_id::create("driver", this);
sequencer = axi4_stream_master_sequencer#(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH))::type_id::create("sequencer",this);
end
 
endfunction : build_phase
 
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
 
if(axi4_stream_cfg.master_active == UVM_ACTIVE)begin
driver.seq_item_port.connect(sequencer.seq_item_export);
end
endfunction : connect_phase
 
endclass : axi4_stream_master_agent
 
`endif // AXI4_STREAM_MASTER_AGENT_SV
/openhmc/trunk/openHMC/sim/UVC/axi4_stream/sv/axi4_stream_hmc_monitor.sv
0,0 → 1,262
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
//
// axi4_stream_packet hmc_monitor
//
//
 
`ifndef AXI4_STREAM_HMC_MONITOR_SV
`define AXI4_STREAM_HMC_MONITOR_SV
 
class axi4_stream_hmc_monitor #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends hmc_module_mon ;
 
 
int FPW ;
int HEADERS ;
int TAILS ;
int VALIDS ;
int valids_per_cycle = 0;
int packet_length = 0;
 
 
//-- uvm_analysis_port #(hmc_packet) item_collected_port;
uvm_analysis_imp #(
axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)),
axi4_stream_hmc_monitor #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH))
) axi4_port;
int n_valids = 0;
int n_valids_after_tail = 0;
int n_valids_in_packet = 0;
int headers_seen = 0;
int tails_seen = 0;
 
typedef bit [127:0] flit_t;
flit_t flit_queue[$];
 
int packets_per_cycle = 0;
hmc_packet packet;
hmc_packet packet_queue[$];
//-- covergroup definition
covergroup axi4_cg;
HMC_PACKET_LENGTH : coverpoint packet_length;
endgroup
covergroup non_valids_cg;
BETWEEN_PACKETS : coverpoint n_valids_after_tail;
IN_PACKETS : coverpoint n_valids_in_packet;
endgroup
covergroup overlap_cg;
PACKETS_WITH_2_CYCLES: coverpoint headers_seen>tails_seen; //-- boolean condition
VALIDS_PER_CYCLE: coverpoint valids_per_cycle;
endgroup
`uvm_component_param_utils(axi4_stream_hmc_monitor #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))
 
 
function new ( string name="axi4_stream_hmc_monitor", uvm_component parent );
super.new(name, parent);
axi4_port = new("axi4_port",this);
axi4_cg = new();
non_valids_cg = new();
overlap_cg = new();
endfunction : new
 
function void build_phase(uvm_phase phase);
super.build_phase(phase);
FPW = DATA_BYTES/16;//-- convert to variables!
HEADERS = FPW;
TAILS = 2*FPW;
VALIDS = 0;
endfunction : build_phase
 
//-- Stuff FLITs into a FIFO, separate control signals
function void collect_flits(input axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vc);
//-- read tuser flags for valid flags
flit_t tmp_flit;
flit_t current_flit;
packets_per_cycle = 0;
valids_per_cycle =0;
for (int i = 0; i<FPW; i++) begin //-- Check bitvektor
//-- Check if valid
if (vc.tuser[VALIDS+i] == 1) begin
valids_per_cycle ++;
//-- Cover not valid flits
if (n_valids > 0) begin
//-- Check if between packets
if (tails_seen == headers_seen) //-- non valids after packet tail
n_valids_after_tail =n_valids;
else //-- non valids between header and tail
n_valids_in_packet = n_valids;
non_valids_cg.sample();
n_valids =0;
n_valids_after_tail = 0;
n_valids_in_packet= 0;
end
//-- Write 2 flit queue
for (int b=0; b<128; b++)
tmp_flit[b] = vc.tdata[128*i+b];
flit_queue.push_back(tmp_flit);
if (vc.tuser[HEADERS+i] == 1) begin
headers_seen++; //-- Complete hmc_packets to assemble
packets_per_cycle ++;
end
//-- Check if tail for complete hmc packet
if (vc.tuser[TAILS+i] == 1) begin
tails_seen++; //-- Complete hmc_packets to assemble
end
//-- Check complete hmc packets
`uvm_info(get_type_name(),$psprintf("Seen %d header and %d tails", headers_seen, tails_seen) ,UVM_HIGH)
assert (tails_seen<= headers_seen)
else `uvm_fatal(get_type_name(), $psprintf("packet is null"))
end
else begin
n_valids ++;
end
end
//-- Sample covergroup
overlap_cg.sample();
endfunction : collect_flits
 
//-- Use FLITs to form packets
function void collect_packet();
int current_packet_length;
flit_t current_flit;
bit bitstream[];
packet_length = 0;
//-- Assemble 1 hmc packet
flit_queue_underflow : assert (flit_queue.size() > 0);
//-- First flit is always header
current_flit = flit_queue.pop_front();
no_length_mismatches_allowed : assert (current_flit[14:11] == current_flit[10:7]); //--check internal hmc_packet length
current_packet_length = current_flit[10:7];
flit_queue_underflow2 : assert (flit_queue.size() >= current_packet_length - 1); //--check check hmc_packet complete received
//-- pack flits 2 bitstream
bitstream = new[current_packet_length*128];
//-- Pack first flit
for (int i=0; i<128; i=i+1)
bitstream[i] = current_flit[i];
//-- Get and pack the remaining flits
for (int flit=1; flit < current_packet_length; flit ++) begin
current_flit = flit_queue.pop_front();
`uvm_info(get_type_name(),$psprintf("pop flit %0d (%0x)", flit, current_flit), UVM_HIGH)
for (int i=0; i<128; i=i+1) begin
bitstream[flit*128+i] = current_flit[i];
end
end
packet_length =current_packet_length;
axi4_cg.sample();
packet = hmc_packet::type_id::create("packet", this);
void'(packet.unpack(bitstream));
tails_seen--;
if (packet == null) begin
`uvm_fatal(get_type_name(), $psprintf("packet is null"))
end
packet_queue.push_back(packet);
if(packet.get_command_type() == HMC_RESPONSE_TYPE)begin
`uvm_info("RESPONSE collected",$psprintf("Rsp %0d : %s",rsp_rcvd, packet.command.name()), UVM_LOW)
rsp_rcvd++;
end else begin
`uvm_info("REQUEST collected",$psprintf("Req %0d : %s",req_rcvd, packet.command.name()), UVM_LOW)
req_rcvd++;
end
`uvm_info("AXI4 to HMC Monitor",$psprintf("\n%s", packet.sprint()), UVM_HIGH)
endfunction : collect_packet
 
function void write(input axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vc);
hmc_packet expected;
hmc_packet packet;
`uvm_info(get_type_name(),$psprintf("got valid cycle"), UVM_HIGH)
collect_flits(vc);
`uvm_info(get_type_name(),$psprintf("got %0d tails and %0d flits",tails_seen, flit_queue.size() ), UVM_HIGH)
//-- Convert flit_queue to hmc_packets
while (tails_seen >0) begin
collect_packet();
end
//-- If flit queue is not empty -> hmc packet striped over 2 axi cycles
while (packet_queue.size()>0) begin
item_collected_port.write(packet_queue.pop_front());
end
endfunction
 
function void check_phase(uvm_phase phase);
if (flit_queue.size() >0)
`uvm_fatal(get_type_name(),$psprintf("flit_queue is not empty: %0d", flit_queue.size()))
endfunction : check_phase
endclass : axi4_stream_hmc_monitor
 
`endif // AXI4_STREAM_HMC_MONITOR_SV
/openhmc/trunk/openHMC/sim/UVC/axi4_stream/sv/axi4_stream_if.sv
0,0 → 1,82
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
//
// AXI4 Stream Interface
//
//
 
`ifndef AXI4_STREAM_IF_SV
`define AXI4_STREAM_IF_SV
 
interface axi4_stream_if #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) (
input logic ACLK, //-- Clock (All signals sampled on the rising edge)
input logic ARESET_N //-- Global Reset
);
//--
//-- Interface signals
//--
 
logic TVALID; // Master valid
logic TREADY; // Slave ready
logic [8*DATA_BYTES-1:0] TDATA; //-- Master data
logic [TUSER_WIDTH-1:0] TUSER; //-- Master sideband signals
//--
//-- Interface Assertions
//--
property data_hold_p;
logic [8*DATA_BYTES-1:0] m_data;
@(posedge ACLK) disable iff(!ARESET_N)
(TVALID == 1 && TREADY == 0,m_data = TDATA) |=> (TDATA == m_data);
endproperty : data_hold_p
chk_data_hold : assert property(data_hold_p);
 
endinterface : axi4_stream_if
 
`endif // AXI4_STREAM_IF_SV
 
/openhmc/trunk/openHMC/sim/UVC/axi4_stream/sv/axi4_stream_valid_cycle.sv
0,0 → 1,71
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
// axi4_valid_cycle
//
 
`ifndef AXI4_STREAM_VALID_CYCLE_SV
`define AXI4_STREAM_VALID_CYCLE_SV
 
class axi4_stream_valid_cycle #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends uvm_sequence_item;
 
rand bit [DATA_BYTES*8-1:0] tdata;
rand bit [TUSER_WIDTH-1:0] tuser;
rand int unsigned delay = 0;
constraint c_packet_delay {
delay < 20 ;
}
 
`uvm_object_param_utils_begin(axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))
`uvm_field_int(tdata, UVM_ALL_ON | UVM_NOPACK | UVM_HEX)
`uvm_field_int(tuser, UVM_ALL_ON | UVM_NOPACK | UVM_HEX)
`uvm_field_int(delay, UVM_DEFAULT | UVM_DEC| UVM_NOPACK)
`uvm_object_utils_end
 
function new (string name = "axi4_stream_valid_cycle");
super.new(name);
endfunction : new
 
endclass : axi4_stream_valid_cycle
 
`endif // AXI4_STREAM_VALID_CYCLE_SV
 
/openhmc/trunk/openHMC/sim/UVC/axi4_stream/sv/axi4_stream_pkg.sv
0,0 → 1,76
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`include "axi4_stream_if.sv"
`include "hmc_base_types_pkg.sv"
 
`timescale 100ps/10ps
 
package axi4_stream_pkg;
 
`include "uvm_macros.svh"
import uvm_pkg::*;
import hmc_base_types_pkg::*;
`include "hmc_module_mon.sv"
 
`include "axi4_stream_config.sv"
 
`include "axi4_stream_valid_cycle.sv"
 
`include "axi4_stream_monitor.sv"
`include "axi4_stream_hmc_monitor.sv"
 
`include "axi4_stream_master_driver.sv"
`include "tag_handler.sv"
`include "axi4_stream_master_sequencer.sv"
`include "axi4_stream_master_agent.sv"
 
`include "axi4_stream_slave_driver.sv"
`include "axi4_stream_slave_agent.sv"
 
`include "axi4_stream_env.sv"
 
endpackage : axi4_stream_pkg
/openhmc/trunk/openHMC/sim/UVC/axi4_stream/sv/axi4_stream_master_sequence.sv
0,0 → 1,109
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef AXI4_STREAM_MASTER_SEQUENCE_SV
`define AXI4_STREAM_MASTER_SEQUENCE_SV
 
class axi4_stream_master_sequence extends uvm_sequence;
 
rand int delay;
rand hmc_packet response;
rand bit error_response;
event item_available;
 
hmc_packet response_queue[$];
constraint delay_c {
delay dist {0:=4, [0:9]:=8, [10:30]:=2, [31:100]:=1};
}
 
`uvm_object_utils(axi4_stream_master_sequence)
`uvm_declare_p_sequencer(axi4_stream_master_sequencer)
 
function new(string name="axi4_stream_master_sequence");
super.new(name);
endfunction : new
 
task body();
void'(this.randomize());
fork
// Convert requests to responses
forever begin : tranlsate_loop
hmc_packet packet;
p_sequencer.req_mailbox.get(packet);
create_response_packet(packet);
end : tranlsate_loop
//
begin
hmc_packet packet;
forever begin : send_loop
if (response_queue.size() > 0) begin
int time_to_wait;
 
time_to_wait = response_queue[0].timestamp - $time;
if (time_to_wait <= 0) begin
packet = response_queue.pop_front();
uvm_report_info(get_type_name(), $psprintf("Sending response packet: %s", packet.command.name()), UVM_HIGH);
`uvm_send(packet)
end else begin
#time_to_wait;
end
end
else begin
// Wait for items to get added to the queue
if (response_queue.size() == 0)
@(item_available);
end
end : send_loop
end
join
endtask : body
 
endclass : axi4_stream_master_sequence
 
`endif // AXI4_STREAM_MASTER_SEQUENCER_SV
 
/openhmc/trunk/openHMC/sim/UVC/axi4_stream/sv/axi4_stream_config.sv
0,0 → 1,63
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef AXI4_STREAM_CONFIG_SV
`define AXI4_STREAM_CONFIG_SV
 
class axi4_stream_config extends uvm_object;
 
uvm_active_passive_enum master_active = UVM_PASSIVE;
uvm_active_passive_enum slave_active = UVM_PASSIVE;
 
`uvm_object_utils_begin(axi4_stream_config)
`uvm_field_enum(uvm_active_passive_enum, master_active, UVM_DEFAULT)
`uvm_field_enum(uvm_active_passive_enum, slave_active, UVM_DEFAULT)
`uvm_object_utils_end
 
function new(string name = "axi4_stream_config");
super.new(name);
endfunction : new
 
virtual function void do_print (uvm_printer printer);
super.do_print(printer);
endfunction : do_print
 
endclass : axi4_stream_config
 
`endif // AXI4_STREAM_CONFIG_SV
/openhmc/trunk/openHMC/sim/UVC/axi4_stream/sv/axi4_stream_master_sequencer.sv
0,0 → 1,56
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef AXI4_STREAM_MASTER_SEQUENCER_SV
`define AXI4_STREAM_MASTER_SEQUENCER_SV
 
class axi4_stream_master_sequencer #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends uvm_sequencer #(axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)));
 
`uvm_component_param_utils(axi4_stream_master_sequencer #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))
function new(string name = "axi4_stream_master_sequencer", uvm_component parent);
super.new(name,parent);
endfunction : new
 
endclass : axi4_stream_master_sequencer
 
`endif // AXI4_STREAM_MASTER_SEQUENCER_SV
 
/openhmc/trunk/openHMC/sim/UVC/axi4_stream/sv/axi4_stream_slave_driver.sv
0,0 → 1,117
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef AXI4_STREAM_SLAVE_DRIVER_SV
`define AXI4_STREAM_SLAVE_DRIVER_SV
 
//-- After this works for HMC, generalize for PCIe as well
class axi4_stream_slave_driver #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends uvm_driver #(hmc_packet);
 
axi4_stream_config axi4_stream_cfg;
 
virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vif;
`uvm_component_param_utils_begin(axi4_stream_slave_driver #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))
`uvm_field_object(axi4_stream_cfg, UVM_DEFAULT)
`uvm_component_utils_end
 
 
function new(string name="axi4_stream_slave_driver", uvm_component parent);
super.new(name,parent);
endfunction : new
 
function void build_phase(uvm_phase phase);
super.build_phase(phase);
 
if(uvm_config_db#(virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))::get(this, "", "vif",vif) ) begin
this.vif = vif;
end else begin
`uvm_fatal(get_type_name(),"vif is not set")
end
endfunction : build_phase
 
task run_phase(uvm_phase phase);
bit ready_asserted = 0;
bit last_valid = 0;
int set_probability;
 
super.run_phase(phase);
 
forever begin
if(vif.ARESET_N !== 1) begin
vif.TREADY <= 1'b0;
@(posedge vif.ARESET_N);
end
 
fork
forever begin
//-- Accept packets
@(negedge vif.ACLK);
 
set_probability_randomization : assert (std::randomize(set_probability) with {set_probability >= 0 && set_probability < 10;});
 
//-- Higher probability to be ready when the master has something to send
if (ready_asserted == 0 && vif.TVALID == 1 && set_probability > 3) begin
ready_asserted = 1;
//-- Can be ready when the master has nothing to send
end else if (ready_asserted == 0 && vif.TVALID == 0 && set_probability > 8) begin
ready_asserted = 1;
//-- Only become not ready after accepting something
end else if (ready_asserted == 1 && vif.TVALID == 1 && set_probability > 3) begin
ready_asserted = 0;
end
vif.TREADY <= ready_asserted;
last_valid = vif.TVALID == 1'b1;
end
begin //-- Asynchronous reset
@(negedge vif.ARESET_N);
end
join_any
disable fork;
end
 
endtask : run_phase
 
endclass : axi4_stream_slave_driver
 
`endif // AXI4_STREAM_SLAVE_DRIVER_SV
 
/openhmc/trunk/openHMC/sim/UVC/axi4_stream/sv/axi4_stream_master_driver.sv
0,0 → 1,127
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef AXI4_STREAM_MASTER_DRIVER_SV
`define AXI4_STREAM_MASTER_DRIVER_SV
 
class axi4_stream_master_driver #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends uvm_driver #(axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)));
 
axi4_stream_config axi4_stream_cfg;
 
virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vif;
 
`uvm_component_param_utils_begin(axi4_stream_master_driver #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))
`uvm_field_object(axi4_stream_cfg, UVM_DEFAULT)
`uvm_component_utils_end
 
function new(string name="axi4_stream_master_driver", uvm_component parent);
super.new(name,parent);
endfunction : new
 
function void build_phase(uvm_phase phase);
super.build_phase(phase);
 
if(!uvm_config_db#(virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))::get(this, "", "vif",vif) ) begin
`uvm_fatal(get_type_name(),"vif is not set")
end
endfunction : build_phase
 
task run_phase(uvm_phase phase);
super.run_phase(phase);
 
forever begin
if(vif.ARESET_N !== 1) begin
vif.TVALID <= 0;
`uvm_info(get_type_name(),$psprintf("reset"), UVM_HIGH)
@(posedge vif.ARESET_N);
`uvm_info(get_type_name(),$psprintf("coming out of reset"), UVM_HIGH)
end
 
fork
begin //-- Asynchronous reset
@(negedge vif.ARESET_N);
end
begin
drive_valid_cycles();
end
join_any
disable fork;
end
 
endtask : run_phase
task drive_valid_cycles();
@(posedge vif.ACLK);
forever begin
axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vc;
//-- Try next AXI4 item
seq_item_port.try_next_item(vc);
if( vc != null) begin
`uvm_info(get_type_name(),$psprintf("There is an item to sent"), UVM_MEDIUM)
`uvm_info(get_type_name(),$psprintf("send %0x %0x", vc.tuser, vc.tdata), UVM_MEDIUM)
//-- Wait until delay
repeat(vc.delay)
@(posedge vif.ACLK);
//-- Send AXI4 cycle
vif.TDATA <= vc.tdata;
vif.TUSER <= vc.tuser;
vif.TVALID <= 1;
@(posedge vif.ACLK)
while(vif.TREADY == 0)
@(posedge vif.ACLK);
vif.TUSER <= 0;
vif.TDATA <= 0;
vif.TVALID <= 0;
`uvm_info(get_type_name(),$psprintf("send done: %0x %0x", vc.tuser, vc.tdata), UVM_MEDIUM)
seq_item_port.item_done();
end else //-- Else wait 1 cycle
@(posedge vif.ACLK);
 
end
endtask : drive_valid_cycles
 
endclass : axi4_stream_master_driver
 
`endif //AXI4_STREAM_MASTER_DRIVER_SV
/openhmc/trunk/openHMC/sim/UVC/axi4_stream/sv/axi4_stream_monitor.sv
0,0 → 1,122
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
//
// axi4_stream_packet monitor
//
//
 
`ifndef AXI4_STREAM_MONITOR_SV
`define AXI4_STREAM_MONITOR_SV
 
class axi4_stream_monitor #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends uvm_monitor;
 
virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vif;
 
uvm_analysis_port #(axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH))) item_collected_port;
 
`uvm_component_param_utils(axi4_stream_monitor #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))
 
function new ( string name="axi4_stream_monitor", uvm_component parent );
super.new(name, parent);
item_collected_port = new("item_collected_port", this);
endfunction : new
 
function void build_phase(uvm_phase phase);
super.build_phase(phase);
 
if(uvm_config_db#(virtual interface axi4_stream_if #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))::get(this, "", "vif",vif) ) begin
this.vif = vif;
end else begin
`uvm_fatal(get_type_name(),"vif is not set")
end
endfunction : build_phase
 
task run();
axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vc;
 
forever begin
if (vif.ARESET_N !== 1)
begin
@(posedge vif.ARESET_N);
end
 
fork
begin // Asynchronous reset
@(negedge vif.ARESET_N);
end
forever begin
// At the positive edge of ACLK
@(posedge vif.ACLK);
// Capture valid bus cycles
if (vif.TVALID == 1 && vif.TREADY == 1) begin
vc = new();
vc.tuser = vif.TUSER;
vc.tdata = vif.TDATA;
assert ( vc.tuser[DATA_BYTES/4-1:0] == //-- assert that hdr flags are part of valid flags
vc.tuser[2*DATA_BYTES/4-1:DATA_BYTES/16]
|vc.tuser[DATA_BYTES/4-1:0])
assert ( vc.tuser[DATA_BYTES/4-1:0] == //-- assert that hdr flags are part of valid flags
vc.tuser[3*DATA_BYTES/4-1:DATA_BYTES/16]
|vc.tuser[DATA_BYTES/4-1:0])
 
item_collected_port.write(vc);
`uvm_info(get_type_name(),$psprintf("valid cycle tuser %0x tdata %0x", vc.tuser, vc.tdata), UVM_HIGH)
end
end
join_any
disable fork;
end
endtask : run
 
endclass : axi4_stream_monitor
 
`endif // AXI4_STREAM_MONITOR_SV
/openhmc/trunk/openHMC/sim/UVC/hmc_base_types/sv/hmc_packet.sv
0,0 → 1,381
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
//
// hmc_packet
//
 
`ifndef HMC_PACKET_SV
`define HMC_PACKET_SV
 
`define HMC_TYPE_MASK 6'h38
 
class hmc_packet extends uvm_sequence_item;
 
// request header fields
rand bit [2:0] cube_ID; // CUB
rand bit [33:0] address; // ADRS
rand bit [8:0] tag; // TAG
rand bit [3:0] packet_length; // LNG 128-bit (16-byte) flits
rand bit [3:0] duplicate_length; // DLN
rand hmc_command_encoding command; // CMD
 
bit [127:0] payload[$]; // 16-byte granularity
 
// request tail fields
rand bit [4:0] return_token_count; // RTC
rand bit [2:0] source_link_ID; // SLID
rand bit [2:0] sequence_number; // SEQ
rand bit [7:0] forward_retry_pointer; // FRP
rand bit [7:0] return_retry_pointer; // RRP
rand bit [31:0] packet_crc; // CRC
 
// response header fields not used before
rand bit [8:0] return_tag; // TGA (Optional)
 
// response tail fields not used before
rand bit [6:0] error_status; // ERRSTAT
rand bit data_invalid; // DINV
 
// special bits for IRTRY
rand bit start_retry;
rand bit clear_error_abort;
 
// CRC status fields
rand bit poisoned; // Inverted CRC
rand bit crc_error;
 
// helper fields
rand int flit_delay;
 
`uvm_object_utils_begin(hmc_packet)
`uvm_field_int(flit_delay, UVM_ALL_ON | UVM_NOPACK | UVM_DEC | UVM_NOCOMPARE | UVM_DEC)
`uvm_field_int(cube_ID, UVM_ALL_ON | UVM_NOPACK | UVM_DEC)
`uvm_field_int(address, UVM_ALL_ON | UVM_NOPACK | UVM_HEX)
`uvm_field_int(tag, UVM_ALL_ON | UVM_NOPACK | UVM_DEC)
`uvm_field_int(packet_length, UVM_ALL_ON | UVM_NOPACK | UVM_DEC)
`uvm_field_int(duplicate_length, UVM_ALL_ON | UVM_NOPACK | UVM_DEC)
`uvm_field_enum(hmc_command_encoding, command, UVM_ALL_ON | UVM_NOPACK )
`uvm_field_queue_int(payload, UVM_ALL_ON | UVM_NOPACK)
`uvm_field_int(return_token_count, UVM_ALL_ON | UVM_NOPACK | UVM_DEC)
`uvm_field_int(source_link_ID, UVM_ALL_ON | UVM_NOPACK | UVM_DEC)
`uvm_field_int(sequence_number, UVM_ALL_ON | UVM_NOPACK | UVM_DEC)
`uvm_field_int(forward_retry_pointer, UVM_ALL_ON | UVM_NOPACK | UVM_DEC)
`uvm_field_int(return_retry_pointer, UVM_ALL_ON | UVM_NOPACK | UVM_DEC)
`uvm_field_int(packet_crc, UVM_ALL_ON | UVM_NOPACK | UVM_HEX)
`uvm_field_int(return_tag, UVM_ALL_ON | UVM_NOPACK | UVM_DEC)
`uvm_field_int(error_status, UVM_ALL_ON | UVM_NOPACK | UVM_DEC)
`uvm_field_int(data_invalid, UVM_ALL_ON | UVM_NOPACK | UVM_DEC)
`uvm_field_int(poisoned, UVM_ALL_ON | UVM_NOPACK | UVM_DEC)
`uvm_field_int(crc_error, UVM_ALL_ON | UVM_NOPACK | UVM_DEC)
`uvm_object_utils_end
 
//constraint c_payload_size { packet_length == 1 || payload.size() == packet_length - 1; }
constraint c_poisoned { poisoned == 0; }
constraint c_cube_id {cube_ID ==0;}
constraint c_address {address ==0;}
constraint c_crc_error { crc_error == 0; }
constraint c_matching_length { packet_length == duplicate_length; }
constraint c_return_tag { return_tag == 0; }
constraint c_packet_length { (
(packet_length == 2 && command == HMC_POSTED_WRITE_16) ||
(packet_length == 3 && command == HMC_POSTED_WRITE_32) ||
(packet_length == 4 && command == HMC_POSTED_WRITE_48) ||
(packet_length == 5 && command == HMC_POSTED_WRITE_64) ||
(packet_length == 6 && command == HMC_POSTED_WRITE_80) ||
(packet_length == 7 && command == HMC_POSTED_WRITE_96) ||
(packet_length == 8 && command == HMC_POSTED_WRITE_112) ||
(packet_length == 9 && command == HMC_POSTED_WRITE_128) ||
(packet_length == 2 && command == HMC_WRITE_16) ||
(packet_length == 3 && command == HMC_WRITE_32) ||
(packet_length == 4 && command == HMC_WRITE_48) ||
(packet_length == 5 && command == HMC_WRITE_64) ||
(packet_length == 6 && command == HMC_WRITE_80) ||
(packet_length == 7 && command == HMC_WRITE_96) ||
(packet_length == 8 && command == HMC_WRITE_112) ||
(packet_length == 9 && command == HMC_WRITE_128) ||
(packet_length > 1 && packet_length <= 9 && command == HMC_READ_RESPONSE) ||
(packet_length == 1 && command == HMC_WRITE_RESPONSE) ||
(packet_length == 1 && command == HMC_MODE_WRITE_RESPONSE) ||
(packet_length == 1 && command == HMC_ERROR_RESPONSE) ||
(packet_length == 2 && (command & `HMC_TYPE_MASK) == HMC_MISC_WRITE_TYPE) ||
(packet_length == 2 && (command & `HMC_TYPE_MASK) == HMC_POSTED_MISC_WRITE_TYPE) ||
(packet_length == 1 && (command & `HMC_TYPE_MASK) == HMC_MODE_READ_TYPE) ||
(packet_length == 1 && (command & `HMC_TYPE_MASK) == HMC_READ_TYPE) ||
(packet_length == 1 && (command & `HMC_TYPE_MASK) == HMC_FLOW_TYPE)
); }
constraint c_flit_delay {
flit_delay dist{0:/90, [1:8]:/8, [8:50]:/2 };
}
 
function new (string name = "hmc_packet");
super.new(name);
endfunction : new
 
function void post_randomize();
bit [127:0] rand_flit;
 
super.post_randomize();
 
if (packet_length > 9)
`uvm_fatal(get_type_name(),$psprintf("post_randomize packet_length = %0d",packet_length))
 
`uvm_info("AXI Packet queued",$psprintf("%0s packet_length = %0d",command.name(), packet_length), UVM_HIGH)
 
if (packet_length < 2)
return;
 
for (int i=0; i<packet_length-1; i++) begin
randomize_flit_successful : assert (std::randomize(rand_flit));
payload.push_back(rand_flit);
end
 
endfunction
 
function hmc_command_type get_command_type();
 
case(command & `HMC_TYPE_MASK)
HMC_FLOW_TYPE: return HMC_FLOW_TYPE;
HMC_READ_TYPE: return HMC_READ_TYPE;
HMC_MODE_READ_TYPE: return HMC_MODE_READ_TYPE;
HMC_POSTED_WRITE_TYPE: return HMC_POSTED_WRITE_TYPE;
HMC_POSTED_MISC_WRITE_TYPE: return HMC_POSTED_MISC_WRITE_TYPE;
HMC_WRITE_TYPE: return HMC_WRITE_TYPE;
HMC_MISC_WRITE_TYPE: return HMC_MISC_WRITE_TYPE;
HMC_RESPONSE_TYPE: return HMC_RESPONSE_TYPE;
default: uvm_report_fatal(get_type_name(), $psprintf("command with an illegal command type='h%0h!", command));
endcase
 
endfunction : get_command_type
 
/*
The CRC algorithm used on the HMC is the Koopman CRC-32K. This algorithm was
chosen for the HMC because of its balance of coverage and ease of implementation. The
polynomial for this algorithm is:
x32 + x30 + x29 + x28 + x26 + x20 + x19 + x17 + x16 + x15 + x11 + x10 + x7 + x6 + x4 + x2 + x + 1
 
bit [31:0] polynomial = 33'b1_0111_0100_0001_1011_1000_1100_1101_0111; // Normal
 
The CRC calculation operates on the LSB of the packet first. The packet CRC calculation
must insert 0s in place of the 32-bits representing the CRC field before generating or
checking the CRC. For example, when generating CRC for a packet, bits [63: 32] of the
Tail presented to the CRC generator should be all zeros. The output of the CRC generator
will have a 32-bit CRC value that will then be inserted in bits [63:32] of the Tail before
forwarding that FLIT of the packet. When checking CRC for a packet, the CRC field
should be removed from bits [63:32] of the Tail and replaced with 32-bits of zeros, then
presented to the CRC checker. The output of the CRC checker will have a 32-bit CRC
value that can be compared with the CRC value that was removed from the tail. If the two
compare, the CRC check indicates no bit failures within the packet.
*/
 
function bit [31:0] calculate_crc();
bit [32:0] polynomial = 33'h1741B8CD7; // Normal
bit [32:0] remainder = 33'h0;
bit bitstream[];
int bits_packed=0;
 
bits_packed = pack(bitstream);
packer_succeeded : assert (bits_packed > 0);
 
/*
if (bits_packed > 128) begin //DEBUG
bit [127:0] flits[9];
for( int i=0; i < bits_packed; i++)
flits[i/128][i%128] = bitstream[i];
for( int i=0; i < bits_packed/128; i++)
`uvm_info(get_type_name(),$psprintf("calculate_crc flits[%0x] %0x",i,flits[i]), UVM_HIGH)
end
*/
 
for( int i=0; i < bits_packed-32; i++ ) begin // without the CRC
remainder = {remainder[31:0], bitstream[i]};
if( remainder[32] ) begin
remainder = remainder ^ polynomial;
end
end
 
for( int i=0; i < 64; i++ ) begin // zeroes for CRC and remainder
remainder = {remainder[31:0], 1'b0};
if( remainder[32] ) begin
remainder = remainder ^ polynomial;
end
end
 
return remainder[31:0];
 
endfunction : calculate_crc
 
virtual function void do_pack(uvm_packer packer);
 
super.do_pack(packer);
packer.big_endian = 0;
 
// pack header half flit
case(command & `HMC_TYPE_MASK)
HMC_FLOW_TYPE:
case (command)
HMC_NULL: packer.pack_field( {64'h0}, 64);
HMC_PRET: packer.pack_field ( {3'h0, 3'h0, 34'h0, 9'h0, duplicate_length[3:0], packet_length[3:0], 1'b0, command[5:0]}, 64);
HMC_TRET: packer.pack_field ( {3'h0, 3'h0, 34'h0, 9'h0, duplicate_length[3:0], packet_length[3:0], 1'b0, command[5:0]}, 64);
HMC_IRTRY: packer.pack_field ( {3'h0, 3'h0, 34'h0, 9'h0, duplicate_length[3:0], packet_length[3:0], 1'b0, command[5:0]}, 64);
default: uvm_report_fatal(get_type_name(), $psprintf("pack function called for a hmc_packet with an illegal FLOW type='h%0h!", command));
endcase
HMC_READ_TYPE: packer.pack_field ( {cube_ID[2:0], 3'h0, address[33:0], tag[8:0], duplicate_length[3:0], packet_length[3:0], 1'b0, command[5:0]}, 64);
HMC_MODE_READ_TYPE: packer.pack_field ( {cube_ID[2:0], 3'h0, address[33:0], tag[8:0], duplicate_length[3:0], packet_length[3:0], 1'b0, command[5:0]}, 64);
HMC_POSTED_WRITE_TYPE: packer.pack_field ( {cube_ID[2:0], 3'h0, address[33:0], tag[8:0], duplicate_length[3:0], packet_length[3:0], 1'b0, command[5:0]}, 64);
HMC_WRITE_TYPE: packer.pack_field ( {cube_ID[2:0], 3'h0, address[33:0], tag[8:0], duplicate_length[3:0], packet_length[3:0], 1'b0, command[5:0]}, 64);
HMC_POSTED_MISC_WRITE_TYPE: packer.pack_field ( {cube_ID[2:0], 3'h0, address[33:0], tag[8:0], duplicate_length[3:0], packet_length[3:0], 1'b0, command[5:0]}, 64);
HMC_MISC_WRITE_TYPE: packer.pack_field ( {cube_ID[2:0], 3'h0, address[33:0], tag[8:0], duplicate_length[3:0], packet_length[3:0], 1'b0, command[5:0]}, 64);
HMC_RESPONSE_TYPE: packer.pack_field ( {22'h0, source_link_ID[2:0], 6'h0, return_tag[8:0], tag[8:0], duplicate_length[3:0], packet_length[3:0], 1'b0, command[5:0]}, 64);
default: uvm_report_fatal(get_type_name(), $psprintf("pack function called for a hmc_packet with an illegal command type='h%0h!", command));
endcase
 
// Allow for errors when packet_length != duplicate_length
if ((packet_length == duplicate_length) && payload.size() + 1 != packet_length && command != HMC_NULL)
uvm_report_fatal(get_type_name(), $psprintf("pack function size mismatch payload.size=%0d packet_length=%0d!", payload.size(), packet_length));
 
// pack payload
for( int i=0; i<payload.size(); i++ ) packer.pack_field ( payload[i], 128);
 
// pack tail half flit
case(command & `HMC_TYPE_MASK)
HMC_FLOW_TYPE:
case (command)
HMC_NULL: packer.pack_field( {64'h0}, 64);
HMC_PRET: packer.pack_field ( {packet_crc[31:0], 5'h0, 3'h0, 5'h0, 3'h0, 8'h0, return_retry_pointer[7:0]}, 64);
HMC_TRET: packer.pack_field ( {packet_crc[31:0], return_token_count[4:0], 3'h0, 5'h0, sequence_number[2:0], forward_retry_pointer[7:0], return_retry_pointer[7:0]}, 64);
HMC_IRTRY: packer.pack_field ( {packet_crc[31:0], 5'h0, 3'h0, 5'h0, 3'h0, 6'h0, clear_error_abort, start_retry, return_retry_pointer[7:0]}, 64);
default: uvm_report_fatal(get_type_name(), $psprintf("pack function (tail) called for a hmc_packet with an illegal FLOW type='h%0h!", command));
endcase
HMC_READ_TYPE: packer.pack_field ( {packet_crc[31:0], return_token_count[4:0], source_link_ID[2:0], 5'h0, sequence_number[2:0], forward_retry_pointer[7:0], return_retry_pointer[7:0]}, 64);
HMC_POSTED_WRITE_TYPE: packer.pack_field ( {packet_crc[31:0], return_token_count[4:0], source_link_ID[2:0], 5'h0, sequence_number[2:0], forward_retry_pointer[7:0], return_retry_pointer[7:0]}, 64);
HMC_WRITE_TYPE: packer.pack_field ( {packet_crc[31:0], return_token_count[4:0], source_link_ID[2:0], 5'h0, sequence_number[2:0], forward_retry_pointer[7:0], return_retry_pointer[7:0]}, 64);
HMC_MODE_READ_TYPE: packer.pack_field ( {packet_crc[31:0], return_token_count[4:0], source_link_ID[2:0], 5'h0, sequence_number[2:0], forward_retry_pointer[7:0], return_retry_pointer[7:0]}, 64);
HMC_POSTED_MISC_WRITE_TYPE: packer.pack_field ( {packet_crc[31:0], return_token_count[4:0], source_link_ID[2:0], 5'h0, sequence_number[2:0], forward_retry_pointer[7:0], return_retry_pointer[7:0]}, 64);
HMC_MISC_WRITE_TYPE: packer.pack_field ( {packet_crc[31:0], return_token_count[4:0], source_link_ID[2:0], 5'h0, sequence_number[2:0], forward_retry_pointer[7:0], return_retry_pointer[7:0]}, 64);
HMC_RESPONSE_TYPE: packer.pack_field ( {packet_crc[31:0], return_token_count[4:0], error_status[6:0], data_invalid, sequence_number[2:0], forward_retry_pointer[7:0], return_retry_pointer[7:0]}, 64);
default: uvm_report_fatal(get_type_name(), $psprintf("pack function (tail) called for a hmc_packet with an illegal command type='h%0h!", command));
endcase
endfunction : do_pack
 
 
virtual function void do_unpack(uvm_packer packer);
bit [63:0] header;
bit [31:0] calculated_crc;
bit [21:0] rsvd22;
bit [5:0] rsvd6;
bit [4:0] rsvd5;
bit [2:0] rsvd3;
bit rsvd1;
 
super.do_unpack(packer);
packer.big_endian = 0;
 
// header
header = packer.unpack_field(64);
command[5:0] = header[5:0];
 
if (get_command_type != HMC_RESPONSE_TYPE)
{cube_ID[2:0], rsvd3, address[33:0], tag[8:0], duplicate_length[3:0], packet_length[3:0], rsvd1, command[5:0]} = header;
else
{rsvd22[21:0], source_link_ID[2:0], rsvd6[5:0], return_tag[8:0], tag[8:0], duplicate_length[3:0], packet_length[3:0], rsvd1, command[5:0]} = header;
 
// Unpack should not be called with length errors
if (duplicate_length != packet_length || packet_length == 0)
`uvm_fatal(get_type_name(), $psprintf("do_unpack: length mismatch dln=%0d len=%0d cmd=%0d!", duplicate_length, packet_length, command));
 
// payload
for (int i = 0; i < packet_length-1; i++)
payload.push_back(packer.unpack_field(128));
 
// tail
if (get_command_type != HMC_RESPONSE_TYPE)
{packet_crc[31:0], return_token_count[4:0], source_link_ID[2:0], rsvd5, sequence_number[2:0], forward_retry_pointer[7:0], return_retry_pointer[7:0]} = packer.unpack_field(64);
else
{packet_crc[31:0], return_token_count[4:0], error_status[6:0], data_invalid, sequence_number[2:0], forward_retry_pointer[7:0], return_retry_pointer[7:0]} = packer.unpack_field(64);
 
start_retry = (command == HMC_IRTRY ? forward_retry_pointer[0] : 1'b0);
clear_error_abort = (command == HMC_IRTRY ? forward_retry_pointer[1] : 1'b0);
 
calculated_crc = calculate_crc();
 
// Inverted CRC means poisoned
poisoned = (packet_crc == ~calculated_crc) ? 1'b1 : 1'b0;
 
crc_error = (packet_crc != calculated_crc && !poisoned) ? 1'b1 : 1'b0;
endfunction : do_unpack
 
 
virtual function bit compare_adaptive_packet(hmc_packet rhs, uvm_comparer comparer);
 
string name_string;
 
compare_adaptive_packet &= comparer.compare_field("packet_length", packet_length, rhs.packet_length, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("payload.size()", payload.size(), rhs.payload.size(), 64, UVM_DEC);
 
for (int i=0; i<packet_length; i++)
begin
if (!compare_adaptive_packet)
return 0;
$sformat(name_string, "payload[%0d]", i);
compare_adaptive_packet &= comparer.compare_field(name_string, payload[i], rhs.payload[i], 128, UVM_HEX);
end
 
compare_adaptive_packet &= comparer.compare_field("cube_ID", cube_ID, rhs.cube_ID, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("address", address, rhs.address, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("tag", tag, rhs.tag, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("packet_length", packet_length, rhs.packet_length, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("duplicate_length", duplicate_length, rhs.duplicate_length, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("command", command, rhs.command, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("return_token_count", return_token_count, rhs.return_token_count, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("source_link_ID", source_link_ID, rhs.source_link_ID, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("sequence_number", sequence_number, rhs.sequence_number, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("forward_retry_pointer", forward_retry_pointer, rhs.forward_retry_pointer, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("return_tag", return_tag, rhs.return_tag, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("error_status", error_status, rhs.error_status, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("data_invalid", data_invalid, rhs.data_invalid, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("start_retry", start_retry, rhs.start_retry, 64, UVM_DEC);
compare_adaptive_packet &= comparer.compare_field("clear_error_abort", clear_error_abort, rhs.clear_error_abort, 64, UVM_DEC);
 
endfunction : compare_adaptive_packet
 
endclass : hmc_packet
 
`endif // HMC_PACKET_SV
 
/openhmc/trunk/openHMC/sim/UVC/hmc_base_types/sv/hmc_types.svh
0,0 → 1,114
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef HMC_TYPES_SVH
`define HMC_TYPES_SVH
 
typedef enum bit [5:0] {
HMC_FLOW_TYPE = 6'h00,
HMC_WRITE_TYPE = 6'h08,
HMC_MISC_WRITE_TYPE = 6'h10,
HMC_POSTED_WRITE_TYPE = 6'h18,
HMC_POSTED_MISC_WRITE_TYPE = 6'h20,
HMC_MODE_READ_TYPE = 6'h28,
HMC_READ_TYPE = 6'h30,
HMC_RESPONSE_TYPE = 6'h38
} hmc_command_type;
 
typedef enum bit [5:0] {
HMC_NULL = 6'h00,
HMC_PRET = 6'h01,
HMC_TRET = 6'h02,
HMC_IRTRY = 6'h03,
HMC_WRITE_16 = 6'h08,
HMC_WRITE_32 = 6'h09,
HMC_WRITE_48 = 6'h0a,
HMC_WRITE_64 = 6'h0b,
HMC_WRITE_80 = 6'h0c,
HMC_WRITE_96 = 6'h0d,
HMC_WRITE_112 = 6'h0e,
HMC_WRITE_128 = 6'h0f,
//HMC_MODE_WRITE = 6'h10,
//HMC_BIT_WRITE = 6'h11,
//HMC_DUAL_8B_ADDI = 6'h12,
//HMC_SINGLE_16B_ADDI = 6'h13,
HMC_POSTED_WRITE_16 = 6'h18,
HMC_POSTED_WRITE_32 = 6'h19,
HMC_POSTED_WRITE_48 = 6'h1a,
HMC_POSTED_WRITE_64 = 6'h1b,
HMC_POSTED_WRITE_80 = 6'h1c,
HMC_POSTED_WRITE_96 = 6'h1d,
HMC_POSTED_WRITE_112 = 6'h1e,
HMC_POSTED_WRITE_128 = 6'h1f,
HMC_POSTED_BIT_WRIT = 6'h21,
//HMC_POSTED_DUAL_8B_ADDI = 6'h22,
//HMC_POSTED_SINGLE_16B_ADDI = 6'h23,
HMC_MODE_READ = 6'h28,
HMC_READ_16 = 6'h30,
HMC_READ_32 = 6'h31,
HMC_READ_48 = 6'h32,
HMC_READ_64 = 6'h33,
HMC_READ_80 = 6'h34,
HMC_READ_96 = 6'h35,
HMC_READ_112 = 6'h36,
HMC_READ_128 = 6'h37,
HMC_READ_RESPONSE = 6'h38,
HMC_WRITE_RESPONSE = 6'h39,
HMC_MODE_READ_RESPONSE = 6'h3A,
HMC_MODE_WRITE_RESPONSE = 6'h3B,
HMC_ERROR_RESPONSE = 6'h3E
} hmc_command_encoding;
 
typedef enum {
RESET,
INIT,
PRBS,
NULL_FLITS,
TS1,
NULL_FLITS_2,
INITIAL_TRETS,
LINK_UP,
START_RETRY_INIT,
CLEAR_RETRY,
SEND_RETRY_PACKETS
 
} init_state_t;
 
`endif // HMC_TYPES_SVH
 
/openhmc/trunk/openHMC/sim/UVC/hmc_base_types/sv/hmc_base_types_pkg.sv
0,0 → 1,50
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`timescale 100ps/10ps
 
package hmc_base_types_pkg;
 
`include "uvm_macros.svh"
import uvm_pkg::*;
 
`include "hmc_types.svh"
`include "hmc_packet.sv"
 
endpackage : hmc_base_types_pkg
/openhmc/trunk/openHMC/sim/UVC/hmc_module/sv/hmc_module_cfg.sv
0,0 → 1,52
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef HMC_MODULE_CFG
`define HMC_MODULE_CFG
class hmc_module_cfg extends uvm_object;
bit cover_enable;
`uvm_object_utils(hmc_module_cfg)
 
function new(string name="hmc_module_cfg");
super.new(name);
endfunction : new
endclass hmc_module_cfg
`endif
/openhmc/trunk/openHMC/sim/UVC/hmc_module/sv/hmc_module_pkg.sv
0,0 → 1,60
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef HMC_MODULE_PKG
`define HMC_MODULE_PKG
`timescale 100ps/10ps
 
package hmc_module_pkg;
 
import uvm_pkg::*;
`include "uvm_macros.svh"
import hmc_base_types_pkg::*;
import axi4_stream_pkg::*;
`include "hmc_module_scb.sv"
`include "hmc_module_mon.sv"
//`include "hmc_module_cfg.sv"
`include "hmc_module_env.sv"
endpackage : hmc_module_pkg
 
`endif
/openhmc/trunk/openHMC/sim/UVC/hmc_module/sv/hmc_module_scb.sv
0,0 → 1,324
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef HMC_SCOREBOARD_SV
`define HMC_SCOREBOARD_SV
 
 
class hmc_module_scb extends uvm_scoreboard;
 
protected int hmc_rsp_packet_count = 0;
protected int hmc_req_packet_count = 0;
protected int axi4_rsp_packet_count = 0;
protected int axi4_req_packet_count = 0;
 
 
typedef hmc_packet hmc_request_queue[$];
typedef bit [127:0] flit_t;
hmc_request_queue axi4_np_requests[*];
hmc_packet axi4_2_hmc[$];
hmc_packet hmc_2_axi4[$];
hmc_packet hmc_2_axi4_axi4_came_first[$];
int valid_cycle = 0;
//--check tags
int tag_count = 512;
bit [512:0]used_tags;
 
 
//-- analysis imports
//-- HMC Interface
`uvm_analysis_imp_decl(_hmc_req)
uvm_analysis_imp_hmc_req #(hmc_packet, hmc_module_scb) hmc_req_port;
`uvm_analysis_imp_decl(_hmc_rsp)
uvm_analysis_imp_hmc_rsp #(hmc_packet, hmc_module_scb) hmc_rsp_port;
//-- Host Interface
`uvm_analysis_imp_decl(_axi4_hmc_req)
uvm_analysis_imp_axi4_hmc_req #(hmc_packet, hmc_module_scb ) axi4_hmc_req;
`uvm_analysis_imp_decl(_axi4_hmc_rsp)
uvm_analysis_imp_axi4_hmc_rsp #(hmc_packet, hmc_module_scb ) axi4_hmc_rsp;
`uvm_component_utils(hmc_module_scb )
 
function new (string name="hmc_module_scb", uvm_component parent);
super.new(name, parent);
axi4_hmc_req = new("axi4_hmc_req",this);
axi4_hmc_rsp = new("axi4_hmc_rsp",this);
hmc_req_port = new("hmc_req_port",this);
hmc_rsp_port = new("hmc_rsp_port",this);
endfunction : new
 
//-- compare the received response packets and check with the previous sent request packet
function void hmc_2_axi4_compare(input hmc_packet expected, input hmc_packet packet);
int i;
hmc_packet request;
 
//-- Check the packet against the request stored in the axi4_np_requests map
label : assert (axi4_np_requests.exists(packet.tag))
else `uvm_fatal(get_type_name(),$psprintf("hmc_2_axi4_compare: Unexpected Response with tag %0x \n%s", packet.tag, packet.sprint()));
//-- delete the previous sent request packet
request = axi4_np_requests[packet.tag].pop_front();
if (axi4_np_requests[packet.tag].size() == 0)
axi4_np_requests.delete(packet.tag);
//-- check the hmc_packet
if (packet.command == HMC_WRITE_RESPONSE
&& request.get_command_type() != HMC_WRITE_TYPE
&& request.get_command_type() != HMC_MISC_WRITE_TYPE)
`uvm_fatal(get_type_name(),$psprintf("hmc_2_axi4_compare: Write Response received with tag %0x for request %s\n%s", packet.tag, request.command.name(), packet.sprint()))
 
if (packet.command == HMC_READ_RESPONSE && request.get_command_type() != HMC_READ_TYPE && request.get_command_type() != HMC_MODE_READ_TYPE )
`uvm_fatal(get_type_name(),$psprintf("hmc_2_axi4_compare: Read Response received with tag %0x for request %s\n%s", packet.tag, request.command.name(), packet.sprint()))
 
if (packet.command == HMC_READ_RESPONSE) begin
int expected_count;
case (request.command)
HMC_MODE_READ: expected_count = 1;
HMC_READ_16: expected_count = 1;
HMC_READ_32: expected_count = 2;
HMC_READ_48: expected_count = 3;
HMC_READ_64: expected_count = 4;
HMC_READ_80: expected_count = 5;
HMC_READ_96: expected_count = 6;
HMC_READ_112: expected_count = 7;
HMC_READ_128: expected_count = 8;
default: expected_count = 0;
endcase
if (expected_count != packet.payload.size())
`uvm_fatal(get_type_name(),$psprintf("hmc_2_axi4_compare: Read Response received with tag %0x and wrong size req=%0s rsp payload size=%0x\n", packet.tag, request.command.name(), packet.payload.size()))
end
 
//-- Check that the HMC command matches the HTOC item
if (packet.get_command_type() != HMC_RESPONSE_TYPE)
`uvm_fatal(get_type_name(),$psprintf("hmc_2_axi4_compare: Unexpected Packet \n%s", packet.sprint()))
 
if (expected.command != packet.command)
`uvm_fatal(get_type_name(),$psprintf("hmc_2_axi4_compare: Expected %s, got %s", expected.command.name(), packet.command.name()))
 
if (expected.packet_length != packet.packet_length)
`uvm_fatal(get_type_name(),$psprintf("hmc_2_axi4_compare: Packet length mismatch %0d != %0d ", expected.packet_length, packet.packet_length))
 
if (expected.payload.size() != packet.payload.size())
`uvm_fatal(get_type_name(),$psprintf("hmc_2_axi4_compare: Payload size mismatch %0d != %0d", expected.payload.size(), packet.payload.size()))
 
for (int i=0; i<packet.payload.size(); i++) begin
if (packet.payload[i] != expected.payload[i])
`uvm_fatal(get_type_name(),$psprintf("hmc_2_axi4_compare: Payload mismatch at %0d %0x != %0x", i, packet.payload[i], expected.payload[i]))
end
 
endfunction : hmc_2_axi4_compare
 
//-- compare and check 2 Request type packets
function void axi4_2_hmc_compare(input hmc_packet expected, hmc_packet packet);
 
hmc_command_type packet_type = packet.get_command_type();
if (packet_type == HMC_FLOW_TYPE || packet_type == HMC_RESPONSE_TYPE)
`uvm_fatal(get_type_name(),$psprintf("axi4_2_hmc_compare: Unexpected Packet \n%s", packet.sprint()))
 
if (expected.command != packet.command)
`uvm_fatal(get_type_name(),$psprintf("axi4_2_hmc_compare: Expected %s, got %s", expected.command.name(), packet.command.name()))
 
if (expected.cube_ID != packet.cube_ID)
`uvm_fatal(get_type_name(),$psprintf("axi4_2_hmc_compare: cube_ID mismatch %0d != %0d", expected.cube_ID, packet.cube_ID))
 
if (expected.address != packet.address)
`uvm_fatal(get_type_name(),$psprintf("axi4_2_hmc_compare: Address mismatch %0d != %0d", expected.address, packet.address))
 
if (expected.packet_length != packet.packet_length)
`uvm_fatal(get_type_name(),$psprintf("axi4_2_hmc_compare: Packet length mismatch %0d != %0d", expected.packet_length, packet.packet_length))
 
if (expected.payload.size() != packet.payload.size())
`uvm_fatal(get_type_name(),$psprintf("axi4_2_hmc_compare: Payload size mismatch %0d != %0d", expected.payload.size(), packet.payload.size()))
 
for (int i=0;i<expected.payload.size();i = i+1) begin
if (expected.payload[i] != packet.payload[i])
`uvm_fatal(get_type_name(),$psprintf("axi4_2_hmc_compare: Payload mismatch at %0d %0x != %0x", i, expected.payload[i], packet.payload[i]))
end
endfunction : axi4_2_hmc_compare
 
function void write_hmc_rsp(input hmc_packet packet);
hmc_packet expected;
 
hmc_rsp_packet_count++;
`uvm_info(get_type_name(),$psprintf("hmc_rsp: received packet #%0d %s", hmc_rsp_packet_count, packet.command.name()), UVM_MEDIUM)
`uvm_info(get_type_name(),$psprintf("hmc_rsp: \n%s", packet.sprint()), UVM_HIGH)
 
//-- check this packet later
hmc_2_axi4.push_back(packet);
endfunction : write_hmc_rsp
 
function void write_hmc_req(input hmc_packet packet);
hmc_packet expected;
 
if (packet == null) begin
`uvm_fatal(get_type_name(), $psprintf("packet is null"))
end
hmc_req_packet_count++;
 
`uvm_info(get_type_name(),$psprintf("hmc_req: received packet #%0d %s@%0x (tok %0d)", hmc_req_packet_count, packet.command.name(), packet.address, packet.return_token_count), UVM_MEDIUM)
`uvm_info(get_type_name(),$psprintf("hmc_req: \n%s", packet.sprint()), UVM_HIGH)
 
//-- expect an request packet on the host (AXI4) request queue
if (axi4_2_hmc.size() == 0)
`uvm_fatal(get_type_name(),$psprintf("write_hmc_req: Unexpected packet (the request queue is empty)\n%s",packet.sprint()))
else
expected = axi4_2_hmc.pop_front();
 
//-- compare and check 2 Request type packets
axi4_2_hmc_compare(expected, packet);
 
`uvm_info(get_type_name(),$psprintf("hmc_req: checked packet #%0d %s@%0x", hmc_req_packet_count, packet.command.name(), packet.address), UVM_MEDIUM)
endfunction : write_hmc_req
function void write_axi4_hmc_rsp(input hmc_packet packet);
hmc_packet expected;
if (packet == null) begin
`uvm_fatal(get_type_name(), $psprintf("packet is null"))
end
axi4_rsp_packet_count++;
 
`uvm_info(get_type_name(),$psprintf("axi4_rsp: received packet #%0d %s", axi4_rsp_packet_count, packet.command.name()), UVM_MEDIUM)
`uvm_info(get_type_name(),$psprintf("axi4_rsp: \n%s", packet.sprint()), UVM_HIGH)
 
//-- compare with previous on the HMC side received response packet
expected = hmc_2_axi4.pop_front();
hmc_2_axi4_compare(expected, packet);
`uvm_info(get_type_name(),$psprintf("axi4_rsp: checked packet #%0d %s", axi4_rsp_packet_count, packet.command.name()), UVM_MEDIUM)
//-- check if open request with tag is available
if (used_tags[packet.tag] == 1'b1) begin
used_tags[packet.tag] = 1'b0;
end else begin
`uvm_fatal(get_type_name(),$psprintf("Packet with Tag %0d was not requested", packet.tag))
end
endfunction :write_axi4_hmc_rsp
 
 
function void write_axi4_hmc_req(input hmc_packet packet);
if (packet == null) begin
`uvm_fatal(get_type_name(), $psprintf("packet is null"))
end
`uvm_info(get_type_name(),$psprintf("collected a packet %s", packet.command.name()), UVM_HIGH)
`uvm_info(get_type_name(),$psprintf("\n%s", packet.sprint()), UVM_HIGH)
//-- check packet later
axi4_req_packet_count++;
axi4_2_hmc.push_back(packet);
//-- check if tag checking is necessary
if (packet.get_command_type() == HMC_WRITE_TYPE
|| packet.get_command_type() == HMC_MISC_WRITE_TYPE
|| packet.get_command_type() == HMC_READ_TYPE
|| packet.get_command_type() == HMC_MODE_READ_TYPE)
begin
//-- store this packet to check corresponding response packet later
if (!axi4_np_requests.exists(packet.tag)) begin
axi4_np_requests[packet.tag] = {};
end
else begin
`uvm_info(get_type_name(),$psprintf("There is already an outstanding axi4 request with tag %0x!", packet.tag), UVM_MEDIUM)
end
axi4_np_requests[packet.tag].push_back(packet);
if (used_tags[packet.tag] == 1'b0) begin
used_tags[packet.tag] = 1'b1;
end else begin
`uvm_fatal(get_type_name(), $psprintf("tag %0d is already in use", packet.tag))
end
end
`uvm_info(get_type_name(),$psprintf("axi4_req: received packet #%0d %s@%0x", axi4_req_packet_count, packet.command.name(), packet.address), UVM_MEDIUM)
`uvm_info(get_type_name(),$psprintf("axi4_req: \n%s", packet.sprint()), UVM_HIGH)
endfunction :write_axi4_hmc_req
function void check_phase(uvm_phase phase);
if (axi4_rsp_packet_count != hmc_rsp_packet_count)
`uvm_fatal(get_type_name(),$psprintf("axi4_rsp_packet_count = %0d hmc_rsp_packet_count = %0d!", axi4_rsp_packet_count, hmc_rsp_packet_count))
if (axi4_req_packet_count != hmc_req_packet_count)
`uvm_fatal(get_type_name(),$psprintf("axi4_req_packet_count = %0d hmc_req_packet_count = %0d!", axi4_req_packet_count, hmc_req_packet_count))
//-- check for open requests on the host side
if (axi4_np_requests.size() > 0) begin
for(int i=0;i<512;i++)begin
if (axi4_np_requests.exists(i))begin
`uvm_info(get_type_name(),$psprintf("Unanswered Requests: %0d with tag %0d", axi4_np_requests[i].size(), i), UVM_NONE)
end
end
`uvm_fatal(get_type_name(),$psprintf("axi4_np_requests.size() = %0d, not all requests have been answered!", axi4_np_requests.size()))
end
//-- check for open tags
if (used_tags >0) begin
foreach(used_tags[i]) begin
if (used_tags[i] == 1'b1)
`uvm_info(get_type_name(),$psprintf("Tag %0d is in use", i), UVM_NONE)
end
`uvm_fatal(get_type_name(),$psprintf("Open Tags!"))
end
endfunction : check_phase
 
function void report_phase(uvm_phase phase);
`uvm_info(get_type_name(),$psprintf("axi4_req_count %0d", axi4_req_packet_count), UVM_NONE)
`uvm_info(get_type_name(),$psprintf("axi4_rsp_count %0d", axi4_rsp_packet_count), UVM_NONE)
`uvm_info(get_type_name(),$psprintf("hmc_req_count %0d", hmc_req_packet_count), UVM_NONE)
`uvm_info(get_type_name(),$psprintf("hmc_rsp_count %0d", hmc_rsp_packet_count), UVM_NONE)
endfunction : report_phase
 
endclass : hmc_module_scb
 
`endif // HMC_SCOREBOARD_SV
/openhmc/trunk/openHMC/sim/UVC/hmc_module/sv/hmc_module_env.sv
0,0 → 1,100
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef HMC_MODULE_ENV
`define HMC_MODULE_ENV
class hmc_module_env extends uvm_env;
//hmc_module_cfg module_cfg;
hmc_module_mon axi4_req_mon;
hmc_module_mon axi4_rsp_mon;
hmc_module_mon hmc_req_mon;
hmc_module_mon hmc_rsp_mon;
 
hmc_module_scb scb;
 
`uvm_component_utils(hmc_module_env)
 
function new (string name = "hmc_module_env", uvm_component parent);
super.new(name, parent);
endfunction : new
virtual function void build_phase(uvm_phase phase);
string inst_name;
super.build_phase(phase);
 
//-- Additional monitor for AXI4 Stream 2 HMC packet conversion
axi4_req_mon = hmc_module_mon::type_id::create("axi4_req_mon", this);
axi4_rsp_mon = hmc_module_mon::type_id::create("axi4_rsp_mon", this);
//-- Additional monitor for BFM 2 HMC packet conversion
hmc_req_mon = hmc_module_mon::type_id::create("hmc_req_mon", this);
hmc_rsp_mon = hmc_module_mon::type_id::create("hmc_rsp_mon", this);
//-- scoreboard
scb = hmc_module_scb::type_id::create("scb", this);
 
endfunction : build_phase
 
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
 
//-- Connect module monitors to scoreboard
axi4_req_mon.item_collected_port.connect(scb.axi4_hmc_req);
axi4_rsp_mon.item_collected_port.connect(scb.axi4_hmc_rsp);
hmc_req_mon.item_collected_port.connect(scb.hmc_req_port);
hmc_rsp_mon.item_collected_port.connect(scb.hmc_rsp_port);
 
 
endfunction : connect_phase
 
endclass: hmc_module_env
`endif
/openhmc/trunk/openHMC/sim/UVC/hmc_module/sv/hmc_module_mon.sv
0,0 → 1,67
/*
* .--------------. .----------------. .------------.
* | .------------. | .--------------. | .----------. |
* | | ____ ____ | | | ____ ____ | | | ______ | |
* | ||_ || _|| | ||_ \ / _|| | | .' ___ || |
* ___ _ __ ___ _ __ | | | |__| | | | | | \/ | | | |/ .' \_|| |
* / _ \| '_ \ / _ \ '_ \ | | | __ | | | | | |\ /| | | | || | | |
* (_) | |_) | __/ | | || | _| | | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
* \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
* | | | | | | | | | | | |
* |_| | '------------' | '--------------' | '----------' |
* '--------------' '----------------' '------------'
*
* openHMC - An Open Source Hybrid Memory Cube Controller
* (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
* www.ziti.uni-heidelberg.de
* B6, 26
* 68159 Mannheim
* Germany
*
* Contact: openhmc@ziti.uni-heidelberg.de
* http://ra.ziti.uni-heidelberg.de/openhmc
*
* This source file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this source file. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
 
`ifndef MODULE_MON
`define MODULE_MON
class hmc_module_mon extends uvm_monitor;
//-- Basic Module monitor
 
uvm_analysis_port #(hmc_packet) item_collected_port;
int req_rcvd = 0;
int rsp_rcvd = 0;
`uvm_component_utils(hmc_module_mon)
function new ( string name = "hmc_module_mon", uvm_component parent );
super.new(name, parent);
item_collected_port = new("item_collected_port", this);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction : build_phase
endclass
 
`endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.