File: /__w/ctu-can-regression/ctu-can-regression/src/can_core/control_counter.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: -- Control counter.
71: --
72: -- Purpose:
73: -- Measures duration of CAN Frame fields which last more bits. Pre-loaded by
74: -- Protocol control FSM and counts till 0. Signals reaching 1 and 0. Contains
75: -- complementary counter which counts from 0 and indicates that whole byte
76: -- elapsed or whole memory word elapsed (4 bytes). Provides byte index within
77: -- a memory word for addressing of CAN Data byte. Contains arbitration lost
78: -- capture register which stores bit position in which unit lost arbitration.
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 control_counter is
93: generic (
94: -- Width of control counter
95: G_CTRL_CTR_WIDTH : natural
96: );
97: port (
98: -------------------------------------------------------------------------------------------
99: -- Clock and Asynchronous Reset
100: -------------------------------------------------------------------------------------------
101: clk_sys : in std_logic;
102: res_n : in std_logic;
103:
104: -------------------------------------------------------------------------------------------
105: -- Control signals
106: -------------------------------------------------------------------------------------------
107: -- RX Trigger (Decrements the counter)
108: rx_trigger : in std_logic;
109:
110: -- Control counter counting is enabled
111: ctrl_ctr_ena : in std_logic;
112:
113: -- Pre-load control counter
114: ctrl_ctr_pload : in std_logic;
115:
116: -- Pre-load value for control counter
117: ctrl_ctr_pload_val : in std_logic_vector(G_CTRL_CTR_WIDTH - 1 downto 0);
118:
119: -- Complementary counter enable
120: compl_ctr_ena : in std_logic;
121:
122: -- Arbitration lost
123: arbitration_lost : in std_logic;
124:
125: -- Arbitration lost
126: arbitration_part : in std_logic_vector(2 downto 0);
127:
128: -------------------------------------------------------------------------------------------
129: -- Status signals
130: -------------------------------------------------------------------------------------------
131: -- Control counter is equal to zero
132: ctrl_ctr_zero : out std_logic;
133:
134: -- Control counter is equal to one
135: ctrl_ctr_one : out std_logic;
136:
137: -- Control counter counted multiple of 8 bits
138: ctrl_counted_byte : out std_logic;
139:
140: -- Control counter byte index within a memory word
141: ctrl_counted_byte_index : out std_logic_vector(1 downto 0);
142:
143: -- Index of memory word in TXT Buffer
144: ctrl_ctr_mem_index : out std_logic_vector(4 downto 0);
145:
146: -------------------------------------------------------------------------------------------
147: -- Memory registers interface
148: -------------------------------------------------------------------------------------------
149: alc_alc_bit : out std_logic_vector(4 downto 0);
150: alc_alc_id_field : out std_logic_vector(2 downto 0)
151: );
152: end entity;
153:
154: architecture rtl of control_counter is
155:
156: -- Control counter
157: signal ctrl_ctr_d : unsigned(G_CTRL_CTR_WIDTH - 1 downto 0);
158: signal ctrl_ctr_q : unsigned(G_CTRL_CTR_WIDTH - 1 downto 0);
159:
160: -- Clock enable
161: signal ctrl_ctr_ce : std_logic;
162:
163: -- Complementary counter
164: signal compl_ctr_d : unsigned(G_CTRL_CTR_WIDTH - 1 downto 0);
165: signal compl_ctr_q : unsigned(G_CTRL_CTR_WIDTH - 1 downto 0);
166: signal compl_ctr_div_32 : unsigned(G_CTRL_CTR_WIDTH - 6 downto 0);
167: signal compl_ctr_div_32_plus_5 : integer range 0 to 20;
168: signal compl_ctr_div_32_plus_5_sat : integer range 0 to 19;
169: signal compl_ctr_ce : std_logic;
170:
171: constant C_CTRL_CTR_ZEROES : unsigned(G_CTRL_CTR_WIDTH - 1 downto 0) :=
172: (others => '0');
173:
174: begin
175:
176: -- Next value
177: ctrl_ctr_d <= unsigned(ctrl_ctr_pload_val) when (ctrl_ctr_pload = '1') else
178: (ctrl_ctr_q - 1) when (rx_trigger = '1') else
179: ctrl_ctr_q;
180:
181: -- Clock enable
182: ctrl_ctr_ce <= '1' when (rx_trigger = '1' and ctrl_ctr_ena = '1') else
183: '1' when (ctrl_ctr_pload = '1') else
184: '0';
185:
186: ctrl_ctr_zero <= '1' when (ctrl_ctr_q = 0)
187: else
188: '0';
189:
190: ctrl_ctr_one <= '1' when (ctrl_ctr_q = 1)
191: else
192: '0';
193:
194: -----------------------------------------------------------------------------------------------
195: -- Control Counter register
196: -----------------------------------------------------------------------------------------------
197: retr_ctr_reg_proc : process(clk_sys, res_n)
198: begin
199: if (res_n = '0') then
200: ctrl_ctr_q <= (others => '0');
201: elsif (rising_edge(clk_sys)) then
202: if (ctrl_ctr_ce = '1') then
203: ctrl_ctr_q <= ctrl_ctr_d;
204: end if;
205: end if;
206: end process;
207:
208: -----------------------------------------------------------------------------------------------
209: -- Complementary counter.
210: --
211: -- Counts bits during data field. This is done to calculate address of Data word in TXT Buffer,
212: -- byte index within memory word and indicate whole byte of data elapsed!
213: --
214: -- Counter is erased when control counter is preloaded (upon data field), and counts only
215: -- during data field.
216: -----------------------------------------------------------------------------------------------
217: compl_ctr_d <= (others => '0') when (ctrl_ctr_pload = '1') else
218: compl_ctr_q + 1;
219:
220: compl_ctr_ce <= '1' when (ctrl_ctr_pload = '1') else
221: '1' when (compl_ctr_ena = '1') else
222: '0';
223:
224: compl_reg_proc : process(clk_sys, res_n)
225: begin
226: if (res_n = '0') then
227: compl_ctr_q <= (others => '0');
228: elsif (rising_edge(clk_sys)) then
229: if (compl_ctr_ce = '1') then
230: compl_ctr_q <= compl_ctr_d;
231: end if;
232: end if;
233: end process;
234:
235: -----------------------------------------------------------------------------------------------
236: -- Status signals calculated from complementary counter
237: -----------------------------------------------------------------------------------------------
238: -- Control counter counted number of bits is on last bit within a byte!
239: ctrl_counted_byte <= '1' when (compl_ctr_q(2 downto 0) = "111")
240: else
241: '0';
242:
243: -- Byte index within memory word!
244: ctrl_counted_byte_index <= std_logic_vector(compl_ctr_q(4 downto 3));
245:
246: -- Complementary counter divided by 32
247: compl_ctr_div_32 <= compl_ctr_q(G_CTRL_CTR_WIDTH - 1 downto 5);
248:
249: -- Complementary counter divided by 32, + 5
250: compl_ctr_div_32_plus_5 <= to_integer(compl_ctr_div_32) + 5;
251:
252: -- Saturate to 19
253: compl_ctr_div_32_plus_5_sat <=
254: compl_ctr_div_32_plus_5 when (compl_ctr_div_32_plus_5 < 19) else
255: 19;
256:
257: -----------------------------------------------------------------------------------------------
258: -- Index of word in TXT Buffer memory. Always Index one word further than we are transmitting
259: -- to allow loading data on TXT Buffer RAM output:
260: -- Data Bytes 1 - 4 (0 - 32) = Address word 5
261: -- Data Bytes 5 - 8 (33 - 64) = Address word 6
262: -- ...
263: -- Data Bytes 61 - 64 () = Address word 19
264: -----------------------------------------------------------------------------------------------
265: ctrl_ctr_mem_index <=
266: std_logic_vector(to_unsigned(compl_ctr_div_32_plus_5_sat, 5));
267:
268:
269: -----------------------------------------------------------------------------------------------
270: -- Arbitration lost capture register
271: -----------------------------------------------------------------------------------------------
272: alc_capt_reg_proc : process(res_n, clk_sys)
273: begin
274: if (res_n = '0') then
275: alc_alc_bit <= (others => '0');
276: alc_alc_id_field <= (others => '0');
277: elsif (rising_edge(clk_sys)) then
278: if (arbitration_lost = '1') then
279: alc_alc_bit <= std_logic_vector(ctrl_ctr_q(4 downto 0));
280: alc_alc_id_field <= arbitration_part;
281: end if;
282: end if;
283: end process;
284:
285: end architecture;