From 674906088f1e639ddb9668d79adcce92f1c8af2b Mon Sep 17 00:00:00 2001 From: Erik Kooistra <kooistra@astron.nl> Date: Thu, 12 Feb 2015 09:53:28 +0000 Subject: [PATCH] Added tx_cnt_arr to MM reg. Added g_mm_broadcast to select for single or multi MM port control. --- .../base/diag/src/vhdl/mms_diag_tx_seq.vhd | 146 ++++++++++++------ 1 file changed, 98 insertions(+), 48 deletions(-) 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 f36ac1e53b..9e5c5e6a6b 100644 --- a/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd +++ b/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd @@ -24,17 +24,28 @@ -- 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: +-- own flow control. Each DP stream also has its own MM control register to +-- support reading tx_cnt per stream. -- -- 31 24 23 16 15 8 7 0 wi -- |-----------------|-----------------|-----------------|-----------------| -- | select = [1], enable = [0] | 0 -- |-----------------------------------------------------------------------| --- | init[31: 0] | 1 +-- | init[31:0] | 1 +-- |-----------------------------------------------------------------------| +-- | tx_cnt[31:0] | 2 -- |-----------------------------------------------------------------------| -- +-- . 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. +-- +-- . g_mm_broadcast +-- Use default g_mm_broadcast=FALSE for multiplexed individual MM access to +-- each reg_mosi_arr/reg_miso_arr MM port. When g_mm_broadcast=TRUE then a +-- write access to MM port [0] is passed on to all ports and a read access +-- is done from MM port [0]. The other MM array ports cannot be read then. +-- -- . 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 @@ -48,6 +59,12 @@ -- . 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. +-- +-- . tx_cnt +-- Counts the number of valid output data that was transmitted onstream 0 +-- since diag_en went active. An incrementing tx_cnt shows that data is +-- being transmitted. +-- LIBRARY IEEE, common_lib, dp_lib; USE IEEE.std_logic_1164.ALL; @@ -57,8 +74,9 @@ USE dp_lib.dp_stream_pkg.ALL; ENTITY mms_diag_tx_seq IS GENERIC ( - g_nof_streams : NATURAL := 1; - g_seq_dat_w : NATURAL := c_word_w -- >= 1, test sequence data width + g_mm_broadcast : BOOLEAN := FALSE; + g_nof_streams : NATURAL := 1; + g_seq_dat_w : NATURAL := c_word_w -- >= 1, test sequence data width ); PORT ( -- Clocks and reset @@ -82,33 +100,43 @@ ARCHITECTURE str OF mms_diag_tx_seq IS -- Define the actual size of the MM slave register CONSTANT c_mm_reg : t_c_mem := (latency => 1, - adr_w => 1, + adr_w => 2, dat_w => c_word_w, -- Use MM bus data width = c_word_w = 32 for all MM registers - nof_dat => 2, + nof_dat => 3, init_sl => '0'); - TYPE t_dat_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_seq_dat_w-1 DOWNTO 0); + CONSTANT c_reg_slv_w : NATURAL := c_mm_reg.nof_dat*c_mm_reg.dat_w; + + TYPE t_reg_slv_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_reg_slv_w-1 DOWNTO 0); + TYPE t_seq_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); + 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); + -- 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 ctrl_reg_arr : t_reg_slv_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0')); + SIGNAL stat_reg_arr : t_reg_slv_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 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'); + SIGNAL diag_init_mm_arr : t_slv_32_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0')); -- can use t_slv_32_arr because c_mm_reg.dat_w = c_word_w = 32 fixed + SIGNAL diag_init_arr : t_seq_dat_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0')); - 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 tx_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 tx_dat_arr : t_seq_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 tx_replicate_arr : t_replicate_arr(g_nof_streams-1 DOWNTO 0); + SIGNAL tx_replicate_dat_arr : t_dp_data_slv_arr(g_nof_streams-1 DOWNTO 0); BEGIN 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_cnt_w => c_word_w, g_dat_w => g_seq_dat_w ) PORT MAP ( @@ -116,53 +144,75 @@ BEGIN clk => dp_clk, -- Write and read back registers: - diag_en => diag_en, - diag_sel => diag_sel, - diag_dat => diag_init, + diag_en => diag_en_arr(I), + diag_sel => diag_sel_arr(I), + diag_dat => diag_init_arr(I), -- Streaming diag_req => tx_req_arr(I), + out_cnt => tx_cnt_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_dat_arr(I) <= REPLICATE_DP_DATA(tx_dat_arr(I)); - 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); + -- for some reason the intermediate tx_replicate_dat_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_dat_arr(I); tx_src_out_arr(I).valid <= tx_val_arr(I); - END GENERATE; - -- 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] + -- Register mapping + 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] + diag_init_mm_arr(I) <= ctrl_reg_arr(I)(2*c_word_w-1 DOWNTO c_word_w); -- address 1, data bits [31:0] + + diag_init_arr(I) <= RESIZE_UVEC(diag_init_mm_arr(I), g_seq_dat_w); + + p_stat_reg : PROCESS(ctrl_reg_arr(I), tx_cnt_arr) + BEGIN + -- Default write / readback: + stat_reg_arr(I) <= ctrl_reg_arr(I); -- address 0, 1: control read back + -- Status read only: + stat_reg_arr(I)(3*c_word_w-1 DOWNTO 2*c_word_w) <= tx_cnt_arr(I); -- address 2: read tx_cnt + END PROCESS; - diag_init <= RESIZE_UVEC(diag_init_mm, g_seq_dat_w); + u_reg : ENTITY common_lib.common_reg_r_w_dc + GENERIC MAP ( + g_cross_clock_domain => TRUE, + g_readback => FALSE, -- must use FALSE for write/read or read only register when g_cross_clock_domain=TRUE + 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), -- connect out_reg to in_reg for write and readback register + out_reg => ctrl_reg_arr(I) + ); + END GENERATE; - u_reg : ENTITY common_lib.common_reg_r_w_dc + -- 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_cross_clock_domain => TRUE, - g_readback => TRUE, -- using TRUE fits for write and readback register - g_reg => c_mm_reg + g_broadcast => g_mm_broadcast, + g_nof_mosi => g_nof_streams, + g_mult_addr_w => c_mm_reg.adr_w ) 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, - 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 + mosi => reg_mosi, + miso => reg_miso, + mosi_arr => reg_mosi_arr, + miso_arr => reg_miso_arr ); END str; -- GitLab