Commit a59dc76e authored by David Cussans's avatar David Cussans

Created a testbench for the trigger input block

Use AIDA_tlu/components/tlu/sim/cfg/triggerInputs_newTLU_tb.dep to build with ipbb
parent b61af01c
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 17.02.2017 11:26:56
-- Design Name:
-- Module Name: testbench_clocks - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity testbench_clocks is
-- Port ( );
end testbench_clocks;
architecture Behavioral of testbench_clocks is
begin
end Behavioral;
Simulation of trigger inputs
ipbb proj create sim triggerInputs_sim fmc-mtlu-gw:AIDA_tlu/components/tlu/sim -t ../../cfg/triggerInputs_newTLU_tb.dep
cd proj/triggerInputs_sim
ipbb sim setup-simlib ipcores fli
ipbb sim make-project
./vsim
Point to input and output files on command line:
vsim -voptargs=+acc work.triggerinputs_newtlu_tb(bench) -G g_BFMINPUT="/users/phdgc/tlu-tmp-2020-2-24/work/build/proj/triggerInputs_sim/BFM_INPUT_01.txt" -G g_BFMOUTPUT="/users/phdgc/tlu-tmp-2020-2-24/work/build/proj/triggerInputs_sim/BFM_OUTPUT_01.txt"
Reads from input file
cmd arg1 arg2 ....
cmd =
0 IPBUS
1 RESET
2 PAUSE
3 PULSE
pulse args...
3 delay0 width0 delay1 width1 delay2 width2 delay3 width3 delay4 width4 delay5 width5
IPBus args
0 w/r/rc addr data
w/r/rc = 0 : write , 1: read , 2: read with check
Pause args ...
2 nclock_cycles
@device_family = "artix7"
@device_name = "xc7a35t"
@device_package = "csg324"
@device_speed = "-2"
@boardname = "enclustra_ax3_pm3"
src -c AIDA_tlu/components/tlu ../../sim/hdl/triggerInputs_newTLU_tb.vhd
src --vhdl2008 -c AIDA_tlu/components/tlu ../../sim/hdl/transactionGenerator_behavioural.vhd
src --vhdl2008 -c AIDA_tlu/components/tlu ../../sim/hdl/ipbusTransactor_behavioural.vhd
src -c AIDA_tlu/components/tlu ../../sim/hdl/variablePulseTransactor_rtl.vhd
src -c AIDA_tlu/components/tlu ../../sim/hdl/BFMTypes.vhd
src -c AIDA_tlu/components/tlu trigger/triggerInputs_newTLU_rtl.vhd
src -c ipbus-firmware:components/ipbus_slaves ipbus_ctrlreg_v.vhd
src -c ipbus-firmware:components/ipbus_slaves ipbus_syncreg_v.vhd
src -c ipbus-firmware:components/ipbus_slaves syncreg_w.vhd
src -c ipbus-firmware:components/ipbus_slaves syncreg_r.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_fabric_sel.vhd
src -c AIDA_tlu/components/tlu synchronizeRegisters_rtl.vhd
src -c AIDA_tlu/components/tlu trigger/arrivalTimeLUT_rtl.vhd
src --vhdl2008 -c AIDA_tlu/components/tlu trigger/dualSERDES_1to4_rtl.vhd
src -c AIDA_tlu/components/tlu trigger/IODELAYCal_FSM_rtl.vhd
src -c AIDA_tlu/components/tlu counterWithReset_rtl.vhd
src -c AIDA_tlu/components/tlu logic_clocks_rtl.vhd
src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_types.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
# Include type definitions for TLU
src -c AIDA_tlu/components/tlu fmcTLU_pkg_body.vhd
src -c AIDA_tlu/components/tlu fmcTLU_pkg.vhd
-- Package File Template
--
-- Purpose: This package defines supplemental types, subtypes,
-- constants, and functions
-- Defines types used for "Bus Functional Model" of pulse generation and
-- IPBus cycle generation
library IEEE;
use IEEE.STD_LOGIC_1164.all;
USE ieee.numeric_std.ALL;
package BFMTypes is
constant c_BUSWIDTH : natural := 32;
-- List transaction types
constant NTRANSACTION_TYPES : integer := 4;
constant IPBUS : integer := 0;
constant RESET : integer := 1;
constant PAUSE : integer := 2;
constant PULSE : integer := 3;
constant COMMENT : integer := 777; -- make it large and easy to remember
constant WRITE_TO_SLAVE : integer := 0;
constant READ_FROM_SLAVE : integer := 1;
constant READ_FROM_SLAVE_WITH_CHECK : integer := 2;
-- map each transaction onto a port with a transactor attached
constant NTRANSACTORS : integer := 2;
constant IPBUSPORT : integer := 0;
constant PULSEPORT : integer := 1;
type t_transactorMap is array (NTRANSACTION_TYPES - 1 downto 0) of integer;
constant c_transactorMap : t_transactorMap := (IPBUS => IPBUSPORT,
RESET => 999,
PAUSE => 999,
PULSE => PULSEPORT
);
type t_transactorReturnValues is array (NTRANSACTORS - 1 downto 0) of integer;
constant TIMEUNIT : time := 100 ps; --! Sets units for pulse and sync
subtype t_wbTransactionReturn is std_logic_vector(c_BUSWIDTH - 1 downto 0);
type t_wbTransaction is record
r_read_write : integer;
r_addr : t_wbTransactionReturn;
r_data : t_wbTransactionReturn;
end record;
constant c_wbNullTransactionReturn : t_wbTransactionReturn := (others => '0');
-- Define the number of channels with pulses on....
constant c_NPULSE_CHANNELS : integer := 6;
type t_PULSEDEF is record
r_delay : integer;
r_width : integer;
end record;
type t_pulseTransaction is array (c_NPULSE_CHANNELS - 1 downto 0) of t_PULSEDEF;
subtype t_pulseTransactionReturn is integer;
-- VHDL 2008 has no dynamically sizable strings :-(
constant c_MAX_COMMAND_LINE_LENGTH : integer := (25 * c_NPULSE_CHANNELS) + 200;
end BFMTypes;
--! @file
--
---------------------------------------------------------------------------------------------------
--! @brief Simulation of a IPBus master ( subset of Wishbone master ) --
---------------------------------------------------------------------------------------------------
--
-- unit name: testbench (main_tb.vhd)
--
-- @author David Cussans
--
--! @details
--! based on code by Miguel Mendez (mmendez@sevensols.com),
--! http://svn.ohwr.org/qdr2-v6-core/trunk/hdl/sim/main_tb.vhd
--
-- @date 29-2-2012
--
-- version: 0.1
--
-- dependencies:
--
---------------------------------------------------------------------------------------------------
-- last changes: see svn log.
---------------------------------------------------------------------------------------------------
-- TODO: - .
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- 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 2.1 of the License, or (at your option) any later version. |
-- This source 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; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use STD.TEXTIO.all;
--! Declaration of transaction types for Bus Functional Model
use work.BFMTypes.all;
use work.ipbus.all; --! Declarations of IPBus records
entity ipbusTransactor is
port (
-- interface to transaction generator
Trans : in t_wbTransaction; --! Transaction from transaction generator
returnedData : out t_wbTransactionReturn; --! Signal end-of-cycle by making a transaction on this port
-- interface to "physical" ports
clk_i : in std_logic; --! System clock, active high
ipb_to_slave : out ipb_wbus; --! Signals from master to slave
ipb_from_slave : in ipb_rbus --! Signals from slave to master
);
end ipbusTransactor;
architecture behavioural of ipbusTransactor is
begin -- behavioural
p_commandloop: process
variable v_addr : integer;
variable v_addr_ack : integer;
variable outline : line;
variable v_data_from_slave : t_wbTransactionReturn := ( others => '0'); --! Temporary store for data
--read from slave.
variable v_receivedAck : boolean := false; -- set true when strobe goes high...
begin -- process p_commandloop
-- set the bus idle
ipb_to_slave.ipb_strobe <= '0';
ipb_to_slave.ipb_write <= '0';
ipb_to_slave.ipb_addr <= ( others => '1'); --! Set to a dummy value....
wait on Trans'TRANSACTION;
report "wishboneMasterBFM: Got transaction" severity note;
ipb_to_slave.ipb_strobe <= '1';
if( Trans.r_read_write = WRITE_TO_SLAVE ) then
-- Write data
ipb_to_slave.ipb_write <= '1';
ipb_to_slave.ipb_wdata <= Trans.r_data;
else
-- Read data
ipb_to_slave.ipb_write <= '0';
end if;
-- Addr for writing and reading
ipb_to_slave.ipb_addr <= Trans.r_addr;
v_receivedAck := false;
-- Loop until the slave raises ack.
while v_receivedAck = false loop
wait until rising_edge(clk_i); -- s_wb_clk'event and s_wb_clk = '1';
--got ack?
if(ipb_from_slave.ipb_ack = '1') then
v_receivedAck := true;
--read data
if(Trans.r_read_write=READ_FROM_SLAVE) or (Trans.r_read_write=READ_FROM_SLAVE_WITH_CHECK) then
-- the read data is stored
v_data_from_slave := ipb_from_slave.ipb_rdata;
report "Read from slave. Data = " & to_hstring(v_data_from_slave) severity note;
else -- if a write then ....
v_data_from_slave := Trans.r_data; -- just return what we were given
end if;
end if;
end loop;
-- terminate the cycle
ipb_to_slave.ipb_strobe <= '0';
ipb_to_slave.ipb_write <= '0';
report "returning data = " & to_hstring(v_data_from_slave) severity note;
returnedData <= v_data_from_slave; -- This event is what signals the end
-- of transaction.
end process p_commandloop;
end behavioural;
--=============================================================================
--! @file wishboneTransactionGenerator_behavioural.vhd
--=============================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
--! Package containg type definition and constants
use work.BFMTypes.all;
use std.TEXTIO.all;
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
-------------------------------------------------------------------------------
-- unit name: wishboneTransactionGenerator
--
--! @brief Loops Generating transactions to send to BFM
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 2\1\2012
--
--! @version v0.1
--
--! @details
--! Must be compiled with VHDL-2008 ( uses HREAD and HWRITE ).
--!
--! <b>Dependencies:</b>\n
--! None
--!
--! <b>References:</b>\n
--! referenced by ipbusMarocADC_tb \n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 9/March/2012 DGC - changing address and data to be STD_LOGIC_VECTOR. \n
--! using HWRITE / HREAD for Hexidecimal IO
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
--------------------------------------------------------------------------------
entity wishboneTransactionGenerator is
generic (
g_BUSWIDTH : integer := c_BUSWIDTH; --! Number of bits in each word
BFMINPUT : string := "$BFMINPUT"; --! File containing list of commands
BFMOUTPUT : string := "$BFMOUTPUT" --! Output file
);
port (
wb_transaction_o : out t_wbTransaction; -- ! signal that carries transaction to
-- IPBus interface
wb_returned_data_i : in t_wbTransactionReturn; -- ! Carrys data back from BFM
pulse_transaction_o : out t_pulseTransaction;
pulse_returned_data_i : in t_pulseTransactionReturn;
--! Signal to clock generator
endOfSim_o : out boolean --! Take high to stop simulation.
);
end wishboneTransactionGenerator;
architecture behavioural of wishboneTransactionGenerator is
signal s_command_time : time; -- Store the time the commands are issued.
begin -- behavioural
p_commandLoop : process
file COMMANDS : text;
file DATA : text;
variable status : file_open_status;
variable Lin : line;
variable Lout : line;
-- variable debugL : line;
variable v_comment : string(1 to c_MAX_COMMAND_LINE_LENGTH);
variable v_wb_returned_data : t_wbTransactionReturn;
variable v_currentWbTransaction : t_wbTransaction;
variable v_pulse_returned_data : t_pulseTransactionReturn;
variable v_currentPulseTransaction : t_pulseTransaction;
variable textLine : line;
variable v_transactor_id : integer := 999; --! Halt with error if
--transactor ID not set...
variable v_transactionType : integer := 999;
variable v_pauseValue : integer;
--variable v_wb_returned_data : t_wbTransactionReturn ;
begin
-- open input and output files
FILE_OPEN(status, COMMANDS, BFMINPUT, read_mode);
FILE_OPEN(status, DATA, BFMOUTPUT, write_mode);
endOfSim_o <= false;
while not ENDFILE(COMMANDS) loop --! Loop over commands from BFMINPUT
s_command_time <= NOW;
READLINE(COMMANDS, Lin);
READ(Lin, v_transactionType); --! Read the transaction type as the first item on line
if (v_transactionType = PULSE) then
for pulseChan in 0 to c_NPULSE_CHANNELS-1 loop
READ(Lin, v_currentPulseTransaction(pulseChan).r_delay);
READ(Lin, v_currentPulseTransaction(pulseChan).r_width);
end loop; -- pulseChan
pulse_transaction_o <= v_currentPulseTransaction;
wait on pulse_returned_data_i'transaction; -- read the data returned by BFM
v_pulse_returned_data := pulse_returned_data_i;
-- bodge up a return printout
WRITE(Lout, v_pulse_returned_data, left, 20);
elsif (v_transactionType = COMMENT) then
-- read in comment string..
assert Lin'length < v_comment'length; -- make sure S is big enough
v_comment := (others => ' '); -- make sure that the previous line is overwritten
if Lin'length > 0 then
read(Lin, v_comment(1 to Lin'length));
end if;
-- we have a comment
WRITE(Lout, v_comment, left, v_comment'length);
elsif (v_transactionType = IPBUS) then
-- we have an IPBus transaction
-- Read line of form
-- r/w addr data
READ(Lin, v_currentWbTransaction.r_read_write);
HREAD(Lin, v_currentWbTransaction.r_addr);
HREAD(Lin, v_currentWbTransaction.r_data); -- Need to provide dummy data for reads.
-- Issue transaction to Wishbone (IPBus) port
wb_transaction_o <= v_currentWbTransaction;
wait on wb_returned_data_i'transaction; -- read the data returned by BFM
v_wb_returned_data := wb_returned_data_i;
write(LOut,
"transaction type, addr, data, returned data, current time: " &
to_hstring(to_unsigned(v_currentWbTransaction.r_read_write, 32)) & string'(" ") &
to_hstring(unsigned(v_currentWbTransaction.r_addr)) & string'(" ") &
to_hstring(unsigned(v_currentWbTransaction.r_data)) & string'(" ") &
to_hstring(unsigned(v_wb_returned_data)) & string'(" ") &
time'image(s_command_time)
);
elsif (v_transactionType = PAUSE) then
-- Read number of time ticks ( 100ps ) to pause for
READ(Lin, v_pauseValue);
report "BFM: Pausing for clock cycles = " & to_string(v_pauseValue) & " starting at " & time'image(s_command_time) severity note;
wait for v_pauseValue * TIMEUNIT;
else
report "BFM: Bad command type. Exiting" severity error;
end if;
WRITELINE(DATA, Lout);
--! Flush the buffers every time we write a line....
FLUSH(DATA);
end loop; -- idx
report "Ending simulation" severity note;
endOfSim_o <= true;
wait;
end process p_commandLoop;
end behavioural;
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;
USE work.ipbus.all;
USE work.ipbus_reg_types.all;
USE work.fmcTLU.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.fmcTLU.all;
use work.BFMTypes.all;
entity triggerInputs_newTLU_tb is
generic (
g_NUM_INPUTS : natural := 6;
g_IPBUS_WIDTH : positive := 32
g_IPBUS_WIDTH : positive := 32;
g_BFMINPUT : string := "$BFMINPUT";
g_BFMOUTPUT : string := "$BFMOUTPUT"
);
end;
architecture bench of triggerInputs_newTLU_tb is
component triggerInputs_newTLU
GENERIC(
generic(
g_NUM_INPUTS : natural := g_NUM_INPUTS;
g_IPBUS_WIDTH : positive := g_IPBUS_WIDTH
);
PORT(
clk_4x_logic : IN std_logic;
clk_200_i : IN std_logic;
strobe_4x_logic_i : IN std_logic;
threshold_discr_p_i : IN std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);
threshold_discr_n_i : IN std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);
reset_i : IN std_logic;
trigger_times_o : OUT t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0);
trigger_o : OUT std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);
edge_rising_times_o : OUT t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0);
edge_falling_times_o : OUT t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0);
edge_rising_o : OUT std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);
edge_falling_o : OUT std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);
ipbus_clk_i : IN std_logic;
ipbus_reset_i : IN std_logic;
ipbus_i : IN ipb_wbus;
ipbus_o : OUT ipb_rbus;
clk_8x_logic_i : IN std_logic;
strobe_8x_logic_i : IN std_logic
port(
clk_4x_logic : in std_logic;
clk_200_i : in std_logic;
strobe_4x_logic_i : in std_logic;
threshold_discr_p_i : in std_logic_vector (g_NUM_INPUTS-1 downto 0);
threshold_discr_n_i : in std_logic_vector (g_NUM_INPUTS-1 downto 0);
reset_i : in std_logic;
trigger_times_o : out t_triggerTimeArray (g_NUM_INPUTS-1 downto 0);
trigger_o : out std_logic_vector (g_NUM_INPUTS-1 downto 0);
edge_rising_times_o : out t_triggerTimeArray (g_NUM_INPUTS-1 downto 0);
edge_falling_times_o : out t_triggerTimeArray (g_NUM_INPUTS-1 downto 0);
edge_rising_o : out std_logic_vector (g_NUM_INPUTS-1 downto 0);
edge_falling_o : out std_logic_vector (g_NUM_INPUTS-1 downto 0);
ipbus_clk_i : in std_logic;
ipbus_reset_i : in std_logic;
ipbus_i : in ipb_wbus;
ipbus_o : out ipb_rbus;
clk_8x_logic_i : in std_logic;
strobe_8x_logic_i : in std_logic
);
end component;
signal clk_4x_logic: std_logic := '0';
signal clk_200_i: std_logic;
signal strobe_4x_logic_i: std_logic;
signal threshold_discr_p_i: std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);
signal threshold_discr_n_i: std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);
signal reset_i: std_logic;
signal trigger_times_o: t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0);
signal trigger_o: std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);
signal edge_rising_times_o: t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0);
signal edge_falling_times_o: t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0);
signal edge_rising_o: std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);
signal edge_falling_o: std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);
signal ipbus_clk_i: std_logic;
signal ipbus_reset_i: std_logic;
signal ipbus_i: ipb_wbus;
signal ipbus_o: ipb_rbus;
signal clk_8x_logic_i: std_logic;
signal clk_4x_logic : std_logic := '0';
signal clk_200_i : std_logic;
signal strobe_4x_logic_i : std_logic;
signal s_pulses : std_logic_vector (g_NUM_INPUTS-1 downto 0);
signal threshold_discr_p_i : std_logic_vector (g_NUM_INPUTS-1 downto 0);
signal threshold_discr_n_i : std_logic_vector (g_NUM_INPUTS-1 downto 0);
signal reset_i : std_logic;
signal trigger_times_o : t_triggerTimeArray (g_NUM_INPUTS-1 downto 0);
signal trigger_o : std_logic_vector (g_NUM_INPUTS-1 downto 0);
signal edge_rising_times_o : t_triggerTimeArray (g_NUM_INPUTS-1 downto 0);
signal edge_falling_times_o : t_triggerTimeArray (g_NUM_INPUTS-1 downto 0);
signal edge_rising_o : std_logic_vector (g_NUM_INPUTS-1 downto 0);
signal edge_falling_o : std_logic_vector (g_NUM_INPUTS-1 downto 0);
signal ipbus_clk_i : std_logic;
signal ipbus_reset_i : std_logic;
signal ipbus_i : ipb_wbus;
signal ipbus_o : ipb_rbus;
signal clk_8x_logic_i : std_logic;
signal clk_logic : std_logic;
signal strobe_8x_logic_i: std_logic ;
constant C_NUM_STROBE_TAPS : positive := 2; --! Adjust to shift strobes relative to 40MHz clock edge
signal s_clk40_delayed_160 : std_logic_vector(C_NUM_STROBE_TAPS downto 0); --! Shift register used to generate clock_4x strobe. Adjust length for correct alignment with incoming clock
signal s_clk40_delayed_320 : std_logic_vector((2*C_NUM_STROBE_TAPS)+1 downto 0); --! Shift register used to generate clock_8x strobe. Adjust length for correct alignment with incoming clock
signal strobe_8x_logic_i : std_logic;
-- constant C_NUM_STROBE_TAPS : positive := 2; --! Adjust to shift strobes relative to 40MHz clock edge
-- signal s_clk40_delayed_160 : std_logic_vector(C_NUM_STROBE_TAPS downto 0); --! Shift register used to generate clock_4x strobe. Adjust length for correct alignment with incoming clock
-- signal s_clk40_delayed_320 : std_logic_vector((2*C_NUM_STROBE_TAPS)+1 downto 0); --! Shift register used to generate clock_8x strobe. Adjust length for correct alignment with incoming clock
signal s_dut_clk, s_clocks_locked , s_logic_reset : std_logic;
signal s_dut_clk, s_clocks_locked, s_logic_reset : std_logic;
signal s_pulseTransaction : t_pulseTransaction;
signal s_pulseTransactionReturn : t_pulseTransactionReturn;
constant delta : time := 0.02 ns; -- make sure IPBus clock drifts w.r.t.
-- logic clocks
constant clockLogic_period : time := 25 ns; -- 40MHz clock
--constant clock320_period: time := 3.125 ns; -- 320 MHz clock
constant clock200_period: time := 5 ns + delta; -- 200 MHz clock
constant clockipbus_period: time := 31.25 ns + delta; -- 320 MHz clock
constant clock200_period : time := 5 ns + delta; -- 200 MHz clock
constant clockipbus_period : time := 31.25 ns + delta; -- 320 MHz clock
signal stop_the_clock: boolean;
signal stop_the_clock : boolean := false;
-- Look at /projects/HEP_Instrumentation/cad/designs/uob-hep-pc043a/trunk/firmware/maroc3_fmc/sim_src/variablePulseTransactor_rtl.vhd
--/projects/HEP_Instrumentation/cad/designs/uob-hep-pc043a/trunk/firmware/maroc3_fmc/sim_src/wishbone_master_behavioural.vhd
-- and friends for parameterizable pulse generator.
begin
-- Insert values for generic parameters !!
uut: triggerInputs_newTLU generic map ( g_NUM_INPUTS => g_NUM_INPUTS,
g_IPBUS_WIDTH => g_IPBUS_WIDTH )
port map ( clk_4x_logic => clk_4x_logic,
uut : triggerInputs_newTLU generic map (g_NUM_INPUTS => g_NUM_INPUTS,
g_IPBUS_WIDTH => g_IPBUS_WIDTH)
port map (clk_4x_logic => clk_4x_logic,
clk_200_i => clk_200_i,
strobe_4x_logic_i => strobe_4x_logic_i,
threshold_discr_p_i => threshold_discr_p_i,
......@@ -98,11 +108,11 @@ begin
ipbus_i => ipbus_i,
ipbus_o => ipbus_o,
clk_8x_logic_i => clk_8x_logic_i,
strobe_8x_logic_i => strobe_8x_logic_i );
strobe_8x_logic_i => strobe_8x_logic_i);
stimulus: process
stimSequence : process
begin
stop_the_clock <= false;
-- Put initialisation code here
reset_i <= '1';
ipbus_reset_i <= '1';
......@@ -110,16 +120,46 @@ begin
reset_i <= '0';
ipbus_reset_i <= '0';
wait for clockLogic_period * 500;
-- Put test bench stimulus code here
stop_the_clock <= true;
-- Wait for commands to be played through
wait until stop_the_clock;
reset_i <= '1';
wait;
end process;
clockGenerator: ENTITY work.logic_clocks
transactionGen : entity work.wishboneTransactionGenerator
generic map (
g_BUSWIDTH => g_IPBUS_WIDTH, --! Number of bits in each word
BFMINPUT => g_BFMINPUT , --! File containing list of commands
BFMOUTPUT => g_BFMOUTPUT --! Output file
)
port map (
wb_transaction_o => open, -- ! signal that carries transaction to
-- IPBus interface
wb_returned_data_i => c_wbNullTransactionReturn, -- ! Carrys data back from BFM
pulse_transaction_o => s_pulseTransaction,
pulse_returned_data_i => s_pulseTransactionReturn,
--! Signal to clock generator
endOfSim_o => stop_the_clock --! Take high to stop simulation.
);
pulseGen: entity work.variablePulseTransactor
generic map (
g_BUSWIDTH => g_IPBUS_WIDTH) -- width for triggernumber and timestamp
port map (
clk_i => strobe_4x_logic_i,
trans_i => s_pulseTransaction,
returnedData_o => s_pulseTransactionReturn,
signal_o => s_pulses,
triggerNumber_o => open,
timeStamp_o => open
);
threshold_discr_p_i <= s_pulses;
threshold_discr_n_i <= not s_pulses;
clockGenerator : entity work.logic_clocks
port map (
ipbus_clk_i => ipbus_clk_i,
ipbus_i => ipbus_i,
......@@ -137,7 +177,7 @@ begin
);
clockLogic: process
clockLogic : process
begin
while not stop_the_clock loop
clk_logic <= '0', '1' after clockLogic_period / 2;
......@@ -146,7 +186,7 @@ begin
wait;
end process;
clockIpbus: process
clockIpbus : process
begin
while not stop_the_clock loop
ipbus_clk_i <= '0', '1' after clockipbus_period / 2;
......@@ -155,7 +195,7 @@ begin
wait;
end process;
clock200: process
clock200 : process
begin
while not stop_the_clock loop
clk_200_i <= '0', '1' after clock200_period / 2;
......@@ -164,5 +204,5 @@ begin
wait;
end process;
end;
end;
--! @file
--!
--! @brief Issues a pulse of variable width and delay. Based on pulseTransactor
--! @author David Cussans
--! @date 23\4\2013
--
--! Note - have to compile with VHDL-2008
--
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use STD.TEXTIO.all;
--! Declaration of transaction types for Bus Functional Model
use work.BFMTypes.all;
use std.TEXTIO.all;
entity variablePulseTransactor is
generic(
g_BUSWIDTH : integer := 32); -- width for triggernumber and timestamp
port(
clk_i : in std_logic;
trans_i : in t_pulseTransaction;
returnedData_o : out t_pulseTransactionReturn;
signal_o : out std_logic_vector(c_NPULSE_CHANNELS - 1 downto 0); --! Signal pulses low-high-low
triggerNumber_o : out std_logic_vector(g_BUSWIDTH - 1 downto 0);
timeStamp_o : out std_logic_vector(g_BUSWIDTH - 1 downto 0)
);
end variablePulseTransactor;
architecture rtl of variablePulseTransactor is
signal s_timeStamp : unsigned(g_BUSWIDTH - 1 downto 0) := (others => '0');
constant c_timeGranularity : time := 1 ps;
signal s_pulseNum : integer := 0;
begin -- rtl
p_pulseGen : process is
variable v_pulseDelay : time := 0 ps;
variable v_pulseWidth : time := 0 ps;
variable v_lastEdge : time := 0 ps;
begin
report "variablePulseBFM: waiting for transaction" severity note;
signal_o <= (others => '0');
wait on trans_i'transaction;
report "variablePulseBFM: Got transaction" severity note;
wait until rising_edge(clk_i);
for chan in 0 to signal_o'length - 1 loop
v_pulseDelay := trans_i(chan).r_delay * TIMEUNIT;
v_pulseWidth := trans_i(chan).r_width * TIMEUNIT;
if (v_pulseDelay + v_pulseWidth ) > v_lastEdge then
v_lastEdge := (v_pulseDelay + v_pulseWidth );
end if;
report "Queing pulse . chan , delay , width " & integer'image(chan) & " " & time'image(v_pulseDelay) & " " & time'image(v_pulseWidth);
signal_o(chan) <= '1' after v_pulseDelay, '0' after (v_pulseDelay + v_pulseWidth);
end loop;
wait for v_lastEdge;
-- Update trigger number
s_pulseNum <= s_pulseNum + 1;
triggerNumber_o <= std_logic_vector(to_unsigned(s_pulseNum, g_BUSWIDTH));
-- output current time-stamp
timeStamp_o <= std_logic_vector(s_timeStamp);
returnedData_o <= s_pulseNum;
end process p_pulseGen;
-- purpose: keeps a timestamp in terms of clock cycles
-- type : sequential
-- inputs : clk_i, s_timeStamp
-- outputs: s_timeStamp
p_timeStamp : process(clk_i)
begin -- process p_timeStamp
if rising_edge(clk_i) then
s_timeStamp <= s_timeStamp + 1;
end if;
end process p_timeStamp;
end rtl;
777 Generate test pulses
2 8000
3 10 1000 100 2000 500 4000 0 200 200 6000 400 8000
2 6000
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