ROD firmware  1.0.5
ATLAS l1-calo - ROD_eFEX and ROD_jFEX firmware for the L1Calo ROD board

Back to ROD documentation
ufc_rx.vhd
1 ----------------------------------------------------------------------------------
2 -- Company:
3 -- Engineer:
4 --
5 -- Create Date: 11.05.2020 19:53:07
6 -- Design Name:
7 -- Module Name: ufc_rx - RTL
8 -- Project Name:
9 -- Target Devices:
10 -- Tool Versions:
11 -- Description:
12 --
13 -- Dependencies:
14 --
15 -- Revision:
16 -- Revision 0.01 - File Created
17 -- Additional Comments:
18 --
19 
20 --The incoming data uses an odd parity scheme which operates on 3 data bits and adds one parity bit on the left.(MSB)
21 --Each word has six data bits plus two parity bits
22 --There are two copies of the 8-bit data+parity. The controller should take one without a parity error if possible
23 
24 --ipbus bits
25 
26 --parity error counter r
27 --six sticky bits to record the source of the busy signal
28 --reset for all of the above in a separate register
29 
30 --bits to determine which output the busy is routed to?
31 --tob0, bulk0, bulk1, bulk2
32 
33 
34 
35 
36 
37 
38 
39 ----------------------------------------------------------------------------------
40 
41 
42 library IEEE;
43 use IEEE.STD_LOGIC_1164.ALL;
44 
45 -- Uncomment the following library declaration if using
46 -- arithmetic functions with Signed or Unsigned values
47 --use IEEE.NUMERIC_STD.ALL;
48 
49 -- Uncomment the following library declaration if instantiating
50 -- any Xilinx leaf cells in this code.
51 --library UNISIM;
52 --use UNISIM.VComponents.all;
53 
54 entity ufc_rx is
55  Port ( clock : in STD_LOGIC;
56  reset : in STD_LOGIC;
57  axi_ufc_rx_tvalid : in STD_LOGIC;
58  axi_ufc_rx_tlast : in STD_LOGIC;
59  axi_ufc_rx_tdata : in STD_LOGIC_Vector(15 downto 0);
60 
61  ufc_message : out STD_LOGIC_Vector(7 downto 0);
62  ufc_parity_error : out STD_LOGIC;
63  ufc_parity_disable : out std_logic;
64  ufc_channel_Busy : out STD_LOGIC
65 
66  );
67 end ufc_rx;
68 
69 architecture RTL of ufc_rx is
70 
71 signal data_cap : STD_LOGIC_Vector(15 downto 0);
72 signal message_i : STD_LOGIC_Vector(7 downto 0);
73 --signal message_1 : STD_LOGIC_Vector(7 downto 0);
74 
75 signal parity_0_0 : STD_LOGIC; --message 0 parity on group 0
76 signal parity_0_1 : STD_LOGIC; --message 0 parity on group 1
77 signal parity_1_0 : STD_LOGIC; --message 1 parity on group 0
78 signal parity_1_1 : STD_LOGIC; --message 1 parity on group 1
79 
80 signal tlast_delay : STD_LOGIC;
81 signal parity_error_i : STD_LOGIC;
82 
83 signal axi_ufc_tdata_1 : STD_LOGIC_Vector(15 downto 0);
84 signal axi_ufc_tvalid_1 : STD_LOGIC;
85 signal axi_ufc_tlast_1 : STD_LOGIC;
86 
87 signal axi_ufc_tdata_2 : STD_LOGIC_Vector(15 downto 0);
88 signal axi_ufc_tvalid_2 : STD_LOGIC;
89 signal axi_ufc_tlast_2 : STD_LOGIC;
90 
91 signal axi_ufc_tdata_3 : STD_LOGIC_Vector(15 downto 0);
92 signal axi_ufc_tvalid_3 : STD_LOGIC;
93 signal axi_ufc_tlast_3 : STD_LOGIC;
94 
95 
96 
97 begin
98 
99 ----first pipeline stage-----
100 process (clock) begin
101  if rising_edge (clock) then
102  axi_ufc_tdata_1 <= axi_ufc_rx_tdata;
103  if (reset = '1') then
104  axi_ufc_tvalid_1 <= '0';
105  axi_ufc_tlast_1 <= '0';
106  else
107  axi_ufc_tvalid_1 <= axi_ufc_rx_tvalid;
108  axi_ufc_tlast_1 <= axi_ufc_rx_tlast;
109  end if;
110  end if;
111 end process;
112 
113 ----second pipeline stage-----
114 process (clock) begin
115  if rising_edge (clock) then
116  axi_ufc_tdata_2 <= axi_ufc_tdata_1;
117  if (reset = '1') then
118  axi_ufc_tvalid_2 <= '0';
119  axi_ufc_tlast_2 <= '0';
120  else
121  axi_ufc_tvalid_2 <= axi_ufc_tvalid_1;
122  axi_ufc_tlast_2 <= axi_ufc_tlast_1;
123  end if;
124  end if;
125 end process;
126 
127 ----third pipeline stage-----
128 process (clock) begin
129  if rising_edge (clock) then
130  axi_ufc_tdata_3 <= axi_ufc_tdata_2;
131  if (reset = '1') then
132  axi_ufc_tvalid_3 <= '0';
133  axi_ufc_tlast_3 <= '0';
134  else
135  axi_ufc_tvalid_3 <= axi_ufc_tvalid_2;
136  axi_ufc_tlast_3 <= axi_ufc_tlast_2;
137  end if;
138  end if;
139 end process;
140 
141 
142 
143 --data capture register
144 process (clock) begin
145  if rising_edge (clock) then
146  if reset = '1' then
147  data_cap <= x"0000";
148  elsif (axi_ufc_tvalid_3 = '1' and axi_ufc_tlast_3 = '1') then
149  data_cap <= axi_ufc_tdata_3;
150  else data_cap <= data_cap;
151  end if;
152  end if;
153 end process;
154 
155 parity_0_0 <= data_cap(3) xor data_cap(2) xor data_cap(1) xor data_cap(0);
156 parity_0_1 <= data_cap(7) xor data_cap(6) xor data_cap(5) xor data_cap(4);
157 parity_1_0 <= data_cap(11) xor data_cap(10) xor data_cap(9) xor data_cap(8);
158 parity_1_1 <= data_cap(15) xor data_cap(14) xor data_cap(13) xor data_cap(12);
159 
160 
161 --capture the 16-bit raw ufc data
162 
163 --process (clock) begin
164 -- if rising_edge (clock) then
165 -- if reset = '1' then
166 -- data_cap <= x"0000";
167 -- elsif (axi_ufc_rx_tvalid = '1' and axi_ufc_rx_tlast = '1') then
168 -- data_cap <= axi_ufc_rx_tdata;
169 -- else data_cap <= data_cap;
170 -- end if;
171 -- end if;
172 --end process;
173 
174 
175 
176 process (clock) begin
177  if rising_edge (clock) then
178  if reset = '1' then
179  message_i(3 downto 0) <= x"0";
180  elsif (parity_0_0 = '1') or (ufc_parity_disable = '1') then
181  message_i(3 downto 0) <= data_cap(3 downto 0);
182  elsif (parity_0_0 = '0') and (parity_1_0 = '1') then
183  message_i(3 downto 0) <= data_cap(11 downto 8);
184  else message_i(3 downto 0) <= x"0";
185  end if;
186  end if;
187 end process;
188 
189 process (clock) begin
190  if rising_edge (clock) then
191  if reset = '1' then
192  message_i(7 downto 4) <= x"0";
193  elsif (parity_0_1 = '1') or (ufc_parity_disable = '1')then
194  message_i(7 downto 4) <= data_cap(7 downto 4);
195  elsif (parity_0_1 = '0') and (parity_1_1 = '1') then
196  message_i(7 downto 4) <= data_cap(15 downto 12);
197  else message_i(7 downto 4) <= x"0";
198  end if;
199  end if;
200 end process;
201 
202 
203 
204 process (clock) begin
205  if rising_edge (clock) then
206  if reset = '1' then
207  tlast_delay <= '0';
208  else
209  tlast_delay <= axi_ufc_tvalid_3 and axi_ufc_tlast_3;
210  end if;
211  end if;
212 end process;
213 
214 --parity error is a single cycle pulse one cycle after the message has been received
215 
216 process (clock) begin
217  if rising_edge (clock) then
218  if (reset = '1') or (tlast_delay = '0') then
219  parity_error_i <= '0';
220  elsif (tlast_delay = '1') then
221  parity_error_i <= ((not parity_0_0) or (not parity_0_1) or (not parity_1_0)or (not parity_1_1)) ;
222  else parity_error_i <= parity_error_i;
223  end if;
224  end if;
225 end process;
226 
227 ufc_parity_error <= parity_error_i;
228 --parity_error <= tlast_delay and ((not parity_0_0) or (not parity_0_1) or (not parity_1_0)or (not parity_1_1)) ;
229 
230 ufc_channel_Busy <= message_i(6) or message_i(5) or message_i(4) or message_i(2) or message_i(1) or message_i(0);
231 
232 ufc_message <= message_i;
233 
234 end RTL;