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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [rtl/] [verilog/] [ethmac/] [eth_fifo.v] - Blame information for rev 501

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

Line No. Rev Author Line
1 6 julius
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  eth_fifo.v                                                  ////
4
////                                                              ////
5
////  This file is part of the Ethernet IP core project           ////
6 439 julius
////  http://www.opencores.org/project,ethmac                     ////
7 6 julius
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - Igor Mohor (igorM@opencores.org)                      ////
10 439 julius
////      - Julius Baxter (julius@opencores.org)                  ////
11 6 julius
////                                                              ////
12
////  All additional information is avaliable in the Readme.txt   ////
13
////  file.                                                       ////
14
////                                                              ////
15
//////////////////////////////////////////////////////////////////////
16
////                                                              ////
17
//// Copyright (C) 2001 Authors                                   ////
18
////                                                              ////
19
//// This source file may be used and distributed without         ////
20
//// restriction provided that this copyright statement is not    ////
21
//// removed from the file and that any derivative work contains  ////
22
//// the original copyright notice and the associated disclaimer. ////
23
////                                                              ////
24
//// This source file is free software; you can redistribute it   ////
25
//// and/or modify it under the terms of the GNU Lesser General   ////
26
//// Public License as published by the Free Software Foundation; ////
27
//// either version 2.1 of the License, or (at your option) any   ////
28
//// later version.                                               ////
29
////                                                              ////
30
//// This source is distributed in the hope that it will be       ////
31
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
32
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
33
//// PURPOSE.  See the GNU Lesser General Public License for more ////
34
//// details.                                                     ////
35
////                                                              ////
36
//// You should have received a copy of the GNU Lesser General    ////
37
//// Public License along with this source; if not, download it   ////
38
//// from http://www.opencores.org/lgpl.shtml                     ////
39
////                                                              ////
40
//////////////////////////////////////////////////////////////////////
41
 
42 409 julius
`include "ethmac_defines.v"
43 6 julius
`include "timescale.v"
44
 
45 439 julius
module eth_fifo (data_in, data_out, clk, reset, write, read, clear,
46
                 almost_full, full, almost_empty, empty, cnt);
47 6 julius
 
48
parameter DATA_WIDTH    = 32;
49
parameter DEPTH         = 8;
50 439 julius
parameter CNT_WIDTH     = 3;
51 6 julius
 
52
input                     clk;
53
input                     reset;
54
input                     write;
55
input                     read;
56
input                     clear;
57
input   [DATA_WIDTH-1:0]  data_in;
58
 
59
output  [DATA_WIDTH-1:0]  data_out;
60
output                    almost_full;
61
output                    full;
62
output                    almost_empty;
63
output                    empty;
64
output  [CNT_WIDTH-1:0]   cnt;
65
 
66
 
67 485 julius
reg     [CNT_WIDTH-1:0]   read_pointer;
68 403 julius
reg [CNT_WIDTH-1:0]        cnt;
69 485 julius
reg                       final_read;
70 403 julius
 
71 6 julius
always @ (posedge clk or posedge reset)
72
begin
73
  if(reset)
74 403 julius
    cnt <= 0;
75 6 julius
  else
76
  if(clear)
77 403 julius
    cnt <= { {(CNT_WIDTH-1){1'b0}}, read^write};
78 6 julius
  else
79
  if(read ^ write)
80
    if(read)
81 439 julius
      cnt <= cnt - 1;
82 6 julius
    else
83 439 julius
      cnt <= cnt + 1;
84 6 julius
end
85
 
86 403 julius
 
87
`ifdef ETH_FIFO_GENERIC
88
 
89
   reg     [DATA_WIDTH-1:0]  fifo  [0:DEPTH-1] /*synthesis syn_ramstyle = "no_rw_check"*/ ;
90
 
91
 
92 439 julius
   // This should make the synthesis tool infer a RAM
93
   reg [CNT_WIDTH-1:0] waddr, raddr, raddr_reg;
94
   reg                 clear_reg; // Register the clear pulse
95
 
96
   reg                 fallthrough_read;
97
   reg [CNT_WIDTH-1:0] fallthrough_read_addr;
98
 
99 403 julius
 
100
   always @(posedge clk)
101
     if (reset)
102 439 julius
       fallthrough_read <= 0;
103
     else
104
       fallthrough_read <= empty & write;
105
 
106
   always @(posedge clk)
107
     if (empty & write)
108
       fallthrough_read_addr <= waddr;
109
 
110
   always @(posedge clk)
111
     if (reset)
112 403 julius
       waddr <= 0;
113
     else if (write)
114
       waddr <= waddr + 1;
115
 
116
   always @(posedge clk)
117
     if (reset)
118
       raddr <= 0;
119
     else if (clear)
120
       raddr <= waddr;
121 439 julius
     else if (read | clear_reg)
122 403 julius
       raddr <= raddr + 1;
123
 
124
   always @ (posedge clk)
125
     if (write & ~full)
126
       fifo[waddr] <=  data_in;
127
 
128
 
129
   always @(posedge clk)
130
     clear_reg <= clear;
131
 
132
   always @ (posedge clk)
133
     if (read | clear_reg)
134
       raddr_reg <= raddr;
135 439 julius
     else if (fallthrough_read) // To pulse RE for fall-through on Xilinx
136
       raddr_reg <= fallthrough_read_addr;
137 403 julius
 
138
   assign  data_out = fifo[raddr_reg];
139
 
140
 
141
   always @(posedge clk)
142
     if (reset)
143
       final_read <= 0;
144
     else if (final_read & read & !write)
145
       final_read <= ~final_read;
146
     else if ((cnt == 1) & read & !write)
147
       final_read <= 1; // Indicate last read data has been output
148
 
149
   assign empty = ~(|cnt);
150
   assign almost_empty = cnt==1;
151 439 julius
   assign full  = {{32-CNT_WIDTH{1'b0}},cnt} == (DEPTH-1);
152 485 julius
   //assign almost_full  = &cnt[CNT_WIDTH-1:0];
153
   assign almost_full  = {{32-CNT_WIDTH{1'b0}},cnt} == (DEPTH-2);
154 403 julius
 
155 485 julius
 
156
 
157
always @ (posedge clk or posedge reset)
158
begin
159
  if(reset)
160
    read_pointer <= 0;
161
  else
162
  if(clear)
163
    // Begin read pointer at 1
164
    read_pointer <= { {(CNT_WIDTH-1){1'b0}}, 1'b1};
165
  else
166
  if(read & ~empty)
167
    read_pointer <= read_pointer + 1'b1;
168
end
169
 
170
 
171 403 julius
`else // !`ifdef ETH_FIFO_GENERIC
172 485 julius
 
173 439 julius
reg     [CNT_WIDTH-1:0]   write_pointer;
174 403 julius
 
175
 
176 6 julius
always @ (posedge clk or posedge reset)
177
begin
178
  if(reset)
179 403 julius
    read_pointer <= 0;
180 6 julius
  else
181
  if(clear)
182 485 julius
    read_pointer <= { {(CNT_WIDTH-1){1'b0}}, read};
183 6 julius
  else
184
  if(read & ~empty)
185 403 julius
    read_pointer <= read_pointer + 1'b1;
186 6 julius
end
187
 
188
always @ (posedge clk or posedge reset)
189
begin
190
  if(reset)
191 403 julius
    write_pointer <= 0;
192 6 julius
  else
193
  if(clear)
194 439 julius
    write_pointer <= { {(CNT_WIDTH-1){1'b0}}, write};
195 6 julius
  else
196
  if(write & ~full)
197 403 julius
    write_pointer <= write_pointer + 1'b1;
198 6 julius
end
199
 
200 485 julius
 `ifdef ETH_FIFO_XILINX
201
 
202
  generate
203
     if (CNT_WIDTH==4)
204
       begin
205
          xilinx_dist_ram_16x32 fifo
206
            ( .data_out(data_out),
207
              .we(write & ~full),
208
              .data_in(data_in),
209
              .read_address( clear ? {CNT_WIDTH-1{1'b0}} : read_pointer[3:0]),
210
              .write_address(clear ? {CNT_WIDTH-1{1'b0}} : write_pointer[3:0]),
211
              .wclk(clk)
212
              );
213
       end // if (CNT_WIDTH==4)
214
     else if (CNT_WIDTH==6)
215
       begin
216
 
217
          wire  [DATA_WIDTH-1:0]  data_out0;
218
          wire [DATA_WIDTH-1:0]   data_out1;
219
          wire [DATA_WIDTH-1:0]   data_out2;
220
          wire [DATA_WIDTH-1:0]   data_out3;
221
 
222
          wire                    ramsel0,ramsel1,ramsel2,ramsel3;
223
 
224
          assign ramsel0 = (read_pointer[5:4]==2'b00);
225
          assign ramsel1 = (read_pointer[5:4]==2'b01);
226
          assign ramsel2 = (read_pointer[5:4]==2'b10);
227
          assign ramsel3 = (read_pointer[5:4]==2'b11);
228
 
229
          assign data_out =  ramsel3 ? data_out3 :
230
                             ramsel2 ? data_out2 :
231
                             ramsel1 ? data_out1 : data_out0;
232
 
233
          xilinx_dist_ram_16x32 fifo0
234
            ( .data_out(data_out0),
235
              .we((write & ~full) & ramsel0),
236
              .data_in(data_in),
237
              .read_address( clear ? {CNT_WIDTH-1{1'b0}} : read_pointer[3:0]),
238
              .write_address(clear ? {CNT_WIDTH-1{1'b0}} : write_pointer[3:0]),
239
              .wclk(clk)
240
              );
241
 
242
          xilinx_dist_ram_16x32 fifo1
243
            ( .data_out(data_out1),
244
              .we(write & ~full & ramsel1),
245
              .data_in(data_in),
246
              .read_address( clear ? {CNT_WIDTH-1{1'b0}} : read_pointer[3:0]),
247
              .write_address(clear ? {CNT_WIDTH-1{1'b0}} : write_pointer[3:0]),
248
              .wclk(clk)
249
              );
250
 
251
          xilinx_dist_ram_16x32 fifo2
252
            ( .data_out(data_out2),
253
              .we(write & ~full & ramsel2),
254
              .data_in(data_in),
255
              .read_address( clear ? {CNT_WIDTH-1{1'b0}} : read_pointer[3:0]),
256
              .write_address(clear ? {CNT_WIDTH-1{1'b0}} : write_pointer[3:0]),
257
              .wclk(clk)
258
              );
259
 
260
          xilinx_dist_ram_16x32 fifo3
261
            ( .data_out(data_out3),
262
              .we(write & ~full & ramsel3),
263
              .data_in(data_in),
264
              .read_address( clear ? {CNT_WIDTH-1{1'b0}} : read_pointer[3:0]),
265
              .write_address(clear ? {CNT_WIDTH-1{1'b0}} : write_pointer[3:0]),
266
              .wclk(clk)
267
              );
268
       end // if (CNT_WIDTH==6)
269
  endgenerate
270
 
271
 
272
 
273
 
274
 
275 6 julius
`else   // !ETH_FIFO_XILINX
276
`ifdef ETH_ALTERA_ALTSYNCRAM
277
  altera_dpram_16x32    altera_dpram_16x32_inst
278 403 julius
  (
279
        .data             (data_in),
280
        .wren             (write & ~full),
281
        .wraddress        (clear ? {CNT_WIDTH-1{1'b0}} : write_pointer),
282
        .rdaddress        (clear ? {CNT_WIDTH-1{1'b0}} : read_pointer ),
283
        .clock            (clk),
284
        .q                (data_out)
285
  );  //exemplar attribute altera_dpram_16x32_inst NOOPT TRUE
286
`endif //  `ifdef ETH_ALTERA_ALTSYNCRAM
287
`endif // !`ifdef ETH_FIFO_XILINX
288 6 julius
 
289
 
290 403 julius
assign empty = ~(|cnt);
291
assign almost_empty = cnt == 1;
292 439 julius
assign full  = cnt == (DEPTH-1);
293
assign almost_full  = &cnt[CNT_WIDTH-1:0];
294 6 julius
 
295 403 julius
`endif // !`ifdef ETH_FIFO_GENERIC
296
 
297 6 julius
 
298
 
299
endmodule

powered by: WebSVN 2.1.0

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