File: /__w/ctu-can-regression/ctu-can-regression/src/tx_arbitrator/priority_decoder.vhd
0: --------------------------------------------------------------------------------
1: --
2: -- CTU CAN FD IP Core
3: -- Copyright (C) 2021-2023 Ondrej Ille
4: -- Copyright (C) 2023- Logic Design Services Ltd.s
5: --
6: -- Permission is hereby granted, free of charge, to any person obtaining a copy
7: -- of this VHDL component and associated documentation files (the "Component"),
8: -- to use, copy, modify, merge, publish, distribute the Component for
9: -- non-commercial purposes. Using the Component for commercial purposes is
10: -- forbidden unless previously agreed with Copyright holder.
11: --
12: -- The above copyright notice and this permission notice shall be included in
13: -- all copies or substantial portions of the Component.
14: --
15: -- THE COMPONENT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16: -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17: -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18: -- AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19: -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20: -- FROM, OUT OF OR IN CONNECTION WITH THE COMPONENT OR THE USE OR OTHER DEALINGS
21: -- IN THE COMPONENT.
22: --
23: -- The CAN protocol is developed by Robert Bosch GmbH and protected by patents.
24: -- Anybody who wants to implement this IP core on silicon has to obtain a CAN
25: -- protocol license from Bosch.
26: --
27: -- -------------------------------------------------------------------------------
28: --
29: -- CTU CAN FD IP Core
30: -- Copyright (C) 2015-2020 MIT License
31: --
32: -- Authors:
33: -- Ondrej Ille <ondrej.ille@gmail.com>
34: -- Martin Jerabek <martin.jerabek01@gmail.com>
35: --
36: -- Project advisors:
37: -- Jiri Novak <jnovak@fel.cvut.cz>
38: -- Pavel Pisa <pisa@cmp.felk.cvut.cz>
39: --
40: -- Department of Measurement (http://meas.fel.cvut.cz/)
41: -- Faculty of Electrical Engineering (http://www.fel.cvut.cz)
42: -- Czech Technical University (http://www.cvut.cz/)
43: --
44: -- Permission is hereby granted, free of charge, to any person obtaining a copy
45: -- of this VHDL component and associated documentation files (the "Component"),
46: -- to deal in the Component without restriction, including without limitation
47: -- the rights to use, copy, modify, merge, publish, distribute, sublicense,
48: -- and/or sell copies of the Component, and to permit persons to whom the
49: -- Component is furnished to do so, subject to the following conditions:
50: --
51: -- The above copyright notice and this permission notice shall be included in
52: -- all copies or substantial portions of the Component.
53: --
54: -- THE COMPONENT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55: -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
56: -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57: -- AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58: -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
59: -- FROM, OUT OF OR IN CONNECTION WITH THE COMPONENT OR THE USE OR OTHER DEALINGS
60: -- IN THE COMPONENT.
61: --
62: -- The CAN protocol is developed by Robert Bosch GmbH and protected by patents.
63: -- Anybody who wants to implement this IP core on silicon has to obtain a CAN
64: -- protocol license from Bosch.
65: --
66: --------------------------------------------------------------------------------
67:
68: --------------------------------------------------------------------------------
69: -- Module:
70: -- Priority decoder.
71: --
72: -- Purpose:
73: -- Combinational decoder for TXT BufferS priority. Considers priority, bufffer
74: -- validity. Generic amount of buffers is available (up to 8). Decoder consists
75: -- of 3 levels of comparators (4+2+1). If two frames have the same priority,
76: -- a frame with lower index is selected.
77: --------------------------------------------------------------------------------
78:
79: Library ieee;
80: use ieee.std_logic_1164.all;
81: use ieee.numeric_std.ALL;
82: use ieee.math_real.ALL;
83:
84: Library ctu_can_fd_rtl;
85: use ctu_can_fd_rtl.can_constants_pkg.all;
86: use ctu_can_fd_rtl.can_types_pkg.all;
87:
88: use ctu_can_fd_rtl.CAN_FD_register_map.all;
89: use ctu_can_fd_rtl.CAN_FD_frame_format.all;
90:
91: entity priority_decoder is
92: generic (
93: -- Number of TXT Buffers
94: G_TXT_BUFFER_COUNT : natural range 2 to 8
95: );
96: port (
97: -------------------------------------------------------------------------------------------
98: -- TXT Buffer information
99: -------------------------------------------------------------------------------------------
100: -- TXT Buffer priority
101: prio : in t_txt_bufs_priorities(G_TXT_BUFFER_COUNT - 1 downto 0);
102:
103: -- TXT Buffer is valid for selection
104: prio_valid : in std_logic_vector(G_TXT_BUFFER_COUNT - 1 downto 0);
105:
106: -------------------------------------------------------------------------------------------
107: -- Output interface
108: -------------------------------------------------------------------------------------------
109: -- Whether selected buffer is valid (at least one buffer must be non-empty and allowed)
110: output_valid : out std_logic;
111:
112: -- Index of highest priority buffer which is non-empty and allowed for transmission
113: output_index : out natural range 0 to G_TXT_BUFFER_COUNT - 1
114: );
115: end entity;
116:
117: architecture rtl of priority_decoder is
118:
119: -----------------------------------------------------------------------------------------------
120: -- Level 0 aliases for input signals to provide variable signal width
121: -----------------------------------------------------------------------------------------------
122: type level0_priority_type is array (7 downto 0) of
123: std_logic_vector(2 downto 0);
124: signal l0_prio : level0_priority_type;
125: signal l0_valid : std_logic_vector(7 downto 0);
126:
127:
128: -----------------------------------------------------------------------------------------------
129: -- Level 1 priorities and valid indicators
130: -----------------------------------------------------------------------------------------------
131: type level1_priority_type is array (3 downto 0) of
132: std_logic_vector(2 downto 0);
133: type level1_comp_valid_type is array (3 downto 0) of
134: std_logic_vector(1 downto 0);
135: signal l1_prio : level1_priority_type;
136: signal l1_valid : std_logic_vector(3 downto 0);
137: signal l1_winner : std_logic_vector(3 downto 0);
138:
139:
140: -----------------------------------------------------------------------------------------------
141: -- Level 2 priorities and valid indicators
142: -----------------------------------------------------------------------------------------------
143: type level2_priority_type is array (1 downto 0) of
144: std_logic_vector(2 downto 0);
145: type level2_comp_valid_type is array (1 downto 0) of
146: std_logic_vector(1 downto 0);
147: signal l2_prio : level2_priority_type;
148: signal l2_valid : std_logic_vector(1 downto 0);
149: signal l2_winner : std_logic_vector(1 downto 0);
150:
151: -----------------------------------------------------------------------------------------------
152: -- Level 3, we dont need the priorities, we only need the outcome which of them is bigger
153: -- (since there is no next stage)
154: -----------------------------------------------------------------------------------------------
155: signal l3_valid : std_logic;
156: signal l3_winner : std_logic;
157:
158: constant LOWER_TREE : std_logic := '0';
159: constant UPPER_TREE : std_logic := '1';
160:
161: begin
162:
163: -----------------------------------------------------------------------------------------------
164: -- Level 0 - aliases
165: -----------------------------------------------------------------------------------------------
166: l0_gen : for i in 0 to G_TXT_BUFFER_COUNT - 1 generate
167:
168: -- pragma translate_off
169: -- coverage off
170:
171: -- Since we cover "00" as inactive value, instead of active values
172: -- "01", "10" or "11", rather make sure that input values are defined
173: l0_val_proc : process(prio_valid(i))
174: begin
175: if (prio_valid(i) /= '0' and prio_valid(i) /= '1' and now /= 0 fs) then
176: report "Input values not exactly defined" severity error;
177: end if;
178: end process;
179:
180: -- coverage on
181: -- pragma translate_on
182:
183: l0_prio(i) <= prio(i);
184: l0_valid(i) <= prio_valid(i);
185:
186: end generate;
187:
188:
189: fill_zeroes_gen : if (G_TXT_BUFFER_COUNT < 8) generate
190: l0_prio(7 downto G_TXT_BUFFER_COUNT) <= (others => (others => '0'));
191: l0_valid(7 downto G_TXT_BUFFER_COUNT) <= (others => '0');
192: end generate;
193:
194:
195: -----------------------------------------------------------------------------------------------
196: -- Level 1 comparators
197: -----------------------------------------------------------------------------------------------
198: l1_prio_dec_proc : process(l0_valid, l0_prio)
199: variable tmp : level1_comp_valid_type;
200: begin
201: tmp := (others => (others => '0'));
202: for i in 0 to 3 loop
203: tmp(i) := l0_valid(2 * i + 1 downto 2 * i);
204: case tmp(i) is
205: when "01" =>
206: l1_prio(i) <= l0_prio(2 * i);
207: l1_valid(i) <= '1';
208: l1_winner(i) <= LOWER_TREE;
209:
210: when "10" =>
211: l1_prio(i) <= l0_prio(2 * i + 1);
212: l1_valid(i) <= '1';
213: l1_winner(i) <= UPPER_TREE;
214:
215: when "11" =>
216: if (unsigned(l0_prio(2 * i + 1)) > unsigned(l0_prio(2 * i))) then
217: l1_prio(i) <= l0_prio(2 * i + 1);
218: l1_winner(i) <= UPPER_TREE;
219: else
220: l1_prio(i) <= l0_prio(2 * i);
221: l1_winner(i) <= LOWER_TREE;
222: end if;
223: l1_valid(i) <= '1';
224:
225: when others =>
226: l1_valid(i) <= '0';
227: l1_prio(i) <= l0_prio(2 * i + 1);
228: l1_winner(i) <= UPPER_TREE;
229:
230: end case;
231: end loop;
232: end process;
233:
234:
235: -----------------------------------------------------------------------------------------------
236: -- Level 2 comparators
237: -----------------------------------------------------------------------------------------------
238: l2_prio_dec_proc : process(l1_valid, l1_prio)
239: variable tmp : level2_comp_valid_type;
240: begin
241: tmp := (others => (others => '0'));
242: for i in 0 to 1 loop
243: tmp(i) := l1_valid(2 * i + 1 downto 2 * i);
244:
245: case tmp(i) is
246: when "01" =>
247: l2_prio(i) <= l1_prio(2 * i);
248: l2_valid(i) <= '1';
249: l2_winner(i) <= LOWER_TREE;
250:
251: when "10" =>
252: l2_prio(i) <= l1_prio(2 * i + 1);
253: l2_valid(i) <= '1';
254: l2_winner(i) <= UPPER_TREE;
255:
256: when "11" =>
257: if (unsigned(l1_prio(2 * i + 1)) > unsigned(l1_prio(2 * i))) then
258: l2_prio(i) <= l1_prio(2 * i + 1);
259: l2_winner(i) <= UPPER_TREE;
260: else
261: l2_prio(i) <= l1_prio(2 * i);
262: l2_winner(i) <= LOWER_TREE;
263: end if;
264: l2_valid(i) <= '1';
265:
266: when others =>
267: l2_valid(i) <= '0';
268: l2_prio(i) <= l1_prio(2 * i + 1);
269: l2_winner(i) <= UPPER_TREE;
270:
271: end case;
272: end loop;
273: end process;
274:
275:
276: -----------------------------------------------------------------------------------------------
277: -- Level 3 comparators
278: -----------------------------------------------------------------------------------------------
279:
280: -- Here we have only one comparator, plus we dont need
281: -- the priority on the output...
282:
283: -- Validity of level 3 is also the output validity
284: l3_valid <= '0' when l2_valid(1 downto 0) = "00"
285: else
286: '1';
287: output_valid <= '1' when l3_valid = '1' else '0';
288:
289: -- Priority comparator of level 3
290: l3_winner <= LOWER_TREE when l2_valid(1 downto 0) = "01" else
291: UPPER_TREE when l2_valid(1 downto 0) = "10" else
292: UPPER_TREE when (l2_valid(1 downto 0) = "11" and
293: unsigned(l2_prio(1)) > unsigned(l2_prio(0)))
294: else
295: LOWER_TREE;
296:
297: -----------------------------------------------------------------------------------------------
298: -- Output index decoder
299: -----------------------------------------------------------------------------------------------
300: -- Just find out the winning buffer index from decisions in the tree
301:
302: -- Note that modulo is used only for purpose of getting rid of compiler warnings. If lower
303: -- amount of buffers is on input (TXT_BUFFER_COUNT), then higher indices of input priorities
304: -- and valid sinals are set to 0. This leads to the case that "buf_index" will NEVER be
305: -- assigned value higher than its available range.
306:
307: out_index_proc : process(l3_winner, l2_winner, l1_winner)
308: begin
309: if (l3_winner = LOWER_TREE) then
310: if (l2_winner(0) = LOWER_TREE) then
311: if (l1_winner(0) = LOWER_TREE) then
312: output_index <= 0;
313: else
314: output_index <= 1;
315: end if;
316: else
317: if (l1_winner(1) = LOWER_TREE) then
318: output_index <= 2 mod G_TXT_BUFFER_COUNT;
319: else
320: output_index <= 3 mod G_TXT_BUFFER_COUNT;
321: end if;
322: end if;
323: else
324: if (l2_winner(1) = LOWER_TREE) then
325: if (l1_winner(2) = LOWER_TREE) then
326: output_index <= 4 mod G_TXT_BUFFER_COUNT;
327: else
328: output_index <= 5 mod G_TXT_BUFFER_COUNT;
329: end if;
330: else
331: if (l1_winner(3) = LOWER_TREE) then
332: output_index <= 6 mod G_TXT_BUFFER_COUNT;
333: else
334: output_index <= 7 mod G_TXT_BUFFER_COUNT;
335: end if;
336: end if;
337: end if;
338: end process;
339:
340: end architecture;