Commit 0f641265 authored by Dimitris Lampridis's avatar Dimitris Lampridis

hdl/testbench: introduce wrtd-system testbench, work in progress

parent 09836380
mock-turtle @ 9b36bddf
Subproject commit a06f916fbee322712c5b3bbdf94c617a42bad406
Subproject commit 9b36bddf1701ea392efa0a7cfa18a61472f36633
work/
Makefile
modelsim.ini
transcript*
*.wlf
# HDLMake 'develop' branch required.
#
# Due to bugs in release v3.0 of hdlmake it is necessary to use the "develop"
# branch of hdlmake, commit db4e1ab.
sim_tool = "modelsim"
sim_top = "main"
action = "simulation"
target = "xilinx"
syn_device = "xc6slx150t"
vcom_opt = "-93 -mixedsvvh"
include_dirs = [
"../../ip_cores/mock-turtle/hdl/testbench/include/",
"../../ip_cores/mock-turtle/hdl/testbench/include/regs/",
"../../ip_cores/general-cores/sim/",
"../../ip_cores/urv-core/rtl/",
]
files = [
"main.sv",
"synthesis_descriptor.vhd",
]
modules = {
"local" : [
"../../top/svec/list_tdc_fd",
],
}
//------------------------------------------------------------------------------
// CERN BE-CO-HT
// LHC Instability Trigger Distribution (LIST)
// https://ohwr.org/projects/list
//------------------------------------------------------------------------------
//
// unit name: main
//
// description: A SystemVerilog testbench to exercise all the main features of
// LIST
//
//------------------------------------------------------------------------------
// Copyright CERN 2018
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`include "mock_turtle_driver.svh"
`include "vhd_wishbone_master.svh"
`timescale 1ns/10fs
module main;
reg rst_n = 0;
reg clk_125m_pllref = 0;
reg clk_20m_vcxo = 0;
reg clk_ext = 0;
wire a2btxp, a2btxn, b2atxp, b2atxn;
always #50ns clk_ext <= ~clk_ext;
always #4ns clk_125m_pllref <= ~clk_125m_pllref;
always #20ns clk_20m_vcxo <= ~clk_20m_vcxo;
initial begin
repeat(20) @(posedge clk_20m_vcxo);
rst_n = 1;
end
svec_list_top #
(
.g_simulation (1),
.g_sim_bypass_vme (1),
.g_dpram_initf("../../ip_cores/wr-cores/bin/wrpc/wrc_phy8_sim.bram")
)
DUT_A
(
.rst_n_i (rst_n),
.clk_125m_pllref_p_i (clk_125m_pllref),
.clk_125m_pllref_n_i (~clk_125m_pllref),
.clk_125m_gtp_p_i (clk_125m_pllref),
.clk_125m_gtp_n_i (~clk_125m_pllref),
.clk_20m_vcxo_i (clk_20m_vcxo),
.sim_wb_i (HostA.out),
.sim_wb_o (HostA.in),
.sfp_txp_o (a2btxp),
.sfp_txn_o (a2btxn),
.sfp_rxp_i (b2atxp),
.sfp_rxn_i (b2atxn)
);
IVHDWishboneMaster HostA
(
.clk_i (DUT_A.clk_sys_62m5),
.rst_n_i (DUT_A.rst_sys_62m5_n));
IMockTurtleIRQ IrqMonitorA (`MT_ATTACH_IRQ(DUT_A.cmp_mock_turtle));
svec_list_top #
(
.g_simulation (1),
.g_sim_bypass_vme (1),
.g_dpram_initf("../../ip_cores/wr-cores/bin/wrpc/wrc_phy8_sim.bram")
)
DUT_B
(
.rst_n_i (rst_n),
.clk_125m_pllref_p_i (clk_125m_pllref),
.clk_125m_pllref_n_i (~clk_125m_pllref),
.clk_125m_gtp_p_i (clk_125m_pllref),
.clk_125m_gtp_n_i (~clk_125m_pllref),
.clk_20m_vcxo_i (clk_20m_vcxo),
.sim_wb_i (HostB.out),
.sim_wb_o (HostB.in),
.sfp_txp_o (b2atxp),
.sfp_txn_o (b2atxn),
.sfp_rxp_i (a2btxp),
.sfp_rxn_i (a2btxn)
);
IVHDWishboneMaster HostB
(
.clk_i (DUT_B.clk_sys_62m5),
.rst_n_i (DUT_B.rst_sys_62m5_n));
IMockTurtleIRQ IrqMonitorB (`MT_ATTACH_IRQ(DUT_B.cmp_mock_turtle));
string fw = "../../ip_cores/mock-turtle/demos/hello_world/firmware/fw-01/fw-hello.bin";
const uint64_t mt_base = 'h2_0000;
MockTurtleDriver drvA, drvB;
initial begin
@(posedge DUT_A.rst_sys_62m5_n);
@(posedge DUT_A.clk_sys_62m5);
drvA = new (HostA.get_accessor(), mt_base, IrqMonitorA, "DUTA");
drvB = new (HostB.get_accessor(), mt_base, IrqMonitorB);
drvA.init();
drvB.init();
drvA.enable_console_irq (0, 1);
drvB.enable_console_irq (0, 1);
drvA.load_firmware(0, fw, 1'b0);
drvB.load_firmware(0, fw, 1'b0);
drvA.reset_core(0, 0);
drvB.reset_core(0, 0);
forever begin
drvA.update ();
drvB.update ();
#1us;
end
end // initial begin
/// ////////////////////////////////////////////////////////////////////////
/// Silence Xilinx unisim DSP48A1 warnings about invalid OPMODE
/// ////////////////////////////////////////////////////////////////////////
initial begin
force DUT_A.cmp_xwrc_board_svec.cmp_board_common.cmp_xwr_core.
WRPC.LM32_CORE.gen_profile_medium_icache.U_Wrapped_LM32.cpu.
multiplier.D1.OPMODE_dly = 0;
force DUT_A.cmp_xwrc_board_svec.cmp_board_common.cmp_xwr_core.
WRPC.LM32_CORE.gen_profile_medium_icache.U_Wrapped_LM32.cpu.
multiplier.D2.OPMODE_dly = 0;
force DUT_A.cmp_xwrc_board_svec.cmp_board_common.cmp_xwr_core.
WRPC.LM32_CORE.gen_profile_medium_icache.U_Wrapped_LM32.cpu.
multiplier.D3.OPMODE_dly = 0;
force DUT_B.cmp_xwrc_board_svec.cmp_board_common.cmp_xwr_core.
WRPC.LM32_CORE.gen_profile_medium_icache.U_Wrapped_LM32.cpu.
multiplier.D1.OPMODE_dly = 0;
force DUT_B.cmp_xwrc_board_svec.cmp_board_common.cmp_xwr_core.
WRPC.LM32_CORE.gen_profile_medium_icache.U_Wrapped_LM32.cpu.
multiplier.D2.OPMODE_dly = 0;
force DUT_B.cmp_xwrc_board_svec.cmp_board_common.cmp_xwr_core.
WRPC.LM32_CORE.gen_profile_medium_icache.U_Wrapped_LM32.cpu.
multiplier.D3.OPMODE_dly = 0;
end
endmodule // main
vsim -quiet -L unisim work.main -novopt -suppress 8683,8684,8822
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
radix -hexadecimal
run 300us
# Modelsim run script for continuous integration
# execute: vsim -c -do "run_ci.do"
vsim -quiet -L unisim work.main -suppress 8683,8684,8822
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
run 500us
exit
--------------------------------------------------------------------------------
-- SDB meta information for svec_list_tdc_fd.xise.
--
-- This file was automatically generated by ../../../ip_cores/general-cores/tools/sdb_desc_gen.tcl on:
-- Friday, July 20 2018
--
-- ../../../ip_cores/general-cores/tools/sdb_desc_gen.tcl is part of OHWR general-cores:
-- https://www.ohwr.org/projects/general-cores/wiki
--
-- For more information on SDB meta information, see also:
-- https://www.ohwr.org/projects/sdb/wiki
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.wishbone_pkg.all;
package synthesis_descriptor is
constant c_sdb_synthesis_info : t_sdb_synthesis := (
syn_module_name => "svec_list_tdc_fd",
syn_commit_id => "4a68a12eede44d878435d25c3c7eaaf4",
syn_tool_name => "ISE ",
syn_tool_version => x"00000147",
syn_date => x"20180720",
syn_username => "Dimitris Lampri");
constant c_sdb_repo_url : t_sdb_repo_url := (
repo_url => "ssh://git@gitlab.cern.ch:7999/coht/wr-trigger-distribution.git ");
end package synthesis_descriptor;
......@@ -47,13 +47,14 @@ use unisim.vcomponents.all;
entity svec_list_top is
generic (
g_dpram_initf : string := "../../../ip_cores/wr-cores/bin/wrpc/wrc_phy8.bram";
g_DPRAM_INITF : string := "../../../ip_cores/wr-cores/bin/wrpc/wrc_phy8.bram";
-- Simulation-mode enable parameter. Set by default (synthesis) to 0, and
-- changed to non-zero in the instantiation of the top level DUT in the
-- testbench. Its purpose is to reduce some internal counters/timeouts
-- to speed up simulations.
g_simulation : integer := 0
);
g_SIMULATION : integer := 0;
-- Bypass VME core, useful only in simulation
g_SIM_BYPASS_VME : boolean := FALSE);
port (
---------------------------------------------------------------------------
-- Clocks/resets
......@@ -75,6 +76,12 @@ entity svec_list_top is
-- VME interface
---------------------------------------------------------------------------
-- Bypass VME core, useful only in simulation
-- synthesis translate_off
sim_wb_i : in t_wishbone_slave_in := cc_dummy_slave_in;
sim_wb_o : out t_wishbone_slave_out;
-- synthesis translate_on
vme_write_n_i : in std_logic;
vme_sysreset_n_i : in std_logic;
vme_retry_oe_o : out std_logic;
......@@ -553,59 +560,69 @@ begin -- architecture arch
-- VME64x Core (WB Master)
-----------------------------------------------------------------------------
cmp_vme_core : xvme64x_core
generic map (
g_CLOCK_PERIOD => 16,
g_DECODE_AM => TRUE,
g_USER_CSR_EXT => FALSE,
g_WB_GRANULARITY => BYTE,
g_MANUFACTURER_ID => c_CERN_ID,
g_BOARD_ID => c_SVEC_ID,
g_REVISION_ID => c_SVEC_REVISION_ID,
g_PROGRAM_ID => c_SVEC_PROGRAM_ID)
port map (
clk_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
vme_i.as_n => vme_as_n_i,
vme_i.rst_n => vme_sysreset_n_i,
vme_i.write_n => vme_write_n_i,
vme_i.am => vme_am_i,
vme_i.ds_n => vme_ds_n_i,
vme_i.ga => vme_ga,
vme_i.lword_n => vme_lword_n_b,
vme_i.addr => vme_addr_b,
vme_i.data => vme_data_b,
vme_i.iack_n => vme_iack_n_i,
vme_i.iackin_n => vme_iackin_n_i,
vme_o.berr_n => vme_berr_n,
vme_o.dtack_n => vme_dtack_n_o,
vme_o.retry_n => vme_retry_n_o,
vme_o.retry_oe => vme_retry_oe_o,
vme_o.lword_n => vme_lword_n_b_out,
vme_o.data => vme_data_b_out,
vme_o.addr => vme_addr_b_out,
vme_o.irq_n => vme_irq_n,
vme_o.iackout_n => vme_iackout_n_o,
vme_o.dtack_oe => vme_dtack_oe_o,
vme_o.data_dir => vme_data_dir_int,
vme_o.data_oe_n => vme_data_oe_n_o,
vme_o.addr_dir => vme_addr_dir_int,
vme_o.addr_oe_n => vme_addr_oe_n_o,
wb_o => cnx_master_out(c_WB_MASTER_VME),
wb_i => cnx_master_in(c_WB_MASTER_VME),
int_i => vic_master_irq);
vme_ga <= vme_gap_i & vme_ga_i;
vme_berr_o <= not vme_berr_n;
vme_irq_o <= not vme_irq_n;
-- VME tri-state buffers
vme_data_b <= vme_data_b_out when vme_data_dir_int = '1' else (others => 'Z');
vme_addr_b <= vme_addr_b_out when vme_addr_dir_int = '1' else (others => 'Z');
vme_lword_n_b <= vme_lword_n_b_out when vme_addr_dir_int = '1' else 'Z';
vme_addr_dir_o <= vme_addr_dir_int;
vme_data_dir_o <= vme_data_dir_int;
gen_with_vme64_core : if not g_SIM_BYPASS_VME generate
cmp_vme_core : xvme64x_core
generic map (
g_CLOCK_PERIOD => 16,
g_DECODE_AM => TRUE,
g_USER_CSR_EXT => FALSE,
g_WB_GRANULARITY => BYTE,
g_MANUFACTURER_ID => c_CERN_ID,
g_BOARD_ID => c_SVEC_ID,
g_REVISION_ID => c_SVEC_REVISION_ID,
g_PROGRAM_ID => c_SVEC_PROGRAM_ID)
port map (
clk_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
vme_i.as_n => vme_as_n_i,
vme_i.rst_n => vme_sysreset_n_i,
vme_i.write_n => vme_write_n_i,
vme_i.am => vme_am_i,
vme_i.ds_n => vme_ds_n_i,
vme_i.ga => vme_ga,
vme_i.lword_n => vme_lword_n_b,
vme_i.addr => vme_addr_b,
vme_i.data => vme_data_b,
vme_i.iack_n => vme_iack_n_i,
vme_i.iackin_n => vme_iackin_n_i,
vme_o.berr_n => vme_berr_n,
vme_o.dtack_n => vme_dtack_n_o,
vme_o.retry_n => vme_retry_n_o,
vme_o.retry_oe => vme_retry_oe_o,
vme_o.lword_n => vme_lword_n_b_out,
vme_o.data => vme_data_b_out,
vme_o.addr => vme_addr_b_out,
vme_o.irq_n => vme_irq_n,
vme_o.iackout_n => vme_iackout_n_o,
vme_o.dtack_oe => vme_dtack_oe_o,
vme_o.data_dir => vme_data_dir_int,
vme_o.data_oe_n => vme_data_oe_n_o,
vme_o.addr_dir => vme_addr_dir_int,
vme_o.addr_oe_n => vme_addr_oe_n_o,
wb_o => cnx_master_out(c_WB_MASTER_VME),
wb_i => cnx_master_in(c_WB_MASTER_VME),
int_i => vic_master_irq);
vme_ga <= vme_gap_i & vme_ga_i;
vme_berr_o <= not vme_berr_n;
vme_irq_o <= not vme_irq_n;
-- VME tri-state buffers
vme_data_b <= vme_data_b_out when vme_data_dir_int = '1' else (others => 'Z');
vme_addr_b <= vme_addr_b_out when vme_addr_dir_int = '1' else (others => 'Z');
vme_lword_n_b <= vme_lword_n_b_out when vme_addr_dir_int = '1' else 'Z';
vme_addr_dir_o <= vme_addr_dir_int;
vme_data_dir_o <= vme_data_dir_int;
end generate gen_with_vme64_core;
gen_without_vme64_core : if g_SIM_BYPASS_VME generate
-- synthesis translate_off
cnx_master_out(c_WB_MASTER_VME) <= sim_wb_i;
sim_wb_o <= cnx_master_in(c_WB_MASTER_VME);
-- synthesis translate_on
end generate gen_without_vme64_core;
cmp_vme_led_extend : gc_extend_pulse
generic map (
......@@ -674,20 +691,20 @@ begin -- architecture arch
cmp_eth_endpoint : entity work.mt_ep_ethernet_single
port map (
clk_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
rmq_src_i => rmq_endpoint_out.snk_out(0)(0),
rmq_src_o => rmq_endpoint_in.snk_in(0)(0),
rmq_src_config_i => rmq_endpoint_out.snk_config_out(0)(0),
rmq_src_config_o => rmq_endpoint_in.snk_config_in(0)(0),
rmq_snk_i => rmq_endpoint_out.src_out(1)(0),
rmq_snk_o => rmq_endpoint_in.src_in(1)(0),
rmq_snk_config_i => rmq_endpoint_out.src_config_out(1)(0),
rmq_snk_config_o => rmq_endpoint_in.src_config_in(1)(0),
eth_src_o => eth_tx_out,
eth_src_i => eth_tx_in,
eth_snk_o => eth_rx_out,
eth_snk_i => eth_rx_in
clk_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
rmq_src_i => rmq_endpoint_out.snk_out(0)(0),
rmq_src_o => rmq_endpoint_in.snk_in(0)(0),
rmq_src_config_i => rmq_endpoint_out.snk_config_out(0)(0),
rmq_src_config_o => rmq_endpoint_in.snk_config_in(0)(0),
rmq_snk_i => rmq_endpoint_out.src_out(1)(0),
rmq_snk_o => rmq_endpoint_in.src_in(1)(0),
rmq_snk_config_i => rmq_endpoint_out.src_config_out(1)(0),
rmq_snk_config_o => rmq_endpoint_in.src_config_in(1)(0),
eth_src_o => eth_tx_out,
eth_src_i => eth_tx_in,
eth_snk_o => eth_rx_out,
eth_snk_i => eth_rx_in
);
rmq_endpoint_in.snk_in(0)(1 to t_maxslot_range'high) <=
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment