1 //////////////////////////////////////////////////////////////////////
6 //// This file is part of the CAN Protocol Controller ////
7 //// http://www.opencores.org/projects/can/ ////
12 //// igorm@opencores.org ////
15 //// All additional information is available in the README.txt ////
18 //////////////////////////////////////////////////////////////////////
20 //// Copyright (C) 2002, 2003, 2004 Authors ////
22 //// This source file may be used and distributed without ////
23 //// restriction provided that this copyright statement is not ////
24 //// removed from the file and that any derivative work contains ////
25 //// the original copyright notice and the associated disclaimer. ////
27 //// This source file is free software; you can redistribute it ////
28 //// and/or modify it under the terms of the GNU Lesser General ////
29 //// Public License as published by the Free Software Foundation; ////
30 //// either version 2.1 of the License, or (at your option) any ////
31 //// later version. ////
33 //// This source is distributed in the hope that it will be ////
34 //// useful, but WITHOUT ANY WARRANTY; without even the implied ////
35 //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
36 //// PURPOSE. See the GNU Lesser General Public License for more ////
39 //// You should have received a copy of the GNU Lesser General ////
40 //// Public License along with this source; if not, download it ////
41 //// from http://www.opencores.org/lgpl.shtml ////
43 //// The CAN protocol is developed by Robert Bosch GmbH and ////
44 //// protected by patents. Anybody who wants to implement this ////
45 //// CAN IP core on silicon has to obtain a CAN protocol license ////
48 //////////////////////////////////////////////////////////////////////
50 // CVS Revision History
52 // $Log: not supported by cvs2svn $
53 // Revision 1.29 2004/05/12 15:58:41 igorm
54 // Core improved to pass all tests with the Bosch VHDL Reference system.
56 // Revision 1.28 2004/02/08 14:25:26 mohor
59 // Revision 1.27 2003/09/30 00:55:13 mohor
60 // Error counters fixed to be compatible with Bosch VHDL reference model.
61 // Small synchronization changes.
63 // Revision 1.26 2003/09/25 18:55:49 mohor
64 // Synchronization changed, error counters fixed.
66 // Revision 1.25 2003/07/16 13:40:35 mohor
67 // Fixed according to the linter.
69 // Revision 1.24 2003/07/10 15:32:28 mohor
70 // Unused signal removed.
72 // Revision 1.23 2003/07/10 01:59:04 tadejm
73 // Synchronization fixed. In some strange cases it didn't work according to
74 // the VHDL reference model.
76 // Revision 1.22 2003/07/07 11:21:37 mohor
77 // Little fixes (to fix warnings).
79 // Revision 1.21 2003/07/03 09:32:20 mohor
80 // Synchronization changed.
82 // Revision 1.20 2003/06/20 14:51:11 mohor
83 // Previous change removed. When resynchronization occurs we go to seg1
84 // stage. sync stage does not cause another start of seg1 stage.
86 // Revision 1.19 2003/06/20 14:28:20 mohor
87 // When hard_sync or resync occure we need to go to seg1 segment. Going to
88 // sync segment is in that case blocked.
90 // Revision 1.18 2003/06/17 15:53:33 mohor
91 // clk_cnt reduced from [8:0] to [6:0].
93 // Revision 1.17 2003/06/17 14:32:17 mohor
94 // Removed few signals.
96 // Revision 1.16 2003/06/16 13:57:58 mohor
97 // tx_point generated one clk earlier. rx_i registered. Data corrected when
98 // using extended mode.
100 // Revision 1.15 2003/06/13 15:02:24 mohor
101 // Synchronization is also needed when transmitting a message.
103 // Revision 1.14 2003/06/13 14:55:11 mohor
104 // Counters width changed.
106 // Revision 1.13 2003/06/11 14:21:35 mohor
107 // When switching to tx, sync stage is overjumped.
109 // Revision 1.12 2003/02/14 20:17:01 mohor
110 // Several registers added. Not finished, yet.
112 // Revision 1.11 2003/02/09 18:40:29 mohor
113 // Overload fixed. Hard synchronization also enabled at the last bit of
116 // Revision 1.10 2003/02/09 02:24:33 mohor
117 // Bosch license warning added. Error counters finished. Overload frames
118 // still need to be fixed.
120 // Revision 1.9 2003/01/31 01:13:38 mohor
123 // Revision 1.8 2003/01/10 17:51:34 mohor
124 // Temporary version (backup).
126 // Revision 1.7 2003/01/08 02:10:53 mohor
127 // Acceptance filter added.
129 // Revision 1.6 2002/12/28 04:13:23 mohor
132 // Revision 1.5 2002/12/27 00:12:52 mohor
133 // Header changed, testbench improved to send a frame (crc still missing).
135 // Revision 1.4 2002/12/26 01:33:05 mohor
136 // Tripple sampling supported.
138 // Revision 1.3 2002/12/25 23:44:16 mohor
139 // Commented lines removed.
141 // Revision 1.2 2002/12/25 14:17:00 mohor
142 // Synchronization working.
144 // Revision 1.1.1.1 2002/12/20 16:39:21 mohor
150 // synopsys translate_off
151 `include "timescale.v"
152 // synopsys translate_on
153 `include "can_defines.v"
162 /* Bus Timing 0 register */
166 /* Bus Timing 1 register */
171 /* Output signals from this module */
178 /* Output from can_bsp module */
201 /* Bus Timing 0 register */
202 input [5:0] baud_r_presc;
203 input [1:0] sync_jump_width;
205 /* Bus Timing 1 register */
206 input [3:0] time_segment1;
207 input [2:0] time_segment2;
208 input triple_sampling;
210 /* Output from can_bsp module */
218 input go_overload_frame;
219 input go_error_frame;
222 input node_error_passive;
224 /* Output signals from this module */
227 output sampled_bit_q;
235 reg hard_sync_blocked;
252 wire [7:0] preset_cnt;
257 assign preset_cnt = (baud_r_presc + 1'b1)<<1; // (BRP+1)*2
258 assign hard_sync = (rx_idle | rx_inter) & (~rx) & sampled_bit & (~hard_sync_blocked); // Hard synchronization
259 assign resync = (~rx_idle) & (~rx_inter) & (~rx) & sampled_bit & (~sync_blocked); // Re-synchronization
263 /* Generating general enable signal that defines baud rate. */
264 always @ (posedge clk or posedge rst)
268 else if (clk_cnt >= (preset_cnt-1'b1))
271 clk_cnt <=#Tp clk_cnt + 1'b1;
275 always @ (posedge clk or posedge rst)
279 else if ({1'b0, clk_cnt} == (preset_cnt-1'b1))
287 always @ (posedge clk or posedge rst)
292 clk_en_q <=#Tp clk_en;
297 /* Changing states */
298 assign go_sync = clk_en_q & seg2 & (quant_cnt[2:0] == time_segment2) & (~hard_sync) & (~resync);
299 assign go_seg1 = clk_en_q & (sync | hard_sync | (resync & seg2 & sync_window) | (resync_latched & sync_window));
300 assign go_seg2 = clk_en_q & (seg1 & (~hard_sync) & (quant_cnt == (time_segment1 + delay)));
304 always @ (posedge clk or posedge rst)
309 tx_point <=#Tp ~tx_point & seg2 & ( clk_en & (quant_cnt[2:0] == time_segment2)
310 | (clk_en | clk_en_q) & (resync | hard_sync)
311 ); // When transmitter we should transmit as soon as possible.
316 /* When early edge is detected outside of the SJW field, synchronization request is latched and performed when
318 always @ (posedge clk or posedge rst)
321 resync_latched <= 1'b0;
322 else if (resync & seg2 & (~sync_window))
323 resync_latched <=#Tp 1'b1;
325 resync_latched <= 1'b0;
330 /* Synchronization stage/segment */
331 always @ (posedge clk or posedge rst)
340 /* Seg1 stage/segment (together with propagation segment which is 1 quant long) */
341 always @ (posedge clk or posedge rst)
352 /* Seg2 stage/segment */
353 always @ (posedge clk or posedge rst)
359 else if (go_sync | go_seg1)
365 always @ (posedge clk or posedge rst)
369 else if (go_sync | go_seg1 | go_seg2)
370 quant_cnt <=#Tp 5'h0;
372 quant_cnt <=#Tp quant_cnt + 1'b1;
376 /* When late edge is detected (in seg1 stage), stage seg1 is prolonged. */
377 always @ (posedge clk or posedge rst)
381 else if (resync & seg1 & (~transmitting | transmitting & (tx_next_sp | (tx & (~rx))))) // when transmitting 0 with positive error delay is set to 0
382 delay <=#Tp (quant_cnt > {3'h0, sync_jump_width})? ({2'h0, sync_jump_width} + 1'b1) : (quant_cnt + 1'b1);
383 else if (go_sync | go_seg1)
388 // If early edge appears within this window (in seg2 stage), phase error is fully compensated
389 assign sync_window = ((time_segment2 - quant_cnt[2:0]) < ( sync_jump_width + 1'b1));
392 // Sampling data (memorizing two samples all the time).
393 always @ (posedge clk or posedge rst)
398 sample <= {sample[0], rx};
402 // When enabled, tripple sampling is done here.
403 always @ (posedge clk or posedge rst)
408 sampled_bit_q <= 1'b1;
409 sample_point <= 1'b0;
411 else if (go_error_frame)
413 sampled_bit_q <=#Tp sampled_bit;
414 sample_point <=#Tp 1'b0;
416 else if (clk_en_q & (~hard_sync))
418 if (seg1 & (quant_cnt == (time_segment1 + delay)))
420 sample_point <=#Tp 1'b1;
421 sampled_bit_q <=#Tp sampled_bit;
423 sampled_bit <=#Tp (sample[0] & sample[1]) | ( sample[0] & rx) | (sample[1] & rx);
425 sampled_bit <=#Tp rx;
429 sample_point <=#Tp 1'b0;
433 // tx_next_sp shows next value that will be driven on the TX. When driving 1 and receiving 0 we
434 // need to synchronize (even when we are a transmitter)
435 always @ (posedge clk or posedge rst)
439 else if (go_overload_frame | (go_error_frame & (~node_error_passive)) | go_tx | send_ack)
440 tx_next_sp <=#Tp 1'b0;
441 else if (go_error_frame & node_error_passive)
442 tx_next_sp <=#Tp 1'b1;
443 else if (sample_point)
444 tx_next_sp <=#Tp tx_next;
449 /* Blocking synchronization (can occur only once in a bit time) */
451 always @ (posedge clk or posedge rst)
454 sync_blocked <=#Tp 1'b1;
458 sync_blocked <=#Tp 1'b1;
460 sync_blocked <=#Tp 1'b0;
465 /* Blocking hard synchronization when occurs once or when we are transmitting a msg */
466 always @ (posedge clk or posedge rst)
469 hard_sync_blocked <=#Tp 1'b0;
470 else if (hard_sync & clk_en_q | (transmitting & transmitter | go_tx) & tx_point & (~tx_next))
471 hard_sync_blocked <=#Tp 1'b1;
472 else if (go_rx_inter | (rx_idle | rx_inter) & sample_point & sampled_bit) // When a glitch performed synchronization
473 hard_sync_blocked <=#Tp 1'b0;