Skip to content
Snippets Groups Projects
Commit 132301fb authored by Reinier van der Walle's avatar Reinier van der Walle
Browse files

inital commit of st_xsq

parent 85965a51
No related branches found
No related tags found
2 merge requests!100Removed text for XSub that is now written in Confluence Subband correlator...,!88Resolve L2SDP-288
...@@ -9,6 +9,7 @@ synth_files = ...@@ -9,6 +9,7 @@ synth_files =
src/vhdl/st_ctrl.vhd src/vhdl/st_ctrl.vhd
src/vhdl/st_calc.vhd src/vhdl/st_calc.vhd
src/vhdl/st_sst.vhd src/vhdl/st_sst.vhd
src/vhdl/st_xsq.vhd
# src/vhdl/st_top.vhd # src/vhdl/st_top.vhd
src/vhdl/st_histogram.vhd src/vhdl/st_histogram.vhd
src/vhdl/st_histogram_reg.vhd src/vhdl/st_histogram_reg.vhd
......
-------------------------------------------------------------------------------
--
-- 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;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment