@@ -12,94 +12,232 @@ entity can_controller is
12
12
data_out : out STD_LOGIC_VECTOR (63 downto 0 );
13
13
data_valid : out STD_LOGIC ;
14
14
sync : in STD_LOGIC ;
15
- bit_time : in STD_LOGIC_VECTOR (15 downto 0 )
15
+ bit_time : in STD_LOGIC_VECTOR (15 downto 0 );
16
+ -- New ports
17
+ tx_request : in STD_LOGIC ;
18
+ tx_done : out STD_LOGIC ;
19
+ rx_busy : out STD_LOGIC ;
20
+ error_flag : out STD_LOGIC ;
21
+ bus_off : out STD_LOGIC ;
22
+ extended_id : in STD_LOGIC ;
23
+ remote_frame : in STD_LOGIC ;
24
+ id_in : in STD_LOGIC_VECTOR (28 downto 0 );
25
+ id_out : out STD_LOGIC_VECTOR (28 downto 0 );
26
+ dlc_in : in STD_LOGIC_VECTOR (3 downto 0 );
27
+ dlc_out : out STD_LOGIC_VECTOR (3 downto 0 )
16
28
);
17
29
end can_controller ;
18
30
19
31
architecture Behavioral of can_controller is
20
- type can_state_type is (IDLE, ARBITRATION, CONTROL, DATA, CRC, ACK, EOF);
32
+ type can_state_type is (IDLE, ARBITRATION, CONTROL, DATA, CRC, ACK, EOF, ERROR , BUS_OFF, TRANSMIT );
21
33
signal state : can_state_type := IDLE;
22
34
signal bit_counter : integer range 0 to 127 := 0 ;
23
35
signal crc : STD_LOGIC_VECTOR (14 downto 0 ) := (others => '0' );
36
+ signal crc_calc : STD_LOGIC_VECTOR (14 downto 0 ) := (others => '0' );
24
37
25
38
-- CAN frame components
26
- signal arbitration_field : STD_LOGIC_VECTOR (11 downto 0 );
39
+ signal arbitration_field : STD_LOGIC_VECTOR (28 downto 0 );
27
40
signal control_field : STD_LOGIC_VECTOR (5 downto 0 );
28
41
signal data_field : STD_LOGIC_VECTOR (63 downto 0 );
29
42
43
+ -- Additional signals
44
+ signal error_counter : unsigned (7 downto 0 ) := (others => '0' );
45
+ signal bit_stuff_counter : unsigned (2 downto 0 ) := (others => '0' );
46
+ signal last_bit : STD_LOGIC := '0' ;
47
+ signal stuff_error : STD_LOGIC := '0' ;
48
+ signal crc_error : STD_LOGIC := '0' ;
49
+ signal form_error : STD_LOGIC := '0' ;
50
+ signal ack_error : STD_LOGIC := '0' ;
51
+ signal tx_buffer : STD_LOGIC_VECTOR (127 downto 0 );
52
+ signal tx_bit_counter : integer range 0 to 127 := 0 ;
53
+ signal is_transmitting : STD_LOGIC := '0' ;
54
+
55
+ -- CRC calculation function
56
+ function update_crc (crc_in : STD_LOGIC_VECTOR (14 downto 0 ); data_in : STD_LOGIC ) return STD_LOGIC_VECTOR is
57
+ variable crc_out : STD_LOGIC_VECTOR (14 downto 0 );
58
+ begin
59
+ crc_out := crc_in(13 downto 0 ) & data_in;
60
+ if crc_in(14 ) /= data_in then
61
+ crc_out := crc_out xor "100010110011001" ;
62
+ end if ;
63
+ return crc_out;
64
+ end function ;
65
+
30
66
begin
31
67
process (clk, rst)
68
+ variable next_bit : STD_LOGIC ;
32
69
begin
33
70
if rst = '1' then
34
71
state <= IDLE;
35
72
bit_counter <= 0 ;
36
73
crc <= (others => '0' );
37
74
tx <= '1' ;
38
75
data_valid <= '0' ;
39
- elsif rising_edge (clk) and sync = '1' then
40
- case state is
41
- when IDLE =>
42
- if rx = '0' then -- Start of Frame detected
43
- state <= ARBITRATION;
44
- bit_counter <= 0 ;
45
- end if ;
46
-
47
- when ARBITRATION =>
48
- if bit_counter < 11 then
49
- arbitration_field(11 - bit_counter) <= rx;
50
- bit_counter <= bit_counter + 1 ;
51
- else
52
- state <= CONTROL;
53
- bit_counter <= 0 ;
54
- end if ;
55
-
56
- when CONTROL =>
57
- if bit_counter < 6 then
58
- control_field(5 - bit_counter) <= rx;
59
- bit_counter <= bit_counter + 1 ;
60
- else
61
- state <= DATA;
62
- bit_counter <= 0 ;
63
- end if ;
64
-
65
- when DATA =>
66
- if bit_counter < 64 then
67
- data_field(63 - bit_counter) <= rx;
68
- bit_counter <= bit_counter + 1 ;
69
- else
70
- state <= CRC;
71
- bit_counter <= 0 ;
72
- end if ;
76
+ error_flag <= '0' ;
77
+ bus_off <= '0' ;
78
+ error_counter <= (others => '0' );
79
+ rx_busy <= '0' ;
80
+ tx_done <= '0' ;
81
+ is_transmitting <= '0' ;
82
+ elsif rising_edge (clk) then
83
+ if sync = '1' then
84
+ case state is
85
+ when IDLE =>
86
+ rx_busy <= '0' ;
87
+ if tx_request = '1' and is_transmitting = '0' then
88
+ state <= TRANSMIT;
89
+ is_transmitting <= '1' ;
90
+ tx_buffer <= id_in & dlc_in & data_in & x"00000000" ; -- Prepare transmit buffer
91
+ tx_bit_counter <= 0 ;
92
+ elsif rx = '0' then -- Start of Frame detected
93
+ state <= ARBITRATION;
94
+ bit_counter <= 0 ;
95
+ crc_calc <= (others => '0' );
96
+ rx_busy <= '1' ;
97
+ end if ;
98
+
99
+ when ARBITRATION =>
100
+ if (extended_id = '0' and bit_counter < 11 ) or (extended_id = '1' and bit_counter < 29 ) then
101
+ arbitration_field(28 - bit_counter) <= rx;
102
+ bit_counter <= bit_counter + 1 ;
103
+ crc_calc <= update_crc(crc_calc, rx);
104
+ else
105
+ state <= CONTROL;
106
+ bit_counter <= 0 ;
107
+ end if ;
108
+
109
+ when CONTROL =>
110
+ if bit_counter < 6 then
111
+ control_field(5 - bit_counter) <= rx;
112
+ bit_counter <= bit_counter + 1 ;
113
+ crc_calc <= update_crc(crc_calc, rx);
114
+ else
115
+ state <= DATA;
116
+ bit_counter <= 0 ;
117
+ end if ;
118
+
119
+ when DATA =>
120
+ if bit_counter < to_integer (unsigned (control_field(3 downto 0 ))) * 8 then
121
+ data_field(63 - bit_counter) <= rx;
122
+ bit_counter <= bit_counter + 1 ;
123
+ crc_calc <= update_crc(crc_calc, rx);
124
+ else
125
+ state <= CRC;
126
+ bit_counter <= 0 ;
127
+ end if ;
128
+
129
+ when CRC =>
130
+ if bit_counter < 15 then
131
+ crc(14 - bit_counter) <= rx;
132
+ bit_counter <= bit_counter + 1 ;
133
+ else
134
+ state <= ACK;
135
+ bit_counter <= 0 ;
136
+ if crc /= crc_calc then
137
+ crc_error <= '1' ;
138
+ end if ;
139
+ end if ;
140
+
141
+ when ACK =>
142
+ if bit_counter = 0 then
143
+ tx <= '0' ; -- Send ACK
144
+ bit_counter <= bit_counter + 1 ;
145
+ elsif bit_counter = 1 then
146
+ tx <= '1' ; -- ACK delimiter
147
+ bit_counter <= 0 ;
148
+ state <= EOF;
149
+ if rx = '1' then
150
+ ack_error <= '1' ;
151
+ end if ;
152
+ end if ;
153
+
154
+ when EOF =>
155
+ if bit_counter < 7 then
156
+ if rx /= '1' then
157
+ form_error <= '1' ;
158
+ end if ;
159
+ bit_counter <= bit_counter + 1 ;
160
+ else
161
+ state <= IDLE;
162
+ bit_counter <= 0 ;
163
+ data_out <= data_field;
164
+ id_out <= arbitration_field;
165
+ dlc_out <= control_field(3 downto 0 );
166
+ data_valid <= '1' ;
167
+ end if ;
168
+
169
+ when ERROR =>
170
+ if bit_counter < 6 then
171
+ tx <= '0' ; -- Transmit error flag
172
+ bit_counter <= bit_counter + 1 ;
173
+ else
174
+ state <= IDLE;
175
+ bit_counter <= 0 ;
176
+ error_counter <= error_counter + 1 ;
177
+ if error_counter = 255 then
178
+ state <= BUS_OFF;
179
+ end if ;
180
+ end if ;
181
+
182
+ when BUS_OFF =>
183
+ bus_off <= '1' ;
184
+ if error_counter = 0 then
185
+ state <= IDLE;
186
+ bus_off <= '0' ;
187
+ end if ;
188
+
189
+ when TRANSMIT =>
190
+ if tx_bit_counter < 128 then
191
+ tx <= tx_buffer(127 - tx_bit_counter);
192
+ tx_bit_counter <= tx_bit_counter + 1 ;
193
+ else
194
+ state <= IDLE;
195
+ is_transmitting <= '0' ;
196
+ tx_done <= '1' ;
197
+ end if ;
73
198
74
- when CRC =>
75
- if bit_counter < 15 then
76
- crc(14 - bit_counter) <= rx;
77
- bit_counter <= bit_counter + 1 ;
78
- else
79
- state <= ACK;
80
- bit_counter <= 0 ;
81
- end if ;
82
-
83
- when ACK =>
84
- if bit_counter = 0 then
85
- tx <= '0' ; -- Send ACK
86
- bit_counter <= bit_counter + 1 ;
87
- elsif bit_counter = 1 then
88
- tx <= '1' ; -- ACK delimiter
89
- bit_counter <= 0 ;
90
- state <= EOF;
91
- end if ;
92
-
93
- when EOF =>
94
- if bit_counter < 7 then
95
- bit_counter <= bit_counter + 1 ;
199
+ end case ;
200
+
201
+ -- Bit stuffing
202
+ if state /= IDLE and state /= ERROR and state /= BUS_OFF and state /= TRANSMIT then
203
+ if rx = last_bit then
204
+ bit_stuff_counter <= bit_stuff_counter + 1 ;
205
+ if bit_stuff_counter = 5 then
206
+ stuff_error <= '1' ;
207
+ end if ;
96
208
else
97
- state <= IDLE;
98
- bit_counter <= 0 ;
99
- data_out <= data_field;
100
- data_valid <= '1' ;
209
+ bit_stuff_counter <= (others => '0' );
101
210
end if ;
102
- end case ;
211
+ last_bit <= rx;
212
+ end if ;
213
+
214
+ -- Error handling
215
+ if stuff_error = '1' or crc_error = '1' or form_error = '1' or ack_error = '1' then
216
+ state <= ERROR ;
217
+ error_flag <= '1' ;
218
+ stuff_error <= '0' ;
219
+ crc_error <= '0' ;
220
+ form_error <= '0' ;
221
+ ack_error <= '0' ;
222
+ end if ;
223
+
224
+ end if ;
225
+ end if ;
226
+ end process ;
227
+
228
+ -- Error counter management
229
+ process (clk, rst)
230
+ begin
231
+ if rst = '1' then
232
+ error_counter <= (others => '0' );
233
+ elsif rising_edge (clk) then
234
+ if state = ERROR then
235
+ if error_counter < 255 then
236
+ error_counter <= error_counter + 1 ;
237
+ end if ;
238
+ elsif state = IDLE and error_counter > 0 then
239
+ error_counter <= error_counter - 1 ;
240
+ end if ;
103
241
end if ;
104
242
end process ;
105
243
0 commit comments