Skip to content
Snippets Groups Projects

Resolve L2SDP-308

Merged
Reinier van der Wallerequested to merge
L2SDP-308 into master
All threads resolved!
5 files
+ 686
1
Compare changes
  • Side-by-side
  • Inline

Files

+ 146
0
-------------------------------------------------------------------------------
--
-- 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:
-- . Read a block of xsq data with size (g_nof_crosslets * g_nof_signal_inputs)
-- from memory mapped (MM) location and stream it as a block of data of
-- size g_nof_crosslets * g_nof_signal_inputs **2.
-- Description:
-- After every in_sosi.sop the st_xsq_mm_to_dp.vhd reads blocks of data
-- via g_nof_streams mm and outputs it as g_nof_streams parallel streams via
-- out_sosi_arr. In_sosi.sync is passed on to out_sosi.
-- --------------------------------------------------------------------------
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;
ENTITY st_xsq_mm_to_dp IS
GENERIC (
g_nof_streams : NATURAL;
g_nof_crosslets : NATURAL;
g_nof_signal_inputs : NATURAL;
g_dsp_data_w : NATURAL := 16
);
PORT (
rst : IN STD_LOGIC;
clk : IN STD_LOGIC;
in_sosi : IN t_dp_sosi; -- sop used as start signal
mm_mosi_arr : OUT t_mem_mosi_arr(g_nof_streams -1 DOWNTO 0);
mm_miso_arr : IN t_mem_miso_arr(g_nof_streams -1 DOWNTO 0);
out_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams -1 DOWNTO 0)
);
END st_xsq_mm_to_dp;
ARCHITECTURE rtl OF st_xsq_mm_to_dp IS
TYPE t_reg IS RECORD
in_sosi_strobe : t_dp_sosi;
out_sosi_ctrl : t_dp_sosi;
busy : STD_LOGIC;
crosslets_index : NATURAL;
in_a_index : NATURAL;
in_b_index : NATURAL;
END RECORD;
CONSTANT c_reg_rst : t_reg := (c_dp_sosi_rst, c_dp_sosi_rst, '0', 0, 0, 0);
SIGNAL r : t_reg;
SIGNAL nxt_r : t_reg;
SIGNAL mm_mosi : t_mem_mosi := c_mem_mosi_rst;
BEGIN
mm_mosi_arr <= (OTHERS => mm_mosi); -- all mosi are identical.
u_sosi : PROCESS(r, mm_miso_arr)
BEGIN
FOR I IN 0 TO g_nof_streams-1 LOOP
out_sosi_arr(I) <= r.out_sosi_ctrl;
out_sosi_arr(I).re <= RESIZE_DP_DSP_DATA(mm_miso_arr(I).rddata(g_dsp_data_w-1 DOWNTO 0));
out_sosi_arr(I).im <= RESIZE_DP_DSP_DATA(mm_miso_arr(I).rddata(c_nof_complex * g_dsp_data_w -1 DOWNTO g_dsp_data_w));
out_sosi_arr(I).valid <= mm_miso_arr(I).rdval; -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so same as the ready latency (RL = 1)
END LOOP;
END PROCESS;
p_reg : PROCESS(rst, clk)
BEGIN
IF rst='1' THEN
r <= c_reg_rst;
ELSIF rising_edge(clk) THEN
r <= nxt_r;
END IF;
END PROCESS;
p_comb : PROCESS(r, in_sosi)
VARIABLE v : t_reg;
BEGIN
v := r;
v.out_sosi_ctrl := c_dp_sosi_rst;
mm_mosi.rd <= '0';
-- initiate next block and capture in_sosi strobe
IF r.busy = '0' AND in_sosi.sop = '1' THEN
v.busy := '1';
v.in_sosi_strobe := in_sosi;
ELSIF r.busy = '1' THEN
-- continue with block
mm_mosi.rd <= '1';
mm_mosi.address <= TO_MEM_ADDRESS(r.crosslets_index * g_nof_signal_inputs + r.in_b_index); -- streams iterate over in_b_index
-- Indices counters to select data order
IF r.in_b_index < g_nof_signal_inputs - 1 THEN
v.in_b_index := r.in_b_index + 1;
ELSE
v.in_b_index := 0;
IF r.in_a_index < g_nof_signal_inputs - 1 THEN
v.in_a_index := r.in_a_index + 1;
ELSE
v.in_a_index := 0;
IF r.crosslets_index < g_nof_crosslets - 1 THEN
v.crosslets_index := r.crosslets_index + 1;
ELSE
v.crosslets_index := 0;
END IF;
END IF;
END IF;
-- check start of block
IF r.crosslets_index = 0 AND r.in_a_index = 0 AND r.in_b_index = 0 THEN
v.out_sosi_ctrl.sop := '1';
v.out_sosi_ctrl.sync := r.in_sosi_strobe.sync;
v.out_sosi_ctrl.bsn := r.in_sosi_strobe.bsn;
END IF;
-- check end of block
IF r.crosslets_index >= (g_nof_crosslets - 1) AND r.in_a_index >= (g_nof_signal_inputs - 1) AND r.in_b_index >= (g_nof_signal_inputs - 1) THEN
v.out_sosi_ctrl.eop := '1';
v.out_sosi_ctrl.err := r.in_sosi_strobe.err;
v.busy := '0';
END IF;
END IF;
nxt_r <= v;
END PROCESS;
END rtl;
Loading