File: /__w/ctu-can-regression/ctu-can-regression/src/interrupt_manager/int_manager.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: -- Interrupt Manager
71: --
72: -- Purpose:
73: -- Captures interrupts to Interrupt vector. Maintains Interrupt Enable and
74: -- Interrupt Mask registers. Configured (Set and Clear) from Memory registers.
75: -- An edge is detected on each interrupt source. If an interrupt is unmasked,
76: -- it is captured to interrupt vector. If an interrupt is enabled and it is
77: -- active in Interrupt vector, it causes Interrupt output to be asserted.
78: -- Interrupt output is pipelined to make sure it is glitch free.
79: --------------------------------------------------------------------------------
80:
81: Library ieee;
82: use ieee.std_logic_1164.all;
83: use ieee.numeric_std.ALL;
84:
85: Library ctu_can_fd_rtl;
86: use ctu_can_fd_rtl.can_constants_pkg.all;
87: use ctu_can_fd_rtl.can_types_pkg.all;
88:
89: use ctu_can_fd_rtl.CAN_FD_register_map.all;
90: use ctu_can_fd_rtl.CAN_FD_frame_format.all;
91:
92: entity int_manager is
93: generic (
94: -- Number of supported interrupts
95: G_INT_COUNT : natural;
96:
97: -- Number of TXT Buffers
98: G_TXT_BUFFER_COUNT : natural
99: );
100: port (
101: -------------------------------------------------------------------------------------------
102: -- Clock and Asynchronous reset
103: -------------------------------------------------------------------------------------------
104: clk_sys : in std_logic;
105: res_n : in std_logic;
106:
107: -------------------------------------------------------------------------------------------
108: -- Interrupt sources
109: -------------------------------------------------------------------------------------------
110: -- Error appeared
111: err_detected : in std_logic;
112:
113: -- Fault confinement state changed
114: fcs_changed : in std_logic;
115:
116: -- Error warning limit reached
117: err_warning_limit_pulse : in std_logic;
118:
119: -- Arbitration was lost input
120: arbitration_lost : in std_logic;
121:
122: -- Transmitted frame is valid
123: tran_valid : in std_logic;
124:
125: -- Bit Rate Was Shifted
126: br_shifted : in std_logic;
127:
128: -- Rx Buffer data overrun
129: rx_data_overrun : in std_logic;
130:
131: -- Received frame is valid
132: rec_valid : in std_logic;
133:
134: -- RX Buffer is full
135: rx_full : in std_logic;
136:
137: -- Recieve buffer is empty
138: rx_empty : in std_logic;
139:
140: -- HW command on TXT Buffers interrupt
141: txtb_hw_cmd_int : in std_logic_vector(G_TXT_BUFFER_COUNT - 1 downto 0);
142:
143: -- Overload frame is being transmitted
144: is_overload : in std_logic;
145:
146: ------------------------------------------------------------------------
147: -- Memory registers Interface
148: ------------------------------------------------------------------------
149: -- Writes to Interrupt registers
150: mr_int_ena_set_int_ena_set : in std_logic_vector(G_INT_COUNT - 1 downto 0);
151: mr_int_ena_clr_int_ena_clr : in std_logic_vector(G_INT_COUNT - 1 downto 0);
152: mr_int_mask_set_int_mask_set : in std_logic_vector(G_INT_COUNT - 1 downto 0);
153: mr_int_mask_clr_int_mask_clr : in std_logic_vector(G_INT_COUNT - 1 downto 0);
154:
155: mr_int_stat_rxi_i : in std_logic;
156: mr_int_stat_txi_i : in std_logic;
157: mr_int_stat_ewli_i : in std_logic;
158: mr_int_stat_doi_i : in std_logic;
159: mr_int_stat_fcsi_i : in std_logic;
160: mr_int_stat_ali_i : in std_logic;
161: mr_int_stat_bei_i : in std_logic;
162: mr_int_stat_ofi_i : in std_logic;
163: mr_int_stat_rxfi_i : in std_logic;
164: mr_int_stat_bsi_i : in std_logic;
165: mr_int_stat_rbnei_i : in std_logic;
166: mr_int_stat_txbhci_i : in std_logic;
167:
168: -- Reads from Interrupt registers
169: mr_int_stat_rxi_o : out std_logic;
170: mr_int_stat_txi_o : out std_logic;
171: mr_int_stat_ewli_o : out std_logic;
172: mr_int_stat_doi_o : out std_logic;
173: mr_int_stat_fcsi_o : out std_logic;
174: mr_int_stat_ali_o : out std_logic;
175: mr_int_stat_bei_o : out std_logic;
176: mr_int_stat_ofi_o : out std_logic;
177: mr_int_stat_rxfi_o : out std_logic;
178: mr_int_stat_bsi_o : out std_logic;
179: mr_int_stat_rbnei_o : out std_logic;
180: mr_int_stat_txbhci_o : out std_logic;
181:
182: mr_int_ena_set_int_ena_set_o : out std_logic_vector(G_INT_COUNT - 1 downto 0);
183: mr_int_mask_set_int_mask_set_o : out std_logic_vector(G_INT_COUNT - 1 downto 0);
184:
185: -------------------------------------------------------------------------------------------
186: -- Interrupt output
187: -------------------------------------------------------------------------------------------
188: int : out std_logic
189: );
190: end entity;
191:
192: architecture rtl of int_manager is
193:
194: signal int_input_active : std_logic_vector(G_INT_COUNT - 1 downto 0);
195: signal int_status_i : std_logic_vector(G_INT_COUNT - 1 downto 0);
196: signal int_status_clr_i : std_logic_vector(G_INT_COUNT - 1 downto 0);
197:
198: constant C_ZERO_MASK : std_logic_vector(G_INT_COUNT - 1 downto 0) := (others => '0');
199:
200: -- Internal value of an interrupt
201: signal int_i : std_logic;
202:
203: -- Internal value of INT_ENA
204: signal mr_int_ena_set_int_ena_set_o_i : std_logic_vector(G_INT_COUNT - 1 downto 0);
205:
206: function or_reduce(
207: constant input : in std_logic_vector
208: ) return std_logic is
209: variable tmp : std_logic := '0';
210: begin
211: for i in input'range loop
212: tmp := tmp or input(i);
213: end loop;
214: return tmp;
215: end function;
216:
217: begin
218:
219: -----------------------------------------------------------------------------------------------
220: -- Driving Interrupt output when there is at least one active interrupt enabled.
221: -----------------------------------------------------------------------------------------------
222: int_i <= '0' when ((int_status_i and mr_int_ena_set_int_ena_set_o_i) = C_ZERO_MASK)
223: else
224: '1';
225:
226: -----------------------------------------------------------------------------------------------
227: -- Unfold individual bits of interrupt signals
228: -----------------------------------------------------------------------------------------------
229: -- Input interrupt sources from other modules
230: int_input_active(RXI_IND) <= rec_valid;
231: int_input_active(TXI_IND) <= tran_valid;
232: int_input_active(EWLI_IND) <= err_warning_limit_pulse;
233: int_input_active(DOI_IND) <= rx_data_overrun;
234: int_input_active(FCSI_IND) <= fcs_changed;
235: int_input_active(ALI_IND) <= arbitration_lost;
236: int_input_active(BEI_IND) <= err_detected;
237: int_input_active(OFI_IND) <= is_overload;
238: int_input_active(RXFI_IND) <= rx_full;
239: int_input_active(BSI_IND) <= br_shifted;
240: int_input_active(RBNEI_IND) <= not rx_empty;
241: int_input_active(TXBHCI_IND) <= or_reduce(txtb_hw_cmd_int);
242:
243: -- INT_STATUS clear
244: int_status_clr_i(RXI_IND) <= mr_int_stat_rxi_i;
245: int_status_clr_i(TXI_IND) <= mr_int_stat_txi_i;
246: int_status_clr_i(EWLI_IND) <= mr_int_stat_ewli_i;
247: int_status_clr_i(DOI_IND) <= mr_int_stat_doi_i;
248: int_status_clr_i(FCSI_IND) <= mr_int_stat_fcsi_i;
249: int_status_clr_i(ALI_IND) <= mr_int_stat_ali_i;
250: int_status_clr_i(BEI_IND) <= mr_int_stat_bei_i;
251: int_status_clr_i(OFI_IND) <= mr_int_stat_ofi_i;
252: int_status_clr_i(RXFI_IND) <= mr_int_stat_rxfi_i;
253: int_status_clr_i(BSI_IND) <= mr_int_stat_bsi_i;
254: int_status_clr_i(RBNEI_IND) <= mr_int_stat_rbnei_i;
255: int_status_clr_i(TXBHCI_IND) <= mr_int_stat_txbhci_i;
256:
257: -- Interrupt status
258: mr_int_stat_rxi_o <= int_status_i(RXI_IND);
259: mr_int_stat_txi_o <= int_status_i(TXI_IND);
260: mr_int_stat_ewli_o <= int_status_i(EWLI_IND);
261: mr_int_stat_doi_o <= int_status_i(DOI_IND);
262: mr_int_stat_fcsi_o <= int_status_i(FCSI_IND);
263: mr_int_stat_ali_o <= int_status_i(ALI_IND);
264: mr_int_stat_bei_o <= int_status_i(BEI_IND);
265: mr_int_stat_ofi_o <= int_status_i(OFI_IND);
266: mr_int_stat_rxfi_o <= int_status_i(RXFI_IND);
267: mr_int_stat_bsi_o <= int_status_i(BSI_IND);
268: mr_int_stat_rbnei_o <= int_status_i(RBNEI_IND);
269: mr_int_stat_txbhci_o <= int_status_i(TXBHCI_IND);
270:
271: -----------------------------------------------------------------------------------------------
272: -- Interrupt module instances
273: -----------------------------------------------------------------------------------------------
274: int_module_gen : for i in 0 to G_INT_COUNT - 1 generate
275:
276: int_module_inst : entity ctu_can_fd_rtl.int_module
277: port map (
278: clk_sys => clk_sys, -- IN
279: res_n => res_n, -- IN
280:
281: int_status_set => int_input_active(i), -- IN
282: int_status_clear => int_status_clr_i(i), -- IN
283:
284: int_mask_set => mr_int_mask_set_int_mask_set(i), -- IN
285: int_mask_clear => mr_int_mask_clr_int_mask_clr(i), -- IN
286:
287: int_ena_set => mr_int_ena_set_int_ena_set(i), -- IN
288: int_ena_clear => mr_int_ena_clr_int_ena_clr(i), -- IN
289:
290: int_status => int_status_i(i), -- OUT
291: int_mask => mr_int_mask_set_int_mask_set_o(i), -- OUT
292: int_ena => mr_int_ena_set_int_ena_set_o_i(i) -- OUT
293: );
294:
295: end generate int_module_gen;
296:
297: -----------------------------------------------------------------------------------------------
298: -- Output interrupt DFF to make sure that interrupt output will be glitch free!
299: -----------------------------------------------------------------------------------------------
300: dff_int_output_reg : entity ctu_can_fd_rtl.dff_arst
301: generic map(
302: G_RESET_POLARITY => '0',
303: G_RST_VAL => '0'
304: )
305: port map(
306: arst => res_n, -- IN
307: clk => clk_sys, -- IN
308: reg_d => int_i, -- IN
309:
310: reg_q => int -- OUT
311: );
312:
313: -- Propagation to output
314: mr_int_ena_set_int_ena_set_o <= mr_int_ena_set_int_ena_set_o_i;
315:
316: end architecture;