-
BRONES Romain authored
* Fix delay on matmul valid signal * Fix length of validity for correction output
BRONES Romain authored* Fix delay on matmul valid signal * Fix length of validity for correction output
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
data_serializer.vhd 4.17 KiB
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library desy;
use desy.ram_tdp;
library desyrdl;
use desyrdl.pkg_corr_matrixpi.t_mem_PSCIDTABLE_out;
use desyrdl.pkg_corr_matrixpi.t_mem_PSCIDTABLE_in;
use work.pkg_corr_matrixpi.all;
entity data_serializer is
port(
clk : in std_logic;
rst_n : in std_logic;
-- PSCID memory
pscid_table_i : in t_mem_PSCIDTABLE_out;
pscid_table_o : out t_mem_PSCIDTABLE_in;
-- Status
overrun : out std_logic;
-- Corr parallel input
corrout_valid : in std_logic;
corrout_seq : in std_logic_vector(C_W_BPMSEQ-1 downto 0);
corrout : in signed_array(0 to C_N_MM_PSC-1)(C_W_COR-1 downto 0);
-- AXIS serial output
m_axis_tdata : out std_logic_vector(C_W_COR+C_W_PSCID-1 downto 0);
m_axis_tuser : out std_logic_vector(C_W_BPMSEQ-1 downto 0);
m_axis_tvalid : out std_logic;
m_axis_tready : in std_logic
);
end entity data_serializer;
architecture rtl of data_serializer is
------------------------
-- SIGNAL DECLARATION --
------------------------
signal cnt : unsigned(C_W_SER_CNT-1 downto 0);
signal run_serial : std_logic;
signal pscid : std_logic_vector(C_W_PSCID-1 downto 0);
signal r_corr : signed_array(0 to C_N_MM_PSC-1)(C_W_COR-1 downto 0);
signal r_seq : std_logic_vector(C_W_BPMSEQ-1 downto 0);
begin
------------------------
-- SERIALIZER COUNTER --
------------------------
p_cnt:process(clk, rst_n)
begin
if rst_n = '0' then
cnt <= (others => '0');
run_serial <= '0';
overrun <= '0';
elsif rising_edge(clk) then
if run_serial = '1' then
if cnt = 0 then
-- stop at the end
run_serial <= '0';
else
if m_axis_tready = '1' then
cnt <= cnt-1;
end if;
end if;
-- Transmit overrun if a valid comes here
overrun <= corrout_valid;
else
if corrout_valid= '1' then
-- start on valid
run_serial <= '1';
cnt <= to_unsigned(C_N_MM_PSC-1, cnt'length);
end if;
-- No overrun possible here
overrun <= '0';
end if;
end if;
end process;
---------------------
-- SHIFT REGISTERS --
---------------------
p_shiftreg:process(clk, rst_n)
begin
if rst_n = '0' then
r_corr <= (others => (others => '0'));
r_seq <= (others => '0');
elsif rising_edge(clk) then
if run_serial = '1' then
if m_axis_tready = '1' then
for I in 0 to C_N_MM_PSC-2 loop
r_corr(I) <= r_corr(I+1);
end loop;
end if;
else
r_corr <= corrout;
r_seq <= corrout_seq;
end if;
end if;
end process;
-----------------
-- PSCID TABLE --
------------------
-- Port A is read write from AXI controller, Port B is read only from logic
inst_refx_table: entity desy.ram_tdp
generic map(
G_ADDR => C_W_SER_CNT,
G_DATA => C_W_PSCID
)
port map(
pi_clk_a => clk,
pi_en_a => pscid_table_i.en,
pi_we_a => pscid_table_i.we,
pi_addr_a => pscid_table_i.addr(C_W_SER_CNT-1 downto 0),
pi_data_a => pscid_table_i.data,
po_data_a => pscid_table_o.data,
pi_clk_b => clk,
pi_en_b => '1',
pi_we_b => '0',
pi_addr_b => std_logic_vector(cnt),
pi_data_b => (others => '0'),
po_data_b => pscid
);
-----------------------
-- OUTPUT CONNEXIONS --
-----------------------
m_axis_tdata <= pscid & std_logic_vector(r_corr(0));
m_axis_tuser <= r_seq;
m_axis_tvalid <= run_serial;
end architecture;