diff --git a/libraries/io/ddr/hdllib.cfg b/libraries/io/ddr/hdllib.cfg index 5e61423acccfd3261bd73ddf9fd3b2b3486dfa4b..888053760366fd20386062fb93a968d311a4e2f3 100644 --- a/libraries/io/ddr/hdllib.cfg +++ b/libraries/io/ddr/hdllib.cfg @@ -1,6 +1,6 @@ hdl_lib_name = io_ddr hdl_library_clause_name = io_ddr_lib -hdl_lib_uses_synth = technology tech_ddr tech_ddr3 common dp diagnostics +hdl_lib_uses_synth = technology tech_ddr tech_ddr3 common dp diag diagnostics hdl_lib_uses_sim = hdl_lib_technology = @@ -16,6 +16,7 @@ synth_files = src/vhdl/io_ddr_reg.vhd src/vhdl/io_ddr.vhd src/vhdl/mms_io_ddr.vhd + src/vhdl/mms_io_ddr_diag.vhd test_bench_files = tb/vhdl/tb_io_ddr.vhd diff --git a/libraries/io/ddr/src/vhdl/mms_io_ddr_diag.vhd b/libraries/io/ddr/src/vhdl/mms_io_ddr_diag.vhd new file mode 100644 index 0000000000000000000000000000000000000000..f8782e879babf0afd1013696e7f1f4000612acef --- /dev/null +++ b/libraries/io/ddr/src/vhdl/mms_io_ddr_diag.vhd @@ -0,0 +1,350 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +-- Purpose: Provide streaming access to IO_DDR using a BG and a DB +-- Description: +-- +-- BG ----> IO_DDR ----> DB +-- | | | +-- | | | +-- MM --+---------+----------+-- +-- + +LIBRARY IEEE, common_lib, dp_lib, diag_lib, technology_lib, tech_ddr_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; +USE diag_lib.diag_pkg.ALL; +USE technology_lib.technology_select_pkg.ALL; +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; + + --------------------------------------------------------------------------- + -- 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 + + --------------------------------------------------------------------------- + -- 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 + ); + PORT ( + --------------------------------------------------------------------------- + -- System + --------------------------------------------------------------------------- + mm_clk : IN STD_LOGIC; + mm_rst : IN STD_LOGIC; + dp_clk : IN STD_LOGIC; + dp_rst : IN STD_LOGIC; + + --------------------------------------------------------------------------- + -- IO_DDR + --------------------------------------------------------------------------- + -- DDR reference clock + ctlr_ref_clk : IN STD_LOGIC; + ctlr_ref_rst : IN STD_LOGIC; + + -- DDR controller clock domain + ctlr_clk_out : OUT STD_LOGIC; + ctlr_rst_out : OUT STD_LOGIC; + + ctlr_clk_in : IN STD_LOGIC; -- connect ctlr_clk_out to ctlr_clk_in at top level to avoid potential delta-cycle differences between the same clock + ctlr_rst_in : IN STD_LOGIC; -- connect ctlr_rst_out to ctlr_rst_in at top level + + -- MM interface + 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; + + term_ctrl_out : OUT t_tech_ddr3_phy_terminationcontrol; + term_ctrl_in : IN t_tech_ddr3_phy_terminationcontrol := c_tech_ddr3_phy_terminationcontrol_rst; + + -- DDR3 PHY external interface + phy3_in : IN t_tech_ddr3_phy_in := c_tech_ddr3_phy_in_x; + phy3_io : INOUT t_tech_ddr3_phy_io; + phy3_ou : OUT t_tech_ddr3_phy_ou; + + -- DDR4 PHY external interface + phy4_in : IN t_tech_ddr4_phy_in := c_tech_ddr4_phy_in_x; + phy4_io : INOUT t_tech_ddr4_phy_io; + phy4_ou : OUT t_tech_ddr4_phy_ou; + + --------------------------------------------------------------------------- + -- DIAG block generator + --------------------------------------------------------------------------- + -- 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 + --------------------------------------------------------------------------- + -- MM interface + reg_data_buf_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- DB control register (one per stream) + reg_data_buf_miso : OUT t_mem_miso; + + ram_data_buf_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- DB buffer RAM (one per streams) + 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) + ); +END mms_io_ddr_diag; + + +ARCHITECTURE str OF mms_io_ddr_diag IS + +BEGIN + + ------------------------------------------------------------------------------ + -- IO_DDR + ------------------------------------------------------------------------------ + u_mms_io_ddr : ENTITY work.mms_io_ddr + GENERIC MAP ( + g_technology => g_io_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 + ) + PORT MAP ( + -- DDR reference clock + ctlr_ref_clk => ctlr_ref_clk, + ctlr_ref_rst => ctlr_ref_rst, + + -- DDR controller clock domain + ctlr_clk_out => ctlr_clk_out, + ctlr_rst_out => ctlr_rst_out, + + ctlr_clk_in => ctlr_clk_in, + ctlr_rst_in => ctlr_rst_in, + + -- MM clock + reset + mm_rst => mm_rst, + mm_clk => mm_clk, + + -- MM interface + reg_io_ddr_mosi => reg_io_ddr_mosi, + reg_io_ddr_miso => reg_io_ddr_miso, + + dvr_clk => dvr_clk, + dvr_rst => dvr_rst, + + -- Write FIFO clock domain + wr_clk => wr_clk, + wr_rst => wr_rst, + + wr_fifo_usedw => wr_fifo_usedw, + wr_sosi => wr_sosi, + wr_siso => wr_siso, + + -- Read FIFO clock domain + rd_clk => rd_clk, + rd_rst => rd_rst, + + rd_fifo_usedw => rd_fifo_usedw, + rd_sosi => rd_sosi, + rd_siso => rd_siso, + + term_ctrl_out => term_ctrl_out, + term_ctrl_in => term_ctrl_in, + + -- DDR3 PHY external interface + phy3_in => phy3_in, + phy3_io => phy3_io, + phy3_ou => phy3_ou, + + -- DDR4 PHY external interface + phy4_in => phy4_in, + phy4_io => phy4_io, + phy4_ou => phy4_ou + ); + + ----------------------------------------------------------------------------- + -- DIAG Block Generator + ----------------------------------------------------------------------------- + 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, + -- General + g_nof_streams => g_bg_nof_streams, + -- 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, + -- Tx_seq + g_seq_dat_w => g_bg_seq_dat_w + ) + PORT MAP ( + -- System + mm_rst => mm_rst, + 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 + ); + + ----------------------------------------------------------------------------- + -- DIAG 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, + -- General + g_nof_streams => g_db_nof_streams, + -- DB settings + g_data_type => g_db_data_type, + g_data_w => g_db_data_w, + g_buf_nof_data => g_db_buf_nof_data, + g_buf_use_sync => g_db_buf_use_sync, + -- Rx_seq + g_seq_dat_w => g_db_seq_dat_w + ) + PORT MAP ( + -- System + mm_rst => mm_rst, + mm_clk => mm_clk, + dp_rst => dp_rst, + dp_clk => dp_clk, + -- MM interface + reg_data_buf_mosi => reg_data_buf_mosi, + reg_data_buf_miso => reg_data_buf_miso, + ram_data_buf_mosi => ram_data_buf_mosi, + ram_data_buf_miso => ram_data_buf_miso, + reg_rx_seq_mosi => reg_rx_seq_mosi, + reg_rx_seq_miso => reg_rx_seq_miso, + + -- ST interface + in_sync => db_sync, + in_sosi_arr => in_sosi_arr + ); + +END str;