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

Subversion Repositories can

[/] [can/] [tags/] [rel_9/] [rtl/] [verilog/] [can_fifo.v] - Blame information for rev 161

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

powered by: WebSVN 2.1.0

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