source: rc_os_nios2/DE0_Nano_QSYS_DEMO/canc/hdl/can_btl.v@ 128

Last change on this file since 128 was 128, checked in by ertl-honda, 9 years ago

追加.

File size: 13.8 KB
Line 
1//////////////////////////////////////////////////////////////////////
2//// ////
3//// can_btl.v ////
4//// ////
5//// ////
6//// This file is part of the CAN Protocol Controller ////
7//// http://www.opencores.org/projects/can/ ////
8//// ////
9//// ////
10//// Author(s): ////
11//// Igor Mohor ////
12//// igorm@opencores.org ////
13//// ////
14//// ////
15//// All additional information is available in the README.txt ////
16//// file. ////
17//// ////
18//////////////////////////////////////////////////////////////////////
19//// ////
20//// Copyright (C) 2002, 2003, 2004 Authors ////
21//// ////
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. ////
26//// ////
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. ////
32//// ////
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 ////
37//// details. ////
38//// ////
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 ////
42//// ////
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 ////
46//// from Bosch. ////
47//// ////
48//////////////////////////////////////////////////////////////////////
49//
50// CVS Revision History
51//
52// $Log: can_btl.v,v $
53// Revision 1.30 2004/10/27 18:51:37 igorm
54// Fixed synchronization problem in real hardware when 0xf is used for TSEG1.
55//
56// Revision 1.29 2004/05/12 15:58:41 igorm
57// Core improved to pass all tests with the Bosch VHDL Reference system.
58//
59// Revision 1.28 2004/02/08 14:25:26 mohor
60// Header changed.
61//
62// Revision 1.27 2003/09/30 00:55:13 mohor
63// Error counters fixed to be compatible with Bosch VHDL reference model.
64// Small synchronization changes.
65//
66// Revision 1.26 2003/09/25 18:55:49 mohor
67// Synchronization changed, error counters fixed.
68//
69// Revision 1.25 2003/07/16 13:40:35 mohor
70// Fixed according to the linter.
71//
72// Revision 1.24 2003/07/10 15:32:28 mohor
73// Unused signal removed.
74//
75// Revision 1.23 2003/07/10 01:59:04 tadejm
76// Synchronization fixed. In some strange cases it didn't work according to
77// the VHDL reference model.
78//
79// Revision 1.22 2003/07/07 11:21:37 mohor
80// Little fixes (to fix warnings).
81//
82// Revision 1.21 2003/07/03 09:32:20 mohor
83// Synchronization changed.
84//
85// Revision 1.20 2003/06/20 14:51:11 mohor
86// Previous change removed. When resynchronization occurs we go to seg1
87// stage. sync stage does not cause another start of seg1 stage.
88//
89// Revision 1.19 2003/06/20 14:28:20 mohor
90// When hard_sync or resync occure we need to go to seg1 segment. Going to
91// sync segment is in that case blocked.
92//
93// Revision 1.18 2003/06/17 15:53:33 mohor
94// clk_cnt reduced from [8:0] to [6:0].
95//
96// Revision 1.17 2003/06/17 14:32:17 mohor
97// Removed few signals.
98//
99// Revision 1.16 2003/06/16 13:57:58 mohor
100// tx_point generated one clk earlier. rx_i registered. Data corrected when
101// using extended mode.
102//
103// Revision 1.15 2003/06/13 15:02:24 mohor
104// Synchronization is also needed when transmitting a message.
105//
106// Revision 1.14 2003/06/13 14:55:11 mohor
107// Counters width changed.
108//
109// Revision 1.13 2003/06/11 14:21:35 mohor
110// When switching to tx, sync stage is overjumped.
111//
112// Revision 1.12 2003/02/14 20:17:01 mohor
113// Several registers added. Not finished, yet.
114//
115// Revision 1.11 2003/02/09 18:40:29 mohor
116// Overload fixed. Hard synchronization also enabled at the last bit of
117// interframe.
118//
119// Revision 1.10 2003/02/09 02:24:33 mohor
120// Bosch license warning added. Error counters finished. Overload frames
121// still need to be fixed.
122//
123// Revision 1.9 2003/01/31 01:13:38 mohor
124// backup.
125//
126// Revision 1.8 2003/01/10 17:51:34 mohor
127// Temporary version (backup).
128//
129// Revision 1.7 2003/01/08 02:10:53 mohor
130// Acceptance filter added.
131//
132// Revision 1.6 2002/12/28 04:13:23 mohor
133// Backup version.
134//
135// Revision 1.5 2002/12/27 00:12:52 mohor
136// Header changed, testbench improved to send a frame (crc still missing).
137//
138// Revision 1.4 2002/12/26 01:33:05 mohor
139// Tripple sampling supported.
140//
141// Revision 1.3 2002/12/25 23:44:16 mohor
142// Commented lines removed.
143//
144// Revision 1.2 2002/12/25 14:17:00 mohor
145// Synchronization working.
146//
147// Revision 1.1.1.1 2002/12/20 16:39:21 mohor
148// Initial
149//
150//
151//
152
153// synopsys translate_off
154`include "timescale.v"
155// synopsys translate_on
156`include "can_defines.v"
157
158module can_btl
159(
160 clk,
161 rst,
162 rx,
163 tx,
164
165 /* Bus Timing 0 register */
166 baud_r_presc,
167 sync_jump_width,
168
169 /* Bus Timing 1 register */
170 time_segment1,
171 time_segment2,
172 triple_sampling,
173
174 /* Output signals from this module */
175 sample_point,
176 sampled_bit,
177 sampled_bit_q,
178 tx_point,
179 hard_sync,
180
181 /* Output from can_bsp module */
182 rx_idle,
183 rx_inter,
184 transmitting,
185 transmitter,
186 go_rx_inter,
187 tx_next,
188
189 go_overload_frame,
190 go_error_frame,
191 go_tx,
192 send_ack,
193 node_error_passive
194);
195
196parameter Tp = 1;
197
198input clk;
199input rst;
200input rx;
201input tx;
202
203
204/* Bus Timing 0 register */
205input [5:0] baud_r_presc;
206input [1:0] sync_jump_width;
207
208/* Bus Timing 1 register */
209input [3:0] time_segment1;
210input [2:0] time_segment2;
211input triple_sampling;
212
213/* Output from can_bsp module */
214input rx_idle;
215input rx_inter;
216input transmitting;
217input transmitter;
218input go_rx_inter;
219input tx_next;
220
221input go_overload_frame;
222input go_error_frame;
223input go_tx;
224input send_ack;
225input node_error_passive;
226
227/* Output signals from this module */
228output sample_point;
229output sampled_bit;
230output sampled_bit_q;
231output tx_point;
232output hard_sync;
233
234reg [6:0] clk_cnt;
235reg clk_en;
236reg clk_en_q;
237reg sync_blocked;
238reg hard_sync_blocked;
239reg sampled_bit;
240reg sampled_bit_q;
241reg [4:0] quant_cnt;
242reg [3:0] delay;
243reg sync;
244reg seg1;
245reg seg2;
246reg resync_latched;
247reg sample_point;
248reg [1:0] sample;
249reg tx_point;
250reg tx_next_sp;
251
252wire go_sync;
253wire go_seg1;
254wire go_seg2;
255wire [7:0] preset_cnt;
256wire sync_window;
257wire resync;
258
259
260assign preset_cnt = (baud_r_presc + 1'b1)<<1; // (BRP+1)*2
261assign hard_sync = (rx_idle | rx_inter) & (~rx) & sampled_bit & (~hard_sync_blocked); // Hard synchronization
262assign resync = (~rx_idle) & (~rx_inter) & (~rx) & sampled_bit & (~sync_blocked); // Re-synchronization
263
264
265
266/* Generating general enable signal that defines baud rate. */
267always @ (posedge clk or posedge rst)
268begin
269 if (rst)
270 clk_cnt <= 7'h0;
271 else if (clk_cnt >= (preset_cnt-1'b1))
272 clk_cnt <=#Tp 7'h0;
273 else
274 clk_cnt <=#Tp clk_cnt + 1'b1;
275end
276
277
278always @ (posedge clk or posedge rst)
279begin
280 if (rst)
281 clk_en <= 1'b0;
282 else if ({1'b0, clk_cnt} == (preset_cnt-1'b1))
283 clk_en <=#Tp 1'b1;
284 else
285 clk_en <=#Tp 1'b0;
286end
287
288
289
290always @ (posedge clk or posedge rst)
291begin
292 if (rst)
293 clk_en_q <= 1'b0;
294 else
295 clk_en_q <=#Tp clk_en;
296end
297
298
299
300/* Changing states */
301assign go_sync = clk_en_q & seg2 & (quant_cnt[2:0] == time_segment2) & (~hard_sync) & (~resync);
302assign go_seg1 = clk_en_q & (sync | hard_sync | (resync & seg2 & sync_window) | (resync_latched & sync_window));
303assign go_seg2 = clk_en_q & (seg1 & (~hard_sync) & (quant_cnt == (time_segment1 + delay)));
304
305
306
307always @ (posedge clk or posedge rst)
308begin
309 if (rst)
310 tx_point <= 1'b0;
311 else
312 tx_point <=#Tp ~tx_point & seg2 & ( clk_en & (quant_cnt[2:0] == time_segment2)
313 | (clk_en | clk_en_q) & (resync | hard_sync)
314 ); // When transmitter we should transmit as soon as possible.
315end
316
317
318
319/* When early edge is detected outside of the SJW field, synchronization request is latched and performed when
320 SJW is reached */
321always @ (posedge clk or posedge rst)
322begin
323 if (rst)
324 resync_latched <= 1'b0;
325 else if (resync & seg2 & (~sync_window))
326 resync_latched <=#Tp 1'b1;
327 else if (go_seg1)
328 resync_latched <= 1'b0;
329end
330
331
332
333/* Synchronization stage/segment */
334always @ (posedge clk or posedge rst)
335begin
336 if (rst)
337 sync <= 1'b0;
338 else if (clk_en_q)
339 sync <=#Tp go_sync;
340end
341
342
343/* Seg1 stage/segment (together with propagation segment which is 1 quant long) */
344always @ (posedge clk or posedge rst)
345begin
346 if (rst)
347 seg1 <= 1'b1;
348 else if (go_seg1)
349 seg1 <=#Tp 1'b1;
350 else if (go_seg2)
351 seg1 <=#Tp 1'b0;
352end
353
354
355/* Seg2 stage/segment */
356always @ (posedge clk or posedge rst)
357begin
358 if (rst)
359 seg2 <= 1'b0;
360 else if (go_seg2)
361 seg2 <=#Tp 1'b1;
362 else if (go_sync | go_seg1)
363 seg2 <=#Tp 1'b0;
364end
365
366
367/* Quant counter */
368always @ (posedge clk or posedge rst)
369begin
370 if (rst)
371 quant_cnt <= 5'h0;
372 else if (go_sync | go_seg1 | go_seg2)
373 quant_cnt <=#Tp 5'h0;
374 else if (clk_en_q)
375 quant_cnt <=#Tp quant_cnt + 1'b1;
376end
377
378
379/* When late edge is detected (in seg1 stage), stage seg1 is prolonged. */
380always @ (posedge clk or posedge rst)
381begin
382 if (rst)
383 delay <= 4'h0;
384 else if (resync & seg1 & (~transmitting | transmitting & (tx_next_sp | (tx & (~rx))))) // when transmitting 0 with positive error delay is set to 0
385 delay <=#Tp (quant_cnt > {3'h0, sync_jump_width})? ({2'h0, sync_jump_width} + 1'b1) : (quant_cnt + 1'b1);
386 else if (go_sync | go_seg1)
387 delay <=#Tp 4'h0;
388end
389
390
391// If early edge appears within this window (in seg2 stage), phase error is fully compensated
392assign sync_window = ((time_segment2 - quant_cnt[2:0]) < ( sync_jump_width + 1'b1));
393
394
395// Sampling data (memorizing two samples all the time).
396always @ (posedge clk or posedge rst)
397begin
398 if (rst)
399 sample <= 2'b11;
400 else if (clk_en_q)
401 sample <= {sample[0], rx};
402end
403
404
405// When enabled, tripple sampling is done here.
406always @ (posedge clk or posedge rst)
407begin
408 if (rst)
409 begin
410 sampled_bit <= 1'b1;
411 sampled_bit_q <= 1'b1;
412 sample_point <= 1'b0;
413 end
414 else if (go_error_frame)
415 begin
416 sampled_bit_q <=#Tp sampled_bit;
417 sample_point <=#Tp 1'b0;
418 end
419 else if (clk_en_q & (~hard_sync))
420 begin
421 if (seg1 & (quant_cnt == (time_segment1 + delay)))
422 begin
423 sample_point <=#Tp 1'b1;
424 sampled_bit_q <=#Tp sampled_bit;
425 if (triple_sampling)
426 sampled_bit <=#Tp (sample[0] & sample[1]) | ( sample[0] & rx) | (sample[1] & rx);
427 else
428 sampled_bit <=#Tp rx;
429 end
430 end
431 else
432 sample_point <=#Tp 1'b0;
433end
434
435
436// tx_next_sp shows next value that will be driven on the TX. When driving 1 and receiving 0 we
437// need to synchronize (even when we are a transmitter)
438always @ (posedge clk or posedge rst)
439begin
440 if (rst)
441 tx_next_sp <= 1'b0;
442 else if (go_overload_frame | (go_error_frame & (~node_error_passive)) | go_tx | send_ack)
443 tx_next_sp <=#Tp 1'b0;
444 else if (go_error_frame & node_error_passive)
445 tx_next_sp <=#Tp 1'b1;
446 else if (sample_point)
447 tx_next_sp <=#Tp tx_next;
448end
449
450
451
452/* Blocking synchronization (can occur only once in a bit time) */
453
454always @ (posedge clk or posedge rst)
455begin
456 if (rst)
457 sync_blocked <=#Tp 1'b1;
458 else if (clk_en_q)
459 begin
460 if (resync)
461 sync_blocked <=#Tp 1'b1;
462 else if (go_seg2)
463 sync_blocked <=#Tp 1'b0;
464 end
465end
466
467
468/* Blocking hard synchronization when occurs once or when we are transmitting a msg */
469always @ (posedge clk or posedge rst)
470begin
471 if (rst)
472 hard_sync_blocked <=#Tp 1'b0;
473 else if (hard_sync & clk_en_q | (transmitting & transmitter | go_tx) & tx_point & (~tx_next))
474 hard_sync_blocked <=#Tp 1'b1;
475 else if (go_rx_inter | (rx_idle | rx_inter) & sample_point & sampled_bit) // When a glitch performed synchronization
476 hard_sync_blocked <=#Tp 1'b0;
477end
478
479
480
481
482
483endmodule
484
Note: See TracBrowser for help on using the repository browser.