From 564e9d007f04588110ea754a58037e660695f9ba Mon Sep 17 00:00:00 2001 From: Pepping <pepping> Date: Fri, 19 Jun 2015 09:44:10 +0000 Subject: [PATCH] Copied from old tree --- .../base/reorder/src/vhdl/reorder_row.vhd | 233 ++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 libraries/base/reorder/src/vhdl/reorder_row.vhd diff --git a/libraries/base/reorder/src/vhdl/reorder_row.vhd b/libraries/base/reorder/src/vhdl/reorder_row.vhd new file mode 100644 index 0000000000..a717bcc85e --- /dev/null +++ b/libraries/base/reorder/src/vhdl/reorder_row.vhd @@ -0,0 +1,233 @@ +------------------------------------------------------------------------------- +-- +-- 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/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_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; + +-- Purpose: Subband Select Reordering. +-- +-- Description: For every clock cycle within a frame a different output +-- configuration can be created, based on the available inputs. +-- +-- The selection buffer stores a set of selection words. Each +-- selection word defines the mapping of the inputs to the outputs +-- for a single clock cylce. +-- +-- Remarks: +-- + +ENTITY ss_reorder IS + GENERIC ( + g_dsp_data_w : NATURAL := 16; + g_frame_size : NATURAL := 256; + g_nof_inputs : NATURAL := 8; + g_nof_outputs : NATURAL := 16; + g_ram_init_file : STRING := "../../../src/data/select_buf"; -- or "UNUSED" + g_pipeline_in : NATURAL := 1; -- pipeline in_data + g_pipeline_in_m : NATURAL := 1; -- pipeline in_data for M-fold fan out + g_pipeline_out : NATURAL := 1 -- pipeline out_data + ); + PORT ( + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; + dp_rst : IN STD_LOGIC; + dp_clk : IN STD_LOGIC; + + -- Memory Mapped + ram_ss_reorder_mosi : IN t_mem_mosi; + ram_ss_reorder_miso : OUT t_mem_miso; + + -- Streaming + input_sosi_arr : IN t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0); + output_sosi_arr : OUT t_dp_sosi_arr(g_nof_outputs-1 DOWNTO 0); + output_siso_arr : IN t_dp_siso_arr(g_nof_outputs-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy) + ); +END ss_reorder; + +ARCHITECTURE str OF ss_reorder IS + + CONSTANT c_sel_buf_read_lat : NATURAL := 1; -- Latency introduced by the counter. + CONSTANT c_tot_pipeline : NATURAL := g_pipeline_in + g_pipeline_in_m + g_pipeline_out + c_sel_buf_read_lat; + + CONSTANT c_select_w : NATURAL := ceil_log2(g_nof_inputs); + CONSTANT c_select_word_w : NATURAL := c_select_w*g_nof_outputs; + CONSTANT c_nof_mm_regs_per_sel : NATURAL := ceil_div(c_select_word_w, c_word_w); + CONSTANT c_mem_dat_w_mm : NATURAL := sel_a_b(c_select_word_w <= c_word_w, c_select_word_w, c_word_w); + CONSTANT c_mem_nof_dat_mm : NATURAL := 2**(true_log2(c_nof_mm_regs_per_sel))*g_frame_size; + CONSTANT c_mem_dat_w_dp : NATURAL := 2**(ceil_log2(c_select_word_w)); + + CONSTANT c_select_buf_mm : t_c_mem := (latency => 1, + adr_w => ceil_log2(c_mem_nof_dat_mm), + dat_w => c_mem_dat_w_mm, + nof_dat => c_mem_nof_dat_mm, + init_sl => '0'); + + + CONSTANT c_select_buf_dp : t_c_mem := (latency => 1, + adr_w => ceil_log2(g_frame_size), + dat_w => c_mem_dat_w_dp, + nof_dat => g_frame_size, + init_sl => '0'); + + CONSTANT c_data_w : NATURAL := g_dsp_data_w*c_nof_complex; + CONSTANT c_mem_ratio_w : NATURAL := c_mem_dat_w_dp/c_mem_dat_w_mm; + + TYPE t_dp_sosi_2arr IS ARRAY (INTEGER RANGE <>) OF t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0); + + TYPE reg_type IS RECORD + pipe_sosi_2arr : t_dp_sosi_2arr(c_tot_pipeline-1 DOWNTO 0); + output_sosi_arr : t_dp_sosi_arr(g_nof_outputs-1 DOWNTO 0); + END RECORD; + + SIGNAL r, rin : reg_type; + + SIGNAL reorder_in_dat : STD_LOGIC_VECTOR(g_nof_inputs*c_data_w-1 DOWNTO 0); + SIGNAL reorder_out_dat : STD_LOGIC_VECTOR(g_nof_outputs*c_data_w-1 DOWNTO 0); + SIGNAL reorder_select : STD_LOGIC_VECTOR(c_mem_dat_w_dp-1 DOWNTO 0); + --SIGNAL reorder_select : STD_LOGIC_VECTOR(g_nof_outputs*c_select_w-1 DOWNTO 0); + SIGNAL reorder_chan_cnt : STD_LOGIC_VECTOR(c_select_buf_dp.adr_w-1 DOWNTO 0); + +BEGIN + --------------------------------------------------------------- + -- PREPARE THE INPUT DATA. + -- + -- Use a delayed version of the input data to correct for the + -- delay that is introduced by the read latency of the + -- selection buffer. + --------------------------------------------------------------- + gen_input : FOR I IN g_nof_inputs-1 DOWNTO 0 GENERATE + reorder_in_dat((I+1)*c_data_w-1 DOWNTO I*c_data_w) <= r.pipe_sosi_2arr(0)(I).im(g_dsp_data_w-1 DOWNTO 0) & + r.pipe_sosi_2arr(0)(I).re(g_dsp_data_w-1 DOWNTO 0); + END GENERATE; + + --------------------------------------------------------------- + -- EXECUTE SELECTION + -- + -- Selection is performed based on the setting of the + -- reorder_select signal. + --------------------------------------------------------------- + u_reorder : ENTITY common_lib.common_select_m_symbols + GENERIC MAP ( + g_nof_input => g_nof_inputs, + g_nof_output => g_nof_outputs, + g_symbol_w => c_nof_complex*g_dsp_data_w, + g_pipeline_in => g_pipeline_in, + g_pipeline_in_m => g_pipeline_in_m, + g_pipeline_out => g_pipeline_out + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + in_data => reorder_in_dat, + in_select => reorder_select(g_nof_outputs*c_select_w-1 DOWNTO 0), + out_data => reorder_out_dat + ); + + --------------------------------------------------------------- + -- SELECTION BUFFER + -- + -- Buffer containing the selection words for a complete frame. + --------------------------------------------------------------- + u_select_buf : ENTITY common_lib.common_ram_crw_crw_ratio + GENERIC MAP( + g_ram_a => c_select_buf_mm, + g_ram_b => c_select_buf_dp, + g_init_file => g_ram_init_file + ) + PORT MAP ( + rst_a => mm_rst, + clk_a => mm_clk, + wr_en_a => ram_ss_reorder_mosi.wr, + wr_dat_a => ram_ss_reorder_mosi.wrdata(c_select_buf_mm.dat_w-1 DOWNTO 0), + adr_a => ram_ss_reorder_mosi.address(c_select_buf_mm.adr_w-1 DOWNTO 0), + rd_en_a => ram_ss_reorder_mosi.rd, + rd_dat_a => ram_ss_reorder_miso.rddata(c_select_buf_mm.dat_w-1 DOWNTO 0), + rd_val_a => ram_ss_reorder_miso.rdval, + + rst_b => dp_rst, + clk_b => dp_clk, + wr_en_b => '0', + wr_dat_b => (OTHERS => '0'), + adr_b => reorder_chan_cnt, + rd_dat_b => reorder_select, + rd_val_b => OPEN + ); + + --------------------------------------------------------------- + -- ADDRESS COUNTER + -- + -- Counter that addresses the selection buffer + --------------------------------------------------------------- + u_adr_chn_cnt : ENTITY common_lib.common_counter + GENERIC MAP( + g_latency => 1, + g_init => 0, + g_width => c_select_buf_dp.adr_w, + g_max => g_frame_size + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + cnt_en => input_sosi_arr(0).valid, + cnt_clr => input_sosi_arr(0).eop, + count => reorder_chan_cnt + ); + + --------------------------------------------------------------- + -- REGISTERING AND PIPELINING + -- + -- This process takes care of registering the incoming SOSI + -- array and the pipelining for all SOSI control fields. + -- Also the data-output of the select_m_symbols block is merged + -- here with the rest of the pipelined SOSI signals. + --------------------------------------------------------------- + comb : PROCESS(r, input_sosi_arr, reorder_out_dat) + VARIABLE v : reg_type; + BEGIN + v := r; + v.pipe_sosi_2arr(0) := input_sosi_arr; + v.pipe_sosi_2arr(c_tot_pipeline-1 DOWNTO 1) := r.pipe_sosi_2arr(c_tot_pipeline-2 DOWNTO 0); + + -- Merge data output to the outgoing SOSI record. + FOR I IN g_nof_outputs-1 DOWNTO 0 LOOP + v.output_sosi_arr(I) := r.pipe_sosi_2arr(c_tot_pipeline-1)(0); + v.output_sosi_arr(I).im := RESIZE_DP_DSP_DATA(reorder_out_dat((I+1)*c_data_w-1 DOWNTO I*c_data_w + g_dsp_data_w)); + v.output_sosi_arr(I).re := RESIZE_DP_DSP_DATA(reorder_out_dat((I+1)*c_data_w-g_dsp_data_w-1 DOWNTO I*c_data_w)); + END LOOP; + + rin <= v; + END PROCESS comb; + + regs : PROCESS(dp_clk) + BEGIN + IF rising_edge(dp_clk) THEN + r <= rin; + END IF; + END PROCESS; + + output_sosi_arr <= r.output_sosi_arr; + +END str; + -- GitLab