diff --git a/libraries/base/diag/src/vhdl/diag_pkg.vhd b/libraries/base/diag/src/vhdl/diag_pkg.vhd index 049a5c3fba578786fe7569d074fd6134f0658278..d8984f16cac6651c2206ef14fbf8a61bb59d7f16 100644 --- a/libraries/base/diag/src/vhdl/diag_pkg.vhd +++ b/libraries/base/diag/src/vhdl/diag_pkg.vhd @@ -158,7 +158,7 @@ PACKAGE diag_pkg IS CONSTANT c_diag_seq_tx_reg_nof_dat : NATURAL := 3; CONSTANT c_diag_seq_tx_reg_adr_w : NATURAL := ceil_log2(c_diag_seq_tx_reg_nof_dat); - CONSTANT c_diag_seq_rx_reg_nof_dat : NATURAL := 3; + CONSTANT c_diag_seq_rx_reg_nof_dat : NATURAL := 4; CONSTANT c_diag_seq_rx_reg_adr_w : NATURAL := ceil_log2(c_diag_seq_rx_reg_nof_dat); -- Record with all diag seq MM register fields @@ -169,6 +169,7 @@ PACKAGE diag_pkg IS tx_cnt : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); -- read cnt and stat rx_cnt : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); rx_stat : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); + rx_sample : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); END RECORD; CONSTANT c_diag_seq_tx_reg_dis : NATURAL := 0; diff --git a/libraries/base/diag/src/vhdl/diag_rx_seq.vhd b/libraries/base/diag/src/vhdl/diag_rx_seq.vhd index 68c38ef3a650077008e551e9051c94a10338686e..6cff0f9828f4af2d18fbbdd405ca870f0a84ab54 100644 --- a/libraries/base/diag/src/vhdl/diag_rx_seq.vhd +++ b/libraries/base/diag/src/vhdl/diag_rx_seq.vhd @@ -47,6 +47,9 @@ USE common_lib.common_lfsr_sequences_pkg.ALL; -- It is possible to use g_diag_res_w=g_dat_w, but then it is not possible to -- distinguish between whether the test has ran at all or whether all bits -- got errors. +-- The diag_sample keeps the last valid in_dat value. When diag_en='0' it is +-- reset to 0. Reading diag_sample via MM gives an impression of the valid +-- in_dat activity. ENTITY diag_rx_seq IS GENERIC ( @@ -66,6 +69,7 @@ ENTITY diag_rx_seq IS diag_sel : IN STD_LOGIC := g_sel; diag_res : OUT STD_LOGIC_VECTOR(g_diag_res_w-1 DOWNTO 0); -- diag_res valid indication bits & aggregate diff of in_dat during diag_en diag_res_val : OUT STD_LOGIC; + diag_sample : OUT STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0); -- monitor last valid in_dat -- ST input in_cnt : OUT STD_LOGIC_VECTOR(g_cnt_w-1 DOWNTO 0); -- count valid input test sequence data @@ -118,10 +122,14 @@ ARCHITECTURE rtl OF diag_rx_seq IS SIGNAL nxt_diag_res : STD_LOGIC_VECTOR(diag_res'RANGE); SIGNAL diag_res_int : STD_LOGIC_VECTOR(diag_res'RANGE) := c_diag_res_invalid; + + SIGNAL i_diag_sample : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0); + SIGNAL nxt_diag_sample : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0); BEGIN diag_dis <= NOT diag_en; + diag_sample <= i_diag_sample; gen_input_reg : IF g_input_reg=TRUE GENERATE p_reg : PROCESS (clk) @@ -175,10 +183,16 @@ BEGIN diag_res_en <= nxt_diag_res_en; diag_res_val <= nxt_diag_res_val; -- Outputs. + i_diag_sample <= nxt_diag_sample; END IF; END IF; END PROCESS; + ------------------------------------------------------------------------------ + -- Keep last valid in_dat value for MM monitoring + ------------------------------------------------------------------------------ + nxt_diag_sample <= (OTHERS=>'0') WHEN diag_en='0' ELSE in_dat WHEN in_val='1' ELSE i_diag_sample; + ------------------------------------------------------------------------------ -- Detect that there has been valid input data for at least two clock cycles ------------------------------------------------------------------------------ diff --git a/libraries/base/diag/src/vhdl/mms_diag_rx_seq.vhd b/libraries/base/diag/src/vhdl/mms_diag_rx_seq.vhd index 60d30d9ba39832b519995708e77f8e56e32f54ef..13997d86f0003c8d9d1ef98b7cd0e0216fccda78 100644 --- a/libraries/base/diag/src/vhdl/mms_diag_rx_seq.vhd +++ b/libraries/base/diag/src/vhdl/mms_diag_rx_seq.vhd @@ -29,17 +29,27 @@ -- -- 31 24 23 16 15 8 7 0 wi -- |-----------------|-----------------|-----------------|-----------------| --- | select = [1], enable = [0] | 0 +-- | diag_sel = [1], diag_en = [0] | 0 RW -- |-----------------------------------------------------------------------| --- | res_val_n = [1], res_ok_n = [0] | 1 +-- | res_val_n = [1], res_ok_n = [0] | 1 RO -- |-----------------------------------------------------------------------| --- | rx_cnt[31:0] | 2 +-- | rx_cnt[31:0] | 2 RO +-- |-----------------------------------------------------------------------| +-- | rx_sample[g_seq_dat_w-1:0] | 3 RO -- |-----------------------------------------------------------------------| -- -- . g_nof_streams -- The MM control register for stream I in 0:g_nof_streams-1 starts at word -- index wi = I * 2**c_mm_reg.adr_w. -- +-- . diag_en +-- '0' = stop and reset input sequence verification +-- '1' = enable input sequence verification +-- +-- . diag_sel +-- '0' = verify PSRG data +-- '1' = verify CNTR data +-- -- . 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 @@ -64,6 +74,10 @@ -- Counts the number of valid input data that was received since diag_en -- went active. An incrementing rx_cnt shows that data is being received. -- +-- . rx_sample +-- The rx_sample keeps the last valid in_dat value. When diag_en='0' it is +-- reset to 0. Reading rx_sample via MM gives an impression of the valid +-- in_dat activity. LIBRARY IEEE, common_lib, dp_lib; USE IEEE.std_logic_1164.ALL; @@ -102,7 +116,7 @@ ARCHITECTURE str OF mms_diag_rx_seq IS CONSTANT c_mm_reg : t_c_mem := (latency => 1, adr_w => c_diag_seq_rx_reg_adr_w, -- = 2 dat_w => c_word_w, -- Use MM bus data width = c_word_w = 32 for all MM registers - nof_dat => c_diag_seq_rx_reg_nof_dat, -- = 3 + nof_dat => c_diag_seq_rx_reg_nof_dat, -- = 4 init_sl => '0'); CONSTANT c_reg_slv_w : NATURAL := c_mm_reg.nof_dat*c_mm_reg.dat_w; @@ -122,6 +136,7 @@ ARCHITECTURE str OF mms_diag_rx_seq IS SIGNAL diag_sel_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); SIGNAL rx_cnt_arr : t_slv_32_arr(g_nof_streams-1 DOWNTO 0); -- can use t_slv_32_arr because c_mm_reg.dat_w = c_word_w = 32 fixed + SIGNAL rx_sample_arr : t_seq_dat_arr(g_nof_streams-1 DOWNTO 0); SIGNAL rx_seq_arr : t_seq_dat_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); @@ -183,6 +198,7 @@ BEGIN -- Read only registers: diag_res => diag_res_arr(I), diag_res_val => diag_res_val_arr(I), + diag_sample => rx_sample_arr(I), -- Streaming in_cnt => rx_cnt_arr(I), @@ -200,7 +216,7 @@ BEGIN 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, rx_cnt_arr) + p_stat_reg_arr : PROCESS(ctrl_reg_arr, stat_res_ok_n_arr, stat_res_val_n_arr, rx_cnt_arr, rx_sample_arr) BEGIN -- Default write / readback: stat_reg_arr(I) <= ctrl_reg_arr(I); -- address 0: control read back @@ -208,6 +224,7 @@ BEGIN stat_reg_arr(I)( 0+1*c_word_w) <= stat_res_ok_n_arr(I); -- address 1, data bit [0] stat_reg_arr(I)( 1+1*c_word_w) <= stat_res_val_n_arr(I); -- address 1, data bit [1] stat_reg_arr(I)(3*c_word_w-1 DOWNTO 2*c_word_w) <= rx_cnt_arr(I); -- address 2: read rx_cnt per stream + stat_reg_arr(I)(4*c_word_w-1 DOWNTO 3*c_word_w) <= RESIZE_UVEC(rx_sample_arr(I), c_word_w); -- address 3: read valid sample per stream END PROCESS; u_reg : ENTITY common_lib.common_reg_r_w_dc diff --git a/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd b/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd index e9d282bd9116ce6a33bc6594c3aab4fb5bb3a8b5..7010768722c50d06e1e54d47c6eb15d8cc587615 100644 --- a/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd +++ b/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd @@ -29,11 +29,11 @@ -- -- 31 24 23 16 15 8 7 0 wi -- |-----------------|-----------------|-----------------|-----------------| --- | diag_dc = [2], diag_sel = [1], diag_en = [0] | 0 +-- | diag_dc = [2], diag_sel = [1], diag_en = [0] | 0 RW -- |-----------------------------------------------------------------------| --- | diag_init[31:0] | 1 +-- | diag_init[31:0] | 1 RW -- |-----------------------------------------------------------------------| --- | tx_cnt[31:0] | 2 +-- | tx_cnt[31:0] | 2 RO -- |-----------------------------------------------------------------------| -- -- . g_nof_streams @@ -61,8 +61,8 @@ -- '1' = enable output sequence -- -- . diag_sel --- '0' = PSRG data --- '1' = CNTR data +-- '0' = generate PSRG data +-- '1' = generate CNTR data -- -- . diag_dc -- '0' = Output sequence data (as selected by diag_sel) diff --git a/libraries/base/diag/tb/vhdl/tb_diag_pkg.vhd b/libraries/base/diag/tb/vhdl/tb_diag_pkg.vhd index d93e0f02aa456c97cc81d3829625494b63affae1..e0f61c1fbbd0961553fdba3c4c807f740863cfb1 100644 --- a/libraries/base/diag/tb/vhdl/tb_diag_pkg.vhd +++ b/libraries/base/diag/tb/vhdl/tb_diag_pkg.vhd @@ -144,6 +144,10 @@ PACKAGE BODY tb_diag_pkg IS proc_mem_mm_bus_rd(c_tx_offset + 2, mm_clk, tx_miso, tx_mosi); proc_mem_mm_bus_rd_latency(1, mm_clk); rd_reg.tx_cnt <= tx_miso.rddata(c_word_w-1 DOWNTO 0); + -- . read rx_sample + proc_mem_mm_bus_rd(c_rx_offset + 3, mm_clk, rx_miso, rx_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + rd_reg.rx_sample <= rx_miso.rddata(c_word_w-1 DOWNTO 0); END proc_diag_seq_read_all; PROCEDURE proc_diag_seq_tx_enable(CONSTANT c_stream : IN NATURAL; @@ -238,16 +242,18 @@ PACKAGE BODY tb_diag_pkg IS SIGNAL tb_mode : INOUT t_tb_diag_seq_mode_enum; SIGNAL tb_verify : OUT STD_LOGIC; SIGNAL rd_reg : INOUT t_diag_seq_mm_reg) IS -- read all MM reg - VARIABLE v_rx_stat : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); - VARIABLE v_rx_cnt : NATURAL; - VARIABLE v_tx_cnt : NATURAL; + VARIABLE v_rx_stat : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); + VARIABLE v_rx_sample : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); + VARIABLE v_rx_cnt : NATURAL; + VARIABLE v_tx_cnt : NATURAL; BEGIN -- Read all proc_diag_seq_read_all(c_stream, mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, rd_reg); proc_common_wait_some_cycles(mm_clk, 1); - v_rx_stat := rd_reg.rx_stat; - v_rx_cnt := TO_UINT(rd_reg.rx_cnt); - v_tx_cnt := TO_UINT(rd_reg.tx_cnt); + v_rx_stat := rd_reg.rx_stat; + v_rx_sample := rd_reg.rx_sample; + v_rx_cnt := TO_UINT(rd_reg.rx_cnt); + v_tx_cnt := TO_UINT(rd_reg.tx_cnt); -- Issue tb_verify pulse eg. to easy recognition in Wave window tb_verify <= '1'; @@ -261,6 +267,7 @@ PACKAGE BODY tb_diag_pkg IS ELSIF v_rx_stat(0)/='0' THEN REPORT "Wrong diag result: one or more data errors." SEVERITY ERROR; END IF; + -- Read rx_cnt and tx_cnt again after some cycles proc_diag_seq_read_all(c_stream, mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, rd_reg); proc_common_wait_some_cycles(mm_clk, 1); @@ -274,6 +281,12 @@ PACKAGE BODY tb_diag_pkg IS ELSIF v_tx_cnt >= TO_UINT(rd_reg.tx_cnt) THEN REPORT "Wrong diag result: tx_cnt did not increase." SEVERITY ERROR; END IF; + -- Read rx_sample again after some cycles + IF UNSIGNED(v_rx_sample)=0 THEN + REPORT "Wrong diag sample: no valid sample." SEVERITY ERROR; + ELSIF v_rx_sample=rd_reg.rx_sample THEN + REPORT "Wrong diag sample: sample did not change." SEVERITY ERROR; + END IF; ELSIF tb_mode=s_expect_error THEN IF v_rx_stat(1)/='0' THEN REPORT "Wrong diag result: no valid result." SEVERITY ERROR; @@ -293,6 +306,9 @@ PACKAGE BODY tb_diag_pkg IS IF v_rx_cnt /= 0 THEN REPORT "Wrong diag result: rx_cnt /= 0." SEVERITY ERROR; END IF; + IF UNSIGNED(v_rx_sample)/=0 THEN + REPORT "Wrong diag sample: rx_sample /= 0." SEVERITY ERROR; + END IF; ELSIF tb_mode=s_off THEN IF v_rx_cnt /= 0 THEN REPORT "Wrong diag result: rx_cnt /= 0." SEVERITY ERROR; @@ -300,6 +316,9 @@ PACKAGE BODY tb_diag_pkg IS IF v_tx_cnt /= 0 THEN REPORT "Wrong diag result: tx_cnt /= 0." SEVERITY ERROR; END IF; + IF UNSIGNED(v_rx_sample)/=0 THEN + REPORT "Wrong diag sample: rx_sample /= 0." SEVERITY ERROR; + END IF; ELSE REPORT "Unknown verify mode" SEVERITY FAILURE; END IF;