From 132301fbf5ac1b966656b4201e426b0fd2150af5 Mon Sep 17 00:00:00 2001 From: Reinier van der Walle <walle@astron.nl> Date: Tue, 4 May 2021 12:56:48 +0200 Subject: [PATCH] inital commit of st_xsq --- libraries/dsp/st/hdllib.cfg | 1 + libraries/dsp/st/src/vhdl/st_xsq.vhd | 225 +++++++++++++++++++++++++++ 2 files changed, 226 insertions(+) create mode 100644 libraries/dsp/st/src/vhdl/st_xsq.vhd diff --git a/libraries/dsp/st/hdllib.cfg b/libraries/dsp/st/hdllib.cfg index 3617a5976a..959d269f23 100644 --- a/libraries/dsp/st/hdllib.cfg +++ b/libraries/dsp/st/hdllib.cfg @@ -9,6 +9,7 @@ synth_files = src/vhdl/st_ctrl.vhd src/vhdl/st_calc.vhd src/vhdl/st_sst.vhd + src/vhdl/st_xsq.vhd # src/vhdl/st_top.vhd src/vhdl/st_histogram.vhd src/vhdl/st_histogram_reg.vhd diff --git a/libraries/dsp/st/src/vhdl/st_xsq.vhd b/libraries/dsp/st/src/vhdl/st_xsq.vhd new file mode 100644 index 0000000000..b151affbd5 --- /dev/null +++ b/libraries/dsp/st/src/vhdl/st_xsq.vhd @@ -0,0 +1,225 @@ +------------------------------------------------------------------------------- +-- +-- 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: +-- Store the (auto)power statistics of a complex input stream with +-- blocks of g_nof_crosslets * g_nof_signal_inputs**2 multiplexed subbands into a MM register. +-- Description: +-- +-- After each sync the MM register gets updated with the (auto) power statistics +-- of the previous sync interval. The length of the sync interval determines +-- the nof accumlations per statistic, hence the integration time. See st_calc +-- for more details. +-- Remarks: +-- . The in_sync is assumed to be a pulse an interpreted directly. +-- . The MM register is single page RAM to save memory resources. Therefore +-- just after the sync its contents is undefined when it gets written, but +-- after that its contents remains stable for the rest of the sync interval. +-- Therefore it is not necessary to use a dual page register that swaps at +-- the sync. +-- . The minimum c_nof_statistics = 8. Lower values lead to simulation errors. This is +-- due to the read latency of 2 of the accumulation memory in the st_calc entity. +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE common_lib.common_field_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE technology_lib.technology_select_pkg.ALL; +ENTITY st_xsq IS + GENERIC ( + g_technology : NATURAL := c_tech_select_default; + g_nof_signal_inputs : NATURAL := 2; + g_nof_crosslets : NATURAL := 1; + g_in_data_w : NATURAL := 18; -- width of the data to be accumulated + g_stat_data_w : NATURAL := 54; -- statistics accumulator width + g_stat_data_sz : NATURAL := 2 -- statistics word width >= statistics accumulator width and fit in a power of 2 multiple 32b MM words + ); + PORT ( + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; + dp_rst : IN STD_LOGIC; + dp_clk : IN STD_LOGIC; + + -- Streaming + in_a : IN t_dp_sosi; -- Complex input data + in_b : IN t_dp_sosi; -- Complex input data + + -- Memory Mapped + ram_st_xsq_mosi : IN t_mem_mosi; + ram_st_xsq_miso : OUT t_mem_miso + ); +END st_xsq; + +ARCHITECTURE str OF st_xsq IS + + CONSTANT c_xsq : NATURAL := g_nof_signal_inputs * g_nof_signal_inputs; + CONSTANT c_nof_statistics : NATURAL := g_nof_crosslets * c_xsq; + + CONSTANT c_nof_stat_w : NATURAL := ceil_log2(c_nof_statistics); + CONSTANT c_nof_word : NATURAL := g_stat_data_sz*c_nof_statistics; + CONSTANT c_nof_word_w : NATURAL := ceil_log2(c_nof_word); + CONSTANT c_stat_word_w : NATURAL := g_stat_data_sz*c_word_w; + + -- Statistics register + CONSTANT c_mm_ram : t_c_mem := (latency => 1, + adr_w => c_nof_word_w, + dat_w => c_word_w, + nof_dat => c_nof_word, + init_sl => '0'); -- MM side : sla_in, sla_out + CONSTANT c_stat_ram : t_c_mem := (latency => 1, + adr_w => c_nof_stat_w, + dat_w => c_stat_word_w, + nof_dat => c_nof_statistics, + init_sl => '0'); -- ST side : stat_mosi + + + SIGNAL stat_data_re : STD_LOGIC_VECTOR(g_stat_data_w-1 DOWNTO 0); + SIGNAL stat_data_im : STD_LOGIC_VECTOR(g_stat_data_w-1 DOWNTO 0); + + SIGNAL wrdata_re : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0); + SIGNAL wrdata_im : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0); + + SIGNAL stat_mosi : t_mem_mosi; + + SIGNAL ram_st_xsq_mosi_arr : t_mem_mosi_arr(c_nof_complex-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst); + SIGNAL ram_st_xsq_miso_arr : t_mem_miso_arr(c_nof_complex-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst); + SIGNAL remapped_ram_st_xsq_mosi : t_mem_mosi; + +BEGIN + -- accumulators + st_calc : ENTITY work.st_calc + GENERIC MAP ( + g_technology => g_technology, + g_nof_mux => 1, + g_nof_stat => c_nof_statistics, + g_in_dat_w => g_in_data_w, + g_out_dat_w => g_stat_data_w, + g_out_adr_w => c_nof_stat_w, + g_complex => TRUE + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + in_ar => in_a.re(g_in_data_w-1 DOWNTO 0), + in_ai => in_a.im(g_in_data_w-1 DOWNTO 0), + in_br => in_b.re(g_in_data_w-1 DOWNTO 0), + in_bi => in_b.im(g_in_data_w-1 DOWNTO 0), + in_val => in_a.valid, + in_sync => in_a.sync, + out_adr => stat_mosi.address(c_stat_ram.adr_w-1 DOWNTO 0), + out_re => stat_data_re, + out_im => stat_data_im, + out_val => stat_mosi.wr, + out_val_m => OPEN + ); + + wrdata_re <= RESIZE_MEM_UDATA(stat_data_re); + wrdata_im <= RESIZE_MEM_UDATA(stat_data_im); + + --------------------------------------------------------------- + -- COMBINE MEMORY MAPPED INTERFACES + --------------------------------------------------------------- + -- Translate incoming MM interface [N_crosslets][S_pn A][S_pn B][N_complex] to + -- [N_complex][N_crosslets][S_pn A][S_pn B] + p_remap : PROCESS(ram_st_xsq_mosi) + BEGIN + remapped_ram_st_xsq_mosi <= ram_st_xsq_mosi; + remapped_ram_st_xsq_mosi.address(ceil_log2(c_nof_complex)+c_nof_word_w -1 DOWNTO c_nof_word_w) <= ram_st_xsq_mosi.address(ceil_log2(c_nof_complex)-1 DOWNTO 0); + remapped_ram_st_xsq_mosi.address(c_nof_word_w -1 DOWNTO 0) <= ram_st_xsq_mosi.address(ceil_log2(c_nof_complex)+c_nof_word_w -1 DOWNTO ceil_log2(c_nof_complex)); + END PROCESS; + + -- Combine the internal array of mm interfaces for both real + -- and imaginary part. + u_mem_mux_select : entity common_lib.common_mem_mux + generic map ( + g_nof_mosi => c_nof_complex, + g_mult_addr_w => c_nof_word_w + ) + port map ( + mosi => remapped_ram_st_xsq_mosi, + miso => ram_st_xsq_miso, + mosi_arr => ram_st_xsq_mosi_arr, + miso_arr => ram_st_xsq_miso_arr + ); + + -- ram for real values + stat_reg_re : ENTITY common_lib.common_ram_crw_crw_ratio + GENERIC MAP ( + g_technology => g_technology, + g_ram_a => c_mm_ram, + g_ram_b => c_stat_ram, + g_init_file => "UNUSED" + ) + PORT MAP ( + rst_a => mm_rst, + clk_a => mm_clk, + + rst_b => dp_rst, + clk_b => dp_clk, + + wr_en_a => ram_st_xsq_mosi_arr(0).wr, -- only for diagnostic purposes, typically statistics are read only + wr_dat_a => ram_st_xsq_mosi_arr(0).wrdata(c_mm_ram.dat_w-1 DOWNTO 0), + adr_a => ram_st_xsq_mosi_arr(0).address(c_mm_ram.adr_w-1 DOWNTO 0), + rd_en_a => ram_st_xsq_mosi_arr(0).rd, + rd_dat_a => ram_st_xsq_miso_arr(0).rddata(c_mm_ram.dat_w-1 DOWNTO 0), + rd_val_a => ram_st_xsq_miso_arr(0).rdval, + + wr_en_b => stat_mosi.wr, + wr_dat_b => wrdata_re(c_stat_ram.dat_w-1 DOWNTO 0), + adr_b => stat_mosi.address(c_stat_ram.adr_w-1 DOWNTO 0), + rd_en_b => '0', + rd_dat_b => OPEN, + rd_val_b => OPEN + ); + + -- ram for imaginary values + stat_reg_im : ENTITY common_lib.common_ram_crw_crw_ratio + GENERIC MAP ( + g_technology => g_technology, + g_ram_a => c_mm_ram, + g_ram_b => c_stat_ram, + g_init_file => "UNUSED" + ) + PORT MAP ( + rst_a => mm_rst, + clk_a => mm_clk, + + rst_b => dp_rst, + clk_b => dp_clk, + + wr_en_a => ram_st_xsq_mosi_arr(1).wr, -- only for diagnostic purposes, typically statistics are read only + wr_dat_a => ram_st_xsq_mosi_arr(1).wrdata(c_mm_ram.dat_w-1 DOWNTO 0), + adr_a => ram_st_xsq_mosi_arr(1).address(c_mm_ram.adr_w-1 DOWNTO 0), + rd_en_a => ram_st_xsq_mosi_arr(1).rd, + rd_dat_a => ram_st_xsq_miso_arr(1).rddata(c_mm_ram.dat_w-1 DOWNTO 0), + rd_val_a => ram_st_xsq_miso_arr(1).rdval, + + wr_en_b => stat_mosi.wr, + wr_dat_b => wrdata_im(c_stat_ram.dat_w-1 DOWNTO 0), + adr_b => stat_mosi.address(c_stat_ram.adr_w-1 DOWNTO 0), + rd_en_b => '0', + rd_dat_b => OPEN, + rd_val_b => OPEN + ); + +END str; -- GitLab