Skip to content
Snippets Groups Projects

Resolve L2SDP-282

Merged Reinier van der Walle requested to merge L2SDP-182 into master
6 files
+ 874
0
Compare changes
  • Side-by-side
  • Inline

Files

 
-------------------------------------------------------------------------------
 
--
 
-- Copyright 2021
 
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
 
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
 
--
 
-- Licensed under the Apache License, Version 2.0 (the "License");
 
-- you may not use this file except in compliance with the License.
 
-- You may obtain a copy of the License at
 
--
 
-- http://www.apache.org/licenses/LICENSE-2.0
 
--
 
-- Unless required by applicable law or agreed to in writing, software
 
-- distributed under the License is distributed on an "AS IS" BASIS,
 
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
-- See the License for the specific language governing permissions and
 
-- limitations under the License.
 
--
 
-------------------------------------------------------------------------------
 
 
-------------------------------------------------------------------------------
 
-- Author : R vd Walle
 
-- Purpose: Reorder block of data in time
 
-- Description:
 
-- Select g_nof_ch_sel complex samples from an input block of g_nof_ch_in
 
-- complex samples. The subband select map is arbitrary (any order and also
 
-- duplicates) and can be set via the MM interface.
 
-- The timing of sync and BSN is passed on in parallel.
 
-- Remarks:
 
-- . The g_nof_ch_sel can be <= g_nof_ch_in <= period size, where g_nof_ch_in
 
-- is the number of valid samples from sop to eop. If g_nof_ch_in is equal to
 
-- the period size then there are no data invalid cycles during a period.
 
-- Note that if g_nof_ch_in is less than the period size, then g_nof_ch_sel
 
-- can be larger than g_nof_ch_in to select channels multiple times.
 
-- . The g_nof_ch_in defines the number of complex input data words in a data
 
-- period, so 1 complex sample via sosi.im and sosi.re.
 
 
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 technology_lib.technology_select_pkg.ALL;
 
 
ENTITY reorder_col_select IS
 
GENERIC (
 
g_technology : NATURAL := c_tech_select_default;
 
g_dsp_data_w : NATURAL := 18;
 
g_nof_ch_in : NATURAL := 1024;
 
g_nof_ch_sel : NATURAL := 12; -- g_nof_ch_sel < g_nof_ch_in
 
g_use_complex : BOOLEAN := TRUE
 
);
 
PORT (
 
dp_rst : IN STD_LOGIC;
 
dp_clk : IN STD_LOGIC;
 
 
-- Memory Mapped
 
col_select_mosi : IN t_mem_mosi; -- channel select control on DP clk
 
col_select_miso : OUT t_mem_miso := c_mem_miso_rst; -- only waitrequest is used
 
 
-- Streaming
 
input_sosi : IN t_dp_sosi; -- complex input
 
 
output_sosi : OUT t_dp_sosi -- selected complex output with flow control
 
);
 
END reorder_col_select;
 
 
 
ARCHITECTURE str OF reorder_col_select IS
 
 
CONSTANT c_store_buf : t_c_mem := (latency => 1,
 
adr_w => ceil_log2(g_nof_ch_in),
 
dat_w => c_nof_complex*g_dsp_data_w,
 
nof_dat => g_nof_ch_in,
 
init_sl => '0'); -- ST side : stat_mosi
 
 
 
CONSTANT c_data_nof_pages : NATURAL := 2; -- fixed dual page SS
 
CONSTANT c_info_nof_pages : NATURAL := 2; -- fixed, fits the dual page block latency and logic latency of the SS
 
CONSTANT c_retrieve_lat : NATURAL := c_store_buf.latency + 1; -- = 2 rd_latency from waitrequest + store_buf latency
 
 
SIGNAL info_sop_wr_en : STD_LOGIC_VECTOR(c_info_nof_pages-1 DOWNTO 0);
 
SIGNAL info_eop_wr_en : STD_LOGIC_VECTOR(c_info_nof_pages-1 DOWNTO 0);
 
SIGNAL info_sosi : t_dp_sosi;
 
 
SIGNAL store_mosi : t_mem_mosi;
 
SIGNAL store_done : STD_LOGIC;
 
 
SIGNAL i_col_select_miso : t_mem_miso := c_mem_miso_rst;
 
 
SIGNAL ch_cnt : INTEGER RANGE 0 TO g_nof_ch_sel-1;
 
SIGNAL nxt_ch_cnt : INTEGER;
 
SIGNAL retrieve_sosi : t_dp_sosi;
 
SIGNAL retrieve_en : STD_LOGIC;
 
SIGNAL retrieve_sop_dly : STD_LOGIC_VECTOR(0 TO c_retrieve_lat);
 
SIGNAL retrieve_eop_dly : STD_LOGIC_VECTOR(0 TO c_retrieve_lat);
 
 
 
BEGIN
 
 
u_store : ENTITY work.reorder_store
 
GENERIC MAP (
 
g_dsp_data_w => g_dsp_data_w,
 
g_nof_ch_in => g_nof_ch_in,
 
g_use_complex => g_use_complex
 
)
 
PORT MAP (
 
rst => dp_rst,
 
clk => dp_clk,
 
 
-- Streaming
 
input_sosi => input_sosi,
 
 
-- Timing
 
store_done => store_done,
 
 
-- Write store buffer control
 
store_mosi => store_mosi
 
);
 
 
u_store_buf : ENTITY common_lib.common_paged_ram_r_w
 
GENERIC MAP (
 
g_technology => g_technology,
 
g_str => "use_adr",
 
g_data_w => c_store_buf.dat_w,
 
g_nof_pages => c_data_nof_pages,
 
g_page_sz => c_store_buf.nof_dat,
 
g_wr_start_page => 0,
 
g_rd_start_page => 1,
 
g_rd_latency => 1
 
)
 
PORT MAP (
 
rst => dp_rst,
 
clk => dp_clk,
 
wr_next_page => store_done,
 
wr_adr => store_mosi.address(c_store_buf.adr_w-1 DOWNTO 0),
 
wr_en => store_mosi.wr,
 
wr_dat => store_mosi.wrdata(c_store_buf.dat_w-1 DOWNTO 0),
 
rd_next_page => store_done,
 
rd_adr => col_select_mosi.address(c_store_buf.adr_w-1 DOWNTO 0),
 
rd_en => col_select_mosi.rd,
 
rd_dat => i_col_select_miso.rddata(c_store_buf.dat_w-1 DOWNTO 0),
 
rd_val => i_col_select_miso.rdval
 
);
 
 
 
-- Enable retrieve when a block has been stored, disable retrieve when the block has been output
 
u_retrieve_en : ENTITY common_lib.common_switch
 
GENERIC MAP (
 
g_rst_level => '0',
 
g_priority_lo => FALSE, -- store_done has priority over nxt_retrieve_done when they occur simultaneously
 
g_or_high => TRUE,
 
g_and_low => FALSE
 
)
 
PORT MAP (
 
rst => dp_rst,
 
clk => dp_clk,
 
switch_high => store_done,
 
switch_low => retrieve_eop_dly(0),
 
out_level => retrieve_en
 
);
 
 
p_reg : PROCESS (dp_clk, dp_rst)
 
BEGIN
 
IF dp_rst = '1' THEN
 
-- Internal registers.
 
ch_cnt <= 0;
 
retrieve_sop_dly(1 TO c_retrieve_lat) <= (OTHERS=>'0');
 
retrieve_eop_dly(1 TO c_retrieve_lat) <= (OTHERS=>'0');
 
ELSIF rising_edge(dp_clk) THEN
 
-- Internal registers.
 
ch_cnt <= nxt_ch_cnt;
 
retrieve_sop_dly(1 TO c_retrieve_lat) <= retrieve_sop_dly(0 TO c_retrieve_lat-1);
 
retrieve_eop_dly(1 TO c_retrieve_lat) <= retrieve_eop_dly(0 TO c_retrieve_lat-1);
 
END IF;
 
END PROCESS;
 
 
p_ch_cnt : PROCESS (retrieve_en, ch_cnt)
 
BEGIN
 
nxt_ch_cnt <= ch_cnt;
 
col_select_miso.waitrequest <= '1';
 
 
IF retrieve_en='1' THEN
 
col_select_miso.waitrequest <= '0';
 
IF ch_cnt=g_nof_ch_sel-1 THEN
 
nxt_ch_cnt <= 0;
 
ELSE
 
nxt_ch_cnt <= ch_cnt + 1;
 
END IF;
 
END IF;
 
 
END PROCESS;
 
 
-- Optional SS output frame control
 
retrieve_sop_dly(0) <= '1' WHEN retrieve_en='1' AND ch_cnt=0 ELSE '0';
 
retrieve_eop_dly(0) <= '1' WHEN retrieve_en='1' AND ch_cnt=g_nof_ch_sel-1 ELSE '0';
 
 
retrieve_sosi.re <= RESIZE_DP_DSP_DATA(i_col_select_miso.rddata( g_dsp_data_w-1 DOWNTO 0));
 
retrieve_sosi.im <= RESIZE_DP_DSP_DATA(i_col_select_miso.rddata(c_nof_complex*g_dsp_data_w-1 DOWNTO g_dsp_data_w));
 
retrieve_sosi.data <= RESIZE_DP_DATA(i_col_select_miso.rddata( c_nof_complex*g_dsp_data_w-1 DOWNTO 0));
 
retrieve_sosi.valid <= i_col_select_miso.rdval;
 
retrieve_sosi.sop <= retrieve_sop_dly(c_retrieve_lat);
 
retrieve_sosi.eop <= retrieve_eop_dly(c_retrieve_lat);
 
-- Page delay the input_sosi info (sync, BSN, channel at sop and err, empty at eop) and combine it with the retrieved SS data to get the output_sosi
 
info_sop_wr_en <= input_sosi.sop & store_done;
 
info_eop_wr_en <= input_sosi.eop & store_done;
 
 
u_info_sosi : ENTITY dp_lib.dp_paged_sop_eop_reg
 
GENERIC MAP (
 
g_nof_pages => c_info_nof_pages
 
)
 
PORT MAP (
 
rst => dp_rst,
 
clk => dp_clk,
 
-- page write enable ctrl
 
sop_wr_en => info_sop_wr_en,
 
eop_wr_en => info_eop_wr_en,
 
-- ST sink
 
snk_in => input_sosi,
 
-- ST source
 
src_out => info_sosi
 
);
 
 
output_sosi <= func_dp_stream_combine_info_and_data(info_sosi, retrieve_sosi);
 
 
END str;
 
Loading