Skip to content
Snippets Groups Projects
Commit 41d27835 authored by Pepping's avatar Pepping
Browse files

Initial commit

parent 7d5d0076
No related branches found
No related tags found
No related merge requests found
-------------------------------------------------------------------------------
--
-- Copyright (C) 2011
-- 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: MM data buffer and Rx seq for multiple parallel SOSI streams
-- Description:
-- . g_use_db
-- The mms_diag_data_buffer can capture data from an input stream in a data
-- buffer when g_use_db=TRUE. Dependend on g_buf_use_sync the data buffer
-- is rewritten after each in_sync or when the last word was read via MM.
-- . g_use_rx_seq
-- The mms_diag_data_buffer can continously verify a input Rx data sequence
-- when g_use_rx_seq=TRUE. The expected sequence data is typically generated
-- by an remote upstream tx_seq source.
-- . The advantage of the rx_seq is that is can continously verify the
-- correctness of all rx data in hardware, whereas the DB can only take a
-- snapshot that then needs to be examined via MM. The advandage of the DB
-- is that it can take a snapshot of the values of the received data. The
-- DB requires RAM resources and the rx_seq does not.
--
-- Block diagram:
--
-- g_use_db
-- g_buf_use_sync
-- .
-- . g_use_tx_seq
-- . .
-- . .
-- /-------------> Rx seq
-- | . |
-- in_sosi_arr -----*---> DB RAM |
-- in_sync -------------> DB reg |
-- || |
-- || |
-- MM ================================
--
-- Remark:
-- . A nice new feature would be to continuously write the DB and to stop
-- writting it on a trigger. This trigger can then eg. be when the rx_seq
-- detects an error. By delaying the trigger somewhat it the DB can then
-- capture some data before and after the trigger event.
LIBRARY IEEE, common_lib, technology_lib, dp_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 work.diag_pkg.ALL;
USE technology_lib.technology_select_pkg.ALL;
ENTITY mms_diag_data_buffer_dev IS
GENERIC (
g_technology : NATURAL := c_tech_select_default;
-- Generate configurationsc_diag_db
g_use_db : BOOLEAN := TRUE;
g_use_rx_seq : BOOLEAN := FALSE;
-- General
g_nof_streams : POSITIVE := 16; -- each stream gets an data buffer
-- DB settings
g_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_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_buf_nof_data : NATURAL := 1024; -- nof words per data buffer
g_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_use_steps : BOOLEAN := FALSE;
g_nof_steps : NATURAL := c_diag_seq_rx_reg_nof_steps;
g_seq_dat_w : NATURAL := 32 -- >= 1, test sequence data width. Choose g_seq_dat_w <= g_data_w
);
PORT (
-- System
mm_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
dp_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC;
-- 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
in_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_nof_streams-1 DOWNTO 0)
);
END mms_diag_data_buffer_dev;
ARCHITECTURE str OF mms_diag_data_buffer_dev IS
CONSTANT c_buf_mm_factor : NATURAL := ceil_div(g_data_w, c_word_w);
CONSTANT c_buf_nof_data_mm : NATURAL := g_buf_nof_data*c_buf_mm_factor;
CONSTANT c_buf_adr_w : NATURAL := ceil_log2(c_buf_nof_data_mm);
CONSTANT c_reg_adr_w : NATURAL := c_diag_db_dev_reg_adr_w;
TYPE t_data_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0);
SIGNAL in_data_arr : t_data_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL ram_data_buf_mosi_arr : t_mem_mosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL ram_data_buf_miso_arr : t_mem_miso_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL reg_data_buf_mosi_arr : t_mem_mosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL reg_data_buf_miso_arr : t_mem_miso_arr(g_nof_streams-1 DOWNTO 0);
BEGIN
no_db : IF g_use_db=FALSE GENERATE
ram_data_buf_miso <= c_mem_miso_rst;
reg_data_buf_miso <= c_mem_miso_rst;
END GENERATE;
gen_db : IF g_use_db=TRUE GENERATE
-- Combine the internal array of mm interfaces for the data_buf to one array that is connected to the port of the MM bus
u_mem_mux_data_buf : ENTITY common_lib.common_mem_mux
GENERIC MAP (
g_nof_mosi => g_nof_streams,
g_mult_addr_w => c_buf_adr_w
)
PORT MAP (
mosi => ram_data_buf_mosi,
miso => ram_data_buf_miso,
mosi_arr => ram_data_buf_mosi_arr,
miso_arr => ram_data_buf_miso_arr
);
u_mem_mux_reg : ENTITY common_lib.common_mem_mux
GENERIC MAP (
g_nof_mosi => g_nof_streams,
g_mult_addr_w => c_reg_adr_w
)
PORT MAP (
mosi => reg_data_buf_mosi,
miso => reg_data_buf_miso,
mosi_arr => reg_data_buf_mosi_arr,
miso_arr => reg_data_buf_miso_arr
);
gen_stream : FOR I IN 0 TO g_nof_streams-1 GENERATE
in_data_arr(I) <= in_sosi_arr(I).im(g_data_w/2-1 DOWNTO 0) & in_sosi_arr(I).re(g_data_w/2-1 DOWNTO 0) WHEN g_data_type=e_complex ELSE
in_sosi_arr(I).re(g_data_w-1 DOWNTO 0) WHEN g_data_type=e_real ELSE
in_sosi_arr(I).im(g_data_w-1 DOWNTO 0) WHEN g_data_type=e_imag ELSE
in_sosi_arr(I).data(g_data_w-1 DOWNTO 0); -- g_data_type=e_data is default
u_diag_data_buffer : ENTITY work.diag_data_buffer_dev
GENERIC MAP (
g_technology => g_technology,
g_data_w => g_data_w,
g_nof_data => g_buf_nof_data,
g_use_in_sync => g_buf_use_sync -- when TRUE start filling the buffer at the in_sync, else after the last word was read
)
PORT MAP (
-- Memory-mapped clock domain
mm_rst => mm_rst,
mm_clk => mm_clk,
ram_mm_mosi => ram_data_buf_mosi_arr(I),
ram_mm_miso => ram_data_buf_miso_arr(I),
reg_mm_mosi => reg_data_buf_mosi_arr(I),
reg_mm_miso => reg_data_buf_miso_arr(I),
-- Streaming clock domain
st_rst => dp_rst,
st_clk => dp_clk,
in_data => in_data_arr(I),
in_sync => in_sync,
in_val => in_sosi_arr(I).valid
);
END GENERATE;
END GENERATE;
no_rx_seq : IF g_use_rx_seq=FALSE GENERATE
reg_rx_seq_miso <= c_mem_miso_rst;
END GENERATE;
gen_rx_seq : IF g_use_rx_seq=TRUE GENERATE
u_mms_diag_rx_seq : ENTITY work.mms_diag_rx_seq
GENERIC MAP (
g_nof_streams => g_nof_streams,
g_use_steps => g_use_steps,
g_nof_steps => g_nof_steps,
g_seq_dat_w => g_seq_dat_w, -- >= 1, test sequence data width
g_data_w => g_data_w -- >= g_seq_dat_w, user data width
)
PORT MAP (
-- Clocks and reset
mm_rst => mm_rst,
mm_clk => mm_clk,
dp_rst => dp_rst,
dp_clk => dp_clk,
-- Memory Mapped Slave
reg_mosi => reg_rx_seq_mosi, -- multiplexed port for g_nof_streams MM control/status registers
reg_miso => reg_rx_seq_miso,
-- Streaming interface
rx_snk_in_arr => in_sosi_arr
);
END GENERATE;
END str;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment