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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [orpsocv2/] [boards/] [actel/] [ordb1a3pe1500/] [rtl/] [verilog/] [versatile_mem_ctrl/] [rtl/] [verilog/] [egress_fifo.v] - Blame information for rev 411

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

Line No. Rev Author Line
1 408 julius
// async FIFO with multiple queues, multiple data
2
`define ORIGINAL_EGRESS_FIFO
3
`ifdef ORIGINAL_EGRESS_FIFO
4
module egress_fifo (
5
    d, fifo_full, write, write_enable, clk1, rst1,
6
    q, fifo_empty, read_adr, read_data, read_enable, clk2, rst2
7
);
8
 
9
parameter a_hi_size = 4;
10
parameter a_lo_size = 4;
11
parameter nr_of_queues = 16;
12
parameter data_width = 36;
13
 
14
input [data_width*nr_of_queues-1:0] d;
15
output [0:nr_of_queues-1] fifo_full;
16
input                     write;
17
input  [0:nr_of_queues-1] write_enable;
18
input clk1;
19
input rst1;
20
 
21
output reg [data_width-1:0] q;
22
output [0:nr_of_queues-1] fifo_empty;
23
input                     read_adr, read_data;
24
input  [0:nr_of_queues-1] read_enable;
25
input clk2;
26
input rst2;
27
 
28
wire [data_width-1:0] fifo_q;
29
 
30
wire [a_lo_size-1:0]  fifo_wadr_bin[0:nr_of_queues-1];
31
wire [a_lo_size-1:0]  fifo_wadr_gray[0:nr_of_queues-1];
32
wire [a_lo_size-1:0]  fifo_radr_bin[0:nr_of_queues-1];
33
wire [a_lo_size-1:0]  fifo_radr_gray[0:nr_of_queues-1];
34
reg [a_lo_size-1:0] wadr;
35
reg [a_lo_size-1:0] radr;
36
reg [data_width-1:0] wdata;
37
wire [data_width-1:0] wdataa[0:nr_of_queues-1];
38
 
39
reg read_adr_reg;
40
reg [0:nr_of_queues-1] read_enable_reg;
41
 
42
genvar i;
43
integer j,k,l;
44
 
45
function [a_lo_size-1:0] onehot2bin;
46
input [0:nr_of_queues-1] a;
47
integer i;
48
begin
49
    onehot2bin = {a_lo_size{1'b0}};
50
    for (i=1;i<nr_of_queues;i=i+1) begin
51
        if (a[i])
52
            onehot2bin = i;
53
    end
54
end
55
endfunction
56
 
57
// a pipeline stage for address read gives higher clock frequency but adds one 
58
// clock latency for adr read
59
always @ (posedge clk2 or posedge rst2)
60
if (rst2)
61
    read_adr_reg <= 1'b0;
62
else
63
    read_adr_reg <= read_adr;
64
 
65
always @ (posedge clk2 or posedge rst2)
66
if (rst2)
67
    read_enable_reg <= {nr_of_queues{1'b0}};
68
else
69
    if (read_adr)
70
        read_enable_reg <= read_enable;
71
 
72
 
73
generate
74
    for (i=0;i<nr_of_queues;i=i+1) begin : fifo_adr
75
 
76
        gray_counter wadrcnt (
77
            .cke(write & write_enable[i]),
78
            .q(fifo_wadr_gray[i]),
79
            .q_bin(fifo_wadr_bin[i]),
80
            .rst(rst1),
81
            .clk(clk1));
82
 
83
        gray_counter radrcnt (
84
            .cke((read_adr_reg | read_data) & read_enable_reg[i]),
85
            .q(fifo_radr_gray[i]),
86
            .q_bin(fifo_radr_bin[i]),
87
            .rst(rst2),
88
            .clk(clk2));
89
 
90
        versatile_fifo_async_cmp
91
            #(.ADDR_WIDTH(a_lo_size))
92
            egresscmp (
93
                .wptr(fifo_wadr_gray[i]),
94
                .rptr(fifo_radr_gray[i]),
95
                .fifo_empty(fifo_empty[i]),
96
                .fifo_full(fifo_full[i]),
97
                .wclk(clk1),
98
                .rclk(clk2),
99
                .rst(rst1));
100
 
101
    end
102
endgenerate
103
 
104
// and-or mux write address
105
always @*
106
begin
107
    wadr = {a_lo_size{1'b0}};
108
    for (j=0;j<nr_of_queues;j=j+1) begin
109
        wadr = (fifo_wadr_bin[j] & {a_lo_size{write_enable[j]}}) | wadr;
110
    end
111
end
112
 
113
// and-or mux read address
114
always @*
115
begin
116
    radr = {a_lo_size{1'b0}};
117
    for (k=0;k<nr_of_queues;k=k+1) begin
118
        radr = (fifo_radr_bin[k] & {a_lo_size{read_enable_reg[k]}}) | radr;
119
    end
120
end
121
 
122
// and-or mux write data
123
generate
124
    for (i=0;i<nr_of_queues;i=i+1) begin : vector2array
125
        assign wdataa[i] = d[(nr_of_queues-i)*data_width-1:(nr_of_queues-1-i)*data_width];
126
    end
127
endgenerate
128
 
129
always @*
130
begin
131
    wdata = {data_width{1'b0}};
132
    for (l=0;l<nr_of_queues;l=l+1) begin
133
        wdata = (wdataa[l] & {data_width{write_enable[l]}}) | wdata;
134
    end
135
end
136
 
137
 
138
 
139
vfifo_dual_port_ram_dc_sw
140
  # (
141
      .DATA_WIDTH(data_width),
142
      .ADDR_WIDTH(a_hi_size+a_lo_size)
143
      )
144
    dpram (
145
    .d_a(wdata),
146
    .adr_a({onehot2bin(write_enable),wadr}),
147
    .we_a(write),
148
    .clk_a(clk1),
149
    .q_b(fifo_q),
150
    .adr_b({onehot2bin(read_enable_reg),radr}),
151
    .clk_b(clk2) );
152
 
153
   // Added registering of FIFO output to break a timing path
154
   always@(posedge clk2)
155
     q <= fifo_q;
156
 
157
 
158
endmodule
159
`else // !`ifdef ORIGINAL_EGRESS_FIFO
160
module egress_fifo (
161
    d, fifo_full, write, write_enable, clk1, rst1,
162
    q, fifo_empty, read_adr, read_data, read_enable, clk2, rst2
163
);
164
 
165
parameter a_hi_size = 2;
166
parameter a_lo_size = 4;
167
parameter nr_of_queues = 16;
168
parameter data_width = 36;
169
 
170
input [data_width*nr_of_queues-1:0] d;
171
output [0:nr_of_queues-1] fifo_full;
172
input                     write;
173
input  [0:nr_of_queues-1] write_enable;
174
input clk1;
175
input rst1;
176
 
177
output reg [data_width-1:0] q;
178
output [0:nr_of_queues-1] fifo_empty;
179
input                     read_adr, read_data;
180
input  [0:nr_of_queues-1] read_enable;
181
input clk2;
182
input rst2;
183
 
184
wire [data_width-1:0] fifo_q;
185
 
186
wire [a_lo_size-1:0]  fifo_wadr_bin[0:nr_of_queues-1];
187
wire [a_lo_size-1:0]  fifo_wadr_gray[0:nr_of_queues-1];
188
wire [a_lo_size-1:0]  fifo_radr_bin[0:nr_of_queues-1];
189
wire [a_lo_size-1:0]  fifo_radr_gray[0:nr_of_queues-1];
190
wire [a_lo_size-1:0] wadr;
191
wire [a_lo_size-1:0] radr;
192
wire [data_width-1:0] wdata;
193
wire [data_width-1:0] wdataa[0:nr_of_queues-1];
194
 
195
reg read_adr_reg;
196
reg [0:nr_of_queues-1] read_enable_reg;
197
 
198
genvar i;
199
integer j,k,l;
200
 
201
// a pipeline stage for address read gives higher clock frequency but adds one 
202
// clock latency for adr read
203
always @ (posedge clk2 or posedge rst2)
204
if (rst2)
205
    read_adr_reg <= 1'b0;
206
else
207
    read_adr_reg <= read_adr;
208
 
209
always @ (posedge clk2 or posedge rst2)
210
if (rst2)
211
    read_enable_reg <= {nr_of_queues{1'b0}};
212
else
213
    if (read_adr)
214
        read_enable_reg <= read_enable;
215
 
216
   // 0        
217
   gray_counter wadrcnt0
218
     (
219
      .cke(write & write_enable[0]),
220
      .q(fifo_wadr_gray[0]),
221
      .q_bin(fifo_wadr_bin[0]),
222
      .rst(rst1),
223
      .clk(clk1)
224
      );
225
 
226
   gray_counter radrcnt0
227
     (
228
      .cke((read_adr_reg | read_data) & read_enable_reg[0]),
229
      .q(fifo_radr_gray[0]),
230
      .q_bin(fifo_radr_bin[0]),
231
      .rst(rst2),
232
      .clk(clk2)
233
      );
234
 
235
   versatile_fifo_async_cmp
236
     #(
237
      .ADDR_WIDTH(a_lo_size)
238
      )
239
   egresscmp0
240
     (
241
       .wptr(fifo_wadr_gray[0]),
242
       .rptr(fifo_radr_gray[0]),
243
       .fifo_empty(fifo_empty[0]),
244
       .fifo_full(fifo_full[0]),
245
       .wclk(clk1),
246
       .rclk(clk2),
247
       .rst(rst1)
248
       );
249
 
250
   // 1
251
      gray_counter wadrcnt1
252
     (
253
      .cke(write & write_enable[1]),
254
      .q(fifo_wadr_gray[1]),
255
      .q_bin(fifo_wadr_bin[1]),
256
      .rst(rst1),
257
      .clk(clk1)
258
      );
259
 
260
   gray_counter radrcnt1
261
     (
262
      .cke((read_adr_reg | read_data) & read_enable_reg[1]),
263
      .q(fifo_radr_gray[1]),
264
      .q_bin(fifo_radr_bin[1]),
265
      .rst(rst2),
266
      .clk(clk2)
267
      );
268
 
269
   versatile_fifo_async_cmp
270
     #(
271
      .ADDR_WIDTH(a_lo_size)
272
      )
273
   egresscmp1
274
     (
275
       .wptr(fifo_wadr_gray[1]),
276
       .rptr(fifo_radr_gray[1]),
277
       .fifo_empty(fifo_empty[1]),
278
       .fifo_full(fifo_full[1]),
279
       .wclk(clk1),
280
       .rclk(clk2),
281
       .rst(rst1)
282
       );
283
 
284
   // 2
285
      gray_counter wadrcnt2
286
     (
287
      .cke(write & write_enable[2]),
288
      .q(fifo_wadr_gray[2]),
289
      .q_bin(fifo_wadr_bin[2]),
290
      .rst(rst1),
291
      .clk(clk1)
292
      );
293
 
294
   gray_counter radrcnt2
295
     (
296
      .cke((read_adr_reg | read_data) & read_enable_reg[2]),
297
      .q(fifo_radr_gray[2]),
298
      .q_bin(fifo_radr_bin[2]),
299
      .rst(rst2),
300
      .clk(clk2)
301
      );
302
 
303
   versatile_fifo_async_cmp
304
     #(
305
      .ADDR_WIDTH(a_lo_size)
306
      )
307
   egresscmp2
308
     (
309
       .wptr(fifo_wadr_gray[2]),
310
       .rptr(fifo_radr_gray[2]),
311
       .fifo_empty(fifo_empty[2]),
312
       .fifo_full(fifo_full[2]),
313
       .wclk(clk1),
314
       .rclk(clk2),
315
       .rst(rst1)
316
       );
317
 
318
 
319
   assign wadr = (fifo_wadr_bin[0] & {a_lo_size{write_enable[0]}}) |
320
                 (fifo_wadr_bin[1] & {a_lo_size{write_enable[1]}}) |
321
                 (fifo_wadr_bin[2] & {a_lo_size{write_enable[2]}});
322
 
323
   assign radr = (fifo_radr_bin[0] & {a_lo_size{read_enable_reg[0]}}) |
324
                 (fifo_radr_bin[1] & {a_lo_size{read_enable_reg[1]}}) |
325
                 (fifo_radr_bin[2] & {a_lo_size{read_enable_reg[2]}});
326
 
327
 
328
   assign wdataa[0] = d[108-1:72];
329
   assign wdataa[1] = d[72-1:36];
330
   assign wdataa[2] = d[36-1:0];
331
 
332
   assign wdata = ( d[108-1:72] & {data_width{write_enable[0]}}) |
333
                  ( d[72-1:36]  & {data_width{write_enable[1]}}) |
334
                  ( d[36-1:0]   & {data_width{write_enable[2]}});
335
 
336
   wire [1:0] wadr_top;
337
   assign wadr_top = write_enable[1] ? 2'b01 :
338
                     write_enable[2] ? 2'b10 :
339
                     2'b00;
340
   wire [1:0] radr_top;
341
   assign radr_top = read_enable_reg[1] ? 2'b01 :
342
                     read_enable_reg[2] ? 2'b10 :
343
                     2'b00;
344
 
345
vfifo_dual_port_ram_dc_sw
346
  # (
347
      .DATA_WIDTH(data_width),
348
      .ADDR_WIDTH(2+a_lo_size)
349
      )
350
    dpram (
351
    .d_a(wdata),
352
    .adr_a({wadr_top,wadr}),
353
    .we_a(write),
354
    .clk_a(clk1),
355
    .q_b(fifo_q),
356
    .adr_b({radr_top,radr}),
357
    .clk_b(clk2) );
358
 
359
   // Added registering of FIFO output to break a timing path
360
   always@(posedge clk2)
361
     q <= fifo_q;
362
 
363
 
364
endmodule
365
`endif // !`ifdef ORIGINAL_EGRESS_FIFO

powered by: WebSVN 2.1.0

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