Skip to content
Snippets Groups Projects
Commit fe531fa0 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Updated mms_diag_tx/rx_seq.vhd with replicate/unreplicate seq in data....

Updated mms_diag_tx/rx_seq.vhd with replicate/unreplicate seq in data. Verified OK with tb_mms_diag_seq.
parent a2a3001b
No related branches found
No related tags found
No related merge requests found
-------------------------------------------------------------------------------
--
-- Copyright (C) 2010
-- Copyright (C) 2015
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
......@@ -20,107 +20,217 @@
--
-------------------------------------------------------------------------------
-- Purpose: Provide MM access via slave register to diag_rx_seq
-- Description:
--
-- Each DP stream has its own diag_rx_seq and its own MM control register.
-- The MM control registers are accessible via a single MM port thanks to
-- the common_mem_mux. Each single MM control register is defined as:
--
-- 31 24 23 16 15 8 7 0 wi
-- |-----------------|-----------------|-----------------|-----------------|
-- | select = [1], enable = [0] | 0
-- |-----------------------------------------------------------------------|
-- | res_val_n = [1], res_ok_n = [0] | 1
-- |-----------------------------------------------------------------------|
--
-- . Results
-- When res_val_n = '1' then no valid data is being received. When
-- res_val_n = '0' then at least two valid data have been received so the
-- diag_rx_seq can detect whether the subsequent data is ok. When res_ok_n
-- = '0' then indeed all data that has been received so far is correct.
-- When res_ok_n = '0' then at least 1 data word was received with errors.
-- Once res_ok_n goes high it remains high.
--
-- . g_data_w and g_seq_dat_w
-- The DP streaming data field is c_dp_stream_data_w bits wide but only
-- g_data_w bits are used. The g_seq_dat_w must be >= 1 and <= g_data_w.
-- If g_seq_dat_w < g_data_w then the data carries replicated copies of
-- the g_seq_dat_w. The maximum g_seq_dat_w depends on the pseudo random
-- data width of the LFSR sequeces in common_lfsr_sequences_pkg and on
-- whether timing closure can still be achieved for wider g_seq_dat_w.
-- Thanks to the replication a smaller g_seq_dat_w can be used to provide
-- CNTR or LFSR data for the DP data. If the higher bits do notmatch the
-- sequence in the lower bits, then the rx data is forced to -1, and that
-- will then be detected and reported by u_diag_rx_seq as a sequence error.
LIBRARY IEEE, common_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
ENTITY mms_diag_rx_seq IS
GENERIC (
g_nof_diag_inst : NATURAL := 1;
g_dat_w : NATURAL := c_word_w; -- >= 1, test data width
g_sim : BOOLEAN := FALSE
g_nof_streams : NATURAL := 1;
g_seq_dat_w : NATURAL := c_word_w; -- >= 1, test sequence data width
g_data_w : NATURAL := c_word_w -- >= g_seq_dat_w, user data width
);
PORT (
-- Clocks and reset
mm_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
st_clk : IN STD_LOGIC;
mm_rst : IN STD_LOGIC; -- reset synchronous with mm_clk
mm_clk : IN STD_LOGIC; -- MM bus clock
dp_rst : IN STD_LOGIC; -- reset synchronous with dp_clk
dp_clk : IN STD_LOGIC; -- DP streaming bus clock
-- Memory Mapped Slave
mm_sla_in : IN t_mem_mosi; -- master out slave in
mm_sla_out : OUT t_mem_miso; -- master in slave out
reg_mosi : IN t_mem_mosi; -- multiplexed port for g_nof_streams MM control/status registers
reg_miso : OUT t_mem_miso;
-- Streaming interface
rx_snk_in : IN t_dp_sosi_arr(g_nof_diag_inst-1 DOWNTO 0) -- source out sink in
rx_snk_in_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0)
);
END mms_diag_rx_seq;
ARCHITECTURE str OF mms_diag_rx_seq IS
CONSTANT c_latency : NATURAL := 1; -- read latency
CONSTANT c_init_sl : STD_LOGIC := '0'; -- optional, init all dat words to std_logic '0', '1' or 'X'
CONSTANT c_init_reg : STD_LOGIC_VECTOR(c_mem_reg_init_w-1 DOWNTO 0) := (OTHERS => '0');
CONSTANT c_nof_mm_regs : NATURAL := 4+g_nof_diag_inst;
CONSTANT c_mm_addr_w : NATURAL := ceil_log2(c_nof_mm_regs);
-- Define the actual size of the MM slave register
CONSTANT c_mm_reg : t_c_mem := (latency => 1,
adr_w => 1,
dat_w => c_word_w, -- Use MM bus data width = c_word_w = 32 for all MM registers
nof_dat => 2,
init_sl => '0');
CONSTANT c_reg_slv_w : NATURAL := c_mm_reg.nof_dat*c_mm_reg.dat_w;
TYPE t_reg_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_reg_slv_w-1 DOWNTO 0);
TYPE t_seq_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_seq_dat_w-1 DOWNTO 0);
TYPE t_data_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0);
-- Registers in dp_clk domain
SIGNAL ctrl_reg_arr : t_reg_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0'));
SIGNAL stat_reg_arr : t_reg_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0'));
SIGNAL diag_en_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL diag_sel_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL rx_seq_arr : t_seq_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL rx_seq_val_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL rx_data_arr : t_data_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL rx_data_val_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL diag_res_arr : t_seq_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL diag_res_val_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL stat_res_ok_n_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL stat_res_val_n_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL reg_mosi_arr : t_mem_mosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL reg_miso_arr : t_mem_miso_arr(g_nof_streams-1 DOWNTO 0);
BEGIN
ASSERT g_data_w >= g_seq_dat_w REPORT "mms_diag_rx_seq: g_data_w < g_seq_dat_w is not allowed." SEVERITY FAILURE;
CONSTANT c_mem_rec : t_c_mem := (c_latency, c_mm_addr_w, c_word_w, c_nof_mm_regs, c_init_sl);
gen_nof_streams: FOR I IN 0 to g_nof_streams-1 GENERATE
-- no unreplicate needed
gen_one : IF g_data_w = g_seq_dat_w GENERATE
rx_seq_arr(I) <= rx_snk_in_arr(i).data(g_seq_dat_w-1 DOWNTO 0);
rx_seq_val_arr(I) <= rx_snk_in_arr(i).valid;
END GENERATE;
SIGNAL out_reg : STD_LOGIC_VECTOR(c_nof_mm_regs*c_word_w-1 DOWNTO 0);
SIGNAL in_reg : STD_LOGIC_VECTOR(c_nof_mm_regs*c_word_w-1 DOWNTO 0);
-- unreplicate needed
gen_unreplicate : IF g_data_w > g_seq_dat_w GENERATE
-- keep sequence in low bits and set high bits to '1' if they mismatch the corresponding bit in the sequence
rx_data_arr(I) <= UNREPLICATE_DP_DATA(rx_snk_in_arr(i).data(g_data_w-1 DOWNTO 0), g_seq_dat_w);
rx_data_val_arr(I) <= rx_snk_in_arr(i).valid;
-- keep sequence in low bits if the high bits match otherwise force low bits value to -1 to indicate the mismatch
p_rx_seq : PROCESS(dp_clk)
BEGIN
IF rising_edge(dp_clk) THEN -- register to ease timing closure
IF UNSIGNED(rx_data_arr(I)(g_data_w-1 DOWNTO g_seq_dat_w))=0 THEN
rx_seq_arr(I) <= rx_data_arr(I)(g_seq_dat_w-1 DOWNTO 0);
ELSE
rx_seq_arr(I) <= TO_SVEC(-1, g_seq_dat_w);
END IF;
rx_seq_val_arr(I) <= rx_data_val_arr(I);
END IF;
END PROCESS;
END GENERATE;
gen_g_nof_diag_inst_times: FOR i IN 0 to g_nof_diag_inst-1 GENERATE
-- detect rx sequence errors
u_diag_rx_seq: ENTITY WORK.diag_rx_seq
GENERIC MAP (
g_dat_w => g_dat_w,
g_diag_res_w => c_word_w+1
g_dat_w => g_seq_dat_w,
g_diag_res_w => g_seq_dat_w -- do not use g_seq_dat_w+1 to include NOT diag_res_val in MSbit, instead use diag_res_val output
)
PORT MAP (
rst => mm_rst,
clk => st_clk,
rst => dp_rst,
clk => dp_clk,
-- Write and read back registers:
diag_en => out_reg( i), -- 0 to 31 (for 12 instances: 11 downto 0 used)
diag_sel => out_reg( c_word_w+i), -- 32 to 63 (for 12 instances: 43 downto 32 used)
diag_en => diag_en_arr(I),
diag_sel => diag_sel_arr(I),
-- Read only registers:
orv(diag_res) => in_reg(2*c_word_w+i), -- 64 to 95 (for 12 instances: 75 downto 64 used)
diag_res_val => in_reg(3*c_word_w+i), -- 96 to 127 (for 12 instances: 107 downto 96 used)
diag_res => diag_res_arr(I),
diag_res_val => diag_res_val_arr(I),
-- Streaming
in_dat => rx_snk_in(i).data(c_word_w-1 DOWNTO 0),
in_val => rx_snk_in(i).valid
in_dat => rx_seq_arr(I),
in_val => rx_seq_val_arr(I)
);
-- Read-only registers for received data, starting from offset 4:
in_reg ( (4+i)*c_word_w+c_word_w-1 DOWNTO (4+i)*c_word_w) <= rx_snk_in(i).data(c_word_w-1 DOWNTO 0);
-- Map diag_res to single bit and register it to ease timing closure
stat_res_ok_n_arr(I) <= orv(diag_res_arr(I)) WHEN rising_edge(dp_clk);
stat_res_val_n_arr(I) <= NOT diag_res_val_arr(I) WHEN rising_edge(dp_clk);
-- Register mapping
-- . write ctrl_reg_arr
diag_en_arr(I) <= ctrl_reg_arr(I)(0); -- address 0, data bit [0]
diag_sel_arr(I) <= ctrl_reg_arr(I)(1); -- address 0, data bit [1]
-- address 1, not used for control
-- . read stat_reg_arr
p_stat_reg_arr : PROCESS(ctrl_reg_arr, stat_res_ok_n_arr, stat_res_val_n_arr)
BEGIN
-- Default write / readback:
stat_reg_arr(I) <= ctrl_reg_arr(I); -- address 0, control read back
-- Status read only:
stat_reg_arr(I)(0+c_word_w) <= stat_res_ok_n_arr(I); -- address 1, data bit [0]
stat_reg_arr(I)(1+c_word_w) <= stat_res_val_n_arr(I); -- address 1, data bit [1]
END PROCESS;
u_reg : ENTITY common_lib.common_reg_r_w_dc
GENERIC MAP (
g_cross_clock_domain => TRUE,
g_readback => FALSE, -- using FALSE fits for write/read or read only register
g_reg => c_mm_reg
)
PORT MAP (
-- Clocks and reset
mm_rst => mm_rst,
mm_clk => mm_clk,
st_rst => dp_rst,
st_clk => dp_clk,
-- Memory Mapped Slave in mm_clk domain
sla_in => reg_mosi_arr(I),
sla_out => reg_miso_arr(I),
-- MM registers in dp_clk domain
in_reg => stat_reg_arr(I),
out_reg => ctrl_reg_arr(I)
);
END GENERATE;
u_common_reg_r_w : ENTITY common_lib.common_reg_r_w
-- Combine the internal array of mm interfaces for the bg_data to one array that is connected to the port of the MM bus
u_mem_mux : ENTITY common_lib.common_mem_mux
GENERIC MAP (
g_reg => c_mem_rec,
g_init_reg => c_init_reg
g_nof_mosi => g_nof_streams,
g_mult_addr_w => c_mm_reg.adr_w
)
PORT MAP (
rst => mm_rst,
clk => mm_clk,
clken => '1',
-- control side
wr_en => mm_sla_in.wr,
wr_adr => mm_sla_in.address(c_mem_rec.adr_w-1 DOWNTO 0),
wr_dat => mm_sla_in.wrdata(c_mem_rec.dat_w-1 DOWNTO 0),
rd_en => mm_sla_in.rd,
rd_adr => mm_sla_in.address(c_mem_rec.adr_w-1 DOWNTO 0),
rd_dat => mm_sla_out.rddata(c_mem_rec.dat_w-1 DOWNTO 0),
rd_val => OPEN,
-- data side
out_reg => out_reg,
in_reg => in_reg
mosi => reg_mosi,
miso => reg_miso,
mosi_arr => reg_mosi_arr,
miso_arr => reg_miso_arr
);
--Connect out_reg to in_reg for write and readback register:
in_reg(63 downto 0) <= out_reg(63 downto 0);
--Connect unused bits to hard zeroes, otherwise SOPC-builder generated cpu0-test benches will halt
in_reg(3*c_word_w-1 DOWNTO 2*c_word_w + g_nof_diag_inst) <= (OTHERS => '0'); --Unused bits in register diag_res
in_reg(4*c_word_w-1 DOWNTO 3*c_word_w + g_nof_diag_inst) <= (OTHERS => '0'); --Unused bits in register diag_res_val
END str;
......
-------------------------------------------------------------------------------
--
-- Copyright (C) 2010
-- Copyright (C) 2015
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
......@@ -20,6 +20,35 @@
--
-------------------------------------------------------------------------------
-- Purpose: Provide MM access via slave register to diag_tx_seq
-- Description:
--
-- Each DP stream has its own diag_tx_seq, because each stream can have its
-- own flow control.
--
-- One MM control register sets all g_nof_streams:
--
-- 31 24 23 16 15 8 7 0 wi
-- |-----------------|-----------------|-----------------|-----------------|
-- | select = [1], enable = [0] | 0
-- |-----------------------------------------------------------------------|
-- | init[31: 0] | 1
-- |-----------------------------------------------------------------------|
--
-- . g_seq_dat_w
-- The g_seq_dat_w must be >= 1. The DP streaming data field is
-- c_dp_stream_data_w bits wide and the REPLICATE_DP_DATA() is used to wire
-- the g_seq_dat_w from the u_diag_tx_seq to fill the entire DP data width.
-- The maximum g_seq_dat_w depends on the pseudo random data width of the
-- LFSR sequeces in common_lfsr_sequences_pkg and on whether timing closure
-- can still be achieved for wider g_seq_dat_w. Thanks to the replication a
-- smaller g_seq_dat_w can be used to provide CNTR or LFSR data for the DP
-- data.
--
-- . diag_init
-- Note that MM diag_init has c_word_w=32 bits, so if g_seq_dat_w is wider
-- then the MSbits are 0 and if it is smaller, then the MSbits are ignored.
LIBRARY IEEE, common_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL;
......@@ -28,92 +57,114 @@ USE dp_lib.dp_stream_pkg.ALL;
ENTITY mms_diag_tx_seq IS
GENERIC (
g_nof_diag_inst : NATURAL := 1;
g_dat_w : NATURAL := c_word_w; -- >= 1, test data width
g_sim : BOOLEAN := FALSE
g_nof_streams : NATURAL := 1;
g_seq_dat_w : NATURAL := c_word_w -- >= 1, test sequence data width
);
PORT (
-- Clocks and reset
mm_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
st_clk : IN STD_LOGIC;
-- Memory Mapped Slave
mm_sla_in : IN t_mem_mosi; -- master out slave in
mm_sla_out : OUT t_mem_miso; -- master in slave out
-- Streaming interface
tx_src_out : OUT t_dp_sosi_arr(g_nof_diag_inst-1 DOWNTO 0); -- source out sink in
tx_src_in : IN t_dp_siso_arr(g_nof_diag_inst-1 DOWNTO 0) -- source in sink out
mm_rst : IN STD_LOGIC; -- reset synchronous with mm_clk
mm_clk : IN STD_LOGIC; -- MM bus clock
dp_rst : IN STD_LOGIC; -- reset synchronous with dp_clk
dp_clk : IN STD_LOGIC; -- DP streaming bus clock
-- MM interface
reg_mosi : IN t_mem_mosi; -- single MM control register applied to all g_nof_streams
reg_miso : OUT t_mem_miso;
-- DP streaming interface
tx_src_out_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
tx_src_in_arr : IN t_dp_siso_arr(g_nof_streams-1 DOWNTO 0)
);
END mms_diag_tx_seq;
ARCHITECTURE str OF mms_diag_tx_seq IS
CONSTANT c_latency : NATURAL := 1; -- read latency
CONSTANT c_init_sl : STD_LOGIC := '0'; -- optional, init all dat words to std_logic '0', '1' or 'X'
CONSTANT c_init_reg : STD_LOGIC_VECTOR(c_mem_reg_init_w-1 DOWNTO 0) := (OTHERS => '0');
CONSTANT c_nof_mm_regs : NATURAL := 2+g_nof_diag_inst;
CONSTANT c_mm_addr_w : NATURAL := ceil_log2(c_nof_mm_regs);
-- Define the actual size of the MM slave register
CONSTANT c_mm_reg : t_c_mem := (latency => 1,
adr_w => 1,
dat_w => c_word_w, -- Use MM bus data width = c_word_w = 32 for all MM registers
nof_dat => 2,
init_sl => '0');
TYPE t_dat_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_seq_dat_w-1 DOWNTO 0);
TYPE t_replicate_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_dp_stream_data_w-1 DOWNTO 0);
-- Registers in dp_clk domain
SIGNAL ctrl_reg : STD_LOGIC_VECTOR(c_mm_reg.nof_dat*c_mm_reg.dat_w-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL diag_en : STD_LOGIC;
SIGNAL diag_sel : STD_LOGIC;
SIGNAL diag_init_mm : STD_LOGIC_VECTOR(c_mm_reg.dat_w-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL diag_init : STD_LOGIC_VECTOR(g_seq_dat_w-1 DOWNTO 0) := (OTHERS=>'0');
CONSTANT c_mem_rec : t_c_mem := (c_latency, c_mm_addr_w, c_word_w, c_nof_mm_regs, c_init_sl);
SIGNAL tx_dat_arr : t_dat_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL tx_val_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL tx_req_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL out_reg : STD_LOGIC_VECTOR(c_nof_mm_regs*c_word_w-1 DOWNTO 0);
SIGNAL in_reg : STD_LOGIC_VECTOR(c_nof_mm_regs*c_word_w-1 DOWNTO 0);
SIGNAL tx_replicate_arr : t_replicate_arr(g_nof_streams-1 DOWNTO 0);
BEGIN
gen_g_nof_diag_inst_times: FOR i IN 0 to g_nof_diag_inst-1 GENERATE
gen_nof_streams: FOR I IN 0 to g_nof_streams-1 GENERATE
u_diag_tx_seq: ENTITY WORK.diag_tx_seq
GENERIC MAP (
g_dat_w => g_dat_w
g_dat_w => g_seq_dat_w
)
PORT MAP (
rst => mm_rst,
clk => st_clk,
rst => dp_rst,
clk => dp_clk,
-- Write and read back registers:
diag_en => out_reg( i), -- 0 to 31
diag_sel => out_reg( c_word_w+i), -- 32 to 63
diag_dat => out_reg(3*c_word_w+i*c_word_w-1 DOWNTO 2*c_word_w+i*c_word_w), -- downto 64
diag_en => diag_en,
diag_sel => diag_sel,
diag_dat => diag_init,
-- Streaming
diag_req => tx_src_in(i).ready,
out_dat => tx_src_out(i).data(c_word_w-1 DOWNTO 0),
out_val => tx_src_out(i).valid
diag_req => tx_req_arr(I),
out_dat => tx_dat_arr(I),
out_val => tx_val_arr(I)
);
tx_req_arr(I) <= tx_src_in_arr(I).ready;
tx_replicate_arr(I) <= REPLICATE_DP_DATA(tx_dat_arr(I));
-- for some reason the intermediate tx_replicate_arr() signal is needed, otherwise the assignment to the tx_src_out_arr().data field remains void in the Wave window
tx_src_out_arr(I).data <= tx_replicate_arr(I);
tx_src_out_arr(I).valid <= tx_val_arr(I);
END GENERATE;
u_common_reg_r_w : ENTITY common_lib.common_reg_r_w
-- Register mapping
diag_en <= ctrl_reg( 0); -- address 0, data bit [0]
diag_sel <= ctrl_reg( 1); -- address 0, data bit [1]
diag_init_mm <= ctrl_reg(2*c_word_w-1 DOWNTO c_word_w); -- address 1, data bits [31:0]
diag_init <= RESIZE_UVEC(diag_init_mm, g_seq_dat_w);
u_reg : ENTITY common_lib.common_reg_r_w_dc
GENERIC MAP (
g_reg => c_mem_rec,
g_init_reg => c_init_reg
g_cross_clock_domain => TRUE,
g_readback => TRUE, -- using TRUE fits for write and readback register
g_reg => c_mm_reg
)
PORT MAP (
rst => mm_rst,
clk => mm_clk,
clken => '1',
-- control side
wr_en => mm_sla_in.wr,
wr_adr => mm_sla_in.address(c_mem_rec.adr_w-1 DOWNTO 0),
wr_dat => mm_sla_in.wrdata(c_mem_rec.dat_w-1 DOWNTO 0),
rd_en => mm_sla_in.rd,
rd_adr => mm_sla_in.address(c_mem_rec.adr_w-1 DOWNTO 0),
rd_dat => mm_sla_out.rddata(c_mem_rec.dat_w-1 DOWNTO 0),
rd_val => OPEN,
-- data side
out_reg => out_reg,
in_reg => in_reg
-- Clocks and reset
mm_rst => mm_rst,
mm_clk => mm_clk,
st_rst => dp_rst,
st_clk => dp_clk,
-- Memory Mapped Slave in mm_clk domain
sla_in => reg_mosi,
sla_out => reg_miso,
-- MM registers in dp_clk domain
in_reg => ctrl_reg, -- connect out_reg to in_reg for write and readback register
out_reg => ctrl_reg
);
--Connect out_reg to in_reg for write and readback register:
in_reg(63 downto 0) <= out_reg(63 downto 0);
--Connect unused bits to hard zeroes, otherwise SOPC-builder generated cpu0-test benches will halt
in_reg((2+g_nof_diag_inst)*c_word_w-1 DOWNTO 2*c_word_w) <= (OTHERS => '0'); --diag_dat
END str;
......
......@@ -41,5 +41,6 @@ BEGIN
u_tb_diag_block_gen : ENTITY work.tb_diag_block_gen;
u_tb_mms_diag_block_gen : ENTITY work.tb_mms_diag_block_gen;
u_tb_mms_diag_seq : ENTITY work.tb_mms_diag_seq;
END tb;
--------------------------------------------------------------------------------
--
-- Copyright (C) 2010
-- Copyright (C) 2015
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
......@@ -20,147 +20,394 @@
--
--------------------------------------------------------------------------------
-- Purpose: Test bench for mms_diag_tx_seq --> mms_diag_rx_seq
-- The tb is self-stopping and self-checking.
-- Usage:
-- > as 5
-- > run -all
LIBRARY IEEE, common_lib, dp_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.numeric_std.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_lfsr_sequences_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.tb_common_mem_pkg.ALL;
USE common_lib.tb_common_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE dp_lib.tb_dp_pkg.ALL;
ENTITY tb_mms_diag_seq IS
GENERIC (
-- general
g_flow_control_verify : t_dp_flow_control_enum := e_active; -- always active, random or pulse flow control
-- specific
g_data_w : NATURAL := 40; -- >= g_seq_dat_w
g_seq_dat_w : NATURAL := 32
);
END ENTITY tb_mms_diag_seq;
ARCHITECTURE str of tb_mms_diag_seq IS
CONSTANT c_nof_diag_inst : NATURAL := 1; -- Enter number of diag instances here. Max = 32.
CONSTANT c_sim : BOOLEAN := TRUE;
CONSTANT c_nof_streams : NATURAL := 1;
CONSTANT mm_clk_period : TIME := 8 ns; -- 125 MHz
CONSTANT st_clk_period : TIME := 5 ns; -- 200 MHz
CONSTANT c_all_bits_high : INTEGER := -1;
CONSTANT c_all_bits_low : INTEGER := 0;
CONSTANT c_offset_rx_en : NATURAL := 0; --offsets relative to MM base address
CONSTANT c_offset_rx_mode : NATURAL := 1;
CONSTANT c_offset_diag_res : NATURAL := 2;
CONSTANT c_offset_diag_res_val : NATURAL := 3;
CONSTANT c_offset_tx_en : NATURAL := 0;
CONSTANT c_offset_tx_mode : NATURAL := 1;
CONSTANT c_offset_tx_dat : NATURAL := 2;
CONSTANT dp_clk_period : TIME := 5 ns; -- 200 MHz
PROCEDURE proc_readback(SIGNAL clk : IN STD_LOGIC;
SIGNAL tx_miso : IN t_mem_miso;
SIGNAL tx_mosi : OUT t_mem_mosi;
SIGNAL rx_miso : IN t_mem_miso;
SIGNAL rx_mosi : OUT t_mem_mosi;
SIGNAL tx_init : OUT STD_LOGIC_VECTOR;
SIGNAL tx_ctrl : OUT STD_LOGIC_VECTOR;
SIGNAL rx_ctrl : OUT STD_LOGIC_VECTOR) IS
BEGIN
-- read back Tx data init
proc_mem_mm_bus_rd(1, clk, tx_miso, tx_mosi);
proc_mem_mm_bus_rd_latency(1, clk);
tx_init <= tx_miso.rddata(c_word_w-1 DOWNTO 0);
-- read back Tx control
proc_mem_mm_bus_rd(0, clk, tx_miso, tx_mosi);
proc_mem_mm_bus_rd_latency(1, clk);
tx_ctrl <= tx_miso.rddata(c_word_w-1 DOWNTO 0);
-- read back Rx control
proc_mem_mm_bus_rd(0, clk, rx_miso, rx_mosi);
proc_mem_mm_bus_rd_latency(1, clk);
rx_ctrl <= rx_miso.rddata(c_word_w-1 DOWNTO 0);
END proc_readback;
PROCEDURE proc_enable_tx(CONSTANT c_pattern : IN STRING; -- "PSRG", "CNTR"
CONSTANT c_tx_init : IN NATURAL;
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL dp_clk : IN STD_LOGIC;
SIGNAL tx_miso : IN t_mem_miso; -- tx ctrl
SIGNAL tx_mosi : OUT t_mem_mosi;
SIGNAL rx_miso : IN t_mem_miso; -- rx ctrl
SIGNAL rx_mosi : OUT t_mem_mosi;
SIGNAL tx_init : OUT STD_LOGIC_VECTOR; -- readback
SIGNAL tx_ctrl : OUT STD_LOGIC_VECTOR;
SIGNAL rx_ctrl : OUT STD_LOGIC_VECTOR) IS
CONSTANT c_en : NATURAL := 1;
VARIABLE v_sel : NATURAL;
VARIABLE v_ctlr : NATURAL;
BEGIN
IF c_pattern="PSRG" THEN
v_sel := 0; -- pseudo random data
ELSE
v_sel := 1; -- counter data
END IF;
v_ctlr := v_sel * 2 + c_en; -- bits [1:0]
-- Enable Tx
proc_mem_mm_bus_wr(0, v_ctlr, mm_clk, tx_miso, tx_mosi);
proc_mem_mm_bus_wr(1, c_tx_init, mm_clk, tx_miso, tx_mosi);
proc_common_wait_some_cycles(mm_clk, dp_clk, 10); -- wait for clock domain crossing
proc_readback(mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, tx_init, tx_ctrl, rx_ctrl);
END proc_enable_tx;
PROCEDURE proc_enable_rx(CONSTANT c_pattern : IN STRING; -- "PSRG", "CNTR"
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL dp_clk : IN STD_LOGIC;
SIGNAL tx_miso : IN t_mem_miso; -- tx ctrl
SIGNAL tx_mosi : OUT t_mem_mosi;
SIGNAL rx_miso : IN t_mem_miso; -- rx ctrl
SIGNAL rx_mosi : OUT t_mem_mosi;
SIGNAL tx_init : OUT STD_LOGIC_VECTOR; -- readback
SIGNAL tx_ctrl : OUT STD_LOGIC_VECTOR;
SIGNAL rx_ctrl : OUT STD_LOGIC_VECTOR) IS
CONSTANT c_en : NATURAL := 1;
VARIABLE v_sel : NATURAL;
VARIABLE v_ctlr : NATURAL;
BEGIN
IF c_pattern="PSRG" THEN
v_sel := 0; -- pseudo random data
ELSE
v_sel := 1; -- counter data
END IF;
v_ctlr := v_sel * 2 + c_en; -- bits [1:0]
proc_mem_mm_bus_wr(0, v_ctlr, mm_clk, rx_miso, rx_mosi);
proc_common_wait_some_cycles(mm_clk, dp_clk, 10); -- wait for clock domain crossing
proc_readback(mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, tx_init, tx_ctrl, rx_ctrl);
END proc_enable_rx;
PROCEDURE proc_disable_tx(SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL dp_clk : IN STD_LOGIC;
SIGNAL tx_miso : IN t_mem_miso; -- tx ctrl
SIGNAL tx_mosi : OUT t_mem_mosi;
SIGNAL rx_miso : IN t_mem_miso; -- rx ctrl
SIGNAL rx_mosi : OUT t_mem_mosi;
SIGNAL tx_init : OUT STD_LOGIC_VECTOR; -- readback
SIGNAL tx_ctrl : OUT STD_LOGIC_VECTOR;
SIGNAL rx_ctrl : OUT STD_LOGIC_VECTOR) IS
BEGIN
proc_mem_mm_bus_wr(0, 0, mm_clk, tx_miso, tx_mosi);
proc_common_wait_some_cycles(mm_clk, dp_clk, 10); -- wait for clock domain crossing
proc_readback(mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, tx_init, tx_ctrl, rx_ctrl);
END proc_disable_tx;
PROCEDURE proc_disable_rx(SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL dp_clk : IN STD_LOGIC;
SIGNAL tx_miso : IN t_mem_miso; -- tx ctrl
SIGNAL tx_mosi : OUT t_mem_mosi;
SIGNAL rx_miso : IN t_mem_miso; -- rx ctrl
SIGNAL rx_mosi : OUT t_mem_mosi;
SIGNAL tx_init : OUT STD_LOGIC_VECTOR; -- readback
SIGNAL tx_ctrl : OUT STD_LOGIC_VECTOR;
SIGNAL rx_ctrl : OUT STD_LOGIC_VECTOR) IS
BEGIN
proc_mem_mm_bus_wr(0, 0, mm_clk, rx_miso, rx_mosi);
proc_common_wait_some_cycles(mm_clk, dp_clk, 10); -- wait for clock domain crossing
proc_readback(mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, tx_init, tx_ctrl, rx_ctrl);
END proc_disable_rx;
TYPE t_tb_mode_enum IS (
s_off,
s_expect_ok,
s_expect_error,
s_expect_no_result
);
SIGNAL st_clk : STD_LOGIC := '0';
PROCEDURE proc_read_and_verify_rx_stat(SIGNAL clk : IN STD_LOGIC;
SIGNAL mm_miso : IN t_mem_miso;
SIGNAL mm_mosi : OUT t_mem_mosi;
SIGNAL tb_mode : INOUT t_tb_mode_enum;
SIGNAL tb_verify : OUT STD_LOGIC;
SIGNAL rx_stat : INOUT STD_LOGIC_VECTOR) IS
BEGIN
-- Read
proc_mem_mm_bus_rd(1, clk, mm_miso, mm_mosi);
proc_mem_mm_bus_rd_latency(1, clk);
rx_stat <= mm_miso.rddata(c_word_w-1 DOWNTO 0);
proc_common_wait_some_cycles(clk, 1);
-- Issue tb_verify pulse eg. to easy recognition in Wave window
tb_verify <= '1';
proc_common_wait_some_cycles(clk, 1);
tb_verify <= '0';
-- Verify
IF tb_mode=s_expect_ok THEN
IF rx_stat(1)/='0' THEN
REPORT "Wrong diag result: no valid result." SEVERITY ERROR;
ELSIF rx_stat(0)/='0' THEN
REPORT "Wrong diag result: one or more data errors." SEVERITY ERROR;
END IF;
ELSIF tb_mode=s_expect_error THEN
IF rx_stat(1)/='0' THEN
REPORT "Wrong diag result: no valid result." SEVERITY ERROR;
ELSIF rx_stat(0)/='1' THEN
REPORT "Wrong diag result: must detect data errors." SEVERITY ERROR;
END IF;
ELSIF tb_mode=s_expect_no_result THEN
IF rx_stat(1)/='1' THEN
REPORT "Wrong diag result: must indicate no valid result." SEVERITY ERROR;
END IF;
ELSE
REPORT "Unknown verify mode" SEVERITY FAILURE;
END IF;
END proc_read_and_verify_rx_stat;
SIGNAL random : STD_LOGIC_VECTOR(15 DOWNTO 0) := (OTHERS=>'0'); -- use different lengths to have different random sequences
SIGNAL pulse : STD_LOGIC;
SIGNAL ready : STD_LOGIC;
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL tb_mode : t_tb_mode_enum := s_off;
SIGNAL tb_verify : STD_LOGIC := '0';
SIGNAL mm_rst : STD_LOGIC;
SIGNAL mm_clk : STD_LOGIC := '0';
SIGNAL sys_rst : STD_LOGIC := '1';
SIGNAL dp_rst : STD_LOGIC := '1';
SIGNAL dp_clk : STD_LOGIC := '0';
SIGNAL tx_mm_mosi : t_mem_mosi;
SIGNAL tx_mm_miso : t_mem_miso;
SIGNAL reg_tx_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL reg_tx_miso : t_mem_miso;
SIGNAL rx_mm_mosi : t_mem_mosi;
SIGNAL rx_mm_miso : t_mem_miso;
SIGNAL reg_rx_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL reg_rx_miso : t_mem_miso;
SIGNAL tx_src_out : t_dp_sosi_arr(c_nof_diag_inst-1 DOWNTO 0); -- source out sink in
SIGNAL tx_src_in : t_dp_siso_arr(c_nof_diag_inst-1 DOWNTO 0); -- source in sink out
SIGNAL tx_ctrl : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
SIGNAL tx_init : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
SIGNAL rx_ctrl : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
SIGNAL rx_stat : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
BEGIN
sys_rst <= '0' AFTER 100 ns;
st_clk <= NOT mm_clk AFTER mm_clk_period/2; -- Would be generated by SOPC if there was one.
mm_clk <= NOT mm_clk AFTER mm_clk_period/2;
p_mm_wr : PROCESS
BEGIN
tx_mm_miso <= c_mem_miso_rst;
tx_mm_mosi <= c_mem_mosi_rst;
rx_mm_miso <= c_mem_miso_rst;
rx_mm_mosi <= c_mem_mosi_rst;
SIGNAL tx_src_out_arr : t_dp_sosi_arr(c_nof_streams-1 DOWNTO 0);
SIGNAL tx_src_in_arr : t_dp_siso_arr(c_nof_streams-1 DOWNTO 0);
WHILE sys_rst='1' LOOP
WAIT UNTIL rising_edge(mm_clk);
END LOOP;
SIGNAL force_low_error : STD_LOGIC;
SIGNAL force_replicate_error : STD_LOGIC;
FOR I IN 0 TO 9 LOOP
WAIT UNTIL rising_edge(mm_clk);
END LOOP;
SIGNAL rx_snk_in_arr : t_dp_sosi_arr(c_nof_streams-1 DOWNTO 0);
-- Enable DIAG TX sequencer, set modes of RX and TX to PRNG
proc_mem_mm_bus_wr(c_offset_tx_mode, c_all_bits_high, mm_clk, tx_mm_mosi);
proc_mem_mm_bus_wr(c_offset_tx_en, c_all_bits_high, mm_clk, tx_mm_mosi);
proc_mem_mm_bus_wr(c_offset_rx_mode, c_all_bits_high, mm_clk, rx_mm_mosi);
BEGIN
WAIT FOR 100 ns;
mm_rst <= '1', '0' AFTER mm_clk_period * 5;
dp_rst <= mm_rst WHEN rising_edge(dp_clk);
-- Receivers should have aligned to the data now. Enable the DIAG RX monitor.
proc_mem_mm_bus_wr(c_offset_rx_en, c_all_bits_high, mm_clk, rx_mm_mosi);
mm_clk <= NOT mm_clk OR tb_end AFTER mm_clk_period/2;
dp_clk <= NOT dp_clk OR tb_end AFTER dp_clk_period/2;
WAIT FOR 200 ns;
------------------------------------------------------------------------------
-- STREAM CONTROL
------------------------------------------------------------------------------
-- Now read the diagnostics result: first put the request on the bus.
proc_mem_mm_bus_rd(c_offset_diag_res, mm_clk, rx_mm_mosi);
random <= func_common_random(random) WHEN rising_edge(dp_clk);
-- Wait because of read latency
proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, mm_clk);
ready <= '1' WHEN g_flow_control_verify=e_active ELSE
random(random'HIGH) WHEN g_flow_control_verify=e_random ELSE
pulse WHEN g_flow_control_verify=e_pulse;
-- Read data is now available in tx_mm_miso.rddata
FOR i in 0 to c_nof_diag_inst-1 LOOP -- All unconnected diag_res signals will of course be 'X' - only read the first c_nof_diag_inst bits.
ASSERT rx_mm_miso.rddata(i) = '0'
REPORT " Uniboard: ************************ MM READ DIAG RESULT NOT ZERO! ************************" SEVERITY FAILURE;
END LOOP;
tx_src_in_arr <= func_dp_stream_arr_set(tx_src_in_arr, ready, "READY");
ASSERT FALSE
REPORT "Uniboard: MM read DIAG result OK." SEVERITY NOTE;
------------------------------------------------------------------------------
-- Stimuli
------------------------------------------------------------------------------
p_stimuli : PROCESS
BEGIN
force_low_error <= '0';
force_replicate_error <= '0';
tb_mode <= s_off;
proc_common_wait_until_low(mm_clk, mm_rst);
proc_common_wait_some_cycles(mm_clk, 10);
-------------------------------------------------------------------------
-- Verify Tx and Rx on and both with the same pattern
-------------------------------------------------------------------------
tb_mode <= s_expect_ok;
proc_disable_tx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
proc_disable_rx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
proc_enable_tx("CNTR", 17, mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
proc_enable_rx("CNTR", mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
-- Run test and read and verify Rx status
proc_common_wait_some_cycles(mm_clk, 100);
proc_read_and_verify_rx_stat(mm_clk, reg_rx_miso, reg_rx_mosi, tb_mode, tb_verify, rx_stat);
-------------------------------------------------------------------------
-- Verify Tx and Rx on but with different pattern
-------------------------------------------------------------------------
tb_mode <= s_expect_error;
proc_enable_tx("PSRG", 17, mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
-- Run test and read and verify Rx status
proc_common_wait_some_cycles(mm_clk, 100);
proc_read_and_verify_rx_stat(mm_clk, reg_rx_miso, reg_rx_mosi, tb_mode, tb_verify, rx_stat);
-------------------------------------------------------------------------
-- Verify Rx off
-------------------------------------------------------------------------
tb_mode <= s_expect_no_result;
proc_disable_rx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
-- Run test and read and verify Rx status
proc_common_wait_some_cycles(mm_clk, 100);
proc_read_and_verify_rx_stat(mm_clk, reg_rx_miso, reg_rx_mosi, tb_mode, tb_verify, rx_stat);
-------------------------------------------------------------------------
-- Verify Tx and Rx on with error in sequence low part
-------------------------------------------------------------------------
tb_mode <= s_expect_ok;
proc_disable_tx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
proc_disable_rx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
proc_enable_tx("CNTR", 17, mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
proc_enable_rx("CNTR", mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
-- Run test and read and verify Rx status
proc_common_wait_some_cycles(mm_clk, 100);
proc_read_and_verify_rx_stat(mm_clk, reg_rx_miso, reg_rx_mosi, tb_mode, tb_verify, rx_stat);
tb_mode <= s_expect_error;
proc_common_wait_some_cycles(dp_clk, 1);
force_low_error <= '1';
proc_common_wait_some_cycles(dp_clk, 1);
force_low_error <= '0';
proc_common_wait_some_cycles(mm_clk, 100);
proc_read_and_verify_rx_stat(mm_clk, reg_rx_miso, reg_rx_mosi, tb_mode, tb_verify, rx_stat);
-------------------------------------------------------------------------
-- Verify Tx and Rx on with error in sequence replicate part
-------------------------------------------------------------------------
tb_mode <= s_expect_ok;
proc_disable_tx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
proc_disable_rx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
proc_enable_tx("CNTR", 17, mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
proc_enable_rx("CNTR", mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
-- Run test and read and verify Rx status
proc_common_wait_some_cycles(mm_clk, 100);
proc_read_and_verify_rx_stat(mm_clk, reg_rx_miso, reg_rx_mosi, tb_mode, tb_verify, rx_stat);
tb_mode <= s_expect_error;
proc_common_wait_some_cycles(dp_clk, 1);
force_replicate_error <= '1';
proc_common_wait_some_cycles(dp_clk, 1);
force_replicate_error <= '0';
proc_common_wait_some_cycles(mm_clk, 100);
proc_read_and_verify_rx_stat(mm_clk, reg_rx_miso, reg_rx_mosi, tb_mode, tb_verify, rx_stat);
-------------------------------------------------------------------------
-- Both off
-------------------------------------------------------------------------
tb_mode <= s_off;
proc_disable_tx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
proc_common_wait_some_cycles(mm_clk, 10);
tb_end <= '1';
WAIT;
END PROCESS;
u_mms_diag_tx_seq: ENTITY WORK.mms_diag_tx_seq
GENERIC MAP(
g_nof_diag_inst => c_nof_diag_inst,
g_dat_w => c_word_w,
g_sim => c_sim
g_nof_streams => c_nof_streams,
g_seq_dat_w => g_seq_dat_w
)
PORT MAP(
-- Clocks and reset
mm_rst => sys_rst,
mm_rst => mm_rst,
mm_clk => mm_clk,
st_clk => st_clk,
dp_rst => dp_rst,
dp_clk => dp_clk,
-- Memory Mapped Slave
mm_sla_in => tx_mm_mosi, -- master out slave in
mm_sla_out => tx_mm_miso, -- master in slave out
-- MM interface
reg_mosi => reg_tx_mosi,
reg_miso => reg_tx_miso,
-- Streaming interface
tx_src_out => tx_src_out,
tx_src_in => tx_src_in
-- DP streaming interface
tx_src_out_arr => tx_src_out_arr,
tx_src_in_arr => tx_src_in_arr
);
gen_ready_signals : FOR i IN 0 TO c_nof_diag_inst-1 GENERATE -- Ready signals for all instantiated diag rx modules
tx_src_in(i).ready <= '1';
END GENERATE;
u_mms_diag_rx_seq: ENTITY WORK.mms_diag_rx_seq
GENERIC MAP(
g_nof_diag_inst => c_nof_diag_inst,
g_dat_w => c_word_w,
g_sim => c_sim
g_nof_streams => c_nof_streams,
g_seq_dat_w => g_seq_dat_w,
g_data_w => g_data_w
)
PORT MAP(
-- Clocks and reset
mm_rst => sys_rst,
mm_rst => mm_rst,
mm_clk => mm_clk,
st_clk => st_clk,
dp_rst => dp_rst,
dp_clk => dp_clk,
-- Memory Mapped Slave
mm_sla_in => rx_mm_mosi, -- master out slave in
mm_sla_out => rx_mm_miso, -- master in slave out
-- MM interface
reg_mosi => reg_rx_mosi,
reg_miso => reg_rx_miso,
-- Streaming interface
rx_snk_in => tx_src_out
-- DP streaming interface
rx_snk_in_arr => rx_snk_in_arr
);
p_connect : PROCESS(tx_src_out_arr, force_low_error, force_replicate_error)
BEGIN
rx_snk_in_arr <= tx_src_out_arr;
IF force_low_error='1' THEN
rx_snk_in_arr(0).data(0) <= NOT tx_src_out_arr(0).data(0);
END IF;
IF force_replicate_error='1' THEN
rx_snk_in_arr(0).data(g_seq_dat_w) <= NOT tx_src_out_arr(0).data(g_seq_dat_w);
END IF;
END PROCESS;
END ARCHITECTURE str;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment