File: /__w/ctu-can-regression/ctu-can-regression/src/can_core/err_counters.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: -- Error counters.
71: --
72: -- Purpose:
73: -- Error counters for fault confinement. Following counters are implemented:
74: -- RX Error counter - Counts errors of reciver.
75: -- TX Error counter - Counts errors of transmitter.
76: -- Nominal Error counter - Counts errors in Nominal Bit rate.
77: -- Data Error counter - Counts errors in Data Bit rate.
78: -- Only RX Error counter and TX Error counter are used for Fault confinement.
79: -- Nominal and Data Error counter are used to distuiguish relative error rate
80: -- of both bit-rates and are always incremented by 1 when Error frame is
81: -- transmitted. All counters can be modified from Driving Bus.
82: --------------------------------------------------------------------------------
83:
84: Library ieee;
85: use ieee.std_logic_1164.all;
86: use ieee.numeric_std.ALL;
87:
88: Library ctu_can_fd_rtl;
89: use ctu_can_fd_rtl.can_constants_pkg.all;
90: use ctu_can_fd_rtl.can_types_pkg.all;
91:
92: use ctu_can_fd_rtl.CAN_FD_register_map.all;
93: use ctu_can_fd_rtl.CAN_FD_frame_format.all;
94:
95: entity err_counters is
96: port (
97: -------------------------------------------------------------------------------------------
98: -- System clock and Asynchronous Reset
99: -------------------------------------------------------------------------------------------
100: clk_sys : in std_logic;
101: res_n : in std_logic;
102:
103: -------------------------------------------------------------------------------------------
104: -- DFT support
105: -------------------------------------------------------------------------------------------
106: scan_enable : in std_logic;
107:
108: -------------------------------------------------------------------------------------------
109: -- Control inputs
110: -------------------------------------------------------------------------------------------
111: -- Sample control (Nominal, Data, Secondary)
112: sp_control : in std_logic_vector(1 downto 0);
113:
114: -- Increment error counter by 1
115: inc_one : in std_logic;
116:
117: -- Increment error counter by 8
118: inc_eight : in std_logic;
119:
120: -- Decrement error counter by 1
121: dec_one : in std_logic;
122:
123: -- Set unit to error active (after re-integration). Erases error
124: -- counters to 0!
125: set_err_active : in std_logic;
126:
127: -- Unit is transmitter
128: is_transmitter : in std_logic;
129:
130: -- Unit is receiver
131: is_receiver : in std_logic;
132:
133: -------------------------------------------------------------------------------------------
134: -- Memory registers interface
135: -------------------------------------------------------------------------------------------
136: mr_ctr_pres_ctpv : in std_logic_vector(8 downto 0);
137: mr_ctr_pres_ptx : in std_logic;
138: mr_ctr_pres_prx : in std_logic;
139: mr_ctr_pres_enorm : in std_logic;
140: mr_ctr_pres_efd : in std_logic;
141:
142: -------------------------------------------------------------------------------------------
143: -- Counter statuses
144: -------------------------------------------------------------------------------------------
145: -- RX Error counter
146: rx_err_ctr : out std_logic_vector(8 downto 0);
147:
148: -- TX Error counter
149: tx_err_ctr : out std_logic_vector(8 downto 0);
150:
151: -- Nominal Bit Rate Error counter
152: norm_err_ctr : out std_logic_vector(15 downto 0);
153:
154: -- Nominal Bit Rate Error counter
155: data_err_ctr : out std_logic_vector(15 downto 0)
156: );
157: end entity;
158:
159: architecture rtl of err_counters is
160:
161: -- Error counter registers
162: signal tx_err_ctr_d : unsigned(8 downto 0);
163: signal rx_err_ctr_d : unsigned(8 downto 0);
164: signal tx_err_ctr_q : unsigned(8 downto 0);
165: signal rx_err_ctr_q : unsigned(8 downto 0);
166:
167: signal rx_err_ctr_inc : unsigned(8 downto 0);
168: signal rx_err_ctr_sat : unsigned(8 downto 0);
169:
170: -- Clock enables for error counter registers
171: signal tx_err_ctr_ce : std_logic;
172: signal rx_err_ctr_ce : std_logic;
173:
174: -- Modify TX/RX Error counter
175: signal modif_tx_ctr : std_logic;
176: signal modif_rx_ctr : std_logic;
177:
178: -- TX/RX Error counter decremented value
179: signal tx_err_ctr_dec : unsigned(8 downto 0);
180: signal rx_err_ctr_dec : unsigned(8 downto 0);
181:
182: -- Error counters for nominal bit errors, data bit errors
183: signal nom_err_ctr_d : unsigned(15 downto 0);
184: signal data_err_ctr_d : unsigned(15 downto 0);
185: signal nom_err_ctr_q : unsigned(15 downto 0);
186: signal data_err_ctr_q : unsigned(15 downto 0);
187:
188: -- Selected value of counter
189: signal nom_dat_sel_ctr : unsigned(15 downto 0);
190:
191: -- Combinationally added value
192: signal nom_dat_sel_ctr_add : unsigned(15 downto 0);
193:
194: -- Clock enables for error counter registers
195: signal nom_err_ctr_ce : std_logic;
196: signal data_err_ctr_ce : std_logic;
197:
198: signal res_err_ctrs_d : std_logic;
199: signal res_err_ctrs_q_scan : std_logic;
200:
201: signal mr_ctr_pres_ptx_q : std_logic;
202: signal mr_ctr_pres_prx_q : std_logic;
203: signal mr_ctr_pres_enorm_q : std_logic;
204: signal mr_ctr_pres_efd_q : std_logic;
205:
206: begin
207:
208: -----------------------------------------------------------------------------------------------
209: -- Counter preset mask - must be registered, since value is also registered! This allows
210: -- setting both by a single access!
211: -----------------------------------------------------------------------------------------------
212: ctr_pres_reg_proc : process(res_n, clk_sys)
213: begin
214: if (res_n = '0') then
215: mr_ctr_pres_ptx_q <= '0';
216: mr_ctr_pres_prx_q <= '0';
217: mr_ctr_pres_enorm_q <= '0';
218: mr_ctr_pres_efd_q <= '0';
219: elsif (rising_edge(clk_sys)) then
220: mr_ctr_pres_ptx_q <= mr_ctr_pres_ptx;
221: mr_ctr_pres_prx_q <= mr_ctr_pres_prx;
222: mr_ctr_pres_enorm_q <= mr_ctr_pres_enorm;
223: mr_ctr_pres_efd_q <= mr_ctr_pres_efd;
224: end if;
225: end process;
226:
227: modif_tx_ctr <= '1' when (inc_eight = '1' or dec_one = '1') else
228: '0';
229:
230: -- Counters are modified either +1. +8 or -1
231: modif_rx_ctr <= '1' when (inc_one = '1' or inc_eight = '1' or dec_one = '1')
232: else
233: '0';
234:
235: -----------------------------------------------------------------------------------------------
236: -- TX Error counter, next value calculation
237: -----------------------------------------------------------------------------------------------
238: tx_err_ctr_dec <= (tx_err_ctr_q - 1) when (tx_err_ctr_q > 0) else
239: tx_err_ctr_q;
240:
241: -- Next value for error counter inctement when any of "inc" commands is
242: -- valid. Decrement otherwise!
243: tx_err_ctr_d <=
244: unsigned(mr_ctr_pres_ctpv) when (mr_ctr_pres_ptx_q = '1') else
245: tx_err_ctr_q + 8 when (inc_eight = '1') else
246: tx_err_ctr_dec;
247:
248: -- Clock enable: Tick error counter register when unit is transmitter and
249: -- one of commands is valid!
250: tx_err_ctr_ce <= '1' when (modif_tx_ctr = '1' and is_transmitter = '1') else
251: '1' when (mr_ctr_pres_ptx_q = '1') else
252: '0';
253:
254: -----------------------------------------------------------------------------------------------
255: -- Registering counter reset (to avoid glitches)
256: -----------------------------------------------------------------------------------------------
257: res_err_ctrs_d <= '0' when (res_n = '0' or set_err_active = '1')
258: else
259: '1';
260:
261: rst_reg_inst : entity ctu_can_fd_rtl.rst_reg
262: generic map (
263: G_RESET_POLARITY => '0'
264: )
265: port map(
266: -- Clock and Reset
267: clk => clk_sys, -- IN
268: arst => res_n, -- IN
269:
270: -- Flip flop input / output
271: d => res_err_ctrs_d, -- IN
272: q => res_err_ctrs_q_scan, -- OUT
273:
274: -- Scan mode control
275: scan_enable => scan_enable -- IN
276: );
277:
278: -----------------------------------------------------------------------------------------------
279: -- TX Error counter register
280: -----------------------------------------------------------------------------------------------
281: tx_err_ctr_reg_proc : process(clk_sys, res_err_ctrs_q_scan)
282: begin
283: if (res_err_ctrs_q_scan = '0') then
284: tx_err_ctr_q <= (others => '0');
285: elsif (rising_edge(clk_sys)) then
286: if (tx_err_ctr_ce = '1') then
287: tx_err_ctr_q <= tx_err_ctr_d;
288: end if;
289: end if;
290: end process;
291:
292: -----------------------------------------------------------------------------------------------
293: -- RX Error counter, next value calculation
294: -----------------------------------------------------------------------------------------------
295: -- Set to 120 when counter is more than 127, decrement otherwise!
296: rx_err_ctr_dec <= to_unsigned(120, 9) when (rx_err_ctr_q > 127) else
297: (rx_err_ctr_q - 1) when (rx_err_ctr_q > 0) else
298: rx_err_ctr_q;
299:
300:
301: -- Inrement RX counter
302: rx_err_ctr_inc <= rx_err_ctr_q + 1 when (inc_one = '1') else
303: rx_err_ctr_q + 8;
304:
305: -- Saturate RX counter when overflow would occur according to 12.1.4.3 of CAN FD ISO spec
306: rx_err_ctr_sat <= (others => '1') when (rx_err_ctr_inc < rx_err_ctr_q) else
307: rx_err_ctr_inc;
308:
309: -----------------------------------------------------------------------------------------------
310: -- Next value for error counter increment when any of "inc" commands is valid, decrement
311: -- otherwise!
312: -----------------------------------------------------------------------------------------------
313: rx_err_ctr_d <= unsigned(mr_ctr_pres_ctpv) when (mr_ctr_pres_prx_q = '1') else
314: rx_err_ctr_sat when (inc_one = '1' or inc_eight = '1') else
315: rx_err_ctr_dec;
316:
317: -- Clock enable: Tick error counter register when unit is transmitter and one of commands is
318: -- valid!
319: rx_err_ctr_ce <= '1' when (modif_rx_ctr = '1' and is_receiver = '1') else
320: '1' when (mr_ctr_pres_prx_q = '1') else
321: '0';
322:
323: -----------------------------------------------------------------------------------------------
324: -- RX error counter register
325: -----------------------------------------------------------------------------------------------
326: rx_err_ctr_reg_proc : process(clk_sys, res_err_ctrs_q_scan)
327: begin
328: if (res_err_ctrs_q_scan = '0') then
329: rx_err_ctr_q <= (others => '0');
330: elsif (rising_edge(clk_sys)) then
331: if (rx_err_ctr_ce = '1') then
332: rx_err_ctr_q <= rx_err_ctr_d;
333: end if;
334: end if;
335: end process;
336:
337:
338: -----------------------------------------------------------------------------------------------
339: -----------------------------------------------------------------------------------------------
340: -- Error counters for Errors in Nominal, Data Bit rate
341: -----------------------------------------------------------------------------------------------
342: -----------------------------------------------------------------------------------------------
343:
344: -- Selection of counter to be incremented
345: nom_dat_sel_ctr <= nom_err_ctr_q when (sp_control = NOMINAL_SAMPLE) else
346: data_err_ctr_q;
347:
348: nom_dat_sel_ctr_add <= nom_dat_sel_ctr + 1;
349:
350: nom_err_ctr_d <= nom_dat_sel_ctr_add when (mr_ctr_pres_enorm_q = '0')
351: else
352: (others => '0');
353:
354: data_err_ctr_d <= nom_dat_sel_ctr_add when (mr_ctr_pres_efd_q = '0')
355: else
356: (others => '0');
357:
358: -- Clock enables for counters, increment only
359: nom_err_ctr_ce <= '1' when (mr_ctr_pres_enorm_q = '1') or
360: ((inc_one = '1' or inc_eight = '1') and
361: (sp_control = NOMINAL_SAMPLE))
362: else
363: '0';
364:
365: data_err_ctr_ce <= '1' when (mr_ctr_pres_efd_q = '1') or
366: ((inc_one = '1' or inc_eight = '1') and
367: (sp_control = DATA_SAMPLE or sp_control = SECONDARY_SAMPLE))
368: else
369: '0';
370:
371: -----------------------------------------------------------------------------------------------
372: -- Nominal / Data Bit rate error counters registers
373: -----------------------------------------------------------------------------------------------
374: nom_err_ctr_proc : process(clk_sys, res_err_ctrs_q_scan)
375: begin
376: if (res_err_ctrs_q_scan = '0') then
377: nom_err_ctr_q <= (others => '0');
378: elsif (rising_edge(clk_sys)) then
379: if (nom_err_ctr_ce = '1') then
380: nom_err_ctr_q <= nom_err_ctr_d;
381: end if;
382: end if;
383: end process;
384:
385: dat_err_ctr_proc : process(clk_sys, res_err_ctrs_q_scan)
386: begin
387: if (res_err_ctrs_q_scan = '0') then
388: data_err_ctr_q <= (others => '0');
389: elsif (rising_edge(clk_sys)) then
390: if (data_err_ctr_ce = '1') then
391: data_err_ctr_q <= data_err_ctr_d;
392: end if;
393: end if;
394: end process;
395:
396: -----------------------------------------------------------------------------------------------
397: -- Internal signals to output propagation
398: -----------------------------------------------------------------------------------------------
399: rx_err_ctr <= std_logic_vector(rx_err_ctr_q);
400: tx_err_ctr <= std_logic_vector(tx_err_ctr_q);
401:
402: norm_err_ctr <= std_logic_vector(nom_err_ctr_q);
403: data_err_ctr <= std_logic_vector(data_err_ctr_q);
404:
405: -----------------------------------------------------------------------------------------------
406: -- Assertions
407: -----------------------------------------------------------------------------------------------
408:
409: -- psl default clock is rising_edge(clk_sys);
410: --
411: -- psl no_simul_inc_dec_asrt : assert never
412: -- (inc_one = '1' and inc_eight = '1') or
413: -- (inc_one = '1' and dec_one = '1') or
414: -- (dec_one = '1' and inc_eight = '1')
415: -- report "Can't manipulate Error counters by multiple commands at once";
416:
417: -- psl no_simul_transm_rec_asrt : assert never
418: -- (is_transmitter = '1' and is_receiver = '1')
419: -- report "Unit can't be transmitter and receiver at once";
420:
421: end architecture;