DEVL: decouple user event counting from events in the event stream, peparation to simulate event recorder functionality
This commit is contained in:
@ -26,6 +26,10 @@ add_sources $LibPath/Firmware/VHDL/evr320/tb {
|
||||
|
||||
# setup tb runs
|
||||
create_tb_run "evr320_decoder_tb"
|
||||
tb_run_add_arguments \
|
||||
"-gg_EVENT_NR_0=16#0F# -gg_EVENT_NR_1=0 -gg_EVENT_NR_2=0 -gg_EVENT_NR_3=0 -gg_EVENT_NR_SOS=0" \
|
||||
"-gg_EVENT_NR_0=2 -gg_EVENT_NR_1=4 -gg_EVENT_NR_2=0 -gg_EVENT_NR_3=3 -gg_EVENT_NR_SOS=0" \
|
||||
"-gg_EVENT_NR_0=0 -gg_EVENT_NR_1=0 -gg_EVENT_NR_2=5 -gg_EVENT_NR_3=0 -gg_EVENT_NR_SOS=6"
|
||||
add_tb_run
|
||||
|
||||
# IFC1210 Bindings
|
||||
|
36
sim/run.tcl
36
sim/run.tcl
@ -1,38 +1,12 @@
|
||||
# Library Path
|
||||
set LibPath "../../../.."
|
||||
|
||||
# Compile UVVM library (if necessary):
|
||||
# -------------------------------------------------------
|
||||
set uvvm_lib $LibPath/Firmware/VHDL/UVVM/uvvm_util/sim/uvvm_util/
|
||||
# compile lib if folder not exist:
|
||||
#if {![file isdirectory $uvvm_lib]} {
|
||||
# copy adapted pkg:
|
||||
file copy -force ../tb/adaptations_pkg.vhd $LibPath/Firmware/VHDL/UVVM/uvvm_util/src/
|
||||
set last_dir [pwd]
|
||||
cd $LibPath/Firmware/VHDL/UVVM/uvvm_util/script/
|
||||
do compile_src.do
|
||||
cd $last_dir
|
||||
#}
|
||||
vmap uvvm_util $LibPath/Firmware/VHDL/UVVM/uvvm_util/sim/uvvm_util/
|
||||
# -------------------------------------------------------
|
||||
|
||||
|
||||
# Check if running in jenkins environment
|
||||
if [info exists env(JENKINS_HOME)] {
|
||||
set jenkins 1
|
||||
# Configure UVVM -> until compile when not existing
|
||||
set uvvm_path $LibPath/Firmware/VHDL/UVVM/uvvm_util
|
||||
if {[file isdirectory uvvm_util]} {
|
||||
puts "UVVM directory evr320/sim/uvvm_util is present --> not compiled again!"
|
||||
} else {
|
||||
set jenkins 0
|
||||
}
|
||||
|
||||
# map different libraries when running on jenkins machine:
|
||||
if {$jenkins == 1} {
|
||||
vmap unisim /home/modelsim/xilinx_libs/13.4/unisim
|
||||
vmap xilinxcorelib /home/modelsim/xilinx_libs/13.4/xilinxcorelib
|
||||
vmap secureip /home/modelsim/xilinx_libs/13.4/secureip
|
||||
} else {
|
||||
vmap unisim C:/Xilinx/13.4/ISE_DS/ISE/vhdl/mti_se/10.3c/nt64/unisim
|
||||
vmap xilinxcorelib C:/Xilinx/13.4/ISE_DS/ISE/vhdl/mti_se/10.3c/nt64/xilinxcorelib
|
||||
vmap secureip C:/Xilinx/13.4/ISE_DS/ISE/vhdl/mti_se/10.3c/nt64/unisim
|
||||
do $uvvm_path/script/compile_src.do $uvvm_path
|
||||
}
|
||||
|
||||
#Load dependencies TODO
|
||||
|
@ -29,297 +29,362 @@ library work;
|
||||
use work.evr320_pkg.all;
|
||||
|
||||
entity evr320_decoder_tb is
|
||||
generic (
|
||||
g_EVENT_NR_0 : integer range 0 to 255 := 16#00#;
|
||||
g_EVENT_NR_1 : integer range 0 to 255 := 16#04#;
|
||||
g_EVENT_NR_2 : integer range 0 to 255 := 16#00#;
|
||||
g_EVENT_NR_3 : integer range 0 to 255 := 16#00#;
|
||||
g_EVENT_NR_SOS : integer range 0 to 255 := 16#00#
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture testbench of evr320_decoder_tb is
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- System
|
||||
---------------------------------------------------------------------------
|
||||
-- System
|
||||
constant C_RXUSRCLK_CYCLE : time:= 7 ns;
|
||||
constant C_USRCLK_CYCLE : time:= 8 ns;
|
||||
---------------------------------------------------------------------------
|
||||
-- MGT stream
|
||||
---------------------------------------------------------------------------
|
||||
type mgt_stream_sample_type is record
|
||||
data : std_logic_vector(7 downto 0);
|
||||
data_k : std_logic_vector(0 downto 0);
|
||||
event : std_logic_vector(7 downto 0);
|
||||
event_k : std_logic_vector(0 downto 0);
|
||||
end record mgt_stream_sample_type;
|
||||
|
||||
type mgt_stream_type is array (natural range <>) of mgt_stream_sample_type;
|
||||
|
||||
signal mgt_stream_index : integer range 0 to 511 := 0;
|
||||
signal mgt_stream : mgt_stream_type(511 downto 0) := (others=>(others=>(others=>'0')));
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Timing decoder interface
|
||||
-----------------------------------------------------------------------------
|
||||
-- Link status
|
||||
signal rxlos : std_logic := '0';
|
||||
-- Clock
|
||||
signal rxusrclk : std_logic := '0';
|
||||
-- Data
|
||||
signal rxdata : std_logic_vector(15 downto 0) := (others => '0');
|
||||
-- Status 8B/10B decoder
|
||||
signal rxcharisk : std_logic_vector( 1 downto 0) := (others => '0');
|
||||
|
||||
signal usr_clk : std_logic := '0';
|
||||
signal evr_params : typ_evr320_params;
|
||||
signal mem_addr : std_logic_vector(11 downto 0) := (others => '0');
|
||||
signal mem_data : std_logic_vector(31 downto 0) := (others => '0');
|
||||
-- Decoder stream:
|
||||
type dec_stream_type is record
|
||||
data : std_logic_vector(7 downto 0);
|
||||
addr : std_logic_vector(10 downto 0);
|
||||
end record dec_stream_type;
|
||||
type dec_stream_check_arr is array (natural range <>) of dec_stream_type;
|
||||
|
||||
signal dec_stream_data : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal dec_stream_addr : std_logic_vector(10 downto 0) := (others => '0');
|
||||
signal dec_stream_valid : std_logic;
|
||||
signal dec_stream_check : dec_stream_check_arr(0 to 2047);
|
||||
signal dec_stream_recv_bytes : integer range 0 to 2047;
|
||||
|
||||
type segment_data_arr is array (natural range <>) of std_logic_vector(7 downto 0);
|
||||
signal segment_addr : std_logic_vector(7 downto 0);
|
||||
signal segment_data : segment_data_arr(0 to 2047);
|
||||
signal segment_length : natural range 0 to 2047;
|
||||
---------------------------------------------------------------------------
|
||||
-- System
|
||||
---------------------------------------------------------------------------
|
||||
constant C_RXUSRCLK_CYCLE : time:= 7 ns;
|
||||
constant C_USRCLK_CYCLE : time:= 8 ns;
|
||||
constant C_EVT_NR : integer := 4;
|
||||
|
||||
signal usr_events : std_logic_vector( 3 downto 0) := (others => '0');
|
||||
|
||||
constant FILTER_ADDRESS : std_logic_vector(11 downto 0) := x"028";
|
||||
constant FILTER_NUM_BYTES : integer := 8;
|
||||
constant STIMULI_RUNS : integer := 2;
|
||||
|
||||
signal received_events : integer := 0;
|
||||
signal expect_num_events : integer := 0;
|
||||
signal filter_data, filter_data_check : std_logic_vector(63 downto 0) := (others => '0');
|
||||
signal filter_valid : std_logic := '0';
|
||||
---------------------------------------------------------------------------
|
||||
-- MGT stream
|
||||
---------------------------------------------------------------------------
|
||||
type mgt_stream_sample_type is record
|
||||
data : std_logic_vector(7 downto 0);
|
||||
data_k : std_logic_vector(0 downto 0);
|
||||
event : std_logic_vector(7 downto 0);
|
||||
event_k : std_logic_vector(0 downto 0);
|
||||
end record mgt_stream_sample_type;
|
||||
|
||||
type mgt_stream_type is array (natural range <>) of mgt_stream_sample_type;
|
||||
|
||||
signal mgt_stream_index : integer range 0 to 511 := 0;
|
||||
signal mgt_stream : mgt_stream_type(511 downto 0) := (others=>(others=>(others=>'0')));
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Timing decoder interface
|
||||
-----------------------------------------------------------------------------
|
||||
-- Link status
|
||||
signal rxlos : std_logic := '0';
|
||||
-- Clock
|
||||
signal rxusrclk : std_logic := '0';
|
||||
-- Data
|
||||
signal rxdata : std_logic_vector(15 downto 0) := (others => '0');
|
||||
-- Status 8B/10B decoder
|
||||
signal rxcharisk : std_logic_vector( 1 downto 0) := (others => '0');
|
||||
|
||||
signal usr_clk : std_logic := '0';
|
||||
signal evr_params : typ_evr320_params;
|
||||
signal mem_addr : std_logic_vector(11 downto 0) := (others => '0');
|
||||
signal mem_data : std_logic_vector(31 downto 0) := (others => '0');
|
||||
|
||||
-- Decoder stream
|
||||
type dec_stream_type is record
|
||||
data : std_logic_vector(7 downto 0);
|
||||
addr : std_logic_vector(10 downto 0);
|
||||
end record dec_stream_type;
|
||||
type dec_stream_check_arr is array (natural range <>) of dec_stream_type;
|
||||
|
||||
signal dec_stream_data : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal dec_stream_addr : std_logic_vector(10 downto 0) := (others => '0');
|
||||
signal dec_stream_valid : std_logic;
|
||||
signal dec_stream_check : dec_stream_check_arr(0 to 2047);
|
||||
signal dec_stream_recv_bytes : integer range 0 to 2047;
|
||||
|
||||
type segment_data_arr is array (natural range <>) of std_logic_vector(7 downto 0);
|
||||
signal segment_addr : std_logic_vector(7 downto 0);
|
||||
signal segment_data : segment_data_arr(0 to 2047);
|
||||
signal segment_length : natural range 0 to 2047;
|
||||
|
||||
constant FILTER_ADDRESS : std_logic_vector(11 downto 0) := x"028";
|
||||
constant FILTER_NUM_BYTES : integer := 8;
|
||||
constant STIMULI_RUNS : integer := 2;
|
||||
|
||||
signal filter_data, filter_data_check : std_logic_vector(63 downto 0) := (others => '0');
|
||||
signal filter_valid : std_logic := '0';
|
||||
|
||||
-- Events
|
||||
signal usr_events : std_logic_vector( 3 downto 0) := (others => '0');
|
||||
signal sos_event : std_logic := '0';
|
||||
|
||||
type typ_arrint is array (natural range <>) of integer;
|
||||
signal received_events : typ_arrint(0 to C_EVT_NR-1) := (others => 0);
|
||||
signal expect_events : typ_arrint(0 to C_EVT_NR-1) := (others => 0);
|
||||
signal expect_events_total : integer := 0;
|
||||
|
||||
-- Event Recorder
|
||||
signal event_recorder_status : typ_evt_rec_status;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Timing decoder
|
||||
-----------------------------------------------------------------------------
|
||||
evr320_decoder_inst: entity work.evr320_decoder
|
||||
port map
|
||||
(
|
||||
--------------------------------------------------------------------------
|
||||
-- Debug interface
|
||||
--------------------------------------------------------------------------
|
||||
debug_clk => open,
|
||||
debug => open,
|
||||
--------------------------------------------------------------------------
|
||||
-- GTX parallel interface
|
||||
--------------------------------------------------------------------------
|
||||
i_mgt_rst => rxlos,
|
||||
i_mgt_rx_clk => rxusrclk,
|
||||
i_mgt_rx_data => rxdata,
|
||||
i_mgt_rx_charisk => rxcharisk,
|
||||
--------------------------------------------------------------------------
|
||||
-- User interface CPU clock
|
||||
--------------------------------------------------------------------------
|
||||
i_usr_clk => usr_clk,
|
||||
i_evr_params => evr_params,
|
||||
o_event_recorder_stat => open,
|
||||
i_event_recorder_ctrl => c_INIT_EVT_REC_CTRL,
|
||||
i_mem_addr => mem_addr,
|
||||
o_mem_data => mem_data,
|
||||
--------------------------------------------------------------------------
|
||||
-- User stream interface User clock
|
||||
--------------------------------------------------------------------------
|
||||
i_stream_clk => usr_clk,
|
||||
o_stream_data => dec_stream_data,
|
||||
o_stream_addr => dec_stream_addr,
|
||||
o_stream_valid => dec_stream_valid,
|
||||
--------------------------------------------------------------------------
|
||||
-- User interface MGT clock
|
||||
--------------------------------------------------------------------------
|
||||
o_usr_events => usr_events,
|
||||
o_usr_events_ext => open,
|
||||
o_sos_event => open
|
||||
);
|
||||
-----------------------------------------------------------------------------
|
||||
-- Timing decoder
|
||||
-----------------------------------------------------------------------------
|
||||
evr320_decoder_inst: entity work.evr320_decoder
|
||||
generic map
|
||||
(
|
||||
EVENT_RECORDER => true,
|
||||
MEM_DATA_WIDTH => 32
|
||||
)
|
||||
port map
|
||||
(
|
||||
--------------------------------------------------------------------------
|
||||
-- Debug interface
|
||||
--------------------------------------------------------------------------
|
||||
debug_clk => open,
|
||||
debug => open,
|
||||
--------------------------------------------------------------------------
|
||||
-- GTX parallel interface
|
||||
--------------------------------------------------------------------------
|
||||
i_mgt_rst => rxlos,
|
||||
i_mgt_rx_clk => rxusrclk,
|
||||
i_mgt_rx_data => rxdata,
|
||||
i_mgt_rx_charisk => rxcharisk,
|
||||
--------------------------------------------------------------------------
|
||||
-- User interface CPU clock
|
||||
--------------------------------------------------------------------------
|
||||
i_usr_clk => usr_clk,
|
||||
i_evr_params => evr_params,
|
||||
o_event_recorder_stat => event_recorder_status,
|
||||
i_event_recorder_ctrl => c_INIT_EVT_REC_CTRL,
|
||||
i_mem_addr => mem_addr,
|
||||
o_mem_data => mem_data,
|
||||
--------------------------------------------------------------------------
|
||||
-- User stream interface User clock
|
||||
--------------------------------------------------------------------------
|
||||
i_stream_clk => usr_clk,
|
||||
o_stream_data => dec_stream_data,
|
||||
o_stream_addr => dec_stream_addr,
|
||||
o_stream_valid => dec_stream_valid,
|
||||
--------------------------------------------------------------------------
|
||||
-- User interface MGT clock
|
||||
--------------------------------------------------------------------------
|
||||
o_usr_events => usr_events,
|
||||
o_usr_events_ext => open,
|
||||
o_sos_event => sos_event
|
||||
);
|
||||
|
||||
evr320_data_filter_inst: entity work.evr320_data_filter
|
||||
generic map (
|
||||
ADDRESS => FILTER_ADDRESS,
|
||||
NUM_BYTES => 8
|
||||
)
|
||||
port map (
|
||||
i_stream_clk => usr_clk,
|
||||
i_stream_data => dec_stream_data,
|
||||
i_stream_addr => dec_stream_addr,
|
||||
i_stream_valid => dec_stream_valid,
|
||||
o_data => filter_data,
|
||||
o_valid => filter_valid
|
||||
);
|
||||
-----------------------------------------------------------------------------
|
||||
-- MGT / User clock
|
||||
-----------------------------------------------------------------------------
|
||||
clock_generator(rxusrclk, C_RXUSRCLK_CYCLE);
|
||||
clock_generator(usr_clk, C_USRCLK_CYCLE);
|
||||
evr320_data_filter_inst: entity work.evr320_data_filter
|
||||
generic map (
|
||||
ADDRESS => FILTER_ADDRESS,
|
||||
NUM_BYTES => 8
|
||||
)
|
||||
port map (
|
||||
i_stream_clk => usr_clk,
|
||||
i_stream_data => dec_stream_data,
|
||||
i_stream_addr => dec_stream_addr,
|
||||
i_stream_valid => dec_stream_valid,
|
||||
o_data => filter_data,
|
||||
o_valid => filter_valid
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- MGT / User clock
|
||||
-----------------------------------------------------------------------------
|
||||
clock_generator(rxusrclk, C_RXUSRCLK_CYCLE);
|
||||
clock_generator(usr_clk, C_USRCLK_CYCLE);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Decoder reset due to MGT main status
|
||||
-----------------------------------------------------------------------------
|
||||
process
|
||||
begin
|
||||
rxlos <= '1';
|
||||
wait for 50 ns;
|
||||
wait until (falling_edge(rxusrclk));
|
||||
rxlos <= '0';
|
||||
wait ;
|
||||
end process;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Decoder reset due to MGT main status
|
||||
-----------------------------------------------------------------------------
|
||||
process
|
||||
begin
|
||||
rxlos <= '1';
|
||||
wait for 50 ns;
|
||||
wait until (falling_edge(rxusrclk));
|
||||
rxlos <= '0';
|
||||
wait ;
|
||||
end process;
|
||||
|
||||
---------------------------------------------------------
|
||||
-- Receive decoder data stream
|
||||
---------------------------------------------------------
|
||||
-----------------------------------------------------------------------------
|
||||
-- Read stimuli file
|
||||
-----------------------------------------------------------------------------
|
||||
file_blk : block
|
||||
file file_stimuli : text;
|
||||
type parse_fsm_state is (idle, seg_start, seg_addr, seg_Wait, seg_payload, seg_payload_wait, seg_done);
|
||||
begin
|
||||
process
|
||||
variable addr : std_logic_vector(10 downto 0);
|
||||
variable data : std_logic_vector(7 downto 0);
|
||||
variable i : integer := 0;
|
||||
variable file_line : line;
|
||||
variable data, event : std_logic_vector(7 downto 0);
|
||||
variable data_k, event_k : std_logic_vector(0 downto 0);
|
||||
variable space : character;
|
||||
variable i : integer;
|
||||
variable parse_fsm : parse_fsm_state := idle;
|
||||
variable payload_cnt : integer range 0 to 2047;
|
||||
variable event_cnt_total : integer := 0;
|
||||
variable event_cnt_0 : integer := 0;
|
||||
variable event_cnt_1 : integer := 0;
|
||||
variable event_cnt_2 : integer := 0;
|
||||
variable event_cnt_3 : integer := 0;
|
||||
begin
|
||||
wait until rising_edge(usr_clk);
|
||||
if (dec_stream_valid = '1') then
|
||||
addr := dec_stream_addr;
|
||||
data := dec_stream_data;
|
||||
i := to_integer(unsigned(addr)) - to_integer(unsigned(segment_addr))*16;
|
||||
-- save stream for later comparision:
|
||||
dec_stream_check(i).addr <= addr;
|
||||
dec_stream_check(i).data <= data;
|
||||
log(ID_SEGMENT_DATA, "Recv Decoder Stream: count=" & integer'image(i) & " addr=0x" & to_string(addr, HEX) & " data=0x" & to_string(data, HEX));
|
||||
i := i + 1;
|
||||
dec_stream_recv_bytes <= i;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------------------------------
|
||||
-- Wait for Event
|
||||
---------------------------------------------------------
|
||||
process
|
||||
begin
|
||||
wait until rising_edge(usr_clk);
|
||||
for i in 0 to 3 loop
|
||||
if (usr_events(i) = '1') then
|
||||
log(ID_CTRL, "Event Received: 0x" & to_string(evr_params.event_numbers(i), HEX) );
|
||||
received_events <= received_events + 1;
|
||||
end if;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
---------------------------------------------------------
|
||||
-- Fetch filter data
|
||||
---------------------------------------------------------
|
||||
process
|
||||
begin
|
||||
wait until rising_edge(usr_clk);
|
||||
if (filter_valid = '1') then
|
||||
filter_data_check <= filter_data;
|
||||
log(ID_SEGMENT_DATA, "Filter Valid: data=0x" & to_string(filter_data, HEX));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Read stimuli file
|
||||
-----------------------------------------------------------------------------
|
||||
file_blk : block
|
||||
file file_stimuli : text;
|
||||
type parse_fsm_state is (idle, seg_start, seg_addr, seg_Wait, seg_payload, seg_payload_wait, seg_done);
|
||||
begin
|
||||
process
|
||||
variable file_line : line;
|
||||
variable data, event : std_logic_vector(7 downto 0);
|
||||
variable data_k, event_k : std_logic_vector(0 downto 0);
|
||||
variable space : character;
|
||||
variable i : integer;
|
||||
variable parse_fsm : parse_fsm_state := idle;
|
||||
variable payload_cnt : integer range 0 to 2047;
|
||||
variable event_cnt : integer := 0;
|
||||
begin
|
||||
file_open(file_stimuli, "../tb/stimuli_mgt.dat", read_mode);
|
||||
readline(file_stimuli, file_line); -- comment
|
||||
readline(file_stimuli, file_line); -- comment
|
||||
i := 0;
|
||||
-- read line by line from .dat file:
|
||||
while not endfile(file_stimuli) loop
|
||||
readline(file_stimuli, file_line);
|
||||
hread(file_line, event);
|
||||
read(file_line, event_k);
|
||||
read(file_line, space);
|
||||
read(file_line, space);
|
||||
hread(file_line, data);
|
||||
read(file_line, space);
|
||||
read(file_line, data_k);
|
||||
-- write to array:
|
||||
mgt_stream(i).data <= data;
|
||||
mgt_stream(i).data_k <= data_k;
|
||||
mgt_stream(i).event <= event;
|
||||
mgt_stream(i).event_k <= event_k;
|
||||
mgt_stream_index <= i;
|
||||
--debug output:
|
||||
--log(ID_SEGMENT_DATA, "stimuli file: i=" & integer'image(i) & " event=0x" & to_string(event, HEX) & " k=" & to_string(event_k, HEX)
|
||||
-- & " data=0x" & to_string(data, HEX) & " k=" & to_string(data_k, HEX) & " ");
|
||||
-- Count Events:
|
||||
----------------
|
||||
if (event /= x"00" and event_k = "0") then
|
||||
event_cnt := event_cnt + 1;
|
||||
file_open(file_stimuli, "../tb/stimuli_mgt.dat", read_mode);
|
||||
readline(file_stimuli, file_line); -- comment
|
||||
readline(file_stimuli, file_line); -- comment
|
||||
i := 0;
|
||||
-- read line by line from .dat file:
|
||||
while not endfile(file_stimuli) loop
|
||||
readline(file_stimuli, file_line);
|
||||
hread(file_line, event);
|
||||
read(file_line, event_k);
|
||||
read(file_line, space);
|
||||
read(file_line, space);
|
||||
hread(file_line, data);
|
||||
read(file_line, space);
|
||||
read(file_line, data_k);
|
||||
-- write to array:
|
||||
mgt_stream(i).data <= data;
|
||||
mgt_stream(i).data_k <= data_k;
|
||||
mgt_stream(i).event <= event;
|
||||
mgt_stream(i).event_k <= event_k;
|
||||
mgt_stream_index <= i;
|
||||
--debug output:
|
||||
--log(ID_SEGMENT_DATA, "stimuli file: i=" & integer'image(i) & " event=0x" & to_string(event, HEX) & " k=" & to_string(event_k, HEX)
|
||||
-- & " data=0x" & to_string(data, HEX) & " k=" & to_string(data_k, HEX) & " ");
|
||||
-- Count Events:
|
||||
----------------
|
||||
if (event /= x"00" and event_k = "0") then
|
||||
event_cnt_total := event_cnt_total + 1;
|
||||
|
||||
if (event = std_logic_vector(to_unsigned(g_EVENT_NR_0, 8))) then
|
||||
event_cnt_0 := event_cnt_0 + 1;
|
||||
end if;
|
||||
expect_num_events <= event_cnt * STIMULI_RUNS;
|
||||
|
||||
if (event = std_logic_vector(to_unsigned(g_EVENT_NR_1, 8))) then
|
||||
event_cnt_1 := event_cnt_1 + 1;
|
||||
end if;
|
||||
|
||||
if (event = std_logic_vector(to_unsigned(g_EVENT_NR_2, 8))) then
|
||||
event_cnt_2 := event_cnt_2 + 1;
|
||||
end if;
|
||||
|
||||
if (event = std_logic_vector(to_unsigned(g_EVENT_NR_3, 8))) then
|
||||
event_cnt_3 := event_cnt_3 + 1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
expect_events_total <= event_cnt_total * STIMULI_RUNS;
|
||||
expect_events(0) <= event_cnt_0 * STIMULI_RUNS;
|
||||
expect_events(1) <= event_cnt_1 * STIMULI_RUNS;
|
||||
expect_events(2) <= event_cnt_2 * STIMULI_RUNS;
|
||||
expect_events(3) <= event_cnt_3 * STIMULI_RUNS;
|
||||
|
||||
-- Event Recorder:
|
||||
------------------
|
||||
if (event = std_logic_vector(to_unsigned(g_EVENT_NR_SOS, 8)) and event_k = "0") then
|
||||
log("Start-of-Sequence Event in Stimuli present");
|
||||
end if;
|
||||
|
||||
-- Parse only segment:
|
||||
----------------------
|
||||
case (parse_fsm) is
|
||||
when idle =>
|
||||
if (data = x"5C" and data_k = "1") then -- check if frame start
|
||||
parse_fsm := seg_start;
|
||||
end if;
|
||||
when seg_start =>
|
||||
parse_fsm := seg_addr;
|
||||
when seg_addr =>
|
||||
segment_addr <= data;
|
||||
parse_fsm := seg_wait;
|
||||
when seg_wait =>
|
||||
parse_fsm := seg_payload;
|
||||
payload_cnt := 0;
|
||||
when seg_payload =>
|
||||
if (data = x"3C" and data_k = "1") then -- check if frame end
|
||||
parse_fsm := seg_done;
|
||||
else
|
||||
segment_data(payload_cnt) <= data;
|
||||
parse_fsm := seg_payload_wait;
|
||||
segment_length <= payload_cnt+1;
|
||||
end if;
|
||||
when seg_payload_wait =>
|
||||
payload_cnt := payload_cnt + 1;
|
||||
parse_fsm := seg_payload;
|
||||
when seg_done =>
|
||||
-- done
|
||||
end case;
|
||||
i := i + 1;
|
||||
end loop;
|
||||
file_close(file_stimuli);
|
||||
wait;
|
||||
end process;
|
||||
end block;
|
||||
|
||||
---------------------------------------------------------
|
||||
-- Receive decoder data stream
|
||||
---------------------------------------------------------
|
||||
process
|
||||
variable addr : std_logic_vector(10 downto 0);
|
||||
variable data : std_logic_vector(7 downto 0);
|
||||
variable i : integer := 0;
|
||||
begin
|
||||
wait until rising_edge(usr_clk);
|
||||
if (dec_stream_valid = '1') then
|
||||
addr := dec_stream_addr;
|
||||
data := dec_stream_data;
|
||||
i := to_integer(unsigned(addr)) - to_integer(unsigned(segment_addr))*16;
|
||||
-- save stream for later comparision:
|
||||
dec_stream_check(i).addr <= addr;
|
||||
dec_stream_check(i).data <= data;
|
||||
log(ID_SEGMENT_DATA, "Recv Decoder Stream: count=" & integer'image(i) & " addr=0x" & to_string(addr, HEX) & " data=0x" & to_string(data, HEX));
|
||||
i := i + 1;
|
||||
dec_stream_recv_bytes <= i;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------------------------------
|
||||
-- Fetch filter data
|
||||
---------------------------------------------------------
|
||||
process
|
||||
begin
|
||||
wait until rising_edge(usr_clk);
|
||||
if (filter_valid = '1') then
|
||||
filter_data_check <= filter_data;
|
||||
log(ID_SEGMENT_DATA, "Filter Valid: data=" & to_string(filter_data, HEX, AS_IS, INCL_RADIX));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------------------------------
|
||||
-- Wait for User Events
|
||||
---------------------------------------------------------
|
||||
process
|
||||
begin
|
||||
wait until rising_edge(rxusrclk);
|
||||
for i in 0 to C_EVT_NR-1 loop
|
||||
if (usr_events(i) = '1') then
|
||||
log(ID_CTRL, "Event Received: " & to_string(evr_params.event_numbers(i), HEX, AS_IS, INCL_RADIX) );
|
||||
received_events(i) <= received_events(i) + 1;
|
||||
end if;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
---------------------------------------------------------
|
||||
-- Wait for Start of Sequence Event
|
||||
---------------------------------------------------------
|
||||
process
|
||||
begin
|
||||
wait until rising_edge(rxusrclk);
|
||||
if (sos_event = '1') then
|
||||
log(ID_CTRL, "Start of Sequence Event Received: "& to_string(std_logic_vector(to_unsigned(g_EVENT_NR_SOS, 8)), HEX, AS_IS, INCL_RADIX) ); -- change to await_value
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Parse only segment:
|
||||
----------------------
|
||||
case (parse_fsm) is
|
||||
when idle =>
|
||||
if (data = x"5C" and data_k = "1") then -- check if frame start
|
||||
parse_fsm := seg_start;
|
||||
end if;
|
||||
when seg_start =>
|
||||
parse_fsm := seg_addr;
|
||||
when seg_addr =>
|
||||
segment_addr <= data;
|
||||
parse_fsm := seg_wait;
|
||||
when seg_wait =>
|
||||
parse_fsm := seg_payload;
|
||||
payload_cnt := 0;
|
||||
when seg_payload =>
|
||||
if (data = x"3C" and data_k = "1") then -- check if frame end
|
||||
parse_fsm := seg_done;
|
||||
else
|
||||
segment_data(payload_cnt) <= data;
|
||||
parse_fsm := seg_payload_wait;
|
||||
segment_length <= payload_cnt+1;
|
||||
end if;
|
||||
when seg_payload_wait =>
|
||||
payload_cnt := payload_cnt + 1;
|
||||
parse_fsm := seg_payload;
|
||||
when seg_done =>
|
||||
-- done
|
||||
end case;
|
||||
i := i + 1;
|
||||
end loop;
|
||||
file_close(file_stimuli);
|
||||
wait;
|
||||
end process;
|
||||
end block;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Stimulus CPU interface
|
||||
-----------------------------------------------------------------------------
|
||||
process
|
||||
constant C_SCOPE : string := C_TB_SCOPE_DEFAULT;
|
||||
constant c_TB_NAME : string := "evr320_decoder_tb";
|
||||
variable mgt_stream_rep_var : integer := 0;
|
||||
variable mgt_stream_index_var : integer := 0;
|
||||
variable i : integer := 0;
|
||||
type state is (idle, payload, frame_end, segment_nr);
|
||||
variable mem_base : integer range 0 to 127;
|
||||
variable segment_data_word : std_logic_vector(31 downto 0);
|
||||
variable var_filter_offset : integer range 0 to 2047;
|
||||
variable var_filter_word : std_logic_vector(FILTER_NUM_BYTES*8-1 downto 0);
|
||||
begin
|
||||
-----------------------------------------------------------------------------
|
||||
-- Stimulus CPU interface
|
||||
-----------------------------------------------------------------------------
|
||||
process
|
||||
constant C_SCOPE : string := C_TB_SCOPE_DEFAULT;
|
||||
constant c_TB_NAME : string := "evr320_decoder_tb";
|
||||
variable mgt_stream_rep_var : integer := 0;
|
||||
variable mgt_stream_index_var : integer := 0;
|
||||
variable i : integer := 0;
|
||||
type state is (idle, payload, frame_end, segment_nr);
|
||||
variable mem_base : integer range 0 to 127;
|
||||
variable segment_data_word : std_logic_vector(31 downto 0);
|
||||
variable var_filter_offset : integer range 0 to 2047;
|
||||
variable var_filter_word : std_logic_vector(FILTER_NUM_BYTES*8-1 downto 0);
|
||||
begin
|
||||
-- init uvvm:
|
||||
set_log_file_name(c_TB_NAME & "_LOG.txt");
|
||||
set_alert_file_name(c_TB_NAME & "_ALERT.txt");
|
||||
@ -331,17 +396,17 @@ begin
|
||||
--------------------------------------------------------------------------
|
||||
-- Get out of reset, enable events
|
||||
--------------------------------------------------------------------------
|
||||
evr_params.event_enable( 0) <= '1';
|
||||
evr_params.event_enable( 1) <= '0';
|
||||
evr_params.event_enable( 2) <= '0';
|
||||
evr_params.event_enable( 3) <= '0';
|
||||
evr_params.event_numbers( 0)<= X"0F";
|
||||
evr_params.event_numbers( 1)<= X"00";
|
||||
evr_params.event_numbers( 2)<= X"00";
|
||||
evr_params.event_numbers( 3)<= X"00";
|
||||
evr_params.cs_min_cnt <= X"00000000";
|
||||
evr_params.cs_min_time <= X"00000000";
|
||||
mem_addr <= x"000";
|
||||
evr_params.event_enable( 0) <= '0' when g_EVENT_NR_0 = 0 else '1';
|
||||
evr_params.event_enable( 1) <= '0' when g_EVENT_NR_1 = 0 else '1';
|
||||
evr_params.event_enable( 2) <= '0' when g_EVENT_NR_2 = 0 else '1';
|
||||
evr_params.event_enable( 3) <= '0' when g_EVENT_NR_3 = 0 else '1';
|
||||
evr_params.event_numbers( 0) <= std_logic_vector(to_unsigned(g_EVENT_NR_0, 8));
|
||||
evr_params.event_numbers( 1) <= std_logic_vector(to_unsigned(g_EVENT_NR_1, 8));
|
||||
evr_params.event_numbers( 2) <= std_logic_vector(to_unsigned(g_EVENT_NR_2, 8));
|
||||
evr_params.event_numbers( 3) <= std_logic_vector(to_unsigned(g_EVENT_NR_3, 8));
|
||||
evr_params.cs_min_cnt <= X"00000000";
|
||||
evr_params.cs_min_time <= X"00000000";
|
||||
mem_addr <= x"000";
|
||||
await_value(rxlos, '0', 0 ns, 10 us, FAILURE, "wait for release RX LOS");
|
||||
--wait until (rxlos = '0');
|
||||
|
||||
@ -383,8 +448,11 @@ begin
|
||||
--------------------------------------------------------------------------
|
||||
-- Check if correct number of events has been detected
|
||||
--------------------------------------------------------------------------
|
||||
check_value(received_events, expect_num_events, ERROR, "Check correct number of received events");
|
||||
|
||||
for i in 0 to C_EVT_NR-1 loop
|
||||
check_value(received_events(i), expect_events(i), ERROR, "Event " & to_string(i) & ": received = " & to_string(received_events(i)) & ", expected = " & to_string(expect_events(i)));
|
||||
end loop;
|
||||
-- check_value(to_integer(unsigned(event_recorder_status.usr_events_counter)), expect_events_total, ERROR, "Total Events: received = " & to_string(event_recorder_status.usr_events_counter) & ", expected = " & to_string(expect_events_total));
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Read DPRAM buffer
|
||||
--------------------------------------------------------------------------
|
||||
@ -408,16 +476,17 @@ begin
|
||||
--------------------------------------------------------------------------
|
||||
-- Test Done
|
||||
--------------------------------------------------------------------------
|
||||
wait for 1000 ns; -- to allow some time for completion
|
||||
report_alert_counters(FINAL); -- Report final counters and print conclusion for simulation (Success/Fail)
|
||||
-- ------------------------------------------------------------------------
|
||||
log(ID_LOG_HDR, "SIMULATION COMPLETED", C_SCOPE);
|
||||
report_alert_counters(VOID);
|
||||
-- ------------------------------------------------------------------------
|
||||
-- assert error if UVVM mismatch flag is 1 => upstream info for scripts/jenkins
|
||||
assert shared_uvvm_status.mismatch_on_expected_simulation_errors_or_worse = 0 report "###ERROR### - UVVM Mismatch Errors with Expected Errors -> Check Log for details" severity ERROR;
|
||||
std.env.stop(0);
|
||||
wait; -- stop simulation
|
||||
|
||||
assert shared_uvvm_status.found_unexpected_simulation_warnings_or_worse = 0
|
||||
report "UVVM Found unexpected warnings or worse" severity ERROR;
|
||||
|
||||
stop(0);
|
||||
-- finish(0); -- wants to close modelsim!?
|
||||
wait;
|
||||
end process;
|
||||
end process;
|
||||
|
||||
end architecture testbench;
|
||||
|
||||
|
@ -129,3 +129,31 @@ BC 1 00 0 align
|
||||
00 0 00 0 gap
|
||||
0F 0 00 0 BPM event
|
||||
00 0 00 0 gap
|
||||
BC 1 00 0 align
|
||||
01 0 00 0 event 1
|
||||
02 0 00 0 event 2
|
||||
03 0 00 0 event 3
|
||||
BC 1 00 0 align
|
||||
04 0 00 0 event 4
|
||||
05 0 00 0 event 5
|
||||
06 0 00 0 event 6
|
||||
BC 1 00 0 align
|
||||
07 0 00 0 event 7
|
||||
04 0 00 0 event 4
|
||||
08 0 00 0 event 8
|
||||
BC 1 00 0 align
|
||||
00 0 00 0 gap
|
||||
0F 0 00 0 gap
|
||||
00 0 00 0 gap
|
||||
BC 1 00 0 align
|
||||
00 0 00 0 gap
|
||||
00 0 00 0 gap
|
||||
00 0 00 0 gap
|
||||
BC 1 00 0 align
|
||||
00 0 00 0 gap
|
||||
00 0 00 0 gap
|
||||
00 0 00 0 gap
|
||||
BC 1 00 0 align
|
||||
00 0 00 0 gap
|
||||
00 0 00 0 gap
|
||||
00 0 00 0 gap
|
Reference in New Issue
Block a user