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

Subversion Repositories can

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

powered by: WebSVN 2.1.0

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