File: /__w/ctu-can-regression/ctu-can-regression/src/can_core/bit_stuffing.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: -- Bit Stuffing.
71: --
72: -- Purpose:
73: -- Inserts Stuff Bits into TX serial stream. Operates in Stuff pipeline stage
74: -- with Bit Stuffing Trigger. Signals insertion of Stuff Bit after n bits of
75: -- equal value were processed. Supports regular and fixed bit stuffing.
76: -- Inserts extra stuff bit upon transition from regular to fixed bit stuffing.
77: -- Length of Stuff rule and bit stuffing method are controlled by Protocol
78: -- control FSM. When disabled, data are only propagated from input to output
79: -- with Bit Stuffing Trigger without insertion of Stuff bits. Processing of
80: -- Input data always takes one clock cycle. Counts number of Inserted Stuff
81: -- Bits modulo 8.
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 bit_stuffing is
96: port (
97: -------------------------------------------------------------------------------------------
98: -- Clock and Asynchronous reset
99: -------------------------------------------------------------------------------------------
100: clk_sys : in std_logic;
101: res_n : in std_logic;
102:
103: -------------------------------------------------------------------------------------------
104: -- Data-path
105: -------------------------------------------------------------------------------------------
106: -- Data Input (from Protocol Control)
107: data_in : in std_logic;
108:
109: -- Data Output (to CAN Bus)
110: data_out : out std_logic;
111:
112: -------------------------------------------------------------------------------------------
113: -- Control signals
114: -------------------------------------------------------------------------------------------
115: -- Bit Stuffing Trigger (in SYNC segment)
116: bst_trigger : in std_logic;
117:
118: -- Bit Stuffing enabled. If not, data are only passed to the output
119: stuff_enable : in std_logic;
120:
121: -- Bit Stuffing type (0-Normal, 1-Fixed)
122: fixed_stuff : in std_logic;
123:
124: -- Frame transmission without SOF started
125: tx_frame_no_sof : in std_logic;
126:
127: -------------------------------------------------------------------------------------------
128: -- Status signals
129: -------------------------------------------------------------------------------------------
130: -- Number of stuffed bits with Normal Bit stuffing
131: bst_ctr : out std_logic_vector(2 downto 0);
132:
133: -- Stuff bit is inserted, Protocol control operation to be halted for one bit time
134: data_halt : out std_logic
135: );
136: end entity;
137:
138: architecture rtl of bit_stuffing is
139:
140: signal data_out_i : std_logic;
141:
142: -----------------------------------------------------------------------------------------------
143: -- Counter with number of equal consequent bits
144: -----------------------------------------------------------------------------------------------
145: signal same_bits_q : unsigned(2 downto 0);
146: signal same_bits_add : unsigned(2 downto 0);
147: signal same_bits_d : unsigned(2 downto 0);
148: signal tx_no_sof_val : unsigned(1 downto 0);
149:
150: -- Halt for CAN Core
151: signal data_halt_q : std_logic;
152: signal data_halt_d : std_logic;
153:
154: -----------------------------------------------------------------------------------------------
155: -- Registered value of fixed stuffing.
156: -----------------------------------------------------------------------------------------------
157: signal fixed_reg_q : std_logic;
158: signal fixed_reg_d : std_logic;
159:
160: -----------------------------------------------------------------------------------------------
161: -- Counter with regularly stuffed bits
162: -----------------------------------------------------------------------------------------------
163: signal bst_ctr_q : unsigned(2 downto 0);
164: signal bst_ctr_add : unsigned(2 downto 0);
165: signal bst_ctr_d : unsigned(2 downto 0);
166:
167: -----------------------------------------------------------------------------------------------
168: -- Registered value of enable input
169: -----------------------------------------------------------------------------------------------
170: signal enable_prev : std_logic;
171:
172:
173: -----------------------------------------------------------------------------------------------
174: -- Combinational signals
175: -----------------------------------------------------------------------------------------------
176:
177: -- Bit stuffing method has changed from non-fixed to fixed bit stuffing. No need to assume
178: -- change from fixed to non-fixed since after coding CRC of CAN FD, there are no further
179: -- stuff bits with non-fixed bit stuffing!
180: signal non_fix_to_fix_chng : std_logic;
181:
182: -- Signals that stuff count has reached number of same consecutive bits and that stuff bit
183: -- should be inserted!
184: signal stuff_lvl_reached : std_logic;
185:
186: -- Counter of equal consecutive bits should be re-set to 1 in next processed bit.
187: signal same_bits_rst_trig : std_logic;
188:
189: -- Counter of equal consecutive bits should be re-set to 1 in next clock cycle.
190: signal same_bits_rst : std_logic;
191:
192: -- Condition for insertion of stuff bit
193: signal insert_stuff_bit : std_logic;
194:
195: -- Calculation of next data output value when circuit is enabled
196: signal data_out_d_ena : std_logic;
197:
198: -- Next data output value (both when enabled and disabled)
199: signal data_out_d : std_logic;
200:
201: -- Clock enable for output data register
202: signal data_out_ce : std_logic;
203:
204: begin
205:
206: -----------------------------------------------------------------------------------------------
207: -- Registering previous value of enable input to detect 0->1 transition.
208: -----------------------------------------------------------------------------------------------
209: dff_ena_reg : entity ctu_can_fd_rtl.dff_arst
210: generic map (
211: G_RESET_POLARITY => '0',
212: G_RST_VAL => '0'
213: )
214: port map (
215: arst => res_n, -- IN
216: clk => clk_sys, -- IN
217: reg_d => stuff_enable, -- IN
218:
219: reg_q => enable_prev -- OUT
220: );
221:
222: -----------------------------------------------------------------------------------------------
223: -- Detection of change on fixed stuff settings upon mismatch between actual and registered
224: -- value of fixed stuff settings from previous bit.
225: -----------------------------------------------------------------------------------------------
226: non_fix_to_fix_chng <= '1' when (fixed_stuff = '1' and fixed_reg_q = '0')
227: else
228: '0';
229:
230: -----------------------------------------------------------------------------------------------
231: -- Calculation of next value in fixed stuff register:
232: -- 1. Re-started upon 0->1 transition on "enable"
233: -- 2. Store "fixed_stuff" configuration when data are processed
234: -----------------------------------------------------------------------------------------------
235: fixed_reg_d <= '0' when (enable_prev = '0') else
236: fixed_stuff when (bst_trigger = '1') else
237: fixed_reg_q;
238:
239: -----------------------------------------------------------------------------------------------
240: -- Registering previous value of fixed bit stuffing to detect first fixed stuff bit and insert
241: -- stuff bit in the beginning of CRC for CAN FD automatically!
242: -----------------------------------------------------------------------------------------------
243: dff_fixed_stuff_reg : entity ctu_can_fd_rtl.dff_arst_ce
244: generic map (
245: G_RESET_POLARITY => '0',
246: G_RST_VAL => '0'
247: )
248: port map (
249: arst => res_n, -- IN
250: clk => clk_sys, -- IN
251: reg_d => fixed_reg_d, -- IN
252: ce => stuff_enable, -- IN
253:
254: reg_q => fixed_reg_q -- OUT
255: );
256:
257: -----------------------------------------------------------------------------------------------
258: -- Combinationally incremented stuff counter by 1.
259: -----------------------------------------------------------------------------------------------
260: bst_ctr_add <= (bst_ctr_q + 1) mod 8;
261:
262: -----------------------------------------------------------------------------------------------
263: -- Calculation of next combinational value for counter of stuffed bits:
264: -- 1. Erase when restarted bit stuffing.
265: -- 2. Upon insertion of non-fixed stuff bit increment.
266: -- 3. Keep previous value otherwise.
267: -----------------------------------------------------------------------------------------------
268: bst_ctr_d <= "000" when (enable_prev = '0') else
269: bst_ctr_add when (bst_trigger = '1' and stuff_lvl_reached = '1' and
270: fixed_stuff = '0') else
271: bst_ctr_q;
272:
273: -----------------------------------------------------------------------------------------------
274: -- Counter of stuffed bits (for CRC of ISO FD).
275: -----------------------------------------------------------------------------------------------
276: stuff_ctr_proc : process(res_n, clk_sys)
277: begin
278: if (res_n = '0') then
279: bst_ctr_q <= (others => '0');
280: elsif rising_edge(clk_sys) then
281: if (stuff_enable = '1') then
282: bst_ctr_q <= bst_ctr_d;
283: end if;
284: end if;
285: end process;
286:
287: -----------------------------------------------------------------------------------------------
288: -- Reset counter of equal consecutive bits to 1 with bit processing when:
289: -- 1. Processing first bit of fixed bit stuffing
290: -- 2. Stuff level was reached -> Stuff bit will be inserted
291: -- 3. Processed bit differs from previous bit (data out register) and regular stuffing is used.
292: -----------------------------------------------------------------------------------------------
293: same_bits_rst_trig <= '1' when (non_fix_to_fix_chng = '1') or
294: (stuff_lvl_reached = '1') or
295: (data_in /= data_out_i and fixed_stuff = '0')
296: else
297: '0';
298:
299: -----------------------------------------------------------------------------------------------
300: -- Reset counter of equal consecutive bits:
301: -- 1. Upon start of bit-stuffing
302: -- 2. When processing bit and should be restarted by dedicated signal.
303: -----------------------------------------------------------------------------------------------
304: same_bits_rst <= '1' when (enable_prev = '0') or
305: (bst_trigger = '1' and same_bits_rst_trig = '1')
306: else
307: '0';
308:
309: -----------------------------------------------------------------------------------------------
310: -- Combinationally incremented value of equal consecutive bits of equal value.
311: -----------------------------------------------------------------------------------------------
312: same_bits_add <= (same_bits_q + 1) mod 8;
313:
314: -----------------------------------------------------------------------------------------------
315: -- Preset value in case of start of transmission without transmission of SOF (as result of
316: -- Sampling dominant and considering this as SOF!):
317: -- 1. If we transmitt dominant, we put two, this accounts for SOF + first bit of ID.
318: -- 2. If we transmitt recessive, we put one, this accounts only for first bit of ID.
319: -----------------------------------------------------------------------------------------------
320: tx_no_sof_val <= "10" when (data_in = DOMINANT) else
321: "01";
322:
323: -----------------------------------------------------------------------------------------------
324: -- Next value for counter of equal consecutive bits:
325: -- 1. Preset to special value when we don't transmit SOF!
326: -- 2. Reset
327: -- 3. Increment if not reset when processing bit.
328: -- 4. Keep original value otherwise.
329: -----------------------------------------------------------------------------------------------
330: same_bits_d <= ('0' & tx_no_sof_val) when (tx_frame_no_sof = '1') else
331: "001" when (same_bits_rst = '1') else
332: same_bits_add when (bst_trigger = '1') else
333: same_bits_q;
334:
335: -----------------------------------------------------------------------------------------------
336: -- Number of stuff bits is reached when:
337: -- 1. Normal bit stuffing, number of same bits is equal to stuff rule length. Stuff bit is
338: -- already included in counting next consecutive bits of equal value (recursive behavior).
339: -- 2. Fixed bit stuffing, number of same bits is equal to one more than rule length, since
340: -- stuff bit is not included then!
341: --
342: -- In both cases the "same_bits_q" is equal to 5, since for fixed stuffing the length of
343: -- stuff rule (4) compensates for recursivity of regular bit stuffing!
344: -----------------------------------------------------------------------------------------------
345: stuff_lvl_reached <= '1' when (same_bits_q = "101")
346: else
347: '0';
348:
349: -----------------------------------------------------------------------------------------------
350: -- Counter of equal consecutive bits on input
351: -----------------------------------------------------------------------------------------------
352: same_bits_ctr_proc : process(res_n, clk_sys)
353: begin
354: if (res_n = '0') then
355: same_bits_q <= "001";
356: elsif rising_edge(clk_sys) then
357: if (stuff_enable = '1') then
358: same_bits_q <= same_bits_d;
359: else
360: same_bits_q <= "001";
361: end if;
362: end if;
363: end process;
364:
365: -----------------------------------------------------------------------------------------------
366: -- Stuff bit should be inserted:
367: -- 1. Upon change of non-fixed to fixed bit stuffing
368: -- 2. Number of equal consecutive bits has reached length of stuff rule.
369: -----------------------------------------------------------------------------------------------
370: insert_stuff_bit <= '1' when (non_fix_to_fix_chng = '1' or stuff_lvl_reached = '1')
371: else
372: '0';
373:
374: -----------------------------------------------------------------------------------------------
375: -- Calculation of output data value:
376: -- 1. Recessive bit after restart
377: -- 2. Negation of previous value when stuff bit is inserted.
378: -- 3. Pipe the input data upon trigger without stufffing
379: -- 4. Keep previous value otherwise
380: -----------------------------------------------------------------------------------------------
381: data_out_d_ena <= (not data_out_i) when (bst_trigger = '1' and insert_stuff_bit = '1') else
382: data_in when (bst_trigger = '1') else
383: data_out_i;
384:
385: data_out_d <= data_out_d_ena when (stuff_enable = '1') else
386: data_in when (bst_trigger = '1') else
387: data_out_i;
388:
389: data_out_ce <= '1' when (stuff_enable = '1' or bst_trigger = '1') else
390: '0';
391:
392: -----------------------------------------------------------------------------------------------
393: -- Output data register. Stuffed data are stored to this register in trigger, or input data
394: -- are piped directly to this register when enable = '0'.
395: -----------------------------------------------------------------------------------------------
396: dff_data_out_reg : entity ctu_can_fd_rtl.dff_arst_ce
397: generic map (
398: G_RESET_POLARITY => '0',
399: G_RST_VAL => RECESSIVE
400: )
401: port map (
402: arst => res_n, -- IN
403: clk => clk_sys, -- IN
404: reg_d => data_out_d, -- IN
405: ce => data_out_ce, -- IN
406:
407: reg_q => data_out_i -- OUT
408: );
409:
410:
411: -----------------------------------------------------------------------------------------------
412: -- Halt register signals to CAN Core that it should wait for one clock cycle because stuff-bit
413: -- was inserted.
414: --
415: -- Next value for halt register:
416: -- 1. Erase upon start of bit-stuffing, or when circuit is disabled.
417: -- 2. Signal halt when stuff bit is inserted.
418: -- 3. Erase when bit is processed, but stuff bit is not inserted.
419: -----------------------------------------------------------------------------------------------
420: data_halt_d <= '0' when (enable_prev = '0' or stuff_enable = '0') else
421: '1' when (bst_trigger = '1' and insert_stuff_bit = '1') else
422: '0' when (bst_trigger = '1') else
423: data_halt_q;
424:
425: -----------------------------------------------------------------------------------------------
426: -- Data halt register is updated in Stuff pipeline stage. But information that stuff bit is
427: -- inserted is already needed by TX Shift register in the same cycle so that it stalls and does
428: -- not shift out data (Data would get lost). So we bypass data_halt signal if there is a change
429: -- so that this information is available one clock cycle earlier!
430: -----------------------------------------------------------------------------------------------
431: data_halt <= data_halt_q when (data_halt_q = data_halt_d) else
432: data_halt_d;
433:
434: -----------------------------------------------------------------------------------------------
435: -- Halt register
436: -----------------------------------------------------------------------------------------------
437: dff_halt_reg : entity ctu_can_fd_rtl.dff_arst
438: generic map (
439: G_RESET_POLARITY => '0',
440: G_RST_VAL => '0'
441: )
442: port map (
443: arst => res_n, -- IN
444: clk => clk_sys, -- IN
445: reg_d => data_halt_d, -- IN
446:
447: reg_q => data_halt_q -- OUT
448: );
449:
450: -----------------------------------------------------------------------------------------------
451: -- Propagating internal signals to output
452: -----------------------------------------------------------------------------------------------
453: bst_ctr <= std_logic_vector(bst_ctr_q);
454: data_out <= data_out_i;
455:
456: end architecture;