From 61f16974f28d9078e750b7aa3fd18910c7068a29 Mon Sep 17 00:00:00 2001 From: Erik Kooistra <kooistra@astron.nl> Date: Fri, 12 Jun 2015 07:49:17 +0000 Subject: [PATCH] Provide streaming access to IO_DDR using a Tx seq and a Rx seq with optional DB RAM. --- libraries/io/ddr/src/vhdl/mms_io_ddr_diag.vhd | 244 +++++++----------- 1 file changed, 93 insertions(+), 151 deletions(-) diff --git a/libraries/io/ddr/src/vhdl/mms_io_ddr_diag.vhd b/libraries/io/ddr/src/vhdl/mms_io_ddr_diag.vhd index f8782e879b..77aa8eac19 100644 --- a/libraries/io/ddr/src/vhdl/mms_io_ddr_diag.vhd +++ b/libraries/io/ddr/src/vhdl/mms_io_ddr_diag.vhd @@ -19,14 +19,29 @@ -- ------------------------------------------------------------------------------- --- Purpose: Provide streaming access to IO_DDR using a BG and a DB +-- Purpose: Provide streaming access to IO_DDR using a Tx seq and a Rx seq with optional DB RAM -- Description: --- --- BG ----> IO_DDR ----> DB --- | | | --- | | | --- MM --+---------+----------+-- +-- The BG Tx seq stream writes the DDR and the read stream is passed on to the DB Rx seq. The BG +-- block generation and BG RAM are not used. The DB RAM can be used for extra read data monitoring. +-- The DDR write and read access is controlled via the driver MM interface of the mms_io_ddr. -- +-- DB RAM +-- Tx seq --> IO_DDR --> Rx seq +-- | | | +-- | | | +-- MM --+---------+----------+-- +-- +-- Remark: +-- . The ratio of g_dp_data_w and func_tech_ddr_ctlr_data_w(g_io_tech_ddr)must be a power of 2 due to the mixed width FIFO. By +-- using a wider g_dp_data_w the DDR data access rate can be increased to the maximum that is possible for the DDR memory. +-- - For DDR3 with ctrl_data_w = dq_w * rsl = 64 * 4 = 256 choose g_dp_data_w e.g. 16, 32, 64, 128, 256, 512. +-- - For DDR4 with ctrl_data_w = dq_w * rsl = 72 * 8 = 576 choose g_dp_data_w e.g. 18, 36, 72, 144, 288, 576, 1152. +-- . The DB RAM gets refilled with new read data from the DDR after the last word has been read via the MM. +-- . The DB RAM only captures the lowest c_word_w=32 bits of the g_dp_data_w. This fits the MM bus data width +-- and it is sufficient because typically g_dp_seq_dat_w <= c_word_w. +-- . This component could have user write input and user read output. The constraint is that the user DDR access is suitable for: +-- - MM control of the mms_io_ddr to issue a write or a read access. +-- - g_wr_flush_mode="VAL" in the io_ddr, because that the Tx seq source does not use "SOP" or "SYNC" LIBRARY IEEE, common_lib, dp_lib, diag_lib, technology_lib, tech_ddr_lib; USE IEEE.STD_LOGIC_1164.ALL; @@ -40,68 +55,28 @@ USE tech_ddr_lib.tech_ddr_pkg.ALL; ENTITY mms_io_ddr_diag IS GENERIC ( - --------------------------------------------------------------------------- - -- IO_DDR - --------------------------------------------------------------------------- - g_io_technology : NATURAL := c_tech_select_default; - g_io_tech_ddr : t_c_tech_ddr; - g_io_cross_domain_dvr_ctlr : BOOLEAN := TRUE; - g_io_cross_domain_delay_len : NATURAL := c_meta_delay_len; - g_io_wr_data_w : NATURAL := 32; - g_io_wr_fifo_depth : NATURAL := 256; -- >=16 , defined at DDR side of the FIFO, default 256 because 32b*256 fits in 1 M9K - g_io_rd_fifo_depth : NATURAL := 256; -- >=16 AND >g_tech_ddr.maxburstsize, defined at DDR side of the FIFO, default 256 because 32b*256 fits in 1 M9K - g_io_rd_fifo_af_margin : NATURAL := 4 + 1*64; -- < g_rd_fifo_depth and sufficient to fit one or more rd burst accesses of g_tech_ddr.maxburstsize each - g_io_rd_data_w : NATURAL := 32; - g_io_wr_flush_mode : STRING := "VAL"; -- "VAL", "SOP", "SYN" - g_io_wr_flush_use_channel : BOOLEAN := FALSE; - g_io_wr_flush_start_channel : NATURAL := 0; - g_io_wr_flush_nof_channels : POSITIVE := 1; + -- System + g_technology : NATURAL := c_tech_select_default; - --------------------------------------------------------------------------- - -- DIAG block generator - --------------------------------------------------------------------------- - -- Generate configurations - g_bg_use_usr_input : BOOLEAN := FALSE; - g_bg_use_bg : BOOLEAN := TRUE; - g_bg_use_tx_seq : BOOLEAN := FALSE; - -- General - g_bg_nof_streams : POSITIVE := 1; - -- BG settings - g_bg_use_bg_buffer_ram : BOOLEAN := TRUE; - g_bg_buf_dat_w : POSITIVE := 32; - g_bg_buf_addr_w : POSITIVE := 7; -- Waveform buffer size 2**g_buf_addr_w nof samples - g_bg_file_index_arr : t_nat_natural_arr := array_init(0, 128, 1); -- default use the instance index as file index 0, 1, 2, 3, 4 ... - g_bg_file_name_prefix : STRING := "data/bf_in_data"; -- Path to the hex files that contain the initial data for the memories. The sequence number and ".hex" are added within the entity. - g_bg_diag_block_gen_rst : t_diag_block_gen := c_diag_block_gen_rst; - -- User input multiplexer option - g_bg_usr_bypass_xonoff : BOOLEAN := FALSE; - -- Tx_seq - g_bg_seq_dat_w : NATURAL := 32; -- >= 1, test sequence data width. Choose g_seq_dat_w <= g_buf_dat_w + g_dp_data_w : NATURAL := 32; -- DP data width, func_tech_ddr_ctlr_data_w(g_io_tech_ddr)/g_dp_data_w must be a power of 2 due to the mixed width FIFO + g_dp_seq_dat_w : NATURAL := 32; -- >= 1, test sequence data width. Choose g_dp_seq_dat_w <= g_dp_data_w. The seq data gets replicated to fill g_dp_data_w. + g_dp_fifo_depth : NATURAL := 2048; -- >= 2048, write FIFO depth and read FIFO depth at DP side of the FIFOs + + -- IO_DDR + g_io_tech_ddr : t_c_tech_ddr; - --------------------------------------------------------------------------- -- DIAG data buffer - --------------------------------------------------------------------------- - -- Generate configurations - g_db_use_db : BOOLEAN := TRUE; - g_db_use_rx_seq : BOOLEAN := FALSE; - -- General - g_db_nof_streams : POSITIVE := 16; -- each stream gets an data buffer - -- DB settings - g_db_data_type : t_diag_data_type_enum := e_data; -- define the sosi field that gets stored: e_data=data, e_complex=im&re, e_real=re, e_imag=im - g_db_data_w : NATURAL := 32; -- the g_data_w is the width of the data, re, im values or of the combined im&re value - g_db_buf_nof_data : NATURAL := 1024; -- nof words per data buffer - g_db_buf_use_sync : BOOLEAN := FALSE; -- when TRUE start filling the buffer at the in_sync, else after the last word was read - -- Rx_seq - g_db_seq_dat_w : NATURAL := 32 -- >= 1, test sequence data width. Choose g_seq_dat_w <= g_data_w + g_db_use_db : BOOLEAN := FALSE; + g_db_buf_nof_data : NATURAL := 1024 -- nof words per data buffer ); PORT ( --------------------------------------------------------------------------- -- System --------------------------------------------------------------------------- - mm_clk : IN STD_LOGIC; - mm_rst : IN STD_LOGIC; - dp_clk : IN STD_LOGIC; - dp_rst : IN STD_LOGIC; + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; + dp_rst : IN STD_LOGIC; + dp_clk : IN STD_LOGIC; -- use alternative external clock or externally connect to ctlr_clk_out --------------------------------------------------------------------------- -- IO_DDR @@ -121,25 +96,11 @@ ENTITY mms_io_ddr_diag IS reg_io_ddr_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- register for DDR controller status info reg_io_ddr_miso : OUT t_mem_miso; - dvr_clk : IN STD_LOGIC; - dvr_rst : IN STD_LOGIC; - - -- Write FIFO clock domain - wr_clk : IN STD_LOGIC; - wr_rst : IN STD_LOGIC; - - wr_fifo_usedw : OUT STD_LOGIC_VECTOR(ceil_log2(g_io_wr_fifo_depth * (func_tech_ddr_ctlr_data_w(g_io_tech_ddr)/g_io_wr_data_w) )-1 DOWNTO 0); -- for monitoring purposes - wr_sosi : IN t_dp_sosi; - wr_siso : OUT t_dp_siso; - - -- Read FIFO clock domain - rd_clk : IN STD_LOGIC; - rd_rst : IN STD_LOGIC; - - rd_fifo_usedw : OUT STD_LOGIC_VECTOR(ceil_log2(g_io_rd_fifo_depth * (func_tech_ddr_ctlr_data_w(g_io_tech_ddr)/g_io_rd_data_w) )-1 DOWNTO 0); - rd_sosi : OUT t_dp_sosi; - rd_siso : IN t_dp_siso; + -- Write / read FIFO status for monitoring purposes (in dp_clk domain) + wr_fifo_usedw : OUT STD_LOGIC_VECTOR(ceil_log2(g_dp_fifo_depth)-1 DOWNTO 0); + rd_fifo_usedw : OUT STD_LOGIC_VECTOR(ceil_log2(g_dp_fifo_depth)-1 DOWNTO 0); + -- DDR3 pass on termination control from master to slave controller term_ctrl_out : OUT t_tech_ddr3_phy_terminationcontrol; term_ctrl_in : IN t_tech_ddr3_phy_terminationcontrol := c_tech_ddr3_phy_terminationcontrol_rst; @@ -154,24 +115,14 @@ ENTITY mms_io_ddr_diag IS phy4_ou : OUT t_tech_ddr4_phy_ou; --------------------------------------------------------------------------- - -- DIAG block generator + -- DIAG Tx seq --------------------------------------------------------------------------- -- MM interface - reg_bg_ctrl_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- BG control register (one for all streams) - reg_bg_ctrl_miso : OUT t_mem_miso; - ram_bg_data_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- BG buffer RAM (one per stream) - ram_bg_data_miso : OUT t_mem_miso; reg_tx_seq_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- Tx seq control (one per stream because c_reg_tx_seq_broadcast=FALSE) reg_tx_seq_miso : OUT t_mem_miso; - -- ST interface - bg_sync : IN STD_LOGIC := '1'; -- block generator enable sync pulse in ST dp_clk domain - usr_siso_arr : OUT t_dp_siso_arr(g_bg_nof_streams-1 DOWNTO 0); -- connect when g_use_usr_input=TRUE, else leave not connected - usr_sosi_arr : IN t_dp_sosi_arr(g_bg_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_sosi_rst); - out_siso_arr : IN t_dp_siso_arr(g_bg_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); -- Default xon='1' - out_sosi_arr : OUT t_dp_sosi_arr(g_bg_nof_streams-1 DOWNTO 0); -- Output SOSI that contains the waveform data - + --------------------------------------------------------------------------- - -- DIAG data buffer + -- DIAG rx seq with optional data buffer --------------------------------------------------------------------------- -- MM interface reg_data_buf_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- DB control register (one per stream) @@ -181,17 +132,23 @@ ENTITY mms_io_ddr_diag IS ram_data_buf_miso : OUT t_mem_miso; reg_rx_seq_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- Rx seq control register (one per streams) - reg_rx_seq_miso : OUT t_mem_miso; - - -- ST interface - db_sync : IN STD_LOGIC := '0'; -- input sync pulse in ST dp_clk domain that starts data buffer when g_use_in_sync = TRUE - in_sosi_arr : IN t_dp_sosi_arr(g_db_nof_streams-1 DOWNTO 0) + reg_rx_seq_miso : OUT t_mem_miso ); END mms_io_ddr_diag; ARCHITECTURE str OF mms_io_ddr_diag IS + CONSTANT c_io_wr_fifo_depth : NATURAL := (g_dp_fifo_depth * g_dp_data_w) / func_tech_ddr_ctlr_data_w(g_io_tech_ddr); -- >=16 , defined at DDR side of the FIFO + CONSTANT c_io_rd_fifo_depth : NATURAL := (g_dp_fifo_depth * g_dp_data_w) / func_tech_ddr_ctlr_data_w(g_io_tech_ddr); -- >=16 AND >g_tech_ddr.maxburstsize, defined at DDR side of the FIFO, default 256 because 32b*256 fits in 1 M9K + CONSTANT c_io_rd_fifo_af_margin : NATURAL := 4 + 1*64; -- < c_io_rd_fifo_depth and sufficient to fit one or more rd burst accesses of g_io_tech_ddr.maxburstsize each + + SIGNAL bg_siso_arr : t_dp_siso_arr(0 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); -- Default xon='1' + SIGNAL bg_sosi_arr : t_dp_sosi_arr(0 DOWNTO 0); -- Output SOSI that contains the waveform data + + SIGNAL db_siso_arr : t_dp_siso_arr(0 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); -- Default ready='1' + SIGNAL db_sosi_arr : t_dp_sosi_arr(0 DOWNTO 0); + BEGIN ------------------------------------------------------------------------------ @@ -199,19 +156,19 @@ BEGIN ------------------------------------------------------------------------------ u_mms_io_ddr : ENTITY work.mms_io_ddr GENERIC MAP ( - g_technology => g_io_technology, + g_technology => g_technology, g_tech_ddr => g_io_tech_ddr, - g_cross_domain_dvr_ctlr => g_io_cross_domain_dvr_ctlr, - g_cross_domain_delay_len => g_io_cross_domain_delay_len, - g_wr_data_w => g_io_wr_data_w, - g_wr_fifo_depth => g_io_wr_fifo_depth, - g_rd_fifo_depth => g_io_rd_fifo_depth, - g_rd_fifo_af_margin => g_io_rd_fifo_af_margin, - g_rd_data_w => g_io_rd_data_w, - g_wr_flush_mode => g_io_wr_flush_mode, - g_wr_flush_use_channel => g_io_wr_flush_use_channel, - g_wr_flush_start_channel => g_io_wr_flush_start_channel, - g_wr_flush_nof_channels => g_io_wr_flush_nof_channels + g_cross_domain_dvr_ctlr => TRUE, -- cross between mm_clk and ctlr_clk_in + g_cross_domain_delay_len => c_meta_delay_len, + g_wr_data_w => g_dp_data_w, + g_wr_fifo_depth => c_io_wr_fifo_depth, + g_rd_fifo_depth => c_io_rd_fifo_depth, + g_rd_fifo_af_margin => c_io_rd_fifo_af_margin, + g_rd_data_w => g_dp_data_w, + g_wr_flush_mode => "VAL", + g_wr_flush_use_channel => FALSE, + g_wr_flush_start_channel => 0, + g_wr_flush_nof_channels => 1 ) PORT MAP ( -- DDR reference clock @@ -233,24 +190,24 @@ BEGIN reg_io_ddr_mosi => reg_io_ddr_mosi, reg_io_ddr_miso => reg_io_ddr_miso, - dvr_clk => dvr_clk, - dvr_rst => dvr_rst, + dvr_clk => mm_clk, + dvr_rst => mm_rst, -- Write FIFO clock domain - wr_clk => wr_clk, - wr_rst => wr_rst, + wr_clk => dp_clk, + wr_rst => dp_rst, wr_fifo_usedw => wr_fifo_usedw, - wr_sosi => wr_sosi, - wr_siso => wr_siso, + wr_sosi => bg_sosi_arr(0), + wr_siso => bg_siso_arr(0), -- Read FIFO clock domain - rd_clk => rd_clk, - rd_rst => rd_rst, + rd_clk => dp_clk, + rd_rst => dp_rst, rd_fifo_usedw => rd_fifo_usedw, - rd_sosi => rd_sosi, - rd_siso => rd_siso, + rd_sosi => db_sosi_arr(0), + rd_siso => db_siso_arr(0), term_ctrl_out => term_ctrl_out, term_ctrl_in => term_ctrl_in, @@ -267,27 +224,20 @@ BEGIN ); ----------------------------------------------------------------------------- - -- DIAG Block Generator + -- DIAG Tx seq ----------------------------------------------------------------------------- u_mms_diag_block_gen: ENTITY diag_lib.mms_diag_block_gen GENERIC MAP ( -- Generate configurations - g_use_usr_input => g_bg_use_usr_input, - g_use_bg => g_bg_use_bg, - g_use_tx_seq => g_bg_use_tx_seq, + g_use_usr_input => FALSE, + g_use_bg => FALSE, + g_use_tx_seq => TRUE, -- General - g_nof_streams => g_bg_nof_streams, + g_nof_streams => 1, -- BG settings - g_use_bg_buffer_ram => g_bg_use_bg_buffer_ram, - g_buf_dat_w => g_bg_buf_dat_w, - g_buf_addr_w => g_bg_buf_addr_w, - g_file_index_arr => g_bg_file_index_arr, - g_file_name_prefix => g_bg_file_name_prefix, - g_diag_block_gen_rst => g_bg_diag_block_gen_rst, - -- User input multiplexer option - g_usr_bypass_xonoff => g_bg_usr_bypass_xonoff, + g_use_bg_buffer_ram => FALSE, -- Tx_seq - g_seq_dat_w => g_bg_seq_dat_w + g_seq_dat_w => g_dp_seq_dat_w ) PORT MAP ( -- System @@ -295,38 +245,31 @@ BEGIN mm_clk => mm_clk, dp_rst => dp_rst, dp_clk => dp_clk, - en_sync => bg_sync, -- MM interface - reg_bg_ctrl_mosi => reg_bg_ctrl_mosi, - reg_bg_ctrl_miso => reg_bg_ctrl_miso, - ram_bg_data_mosi => ram_bg_data_mosi, - ram_bg_data_miso => ram_bg_data_miso, reg_tx_seq_mosi => reg_tx_seq_mosi, reg_tx_seq_miso => reg_tx_seq_miso, -- ST interface - usr_siso_arr => usr_siso_arr, - usr_sosi_arr => usr_sosi_arr, - out_siso_arr => out_siso_arr, - out_sosi_arr => out_sosi_arr + out_siso_arr => bg_siso_arr, + out_sosi_arr => bg_sosi_arr ); - + ----------------------------------------------------------------------------- - -- DIAG Data Buffer + -- DIAG Rx seq with optional Data Buffer ----------------------------------------------------------------------------- u_mms_diag_data_buffer: ENTITY diag_lib.mms_diag_data_buffer GENERIC MAP ( -- Generate configurations g_use_db => g_db_use_db, - g_use_rx_seq => g_db_use_rx_seq, + g_use_rx_seq => TRUE, -- General - g_nof_streams => g_db_nof_streams, + g_nof_streams => 1, -- DB settings - g_data_type => g_db_data_type, - g_data_w => g_db_data_w, + g_data_type => e_data, -- define the sosi field that gets stored: e_data=data, e_complex=im&re, e_real=re, e_imag=im, + g_data_w => c_word_w, -- only capture the lowest c_word_w=32 bits of the g_dp_data_w g_buf_nof_data => g_db_buf_nof_data, - g_buf_use_sync => g_db_buf_use_sync, + g_buf_use_sync => FALSE, -- when TRUE start filling the buffer at the in_sync, else after the last word was read, -- Rx_seq - g_seq_dat_w => g_db_seq_dat_w + g_seq_dat_w => g_dp_seq_dat_w ) PORT MAP ( -- System @@ -343,8 +286,7 @@ BEGIN reg_rx_seq_miso => reg_rx_seq_miso, -- ST interface - in_sync => db_sync, - in_sosi_arr => in_sosi_arr + in_sosi_arr => db_sosi_arr ); END str; -- GitLab