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

Subversion Repositories can

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

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

powered by: WebSVN 2.1.0

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