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;
--! @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