Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
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_SEQ-1 downto 0);
corrout : in signed_array(0 to C_N_MM_PSC-1)(C_W_COR_OUT-1 downto 0);
-- AXIS serial output
m_axis_tdata : out std_logic_vector(C_W_COR_OUT-1 downto 0);
m_axis_tuser : out std_logic_vector(C_W_SEQ-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(pscif_table_i.addr'length-1 downto 0);
signal run_serial : std_logic;
signal r_corr : signed_array(0 to C_N_MM_PSC-1)(C_W_COR_OUT-1 downto 0);
signal r_seq : std_logic_vector(C_W_SEQ-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, 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-1 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 => pscif_table_i.addr'length,
G_DATA => C_W_PSDID
)
port map(
pi_clk_a => clk,
pi_en_a => pscif_table_i.en,
pi_we_a => pscif_table_i.we,
pi_addr_a => pscif_table_i.addr,
pi_data_a => pscif_table_i.data,
po_data_a => pscif_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 & r_corr(0);
m_axis_tuser <= r_seq;
m_axis_tvalid <= run_serial;
end architecture;