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

Provide streaming access to IO_DDR using a Tx seq and a Rx seq with optional DB RAM.

parent 3bd9c874
No related branches found
No related tags found
No related merge requests found
...@@ -19,14 +19,29 @@ ...@@ -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: -- Description:
-- -- The BG Tx seq stream writes the DDR and the read stream is passed on to the DB Rx seq. The BG
-- BG ----> IO_DDR ----> DB -- 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.
-- | | |
-- MM --+---------+----------+--
-- --
-- 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; LIBRARY IEEE, common_lib, dp_lib, diag_lib, technology_lib, tech_ddr_lib;
USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_1164.ALL;
...@@ -40,68 +55,28 @@ USE tech_ddr_lib.tech_ddr_pkg.ALL; ...@@ -40,68 +55,28 @@ USE tech_ddr_lib.tech_ddr_pkg.ALL;
ENTITY mms_io_ddr_diag IS ENTITY mms_io_ddr_diag IS
GENERIC ( GENERIC (
--------------------------------------------------------------------------- -- System
-- IO_DDR g_technology : NATURAL := c_tech_select_default;
---------------------------------------------------------------------------
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;
--------------------------------------------------------------------------- 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
-- DIAG block generator 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
-- Generate configurations
g_bg_use_usr_input : BOOLEAN := FALSE; -- IO_DDR
g_bg_use_bg : BOOLEAN := TRUE; g_io_tech_ddr : t_c_tech_ddr;
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
---------------------------------------------------------------------------
-- DIAG data buffer -- DIAG data buffer
--------------------------------------------------------------------------- g_db_use_db : BOOLEAN := FALSE;
-- Generate configurations g_db_buf_nof_data : NATURAL := 1024 -- nof words per data buffer
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
); );
PORT ( PORT (
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- System -- System
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
mm_clk : IN STD_LOGIC; mm_rst : IN STD_LOGIC;
mm_rst : IN STD_LOGIC; mm_clk : IN STD_LOGIC;
dp_clk : IN STD_LOGIC; dp_rst : 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 -- IO_DDR
...@@ -121,25 +96,11 @@ ENTITY mms_io_ddr_diag IS ...@@ -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_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- register for DDR controller status info
reg_io_ddr_miso : OUT t_mem_miso; reg_io_ddr_miso : OUT t_mem_miso;
dvr_clk : IN STD_LOGIC; -- Write / read FIFO status for monitoring purposes (in dp_clk domain)
dvr_rst : IN STD_LOGIC; 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);
-- 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;
-- DDR3 pass on termination control from master to slave controller
term_ctrl_out : OUT t_tech_ddr3_phy_terminationcontrol; term_ctrl_out : OUT t_tech_ddr3_phy_terminationcontrol;
term_ctrl_in : IN t_tech_ddr3_phy_terminationcontrol := c_tech_ddr3_phy_terminationcontrol_rst; 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 ...@@ -154,24 +115,14 @@ ENTITY mms_io_ddr_diag IS
phy4_ou : OUT t_tech_ddr4_phy_ou; phy4_ou : OUT t_tech_ddr4_phy_ou;
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- DIAG block generator -- DIAG Tx seq
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- MM interface -- 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_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; 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 -- MM interface
reg_data_buf_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- DB control register (one per stream) 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 ...@@ -181,17 +132,23 @@ ENTITY mms_io_ddr_diag IS
ram_data_buf_miso : OUT t_mem_miso; 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_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- Rx seq control register (one per streams)
reg_rx_seq_miso : OUT t_mem_miso; 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)
); );
END mms_io_ddr_diag; END mms_io_ddr_diag;
ARCHITECTURE str OF mms_io_ddr_diag IS 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 BEGIN
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
...@@ -199,19 +156,19 @@ BEGIN ...@@ -199,19 +156,19 @@ BEGIN
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
u_mms_io_ddr : ENTITY work.mms_io_ddr u_mms_io_ddr : ENTITY work.mms_io_ddr
GENERIC MAP ( GENERIC MAP (
g_technology => g_io_technology, g_technology => g_technology,
g_tech_ddr => g_io_tech_ddr, g_tech_ddr => g_io_tech_ddr,
g_cross_domain_dvr_ctlr => g_io_cross_domain_dvr_ctlr, g_cross_domain_dvr_ctlr => TRUE, -- cross between mm_clk and ctlr_clk_in
g_cross_domain_delay_len => g_io_cross_domain_delay_len, g_cross_domain_delay_len => c_meta_delay_len,
g_wr_data_w => g_io_wr_data_w, g_wr_data_w => g_dp_data_w,
g_wr_fifo_depth => g_io_wr_fifo_depth, g_wr_fifo_depth => c_io_wr_fifo_depth,
g_rd_fifo_depth => g_io_rd_fifo_depth, g_rd_fifo_depth => c_io_rd_fifo_depth,
g_rd_fifo_af_margin => g_io_rd_fifo_af_margin, g_rd_fifo_af_margin => c_io_rd_fifo_af_margin,
g_rd_data_w => g_io_rd_data_w, g_rd_data_w => g_dp_data_w,
g_wr_flush_mode => g_io_wr_flush_mode, g_wr_flush_mode => "VAL",
g_wr_flush_use_channel => g_io_wr_flush_use_channel, g_wr_flush_use_channel => FALSE,
g_wr_flush_start_channel => g_io_wr_flush_start_channel, g_wr_flush_start_channel => 0,
g_wr_flush_nof_channels => g_io_wr_flush_nof_channels g_wr_flush_nof_channels => 1
) )
PORT MAP ( PORT MAP (
-- DDR reference clock -- DDR reference clock
...@@ -233,24 +190,24 @@ BEGIN ...@@ -233,24 +190,24 @@ BEGIN
reg_io_ddr_mosi => reg_io_ddr_mosi, reg_io_ddr_mosi => reg_io_ddr_mosi,
reg_io_ddr_miso => reg_io_ddr_miso, reg_io_ddr_miso => reg_io_ddr_miso,
dvr_clk => dvr_clk, dvr_clk => mm_clk,
dvr_rst => dvr_rst, dvr_rst => mm_rst,
-- Write FIFO clock domain -- Write FIFO clock domain
wr_clk => wr_clk, wr_clk => dp_clk,
wr_rst => wr_rst, wr_rst => dp_rst,
wr_fifo_usedw => wr_fifo_usedw, wr_fifo_usedw => wr_fifo_usedw,
wr_sosi => wr_sosi, wr_sosi => bg_sosi_arr(0),
wr_siso => wr_siso, wr_siso => bg_siso_arr(0),
-- Read FIFO clock domain -- Read FIFO clock domain
rd_clk => rd_clk, rd_clk => dp_clk,
rd_rst => rd_rst, rd_rst => dp_rst,
rd_fifo_usedw => rd_fifo_usedw, rd_fifo_usedw => rd_fifo_usedw,
rd_sosi => rd_sosi, rd_sosi => db_sosi_arr(0),
rd_siso => rd_siso, rd_siso => db_siso_arr(0),
term_ctrl_out => term_ctrl_out, term_ctrl_out => term_ctrl_out,
term_ctrl_in => term_ctrl_in, term_ctrl_in => term_ctrl_in,
...@@ -267,27 +224,20 @@ BEGIN ...@@ -267,27 +224,20 @@ BEGIN
); );
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- DIAG Block Generator -- DIAG Tx seq
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
u_mms_diag_block_gen: ENTITY diag_lib.mms_diag_block_gen u_mms_diag_block_gen: ENTITY diag_lib.mms_diag_block_gen
GENERIC MAP ( GENERIC MAP (
-- Generate configurations -- Generate configurations
g_use_usr_input => g_bg_use_usr_input, g_use_usr_input => FALSE,
g_use_bg => g_bg_use_bg, g_use_bg => FALSE,
g_use_tx_seq => g_bg_use_tx_seq, g_use_tx_seq => TRUE,
-- General -- General
g_nof_streams => g_bg_nof_streams, g_nof_streams => 1,
-- BG settings -- BG settings
g_use_bg_buffer_ram => g_bg_use_bg_buffer_ram, g_use_bg_buffer_ram => FALSE,
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,
-- Tx_seq -- Tx_seq
g_seq_dat_w => g_bg_seq_dat_w g_seq_dat_w => g_dp_seq_dat_w
) )
PORT MAP ( PORT MAP (
-- System -- System
...@@ -295,38 +245,31 @@ BEGIN ...@@ -295,38 +245,31 @@ BEGIN
mm_clk => mm_clk, mm_clk => mm_clk,
dp_rst => dp_rst, dp_rst => dp_rst,
dp_clk => dp_clk, dp_clk => dp_clk,
en_sync => bg_sync,
-- MM interface -- 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_mosi => reg_tx_seq_mosi,
reg_tx_seq_miso => reg_tx_seq_miso, reg_tx_seq_miso => reg_tx_seq_miso,
-- ST interface -- ST interface
usr_siso_arr => usr_siso_arr, out_siso_arr => bg_siso_arr,
usr_sosi_arr => usr_sosi_arr, out_sosi_arr => bg_sosi_arr
out_siso_arr => out_siso_arr,
out_sosi_arr => out_sosi_arr
); );
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- DIAG Data Buffer -- DIAG Rx seq with optional Data Buffer
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
u_mms_diag_data_buffer: ENTITY diag_lib.mms_diag_data_buffer u_mms_diag_data_buffer: ENTITY diag_lib.mms_diag_data_buffer
GENERIC MAP ( GENERIC MAP (
-- Generate configurations -- Generate configurations
g_use_db => g_db_use_db, g_use_db => g_db_use_db,
g_use_rx_seq => g_db_use_rx_seq, g_use_rx_seq => TRUE,
-- General -- General
g_nof_streams => g_db_nof_streams, g_nof_streams => 1,
-- DB settings -- DB settings
g_data_type => g_db_data_type, 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 => g_db_data_w, 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_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 -- Rx_seq
g_seq_dat_w => g_db_seq_dat_w g_seq_dat_w => g_dp_seq_dat_w
) )
PORT MAP ( PORT MAP (
-- System -- System
...@@ -343,8 +286,7 @@ BEGIN ...@@ -343,8 +286,7 @@ BEGIN
reg_rx_seq_miso => reg_rx_seq_miso, reg_rx_seq_miso => reg_rx_seq_miso,
-- ST interface -- ST interface
in_sync => db_sync, in_sosi_arr => db_sosi_arr
in_sosi_arr => in_sosi_arr
); );
END str; END str;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment