OpenCores
URL https://opencores.org/ocsvn/can/can/trunk

Subversion Repositories can

[/] [can/] [trunk/] [rtl/] [verilog/] [can_fifo.v] - Blame information for rev 109

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 mohor
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  can_fifo.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 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 28 mohor
//// 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 11 mohor
//////////////////////////////////////////////////////////////////////
49
//
50
// CVS Revision History
51
//
52
// $Log: not supported by cvs2svn $
53 109 mohor
// Revision 1.19  2003/07/03 09:30:44  mohor
54
// PCI_BIST replaced with CAN_BIST.
55
//
56 99 mohor
// Revision 1.18  2003/06/27 22:14:23  simons
57
// Overrun fifo implemented with FFs, because it is not possible to create such a memory.
58
//
59 97 simons
// Revision 1.17  2003/06/27 20:56:15  simons
60
// Virtual silicon ram instances added.
61
//
62 95 simons
// Revision 1.16  2003/06/18 23:03:44  mohor
63
// Typo fixed.
64
//
65 85 mohor
// Revision 1.15  2003/06/11 09:37:05  mohor
66
// overrun and length_info fifos are initialized at the end of reset.
67
//
68 73 mohor
// Revision 1.14  2003/03/05 15:02:30  mohor
69
// Xilinx RAM added.
70
//
71 51 mohor
// Revision 1.13  2003/03/01 22:53:33  mohor
72
// Actel APA ram supported.
73
//
74 48 mohor
// Revision 1.12  2003/02/19 14:44:03  mohor
75
// CAN core finished. Host interface added. Registers finished.
76
// Synchronization to the wishbone finished.
77
//
78 39 mohor
// Revision 1.11  2003/02/14 20:17:01  mohor
79
// Several registers added. Not finished, yet.
80
//
81 35 mohor
// Revision 1.10  2003/02/11 00:56:06  mohor
82
// Wishbone interface added.
83
//
84 31 mohor
// Revision 1.9  2003/02/09 02:24:33  mohor
85
// Bosch license warning added. Error counters finished. Overload frames
86
// still need to be fixed.
87
//
88 28 mohor
// Revision 1.8  2003/01/31 01:13:38  mohor
89
// backup.
90
//
91 24 mohor
// Revision 1.7  2003/01/17 17:44:31  mohor
92
// Fifo corrected to be synthesizable.
93
//
94 23 mohor
// Revision 1.6  2003/01/15 13:16:47  mohor
95 31 mohor
// When a frame with "remote request" is received, no data is stored
96
// to fifo, just the frame information (identifier, ...). Data length
97
// that is stored is the received data length and not the actual data
98
// length that is stored to fifo.
99 23 mohor
//
100 18 mohor
// Revision 1.5  2003/01/14 17:25:09  mohor
101
// Addresses corrected to decimal values (previously hex).
102
//
103 17 mohor
// Revision 1.4  2003/01/14 12:19:35  mohor
104
// rx_fifo is now working.
105
//
106 16 mohor
// Revision 1.3  2003/01/09 21:54:45  mohor
107
// rx fifo added. Not 100 % verified, yet.
108
//
109 14 mohor
// Revision 1.2  2003/01/09 14:46:58  mohor
110
// Temporary files (backup).
111
//
112 13 mohor
// Revision 1.1  2003/01/08 02:10:55  mohor
113
// Acceptance filter added.
114 11 mohor
//
115
//
116
//
117 13 mohor
//
118 11 mohor
 
119
// synopsys translate_off
120
`include "timescale.v"
121
// synopsys translate_on
122
`include "can_defines.v"
123
 
124
module can_fifo
125
(
126
  clk,
127
  rst,
128
 
129
  wr,
130
 
131
  data_in,
132 14 mohor
  addr,
133 11 mohor
  data_out,
134 48 mohor
  fifo_selected,
135 11 mohor
 
136
  reset_mode,
137 14 mohor
  release_buffer,
138 35 mohor
  extended_mode,
139
  overrun,
140 39 mohor
  info_empty,
141
  info_cnt
142 13 mohor
 
143 95 simons
`ifdef CAN_BIST
144
  ,
145
  scanb_rst,
146
  scanb_clk,
147
  scanb_si,
148
  scanb_so,
149
  scanb_en
150
`endif
151 11 mohor
);
152
 
153
parameter Tp = 1;
154
 
155
input         clk;
156
input         rst;
157
input         wr;
158
input   [7:0] data_in;
159 109 mohor
input   [5:0] addr;
160 11 mohor
input         reset_mode;
161
input         release_buffer;
162 14 mohor
input         extended_mode;
163 48 mohor
input         fifo_selected;
164 11 mohor
 
165 13 mohor
output  [7:0] data_out;
166 35 mohor
output        overrun;
167
output        info_empty;
168 39 mohor
output  [6:0] info_cnt;
169 11 mohor
 
170 95 simons
`ifdef CAN_BIST
171
input         scanb_rst;
172
input         scanb_clk;
173
input         scanb_si;
174
output        scanb_so;
175
input         scanb_en;
176
wire          scanb_s_0;
177
`endif
178
 
179 48 mohor
`ifdef ACTEL_APA_RAM
180
`else
181 51 mohor
`ifdef XILINX_RAM
182
`else
183 95 simons
`ifdef VIRTUALSILICON_RAM
184 97 simons
  reg           overrun_info[0:63];
185 95 simons
`else
186 48 mohor
  reg     [7:0] fifo [0:63];
187
  reg     [3:0] length_fifo[0:63];
188
  reg           overrun_info[0:63];
189
`endif
190 51 mohor
`endif
191 95 simons
`endif
192 11 mohor
 
193
reg     [5:0] rd_pointer;
194
reg     [5:0] wr_pointer;
195 14 mohor
reg     [5:0] read_address;
196 16 mohor
reg     [5:0] wr_info_pointer;
197
reg     [5:0] rd_info_pointer;
198 13 mohor
reg           wr_q;
199
reg     [3:0] len_cnt;
200 16 mohor
reg     [6:0] fifo_cnt;
201 24 mohor
reg     [6:0] info_cnt;
202 16 mohor
reg           latch_overrun;
203 73 mohor
reg           initialize_memories;
204 11 mohor
 
205 48 mohor
wire    [3:0] length_info;
206 13 mohor
wire          write_length_info;
207 16 mohor
wire          fifo_empty;
208
wire          fifo_full;
209 24 mohor
wire          info_full;
210 11 mohor
 
211 13 mohor
assign write_length_info = (~wr) & wr_q;
212
 
213
// Delayed write signal
214
always @ (posedge clk or posedge rst)
215
begin
216
  if (rst)
217 109 mohor
    wr_q <=#Tp 1'b0;
218 13 mohor
  else if (reset_mode)
219 109 mohor
    wr_q <=#Tp 1'b0;
220 13 mohor
  else
221
    wr_q <=#Tp wr;
222
end
223
 
224
 
225
// length counter
226
always @ (posedge clk or posedge rst)
227
begin
228
  if (rst)
229 109 mohor
    len_cnt <= 4'h0;
230 13 mohor
  else if (reset_mode | write_length_info)
231 109 mohor
    len_cnt <=#Tp 4'h0;
232 16 mohor
  else if (wr & (~fifo_full))
233 13 mohor
    len_cnt <=#Tp len_cnt + 1'b1;
234
end
235
 
236
 
237
// wr_info_pointer
238
always @ (posedge clk or posedge rst)
239
begin
240
  if (rst)
241 109 mohor
    wr_info_pointer <= 6'h0;
242 73 mohor
  else if (write_length_info & (~info_full) | initialize_memories)
243
    wr_info_pointer <=#Tp wr_info_pointer + 1'b1;
244 13 mohor
  else if (reset_mode)
245 109 mohor
    wr_info_pointer <=#Tp 6'h0;
246 13 mohor
end
247
 
248
 
249
 
250
// rd_info_pointer
251 11 mohor
always @ (posedge clk or posedge rst)
252
begin
253
  if (rst)
254 109 mohor
    rd_info_pointer <= 6'h0;
255 11 mohor
  else if (reset_mode)
256 109 mohor
    rd_info_pointer <=#Tp 6'h0;
257 16 mohor
  else if (release_buffer & (~fifo_empty))
258 13 mohor
    rd_info_pointer <=#Tp rd_info_pointer + 1'b1;
259 11 mohor
end
260
 
261
 
262
// rd_pointer
263
always @ (posedge clk or posedge rst)
264
begin
265
  if (rst)
266 109 mohor
    rd_pointer <= 5'h0;
267 16 mohor
  else if (release_buffer & (~fifo_empty))
268 109 mohor
    rd_pointer <=#Tp rd_pointer + {2'h0, length_info};
269 11 mohor
  else if (reset_mode)
270 109 mohor
    rd_pointer <=#Tp 5'h0;
271 11 mohor
end
272
 
273
 
274
// wr_pointer
275
always @ (posedge clk or posedge rst)
276
begin
277
  if (rst)
278 109 mohor
    wr_pointer <= 5'h0;
279 16 mohor
  else if (wr & (~fifo_full))
280 13 mohor
    wr_pointer <=#Tp wr_pointer + 1'b1;
281 11 mohor
  else if (reset_mode)
282 109 mohor
    wr_pointer <=#Tp 5'h0;
283 11 mohor
end
284
 
285
 
286 16 mohor
// latch_overrun
287
always @ (posedge clk or posedge rst)
288
begin
289
  if (rst)
290 109 mohor
    latch_overrun <= 1'b0;
291 16 mohor
  else if (reset_mode | write_length_info)
292 109 mohor
    latch_overrun <=#Tp 1'b0;
293 16 mohor
  else if (wr & fifo_full)
294
    latch_overrun <=#Tp 1'b1;
295
end
296
 
297
 
298
// Counting data in fifo
299
always @ (posedge clk or posedge rst)
300
begin
301
  if (rst)
302 109 mohor
    fifo_cnt <= 7'h0;
303 16 mohor
  else if (wr & (~release_buffer) & (~fifo_full))
304
    fifo_cnt <=#Tp fifo_cnt + 1'b1;
305
  else if ((~wr) & release_buffer & (~fifo_empty))
306 109 mohor
    fifo_cnt <=#Tp fifo_cnt - {3'h0, length_info};
307 16 mohor
  else if (wr & release_buffer & (~fifo_full) & (~fifo_empty))
308 109 mohor
    fifo_cnt <=#Tp fifo_cnt - {3'h0, length_info} + 1'b1;
309 16 mohor
  else if (reset_mode)
310 109 mohor
    fifo_cnt <=#Tp 7'h0;
311 16 mohor
end
312
 
313 109 mohor
assign fifo_full = fifo_cnt == 7'd64;
314
assign fifo_empty = fifo_cnt == 7'd0;
315 16 mohor
 
316
 
317 48 mohor
// Counting data in length_fifo and overrun_info fifo
318 24 mohor
always @ (posedge clk or posedge rst)
319
begin
320
  if (rst)
321 109 mohor
    info_cnt <=#Tp 7'h0;
322
  else if (reset_mode)
323
    info_cnt <=#Tp 7'h0;
324 24 mohor
  else if (write_length_info ^ release_buffer)
325
    begin
326
      if (release_buffer & (~info_empty))
327
        info_cnt <=#Tp info_cnt - 1'b1;
328
      else if (write_length_info & (~info_full))
329
        info_cnt <=#Tp info_cnt + 1'b1;
330
    end
331
end
332
 
333 109 mohor
assign info_full = info_cnt == 7'd64;
334
assign info_empty = info_cnt == 7'd0;
335 16 mohor
 
336 24 mohor
 
337 14 mohor
// Selecting which address will be used for reading data from rx fifo
338
always @ (extended_mode or rd_pointer or addr)
339
begin
340
  if (extended_mode)      // extended mode
341 109 mohor
    read_address = rd_pointer + (addr - 6'd16);
342 14 mohor
  else                    // normal mode
343 109 mohor
    read_address = rd_pointer + (addr - 6'd20);
344 14 mohor
end
345 11 mohor
 
346
 
347 73 mohor
always @ (posedge clk or posedge rst)
348
begin
349
  if (rst)
350 109 mohor
    initialize_memories <= 1'b1;
351 73 mohor
  else if (&wr_info_pointer)
352
    initialize_memories <=#Tp 1'b0;
353
end
354 14 mohor
 
355 73 mohor
 
356 48 mohor
`ifdef ACTEL_APA_RAM
357
  actel_ram_64x8_sync fifo
358
  (
359
    .DO      (data_out),
360
    .RCLOCK  (clk),
361
    .WCLOCK  (clk),
362
    .DI      (data_in),
363
    .PO      (),                       // parity not used
364
    .WRB     (~(wr & (~fifo_full))),
365
    .RDB     (~fifo_selected),
366
    .WADDR   (wr_pointer),
367
    .RADDR   (read_address)
368
  );
369 14 mohor
 
370
 
371 48 mohor
  actel_ram_64x4_sync info_fifo
372
  (
373
    .DO      (length_info),
374
    .RCLOCK  (clk),
375
    .WCLOCK  (clk),
376 73 mohor
    .DI      (len_cnt & {4{~initialize_memories}}),
377 48 mohor
    .PO      (),                       // parity not used
378 73 mohor
    .WRB     (~(write_length_info & (~info_full) | initialize_memories)),
379 48 mohor
    .RDB     (1'b0),                   // always enabled
380
    .WADDR   (wr_info_pointer),
381
    .RADDR   (rd_info_pointer)
382
  );
383 14 mohor
 
384
 
385 48 mohor
  actel_ram_64x1_sync overrun_fifo
386
  (
387
    .DO      (overrun),
388
    .RCLOCK  (clk),
389
    .WCLOCK  (clk),
390 73 mohor
    .DI      ((latch_overrun | (wr & fifo_full)) & (~initialize_memories)),
391 48 mohor
    .PO      (),                       // parity not used
392 73 mohor
    .WRB     (~(write_length_info & (~info_full) | initialize_memories)),
393 48 mohor
    .RDB     (1'b0),                   // always enabled
394
    .WADDR   (wr_info_pointer),
395
    .RADDR   (rd_info_pointer)
396
  );
397
`else
398 51 mohor
`ifdef XILINX_RAM
399
 
400
/*
401
  ram_64x8_sync fifo
402
  (
403
    .addra(wr_pointer),
404
    .addrb(read_address),
405
    .clka(clk),
406
    .clkb(clk),
407
    .dina(data_in),
408
    .doutb(data_out),
409
    .wea(wr & (~fifo_full))
410
  );
411
*/
412
 
413
  RAMB4_S8_S8 fifo
414
  (
415
    .DOA(),
416
    .DOB(data_out),
417
    .ADDRA({3'h0, wr_pointer}),
418
    .CLKA(clk),
419
    .DIA(data_in),
420
    .ENA(1'b1),
421
    .RSTA(1'b0),
422
    .WEA(wr & (~fifo_full)),
423
    .ADDRB({3'h0, read_address}),
424
    .CLKB(clk),
425
    .DIB(8'h0),
426
    .ENB(1'b1),
427
    .RSTB(1'b0),
428
    .WEB(1'b0)
429
  );
430
 
431
 
432
 
433
/*
434
  ram_64x4_sync info_fifo
435
  (
436
    .addra(wr_info_pointer),
437
    .addrb(rd_info_pointer),
438
    .clka(clk),
439
    .clkb(clk),
440
    .dina(len_cnt),
441
    .doutb(length_info),
442
    .wea(write_length_info & (~info_full))
443
  );
444
*/
445
  RAMB4_S4_S4 info_fifo
446
  (
447
    .DOA(),
448
    .DOB(length_info),
449
    .ADDRA({4'h0, wr_info_pointer}),
450
    .CLKA(clk),
451 73 mohor
    .DIA(len_cnt & {4{~initialize_memories}}),
452 51 mohor
    .ENA(1'b1),
453
    .RSTA(1'b0),
454 73 mohor
    .WEA(write_length_info & (~info_full) | initialize_memories),
455 51 mohor
    .ADDRB({4'h0, rd_info_pointer}),
456
    .CLKB(clk),
457
    .DIB(4'h0),
458
    .ENB(1'b1),
459
    .RSTB(1'b0),
460
    .WEB(1'b0)
461
  );
462
 
463
/*
464
  ram_64x1_sync overrun_fifo
465
  (
466
    .addra(wr_info_pointer),
467
    .addrb(rd_info_pointer),
468
    .clka(clk),
469
    .clkb(clk),
470
    .dina(latch_overrun | (wr & fifo_full)),
471
    .doutb(overrun),
472
    .wea(write_length_info & (~info_full))
473
  );
474
*/
475
 
476
 
477
  RAMB4_S1_S1 overrun_fifo
478
  (
479
    .DOA(),
480
    .DOB(overrun),
481
    .ADDRA({6'h0, wr_info_pointer}),
482
    .CLKA(clk),
483 73 mohor
    .DIA((latch_overrun | (wr & fifo_full)) & (~initialize_memories)),
484 51 mohor
    .ENA(1'b1),
485
    .RSTA(1'b0),
486 73 mohor
    .WEA(write_length_info & (~info_full) | initialize_memories),
487 51 mohor
    .ADDRB({6'h0, rd_info_pointer}),
488
    .CLKB(clk),
489
    .DIB(1'h0),
490
    .ENB(1'b1),
491
    .RSTB(1'b0),
492
    .WEB(1'b0)
493
  );
494
 
495
 
496
`else
497 95 simons
`ifdef VIRTUALSILICON_RAM
498
 
499 99 mohor
`ifdef CAN_BIST
500 95 simons
    vs_hdtp_64x8_bist fifo
501
`else
502
    vs_hdtp_64x8 fifo
503
`endif
504
    (
505
        .RCK        (clk),
506
        .WCK        (clk),
507
        .RADR       (read_address),
508
        .WADR       (wr_pointer),
509
        .DI         (data_in),
510
        .DOUT       (data_out),
511
        .REN        (~fifo_selected),
512
        .WEN        (~(wr & (~fifo_full)))
513 99 mohor
    `ifdef CAN_BIST
514 95 simons
        ,
515
        // debug chain signals
516
        .scanb_rst  (scanb_rst),
517
        .scanb_clk  (scanb_clk),
518
        .scanb_si   (scanb_si),
519
        .scanb_so   (scanb_s_0),
520
        .scanb_en   (scanb_en)
521
    `endif
522
    );
523
 
524 99 mohor
`ifdef CAN_BIST
525 95 simons
    vs_hdtp_64x4_bist info_fifo
526
`else
527
    vs_hdtp_64x4 info_fifo
528
`endif
529
    (
530
        .RCK        (clk),
531
        .WCK        (clk),
532
        .RADR       (rd_info_pointer),
533
        .WADR       (wr_info_pointer),
534
        .DI         (len_cnt & {4{~initialize_memories}}),
535
        .DOUT       (length_info),
536
        .REN        (1'b0),
537
        .WEN        (~(write_length_info & (~info_full) | initialize_memories))
538 99 mohor
    `ifdef CAN_BIST
539 95 simons
        ,
540
        // debug chain signals
541
        .scanb_rst  (scanb_rst),
542
        .scanb_clk  (scanb_clk),
543
        .scanb_si   (scanb_s_0),
544
        .scanb_so   (scanb_so),
545
        .scanb_en   (scanb_en)
546
    `endif
547
    );
548
 
549 97 simons
    // overrun_info
550
    always @ (posedge clk)
551
    begin
552
      if (write_length_info & (~info_full) | initialize_memories)
553
        overrun_info[wr_info_pointer] <=#Tp (latch_overrun | (wr & fifo_full)) & (~initialize_memories);
554
    end
555
 
556
 
557
    // reading overrun
558
    assign overrun = overrun_info[rd_info_pointer];
559
 
560 95 simons
`else
561 48 mohor
  // writing data to fifo
562
  always @ (posedge clk)
563
  begin
564
    if (wr & (~fifo_full))
565
      fifo[wr_pointer] <=#Tp data_in;
566
  end
567
 
568
  // reading from fifo
569
  assign data_out = fifo[read_address];
570
 
571
 
572
  // writing length_fifo
573
  always @ (posedge clk)
574
  begin
575 85 mohor
    if (write_length_info & (~info_full) | initialize_memories)
576 73 mohor
      length_fifo[wr_info_pointer] <=#Tp len_cnt & {4{~initialize_memories}};
577 48 mohor
  end
578
 
579 73 mohor
 
580 48 mohor
  // reading length_fifo
581
  assign length_info = length_fifo[rd_info_pointer];
582
 
583
  // overrun_info
584
  always @ (posedge clk)
585
  begin
586 73 mohor
    if (write_length_info & (~info_full) | initialize_memories)
587
      overrun_info[wr_info_pointer] <=#Tp (latch_overrun | (wr & fifo_full)) & (~initialize_memories);
588 48 mohor
  end
589
 
590
 
591
  // reading overrun
592
  assign overrun = overrun_info[rd_info_pointer];
593
 
594
 
595
`endif
596 51 mohor
`endif
597 95 simons
`endif
598 48 mohor
 
599
 
600
 
601
 
602
 
603 11 mohor
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.