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

Subversion Repositories versatile_library

[/] [versatile_library/] [trunk/] [rtl/] [verilog/] [versatile_library_actel.v] - Blame information for rev 152

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

Line No. Rev Author Line
1 60 unneback
// default SYN_KEEP definition
2 98 unneback
    // ACTEL FPGA should not use logic to handle rw collision
3 136 unneback
///////////////////////////////////////
4
// dependencies
5
///////////////////////////////////////
6 97 unneback
// size to width
7 6 unneback
//////////////////////////////////////////////////////////////////////
8
////                                                              ////
9
////  Versatile library, clock and reset                          ////
10
////                                                              ////
11
////  Description                                                 ////
12
////  Logic related to clock and reset                            ////
13
////                                                              ////
14
////                                                              ////
15
////  To Do:                                                      ////
16
////   - add more different registers                             ////
17
////                                                              ////
18
////  Author(s):                                                  ////
19
////      - Michael Unneback, unneback@opencores.org              ////
20
////        ORSoC AB                                              ////
21
////                                                              ////
22
//////////////////////////////////////////////////////////////////////
23
////                                                              ////
24
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
25
////                                                              ////
26
//// This source file may be used and distributed without         ////
27
//// restriction provided that this copyright statement is not    ////
28
//// removed from the file and that any derivative work contains  ////
29
//// the original copyright notice and the associated disclaimer. ////
30
////                                                              ////
31
//// This source file is free software; you can redistribute it   ////
32
//// and/or modify it under the terms of the GNU Lesser General   ////
33
//// Public License as published by the Free Software Foundation; ////
34
//// either version 2.1 of the License, or (at your option) any   ////
35
//// later version.                                               ////
36
////                                                              ////
37
//// This source is distributed in the hope that it will be       ////
38
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
39
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
40
//// PURPOSE.  See the GNU Lesser General Public License for more ////
41
//// details.                                                     ////
42
////                                                              ////
43
//// You should have received a copy of the GNU Lesser General    ////
44
//// Public License along with this source; if not, download it   ////
45
//// from http://www.opencores.org/lgpl.shtml                     ////
46
////                                                              ////
47
//////////////////////////////////////////////////////////////////////
48 48 unneback
`timescale 1 ns/100 ps
49 6 unneback
// Global buffer
50
// usage:
51
// use to enable global buffers for high fan out signals such as clock and reset
52
// Version: 8.4 8.4.0.33
53
module gbuf(GL,CLK);
54
output GL;
55
input  CLK;
56
    wire GND;
57
    GND GND_1_net(.Y(GND));
58
    CLKDLY Inst1(.CLK(CLK), .GL(GL), .DLYGL0(GND), .DLYGL1(GND),
59
        .DLYGL2(GND), .DLYGL3(GND), .DLYGL4(GND)) /* synthesis black_box */;
60
endmodule
61
`timescale 1 ns/1 ns
62
module vl_gbuf ( i, o);
63
input i;
64
output o;
65
`ifdef SIM_GBUF
66
assign o=i;
67
`else
68
gbuf gbuf_i0 ( .CLK(i), .GL(o));
69
`endif
70
endmodule
71
 //ACTEL
72
// sync reset
73 17 unneback
// input active lo async reset, normally from external reset generator and/or switch
74 6 unneback
// output active high global reset sync with two DFFs 
75
`timescale 1 ns/100 ps
76
module vl_sync_rst ( rst_n_i, rst_o, clk);
77
input rst_n_i, clk;
78
output rst_o;
79 18 unneback
reg [1:0] tmp;
80 6 unneback
always @ (posedge clk or negedge rst_n_i)
81
if (!rst_n_i)
82 17 unneback
        tmp <= 2'b11;
83 6 unneback
else
84 33 unneback
        tmp <= {1'b0,tmp[1]};
85 17 unneback
vl_gbuf buf_i0( .i(tmp[0]), .o(rst_o));
86 6 unneback
endmodule
87
// vl_pll
88 32 unneback
///////////////////////////////////////////////////////////////////////////////
89 17 unneback
`timescale 1 ps/1 ps
90 6 unneback
module vl_pll ( clk_i, rst_n_i, lock, clk_o, rst_o);
91
parameter index = 0;
92
parameter number_of_clk = 1;
93 17 unneback
parameter period_time_0 = 20000;
94
parameter period_time_1 = 20000;
95
parameter period_time_2 = 20000;
96
parameter lock_delay = 2000000;
97 6 unneback
input clk_i, rst_n_i;
98
output lock;
99
output reg [0:number_of_clk-1] clk_o;
100
output [0:number_of_clk-1] rst_o;
101
`ifdef SIM_PLL
102
always
103
     #((period_time_0)/2) clk_o[0] <=  (!rst_n_i) ? 0 : ~clk_o[0];
104
generate if (number_of_clk > 1)
105
always
106
     #((period_time_1)/2) clk_o[1] <=  (!rst_n_i) ? 0 : ~clk_o[1];
107
endgenerate
108
generate if (number_of_clk > 2)
109
always
110
     #((period_time_2)/2) clk_o[2] <=  (!rst_n_i) ? 0 : ~clk_o[2];
111
endgenerate
112
genvar i;
113
generate for (i=0;i<number_of_clk;i=i+1) begin: clock
114
     vl_sync_rst rst_i0 ( .rst_n_i(rst_n_i | lock), .rst_o(rst_o[i]), .clk(clk_o[i]));
115
end
116
endgenerate
117
assign #lock_delay lock = rst_n_i;
118
endmodule
119
`else
120
generate if (number_of_clk==1 & index==0) begin
121
        pll0 pll_i0 (.POWERDOWN(1'b1), .CLKA(clk_i), .LOCK(lock), .GLA(clk_o[0]));
122
end
123
endgenerate // index==0
124
generate if (number_of_clk==1 & index==1) begin
125
        pll1 pll_i0 (.POWERDOWN(1'b1), .CLKA(clk_i), .LOCK(lock), .GLA(clk_o[0]));
126
end
127
endgenerate // index==1
128
generate if (number_of_clk==1 & index==2) begin
129
        pll2 pll_i0 (.POWERDOWN(1'b1), .CLKA(clk_i), .LOCK(lock), .GLA(clk_o[0]));
130
end
131
endgenerate // index==2
132
generate if (number_of_clk==1 & index==3) begin
133
        pll3 pll_i0 (.POWERDOWN(1'b1), .CLKA(clk_i), .LOCK(lock), .GLA(clk_o[0]));
134
end
135
endgenerate // index==0
136
generate if (number_of_clk==2 & index==0) begin
137
        pll0 pll_i0 (.POWERDOWN(1'b1), .CLKA(clk_i), .LOCK(lock), .GLA(clk_o[0]), .GLB(clk_o[1]));
138
end
139
endgenerate // index==0
140
generate if (number_of_clk==2 & index==1) begin
141
        pll1 pll_i0 (.POWERDOWN(1'b1), .CLKA(clk_i), .LOCK(lock), .GLA(clk_o[0]), .GLB(clk_o[1]));
142
end
143
endgenerate // index==1
144
generate if (number_of_clk==2 & index==2) begin
145
        pll2 pll_i0 (.POWERDOWN(1'b1), .CLKA(clk_i), .LOCK(lock), .GLA(clk_o[0]), .GLB(clk_o[1]));
146
end
147
endgenerate // index==2
148
generate if (number_of_clk==2 & index==3) begin
149
        pll3 pll_i0 (.POWERDOWN(1'b1), .CLKA(clk_i), .LOCK(lock), .GLA(clk_o[0]), .GLB(clk_o[1]));
150
end
151
endgenerate // index==0
152
generate if (number_of_clk==3 & index==0) begin
153
        pll0 pll_i0 (.POWERDOWN(1'b1), .CLKA(clk_i), .LOCK(lock), .GLA(clk_o[0]), .GLB(clk_o[1]), .GLC(clk_o[2]));
154
end
155
endgenerate // index==0
156
generate if (number_of_clk==3 & index==1) begin
157
        pll1 pll_i0 (.POWERDOWN(1'b1), .CLKA(clk_i), .LOCK(lock), .GLA(clk_o[0]), .GLB(clk_o[1]), .GLC(clk_o[2]));
158
end
159
endgenerate // index==1
160
generate if (number_of_clk==3 & index==2) begin
161
        pll2 pll_i0 (.POWERDOWN(1'b1), .CLKA(clk_i), .LOCK(lock), .GLA(clk_o[0]), .GLB(clk_o[1]), .GLC(clk_o[2]));
162
end
163
endgenerate // index==2
164
generate if (number_of_clk==3 & index==3) begin
165
        pll3 pll_i0 (.POWERDOWN(1'b1), .CLKA(clk_i), .LOCK(lock), .GLA(clk_o[0]), .GLB(clk_o[1]), .GLC(clk_o[2]));
166
end
167
endgenerate // index==0
168
genvar i;
169
generate for (i=0;i<number_of_clk;i=i+1) begin: clock
170 40 unneback
        vl_sync_rst rst_i0 ( .rst_n_i(rst_n_i | lock), .rst_o(rst_o), .clk(clk_o[i]));
171 6 unneback
end
172
endgenerate
173
endmodule
174
`endif
175 32 unneback
///////////////////////////////////////////////////////////////////////////////
176 6 unneback
 //actel
177
//////////////////////////////////////////////////////////////////////
178
////                                                              ////
179
////  Versatile library, registers                                ////
180
////                                                              ////
181
////  Description                                                 ////
182
////  Different type of registers                                 ////
183
////                                                              ////
184
////                                                              ////
185
////  To Do:                                                      ////
186
////   - add more different registers                             ////
187
////                                                              ////
188
////  Author(s):                                                  ////
189
////      - Michael Unneback, unneback@opencores.org              ////
190
////        ORSoC AB                                              ////
191
////                                                              ////
192
//////////////////////////////////////////////////////////////////////
193
////                                                              ////
194
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
195
////                                                              ////
196
//// This source file may be used and distributed without         ////
197
//// restriction provided that this copyright statement is not    ////
198
//// removed from the file and that any derivative work contains  ////
199
//// the original copyright notice and the associated disclaimer. ////
200
////                                                              ////
201
//// This source file is free software; you can redistribute it   ////
202
//// and/or modify it under the terms of the GNU Lesser General   ////
203
//// Public License as published by the Free Software Foundation; ////
204
//// either version 2.1 of the License, or (at your option) any   ////
205
//// later version.                                               ////
206
////                                                              ////
207
//// This source is distributed in the hope that it will be       ////
208
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
209
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
210
//// PURPOSE.  See the GNU Lesser General Public License for more ////
211
//// details.                                                     ////
212
////                                                              ////
213
//// You should have received a copy of the GNU Lesser General    ////
214
//// Public License along with this source; if not, download it   ////
215
//// from http://www.opencores.org/lgpl.shtml                     ////
216
////                                                              ////
217
//////////////////////////////////////////////////////////////////////
218 18 unneback
module vl_dff ( d, q, clk, rst);
219 6 unneback
        parameter width = 1;
220 139 unneback
        parameter reset_value = {width{1'b0}};
221 6 unneback
        input [width-1:0] d;
222
        input clk, rst;
223
        output reg [width-1:0] q;
224
        always @ (posedge clk or posedge rst)
225
        if (rst)
226
                q <= reset_value;
227
        else
228
                q <= d;
229
endmodule
230 18 unneback
module vl_dff_array ( d, q, clk, rst);
231 6 unneback
        parameter width = 1;
232
        parameter depth = 2;
233
        parameter reset_value = 1'b0;
234
        input [width-1:0] d;
235
        input clk, rst;
236
        output [width-1:0] q;
237
        reg  [0:depth-1] q_tmp [width-1:0];
238
        integer i;
239
        always @ (posedge clk or posedge rst)
240
        if (rst) begin
241
            for (i=0;i<depth;i=i+1)
242
                q_tmp[i] <= {width{reset_value}};
243
        end else begin
244
            q_tmp[0] <= d;
245
            for (i=1;i<depth;i=i+1)
246
                q_tmp[i] <= q_tmp[i-1];
247
        end
248
    assign q = q_tmp[depth-1];
249
endmodule
250 18 unneback
module vl_dff_ce ( d, ce, q, clk, rst);
251 6 unneback
        parameter width = 1;
252 139 unneback
        parameter reset_value = {width{1'b0}};
253 6 unneback
        input [width-1:0] d;
254
        input ce, clk, rst;
255
        output reg [width-1:0] q;
256
        always @ (posedge clk or posedge rst)
257
        if (rst)
258
                q <= reset_value;
259
        else
260
                if (ce)
261
                        q <= d;
262
endmodule
263 18 unneback
module vl_dff_ce_clear ( d, ce, clear, q, clk, rst);
264 8 unneback
        parameter width = 1;
265 139 unneback
        parameter reset_value = {width{1'b0}};
266 8 unneback
        input [width-1:0] d;
267 10 unneback
        input ce, clear, clk, rst;
268 8 unneback
        output reg [width-1:0] q;
269
        always @ (posedge clk or posedge rst)
270
        if (rst)
271
            q <= reset_value;
272
        else
273
            if (ce)
274
                if (clear)
275
                    q <= {width{1'b0}};
276
                else
277
                    q <= d;
278
endmodule
279 24 unneback
module vl_dff_ce_set ( d, ce, set, q, clk, rst);
280
        parameter width = 1;
281 139 unneback
        parameter reset_value = {width{1'b0}};
282 24 unneback
        input [width-1:0] d;
283
        input ce, set, clk, rst;
284
        output reg [width-1:0] q;
285
        always @ (posedge clk or posedge rst)
286
        if (rst)
287
            q <= reset_value;
288
        else
289
            if (ce)
290
                if (set)
291
                    q <= {width{1'b1}};
292
                else
293
                    q <= d;
294
endmodule
295 29 unneback
module vl_spr ( sp, r, q, clk, rst);
296 64 unneback
        //parameter width = 1;
297
        parameter reset_value = 1'b0;
298 29 unneback
        input sp, r;
299
        output reg q;
300
        input clk, rst;
301
        always @ (posedge clk or posedge rst)
302
        if (rst)
303
            q <= reset_value;
304
        else
305
            if (sp)
306
                q <= 1'b1;
307
            else if (r)
308
                q <= 1'b0;
309
endmodule
310
module vl_srp ( s, rp, q, clk, rst);
311
        parameter width = 1;
312
        parameter reset_value = 0;
313
        input s, rp;
314
        output reg q;
315
        input clk, rst;
316
        always @ (posedge clk or posedge rst)
317
        if (rst)
318
            q <= reset_value;
319
        else
320
            if (rp)
321
                q <= 1'b0;
322
            else if (s)
323
                q <= 1'b1;
324
endmodule
325 18 unneback
module vl_dff_sr ( aclr, aset, clock, data, q);
326 6 unneback
    input         aclr;
327
    input         aset;
328
    input         clock;
329
    input         data;
330
    output reg    q;
331
   always @ (posedge clock or posedge aclr or posedge aset)
332
     if (aclr)
333
       q <= 1'b0;
334
     else if (aset)
335
       q <= 1'b1;
336
     else
337
       q <= data;
338
endmodule
339
// LATCH
340
// For targtes not supporting LATCH use dff_sr with clk=1 and data=1
341 40 unneback
module vl_latch ( d, le, q, clk);
342 6 unneback
input d, le;
343 48 unneback
input clk;
344
always @ (le or d)
345 60 unneback
if (le)
346 48 unneback
    d <= q;
347 6 unneback
endmodule
348 18 unneback
module vl_shreg ( d, q, clk, rst);
349 17 unneback
parameter depth = 10;
350
input d;
351
output q;
352
input clk, rst;
353
reg [1:depth] dffs;
354
always @ (posedge clk or posedge rst)
355
if (rst)
356
    dffs <= {depth{1'b0}};
357
else
358
    dffs <= {d,dffs[1:depth-1]};
359
assign q = dffs[depth];
360
endmodule
361 18 unneback
module vl_shreg_ce ( d, ce, q, clk, rst);
362 17 unneback
parameter depth = 10;
363
input d, ce;
364
output q;
365
input clk, rst;
366
reg [1:depth] dffs;
367
always @ (posedge clk or posedge rst)
368
if (rst)
369
    dffs <= {depth{1'b0}};
370
else
371
    if (ce)
372
        dffs <= {d,dffs[1:depth-1]};
373
assign q = dffs[depth];
374
endmodule
375 18 unneback
module vl_delay ( d, q, clk, rst);
376 15 unneback
parameter depth = 10;
377
input d;
378
output q;
379
input clk, rst;
380
reg [1:depth] dffs;
381
always @ (posedge clk or posedge rst)
382
if (rst)
383
    dffs <= {depth{1'b0}};
384
else
385
    dffs <= {d,dffs[1:depth-1]};
386
assign q = dffs[depth];
387
endmodule
388 18 unneback
module vl_delay_emptyflag ( d, q, emptyflag, clk, rst);
389 17 unneback
parameter depth = 10;
390
input d;
391
output q, emptyflag;
392
input clk, rst;
393
reg [1:depth] dffs;
394
always @ (posedge clk or posedge rst)
395
if (rst)
396
    dffs <= {depth{1'b0}};
397
else
398
    dffs <= {d,dffs[1:depth-1]};
399
assign q = dffs[depth];
400
assign emptyflag = !(|dffs);
401
endmodule
402 98 unneback
module vl_pulse2toggle ( pl, q, clk, rst);
403 94 unneback
input pl;
404 98 unneback
output reg q;
405 94 unneback
input clk, rst;
406
always @ (posedge clk or posedge rst)
407
if (rst)
408
    q <= 1'b0;
409
else
410
    q <= pl ^ q;
411
endmodule
412 98 unneback
module vl_toggle2pulse (d, pl, clk, rst);
413 94 unneback
input d;
414
output pl;
415
input clk, rst;
416
reg dff;
417
always @ (posedge clk or posedge rst)
418
if (rst)
419
    dff <= 1'b0;
420
else
421
    dff <= d;
422 98 unneback
assign pl = d ^ dff;
423 94 unneback
endmodule
424
module vl_synchronizer (d, q, clk, rst);
425
input d;
426
output reg q;
427 116 unneback
input clk, rst;
428 94 unneback
reg dff;
429
always @ (posedge clk or posedge rst)
430
if (rst)
431 100 unneback
    {q,dff} <= 2'b00;
432 94 unneback
else
433 100 unneback
    {q,dff} <= {dff,d};
434 94 unneback
endmodule
435 97 unneback
module vl_cdc ( start_pl, take_it_pl, take_it_grant_pl, got_it_pl, clk_src, rst_src, clk_dst, rst_dst);
436 94 unneback
input start_pl;
437
output take_it_pl;
438
input take_it_grant_pl; // note: connect to take_it_pl to generate automatic ack
439
output got_it_pl;
440
input clk_src, rst_src;
441
input clk_dst, rst_dst;
442
wire take_it_tg, take_it_tg_sync;
443
wire got_it_tg, got_it_tg_sync;
444
// src -> dst
445
vl_pulse2toggle p2t0 (
446
    .pl(start_pl),
447
    .q(take_it_tg),
448
    .clk(clk_src),
449
    .rst(rst_src));
450
vl_synchronizer sync0 (
451
    .d(take_it_tg),
452
    .q(take_it_tg_sync),
453
    .clk(clk_dst),
454
    .rst(rst_dst));
455
vl_toggle2pulse t2p0 (
456 100 unneback
    .d(take_it_tg_sync),
457 94 unneback
    .pl(take_it_pl),
458
    .clk(clk_dst),
459
    .rst(rst_dst));
460
// dst -> src
461 98 unneback
vl_pulse2toggle p2t1 (
462 94 unneback
    .pl(take_it_grant_pl),
463
    .q(got_it_tg),
464
    .clk(clk_dst),
465
    .rst(rst_dst));
466
vl_synchronizer sync1 (
467
    .d(got_it_tg),
468
    .q(got_it_tg_sync),
469
    .clk(clk_src),
470
    .rst(rst_src));
471
vl_toggle2pulse t2p1 (
472 100 unneback
    .d(got_it_tg_sync),
473 94 unneback
    .pl(got_it_pl),
474
    .clk(clk_src),
475
    .rst(rst_src));
476
endmodule
477 6 unneback
//////////////////////////////////////////////////////////////////////
478
////                                                              ////
479 18 unneback
////  Logic functions                                             ////
480
////                                                              ////
481
////  Description                                                 ////
482
////  Logic functions such as multiplexers                        ////
483
////                                                              ////
484
////                                                              ////
485
////  To Do:                                                      ////
486
////   -                                                          ////
487
////                                                              ////
488
////  Author(s):                                                  ////
489
////      - Michael Unneback, unneback@opencores.org              ////
490
////        ORSoC AB                                              ////
491
////                                                              ////
492
//////////////////////////////////////////////////////////////////////
493
////                                                              ////
494
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
495
////                                                              ////
496
//// This source file may be used and distributed without         ////
497
//// restriction provided that this copyright statement is not    ////
498
//// removed from the file and that any derivative work contains  ////
499
//// the original copyright notice and the associated disclaimer. ////
500
////                                                              ////
501
//// This source file is free software; you can redistribute it   ////
502
//// and/or modify it under the terms of the GNU Lesser General   ////
503
//// Public License as published by the Free Software Foundation; ////
504
//// either version 2.1 of the License, or (at your option) any   ////
505
//// later version.                                               ////
506
////                                                              ////
507
//// This source is distributed in the hope that it will be       ////
508
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
509
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
510
//// PURPOSE.  See the GNU Lesser General Public License for more ////
511
//// details.                                                     ////
512
////                                                              ////
513
//// You should have received a copy of the GNU Lesser General    ////
514
//// Public License along with this source; if not, download it   ////
515
//// from http://www.opencores.org/lgpl.shtml                     ////
516
////                                                              ////
517
//////////////////////////////////////////////////////////////////////
518 36 unneback
module vl_mux_andor ( a, sel, dout);
519
parameter width = 32;
520
parameter nr_of_ports = 4;
521
input [nr_of_ports*width-1:0] a;
522
input [nr_of_ports-1:0] sel;
523
output reg [width-1:0] dout;
524 38 unneback
integer i,j;
525 36 unneback
always @ (a, sel)
526
begin
527
    dout = a[width-1:0] & {width{sel[0]}};
528 42 unneback
    for (i=1;i<nr_of_ports;i=i+1)
529
        for (j=0;j<width;j=j+1)
530
            dout[j] = (a[i*width + j] & sel[i]) | dout[j];
531 36 unneback
end
532
endmodule
533 34 unneback
module vl_mux2_andor ( a1, a0, sel, dout);
534
parameter width = 32;
535 35 unneback
localparam nr_of_ports = 2;
536 34 unneback
input [width-1:0] a1, a0;
537
input [nr_of_ports-1:0] sel;
538
output [width-1:0] dout;
539 36 unneback
vl_mux_andor
540 38 unneback
    # ( .width(width), .nr_of_ports(nr_of_ports))
541 36 unneback
    mux0( .a({a1,a0}), .sel(sel), .dout(dout));
542 34 unneback
endmodule
543
module vl_mux3_andor ( a2, a1, a0, sel, dout);
544
parameter width = 32;
545 35 unneback
localparam nr_of_ports = 3;
546 34 unneback
input [width-1:0] a2, a1, a0;
547
input [nr_of_ports-1:0] sel;
548
output [width-1:0] dout;
549 36 unneback
vl_mux_andor
550 38 unneback
    # ( .width(width), .nr_of_ports(nr_of_ports))
551 36 unneback
    mux0( .a({a2,a1,a0}), .sel(sel), .dout(dout));
552 34 unneback
endmodule
553 18 unneback
module vl_mux4_andor ( a3, a2, a1, a0, sel, dout);
554
parameter width = 32;
555 35 unneback
localparam nr_of_ports = 4;
556 18 unneback
input [width-1:0] a3, a2, a1, a0;
557
input [nr_of_ports-1:0] sel;
558 22 unneback
output [width-1:0] dout;
559 36 unneback
vl_mux_andor
560 38 unneback
    # ( .width(width), .nr_of_ports(nr_of_ports))
561 36 unneback
    mux0( .a({a3,a2,a1,a0}), .sel(sel), .dout(dout));
562 18 unneback
endmodule
563
module vl_mux5_andor ( a4, a3, a2, a1, a0, sel, dout);
564
parameter width = 32;
565 35 unneback
localparam nr_of_ports = 5;
566 18 unneback
input [width-1:0] a4, a3, a2, a1, a0;
567
input [nr_of_ports-1:0] sel;
568 22 unneback
output [width-1:0] dout;
569 36 unneback
vl_mux_andor
570 38 unneback
    # ( .width(width), .nr_of_ports(nr_of_ports))
571 36 unneback
    mux0( .a({a4,a3,a2,a1,a0}), .sel(sel), .dout(dout));
572 18 unneback
endmodule
573
module vl_mux6_andor ( a5, a4, a3, a2, a1, a0, sel, dout);
574
parameter width = 32;
575 35 unneback
localparam nr_of_ports = 6;
576 18 unneback
input [width-1:0] a5, a4, a3, a2, a1, a0;
577
input [nr_of_ports-1:0] sel;
578 22 unneback
output [width-1:0] dout;
579 36 unneback
vl_mux_andor
580 38 unneback
    # ( .width(width), .nr_of_ports(nr_of_ports))
581 36 unneback
    mux0( .a({a5,a4,a3,a2,a1,a0}), .sel(sel), .dout(dout));
582 18 unneback
endmodule
583 43 unneback
module vl_parity_generate (data, parity);
584
parameter word_size = 32;
585
parameter chunk_size = 8;
586
parameter parity_type = 1'b0; // 0 - even, 1 - odd parity
587
input [word_size-1:0] data;
588
output reg [word_size/chunk_size-1:0] parity;
589
integer i,j;
590
always @ (data)
591
for (i=0;i<word_size/chunk_size;i=i+1) begin
592
    parity[i] = parity_type;
593
    for (j=0;j<chunk_size;j=j+1) begin
594 46 unneback
        parity[i] = data[i*chunk_size+j] ^ parity[i];
595 43 unneback
    end
596
end
597
endmodule
598
module vl_parity_check( data, parity, parity_error);
599
parameter word_size = 32;
600
parameter chunk_size = 8;
601
parameter parity_type = 1'b0; // 0 - even, 1 - odd parity
602
input [word_size-1:0] data;
603
input [word_size/chunk_size-1:0] parity;
604
output parity_error;
605 44 unneback
reg [word_size/chunk_size-1:0] error_flag;
606 43 unneback
integer i,j;
607
always @ (data or parity)
608
for (i=0;i<word_size/chunk_size;i=i+1) begin
609
    error_flag[i] = parity[i] ^ parity_type;
610
    for (j=0;j<chunk_size;j=j+1) begin
611 46 unneback
        error_flag[i] = data[i*chunk_size+j] ^ error_flag[i];
612 43 unneback
    end
613
end
614
assign parity_error = |error_flag;
615
endmodule
616 18 unneback
//////////////////////////////////////////////////////////////////////
617
////                                                              ////
618 44 unneback
////  IO functions                                                ////
619
////                                                              ////
620
////  Description                                                 ////
621
////  IO functions such as IOB flip-flops                         ////
622
////                                                              ////
623
////                                                              ////
624
////  To Do:                                                      ////
625
////   -                                                          ////
626
////                                                              ////
627
////  Author(s):                                                  ////
628
////      - Michael Unneback, unneback@opencores.org              ////
629
////        ORSoC AB                                              ////
630
////                                                              ////
631
//////////////////////////////////////////////////////////////////////
632
////                                                              ////
633
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
634
////                                                              ////
635
//// This source file may be used and distributed without         ////
636
//// restriction provided that this copyright statement is not    ////
637
//// removed from the file and that any derivative work contains  ////
638
//// the original copyright notice and the associated disclaimer. ////
639
////                                                              ////
640
//// This source file is free software; you can redistribute it   ////
641
//// and/or modify it under the terms of the GNU Lesser General   ////
642
//// Public License as published by the Free Software Foundation; ////
643
//// either version 2.1 of the License, or (at your option) any   ////
644
//// later version.                                               ////
645
////                                                              ////
646
//// This source is distributed in the hope that it will be       ////
647
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
648
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
649
//// PURPOSE.  See the GNU Lesser General Public License for more ////
650
//// details.                                                     ////
651
////                                                              ////
652
//// You should have received a copy of the GNU Lesser General    ////
653
//// Public License along with this source; if not, download it   ////
654
//// from http://www.opencores.org/lgpl.shtml                     ////
655
////                                                              ////
656
//////////////////////////////////////////////////////////////////////
657 45 unneback
`timescale 1ns/1ns
658 44 unneback
module vl_o_dff (d_i, o_pad, clk, rst);
659
parameter width = 1;
660 45 unneback
parameter reset_value = {width{1'b0}};
661
input  [width-1:0]  d_i;
662 44 unneback
output [width-1:0] o_pad;
663
input clk, rst;
664
wire [width-1:0] d_i_int /*synthesis syn_keep = 1*/;
665 45 unneback
reg  [width-1:0] o_pad_int;
666 44 unneback
assign d_i_int = d_i;
667
genvar i;
668 45 unneback
generate
669 136 unneback
for (i=0;i<width;i=i+1) begin : dffs
670 44 unneback
    always @ (posedge clk or posedge rst)
671
    if (rst)
672 45 unneback
        o_pad_int[i] <= reset_value[i];
673 44 unneback
    else
674 45 unneback
        o_pad_int[i] <= d_i_int[i];
675
    assign #1 o_pad[i] = o_pad_int[i];
676 44 unneback
end
677
endgenerate
678
endmodule
679 45 unneback
`timescale 1ns/1ns
680 44 unneback
module vl_io_dff_oe ( d_i, d_o, oe, io_pad, clk, rst);
681
parameter width = 1;
682 140 unneback
parameter reset_value = 1'b0;
683 44 unneback
input  [width-1:0] d_o;
684
output reg [width-1:0] d_i;
685
input oe;
686
inout [width-1:0] io_pad;
687
input clk, rst;
688
wire [width-1:0] oe_d /*synthesis syn_keep = 1*/;
689
reg [width-1:0] oe_q;
690
reg [width-1:0] d_o_q;
691
assign oe_d = {width{oe}};
692
genvar i;
693
generate
694 136 unneback
for (i=0;i<width;i=i+1) begin : dffs
695 44 unneback
    always @ (posedge clk or posedge rst)
696
    if (rst)
697
        oe_q[i] <= 1'b0;
698
    else
699
        oe_q[i] <= oe_d[i];
700
    always @ (posedge clk or posedge rst)
701
    if (rst)
702 140 unneback
        d_o_q[i] <= reset_value;
703 44 unneback
    else
704
        d_o_q[i] <= d_o[i];
705
    always @ (posedge clk or posedge rst)
706
    if (rst)
707 140 unneback
        d_i[i] <= reset_value;
708 44 unneback
    else
709
        d_i[i] <= io_pad[i];
710 45 unneback
    assign #1 io_pad[i] = (oe_q[i]) ? d_o_q[i] : 1'bz;
711 44 unneback
end
712
endgenerate
713
endmodule
714 136 unneback
module vl_o_ddr (d_h_i, d_l_i, o_pad, clk, rst);
715
parameter width = 1;
716
input  [width-1:0] d_h_i, d_l_i;
717
output [width-1:0] o_pad;
718
input clk, rst;
719
reg [width-1:0] ff1;
720
reg [width-1:0] ff2;
721
genvar i;
722
generate
723
for (i=0;i<width;i=i+1) begin : ddr
724
    always @ (posedge clk or posedge rst)
725
    if (rst)
726
        ff1[i] <= 1'b0;
727
    else
728
        ff1[i] <= d_h_i[i];
729
    always @ (posedge clk or posedge rst)
730
    if (rst)
731
        ff2[i] <= 1'b0;
732
    else
733
        ff2[i] <= d_l_i[i];
734
    assign o_pad = (clk) ? ff1 : ff2;
735
end
736
endgenerate
737
endmodule
738
module vl_o_clk ( clk_o_pad, clk, rst);
739
input clk, rst;
740
output clk_o_pad;
741
vl_o_ddr o_ddr0( .d_h_i(1'b1), .d_l_i(1'b0), .o_pad(clk_o_pad), .clk(clk), .rst(rst));
742
endmodule
743 44 unneback
//////////////////////////////////////////////////////////////////////
744
////                                                              ////
745 6 unneback
////  Versatile counter                                           ////
746
////                                                              ////
747
////  Description                                                 ////
748
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
749
////  counter                                                     ////
750
////                                                              ////
751
////  To Do:                                                      ////
752
////   - add LFSR with more taps                                  ////
753
////                                                              ////
754
////  Author(s):                                                  ////
755
////      - Michael Unneback, unneback@opencores.org              ////
756
////        ORSoC AB                                              ////
757
////                                                              ////
758
//////////////////////////////////////////////////////////////////////
759
////                                                              ////
760
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
761
////                                                              ////
762
//// This source file may be used and distributed without         ////
763
//// restriction provided that this copyright statement is not    ////
764
//// removed from the file and that any derivative work contains  ////
765
//// the original copyright notice and the associated disclaimer. ////
766
////                                                              ////
767
//// This source file is free software; you can redistribute it   ////
768
//// and/or modify it under the terms of the GNU Lesser General   ////
769
//// Public License as published by the Free Software Foundation; ////
770
//// either version 2.1 of the License, or (at your option) any   ////
771
//// later version.                                               ////
772
////                                                              ////
773
//// This source is distributed in the hope that it will be       ////
774
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
775
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
776
//// PURPOSE.  See the GNU Lesser General Public License for more ////
777
//// details.                                                     ////
778
////                                                              ////
779
//// You should have received a copy of the GNU Lesser General    ////
780
//// Public License along with this source; if not, download it   ////
781
//// from http://www.opencores.org/lgpl.shtml                     ////
782
////                                                              ////
783
//////////////////////////////////////////////////////////////////////
784
// binary counter
785 139 unneback
module vl_cnt_bin (
786
 q, rst, clk);
787
   parameter length = 4;
788
   output [length:1] q;
789
   input rst;
790
   input clk;
791
   parameter clear_value = 0;
792
   parameter set_value = 1;
793
   parameter wrap_value = 0;
794
   parameter level1_value = 15;
795
   reg  [length:1] qi;
796
   wire [length:1] q_next;
797
   assign q_next = qi + {{length-1{1'b0}},1'b1};
798
   always @ (posedge clk or posedge rst)
799
     if (rst)
800
       qi <= {length{1'b0}};
801
     else
802
       qi <= q_next;
803
   assign q = qi;
804
endmodule
805
//////////////////////////////////////////////////////////////////////
806
////                                                              ////
807
////  Versatile counter                                           ////
808
////                                                              ////
809
////  Description                                                 ////
810
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
811
////  counter                                                     ////
812
////                                                              ////
813
////  To Do:                                                      ////
814
////   - add LFSR with more taps                                  ////
815
////                                                              ////
816
////  Author(s):                                                  ////
817
////      - Michael Unneback, unneback@opencores.org              ////
818
////        ORSoC AB                                              ////
819
////                                                              ////
820
//////////////////////////////////////////////////////////////////////
821
////                                                              ////
822
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
823
////                                                              ////
824
//// This source file may be used and distributed without         ////
825
//// restriction provided that this copyright statement is not    ////
826
//// removed from the file and that any derivative work contains  ////
827
//// the original copyright notice and the associated disclaimer. ////
828
////                                                              ////
829
//// This source file is free software; you can redistribute it   ////
830
//// and/or modify it under the terms of the GNU Lesser General   ////
831
//// Public License as published by the Free Software Foundation; ////
832
//// either version 2.1 of the License, or (at your option) any   ////
833
//// later version.                                               ////
834
////                                                              ////
835
//// This source is distributed in the hope that it will be       ////
836
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
837
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
838
//// PURPOSE.  See the GNU Lesser General Public License for more ////
839
//// details.                                                     ////
840
////                                                              ////
841
//// You should have received a copy of the GNU Lesser General    ////
842
//// Public License along with this source; if not, download it   ////
843
//// from http://www.opencores.org/lgpl.shtml                     ////
844
////                                                              ////
845
//////////////////////////////////////////////////////////////////////
846
// binary counter
847
module vl_cnt_bin_clear (
848
 clear, q, rst, clk);
849
   parameter length = 4;
850
   input clear;
851
   output [length:1] q;
852
   input rst;
853
   input clk;
854
   parameter clear_value = 0;
855
   parameter set_value = 1;
856
   parameter wrap_value = 0;
857
   parameter level1_value = 15;
858
   reg  [length:1] qi;
859
   wire [length:1] q_next;
860
   assign q_next =  clear ? {length{1'b0}} :qi + {{length-1{1'b0}},1'b1};
861
   always @ (posedge clk or posedge rst)
862
     if (rst)
863
       qi <= {length{1'b0}};
864
     else
865
       qi <= q_next;
866
   assign q = qi;
867
endmodule
868
//////////////////////////////////////////////////////////////////////
869
////                                                              ////
870
////  Versatile counter                                           ////
871
////                                                              ////
872
////  Description                                                 ////
873
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
874
////  counter                                                     ////
875
////                                                              ////
876
////  To Do:                                                      ////
877
////   - add LFSR with more taps                                  ////
878
////                                                              ////
879
////  Author(s):                                                  ////
880
////      - Michael Unneback, unneback@opencores.org              ////
881
////        ORSoC AB                                              ////
882
////                                                              ////
883
//////////////////////////////////////////////////////////////////////
884
////                                                              ////
885
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
886
////                                                              ////
887
//// This source file may be used and distributed without         ////
888
//// restriction provided that this copyright statement is not    ////
889
//// removed from the file and that any derivative work contains  ////
890
//// the original copyright notice and the associated disclaimer. ////
891
////                                                              ////
892
//// This source file is free software; you can redistribute it   ////
893
//// and/or modify it under the terms of the GNU Lesser General   ////
894
//// Public License as published by the Free Software Foundation; ////
895
//// either version 2.1 of the License, or (at your option) any   ////
896
//// later version.                                               ////
897
////                                                              ////
898
//// This source is distributed in the hope that it will be       ////
899
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
900
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
901
//// PURPOSE.  See the GNU Lesser General Public License for more ////
902
//// details.                                                     ////
903
////                                                              ////
904
//// You should have received a copy of the GNU Lesser General    ////
905
//// Public License along with this source; if not, download it   ////
906
//// from http://www.opencores.org/lgpl.shtml                     ////
907
////                                                              ////
908
//////////////////////////////////////////////////////////////////////
909
// binary counter
910 40 unneback
module vl_cnt_bin_ce (
911
 cke, q, rst, clk);
912 22 unneback
   parameter length = 4;
913 6 unneback
   input cke;
914
   output [length:1] q;
915
   input rst;
916
   input clk;
917
   parameter clear_value = 0;
918
   parameter set_value = 1;
919
   parameter wrap_value = 0;
920
   parameter level1_value = 15;
921
   reg  [length:1] qi;
922
   wire [length:1] q_next;
923
   assign q_next = qi + {{length-1{1'b0}},1'b1};
924
   always @ (posedge clk or posedge rst)
925
     if (rst)
926
       qi <= {length{1'b0}};
927
     else
928
     if (cke)
929
       qi <= q_next;
930
   assign q = qi;
931
endmodule
932
//////////////////////////////////////////////////////////////////////
933
////                                                              ////
934
////  Versatile counter                                           ////
935
////                                                              ////
936
////  Description                                                 ////
937
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
938
////  counter                                                     ////
939
////                                                              ////
940
////  To Do:                                                      ////
941
////   - add LFSR with more taps                                  ////
942
////                                                              ////
943
////  Author(s):                                                  ////
944
////      - Michael Unneback, unneback@opencores.org              ////
945
////        ORSoC AB                                              ////
946
////                                                              ////
947
//////////////////////////////////////////////////////////////////////
948
////                                                              ////
949
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
950
////                                                              ////
951
//// This source file may be used and distributed without         ////
952
//// restriction provided that this copyright statement is not    ////
953
//// removed from the file and that any derivative work contains  ////
954
//// the original copyright notice and the associated disclaimer. ////
955
////                                                              ////
956
//// This source file is free software; you can redistribute it   ////
957
//// and/or modify it under the terms of the GNU Lesser General   ////
958
//// Public License as published by the Free Software Foundation; ////
959
//// either version 2.1 of the License, or (at your option) any   ////
960
//// later version.                                               ////
961
////                                                              ////
962
//// This source is distributed in the hope that it will be       ////
963
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
964
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
965
//// PURPOSE.  See the GNU Lesser General Public License for more ////
966
//// details.                                                     ////
967
////                                                              ////
968
//// You should have received a copy of the GNU Lesser General    ////
969
//// Public License along with this source; if not, download it   ////
970
//// from http://www.opencores.org/lgpl.shtml                     ////
971
////                                                              ////
972
//////////////////////////////////////////////////////////////////////
973
// binary counter
974 139 unneback
module vl_cnt_bin_ce_clear (
975
 clear, cke, q, rst, clk);
976
   parameter length = 4;
977
   input clear;
978
   input cke;
979
   output [length:1] q;
980
   input rst;
981
   input clk;
982
   parameter clear_value = 0;
983
   parameter set_value = 1;
984
   parameter wrap_value = 0;
985
   parameter level1_value = 15;
986
   reg  [length:1] qi;
987
   wire [length:1] q_next;
988
   assign q_next =  clear ? {length{1'b0}} :qi + {{length-1{1'b0}},1'b1};
989
   always @ (posedge clk or posedge rst)
990
     if (rst)
991
       qi <= {length{1'b0}};
992
     else
993
     if (cke)
994
       qi <= q_next;
995
   assign q = qi;
996
endmodule
997
//////////////////////////////////////////////////////////////////////
998
////                                                              ////
999
////  Versatile counter                                           ////
1000
////                                                              ////
1001
////  Description                                                 ////
1002
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1003
////  counter                                                     ////
1004
////                                                              ////
1005
////  To Do:                                                      ////
1006
////   - add LFSR with more taps                                  ////
1007
////                                                              ////
1008
////  Author(s):                                                  ////
1009
////      - Michael Unneback, unneback@opencores.org              ////
1010
////        ORSoC AB                                              ////
1011
////                                                              ////
1012
//////////////////////////////////////////////////////////////////////
1013
////                                                              ////
1014
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1015
////                                                              ////
1016
//// This source file may be used and distributed without         ////
1017
//// restriction provided that this copyright statement is not    ////
1018
//// removed from the file and that any derivative work contains  ////
1019
//// the original copyright notice and the associated disclaimer. ////
1020
////                                                              ////
1021
//// This source file is free software; you can redistribute it   ////
1022
//// and/or modify it under the terms of the GNU Lesser General   ////
1023
//// Public License as published by the Free Software Foundation; ////
1024
//// either version 2.1 of the License, or (at your option) any   ////
1025
//// later version.                                               ////
1026
////                                                              ////
1027
//// This source is distributed in the hope that it will be       ////
1028
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1029
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1030
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1031
//// details.                                                     ////
1032
////                                                              ////
1033
//// You should have received a copy of the GNU Lesser General    ////
1034
//// Public License along with this source; if not, download it   ////
1035
//// from http://www.opencores.org/lgpl.shtml                     ////
1036
////                                                              ////
1037
//////////////////////////////////////////////////////////////////////
1038
// binary counter
1039
module vl_cnt_bin_ce_clear_l1_l2 (
1040
 clear, cke, q, level1, level2, rst, clk);
1041
   parameter length = 4;
1042
   input clear;
1043
   input cke;
1044
   output [length:1] q;
1045
   output reg level1;
1046
   output reg level2;
1047
   input rst;
1048
   input clk;
1049
   parameter clear_value = 0;
1050
   parameter set_value = 1;
1051
   parameter wrap_value = 15;
1052
   parameter level1_value = 8;
1053
   parameter level2_value = 15;
1054
   wire rew;
1055
   assign rew = 1'b0;
1056
   reg  [length:1] qi;
1057
   wire [length:1] q_next;
1058
   assign q_next =  clear ? {length{1'b0}} :qi + {{length-1{1'b0}},1'b1};
1059
   always @ (posedge clk or posedge rst)
1060
     if (rst)
1061
       qi <= {length{1'b0}};
1062
     else
1063
     if (cke)
1064
       qi <= q_next;
1065
   assign q = qi;
1066
    always @ (posedge clk or posedge rst)
1067
    if (rst)
1068
        level1 <= 1'b0;
1069
    else
1070
    if (cke)
1071
    if (clear)
1072
        level1 <= 1'b0;
1073
    else if (q_next == level1_value)
1074
        level1 <= 1'b1;
1075
    else if (qi == level1_value & rew)
1076
        level1 <= 1'b0;
1077
    always @ (posedge clk or posedge rst)
1078
    if (rst)
1079
        level2 <= 1'b0;
1080
    else
1081
    if (cke)
1082
    if (clear)
1083
        level2 <= 1'b0;
1084
    else if (q_next == level2_value)
1085
        level2 <= 1'b1;
1086
    else if (qi == level2_value & rew)
1087
        level2 <= 1'b0;
1088
endmodule
1089
//////////////////////////////////////////////////////////////////////
1090
////                                                              ////
1091
////  Versatile counter                                           ////
1092
////                                                              ////
1093
////  Description                                                 ////
1094
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1095
////  counter                                                     ////
1096
////                                                              ////
1097
////  To Do:                                                      ////
1098
////   - add LFSR with more taps                                  ////
1099
////                                                              ////
1100
////  Author(s):                                                  ////
1101
////      - Michael Unneback, unneback@opencores.org              ////
1102
////        ORSoC AB                                              ////
1103
////                                                              ////
1104
//////////////////////////////////////////////////////////////////////
1105
////                                                              ////
1106
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1107
////                                                              ////
1108
//// This source file may be used and distributed without         ////
1109
//// restriction provided that this copyright statement is not    ////
1110
//// removed from the file and that any derivative work contains  ////
1111
//// the original copyright notice and the associated disclaimer. ////
1112
////                                                              ////
1113
//// This source file is free software; you can redistribute it   ////
1114
//// and/or modify it under the terms of the GNU Lesser General   ////
1115
//// Public License as published by the Free Software Foundation; ////
1116
//// either version 2.1 of the License, or (at your option) any   ////
1117
//// later version.                                               ////
1118
////                                                              ////
1119
//// This source is distributed in the hope that it will be       ////
1120
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1121
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1122
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1123
//// details.                                                     ////
1124
////                                                              ////
1125
//// You should have received a copy of the GNU Lesser General    ////
1126
//// Public License along with this source; if not, download it   ////
1127
//// from http://www.opencores.org/lgpl.shtml                     ////
1128
////                                                              ////
1129
//////////////////////////////////////////////////////////////////////
1130
// binary counter
1131
module vl_cnt_bin_ce_clear_set_rew (
1132
 clear, set, cke, rew, q, rst, clk);
1133
   parameter length = 4;
1134
   input clear;
1135
   input set;
1136
   input cke;
1137
   input rew;
1138
   output [length:1] q;
1139
   input rst;
1140
   input clk;
1141
   parameter clear_value = 0;
1142
   parameter set_value = 1;
1143
   parameter wrap_value = 0;
1144
   parameter level1_value = 15;
1145
   reg  [length:1] qi;
1146
   wire  [length:1] q_next, q_next_fw, q_next_rew;
1147
   assign q_next_fw  =  clear ? {length{1'b0}} : set ? set_value :qi + {{length-1{1'b0}},1'b1};
1148
   assign q_next_rew =  clear ? clear_value : set ? set_value :qi - {{length-1{1'b0}},1'b1};
1149
   assign q_next = rew ? q_next_rew : q_next_fw;
1150
   always @ (posedge clk or posedge rst)
1151
     if (rst)
1152
       qi <= {length{1'b0}};
1153
     else
1154
     if (cke)
1155
       qi <= q_next;
1156
   assign q = qi;
1157
endmodule
1158
//////////////////////////////////////////////////////////////////////
1159
////                                                              ////
1160
////  Versatile counter                                           ////
1161
////                                                              ////
1162
////  Description                                                 ////
1163
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1164
////  counter                                                     ////
1165
////                                                              ////
1166
////  To Do:                                                      ////
1167
////   - add LFSR with more taps                                  ////
1168
////                                                              ////
1169
////  Author(s):                                                  ////
1170
////      - Michael Unneback, unneback@opencores.org              ////
1171
////        ORSoC AB                                              ////
1172
////                                                              ////
1173
//////////////////////////////////////////////////////////////////////
1174
////                                                              ////
1175
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1176
////                                                              ////
1177
//// This source file may be used and distributed without         ////
1178
//// restriction provided that this copyright statement is not    ////
1179
//// removed from the file and that any derivative work contains  ////
1180
//// the original copyright notice and the associated disclaimer. ////
1181
////                                                              ////
1182
//// This source file is free software; you can redistribute it   ////
1183
//// and/or modify it under the terms of the GNU Lesser General   ////
1184
//// Public License as published by the Free Software Foundation; ////
1185
//// either version 2.1 of the License, or (at your option) any   ////
1186
//// later version.                                               ////
1187
////                                                              ////
1188
//// This source is distributed in the hope that it will be       ////
1189
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1190
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1191
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1192
//// details.                                                     ////
1193
////                                                              ////
1194
//// You should have received a copy of the GNU Lesser General    ////
1195
//// Public License along with this source; if not, download it   ////
1196
//// from http://www.opencores.org/lgpl.shtml                     ////
1197
////                                                              ////
1198
//////////////////////////////////////////////////////////////////////
1199
// binary counter
1200
module vl_cnt_bin_ce_rew_l1 (
1201
 cke, rew, level1, rst, clk);
1202
   parameter length = 4;
1203
   input cke;
1204
   input rew;
1205
   output reg level1;
1206
   input rst;
1207
   input clk;
1208
   parameter clear_value = 0;
1209
   parameter set_value = 1;
1210
   parameter wrap_value = 1;
1211
   parameter level1_value = 15;
1212
   wire clear;
1213
   assign clear = 1'b0;
1214
   reg  [length:1] qi;
1215
   wire  [length:1] q_next, q_next_fw, q_next_rew;
1216
   assign q_next_fw  = qi + {{length-1{1'b0}},1'b1};
1217
   assign q_next_rew = qi - {{length-1{1'b0}},1'b1};
1218
   assign q_next = rew ? q_next_rew : q_next_fw;
1219
   always @ (posedge clk or posedge rst)
1220
     if (rst)
1221
       qi <= {length{1'b0}};
1222
     else
1223
     if (cke)
1224
       qi <= q_next;
1225
    always @ (posedge clk or posedge rst)
1226
    if (rst)
1227
        level1 <= 1'b0;
1228
    else
1229
    if (cke)
1230
    if (clear)
1231
        level1 <= 1'b0;
1232
    else if (q_next == level1_value)
1233
        level1 <= 1'b1;
1234
    else if (qi == level1_value & rew)
1235
        level1 <= 1'b0;
1236
endmodule
1237
//////////////////////////////////////////////////////////////////////
1238
////                                                              ////
1239
////  Versatile counter                                           ////
1240
////                                                              ////
1241
////  Description                                                 ////
1242
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1243
////  counter                                                     ////
1244
////                                                              ////
1245
////  To Do:                                                      ////
1246
////   - add LFSR with more taps                                  ////
1247
////                                                              ////
1248
////  Author(s):                                                  ////
1249
////      - Michael Unneback, unneback@opencores.org              ////
1250
////        ORSoC AB                                              ////
1251
////                                                              ////
1252
//////////////////////////////////////////////////////////////////////
1253
////                                                              ////
1254
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1255
////                                                              ////
1256
//// This source file may be used and distributed without         ////
1257
//// restriction provided that this copyright statement is not    ////
1258
//// removed from the file and that any derivative work contains  ////
1259
//// the original copyright notice and the associated disclaimer. ////
1260
////                                                              ////
1261
//// This source file is free software; you can redistribute it   ////
1262
//// and/or modify it under the terms of the GNU Lesser General   ////
1263
//// Public License as published by the Free Software Foundation; ////
1264
//// either version 2.1 of the License, or (at your option) any   ////
1265
//// later version.                                               ////
1266
////                                                              ////
1267
//// This source is distributed in the hope that it will be       ////
1268
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1269
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1270
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1271
//// details.                                                     ////
1272
////                                                              ////
1273
//// You should have received a copy of the GNU Lesser General    ////
1274
//// Public License along with this source; if not, download it   ////
1275
//// from http://www.opencores.org/lgpl.shtml                     ////
1276
////                                                              ////
1277
//////////////////////////////////////////////////////////////////////
1278
// binary counter
1279 40 unneback
module vl_cnt_bin_ce_rew_zq_l1 (
1280
 cke, rew, zq, level1, rst, clk);
1281 6 unneback
   parameter length = 4;
1282
   input cke;
1283
   input rew;
1284 25 unneback
   output reg zq;
1285
   output reg level1;
1286
   input rst;
1287
   input clk;
1288
   parameter clear_value = 0;
1289
   parameter set_value = 1;
1290
   parameter wrap_value = 1;
1291
   parameter level1_value = 15;
1292 29 unneback
   wire clear;
1293 30 unneback
   assign clear = 1'b0;
1294 25 unneback
   reg  [length:1] qi;
1295
   wire  [length:1] q_next, q_next_fw, q_next_rew;
1296
   assign q_next_fw  = qi + {{length-1{1'b0}},1'b1};
1297
   assign q_next_rew = qi - {{length-1{1'b0}},1'b1};
1298
   assign q_next = rew ? q_next_rew : q_next_fw;
1299
   always @ (posedge clk or posedge rst)
1300
     if (rst)
1301
       qi <= {length{1'b0}};
1302
     else
1303
     if (cke)
1304
       qi <= q_next;
1305
   always @ (posedge clk or posedge rst)
1306
     if (rst)
1307
       zq <= 1'b1;
1308
     else
1309
     if (cke)
1310
       zq <= q_next == {length{1'b0}};
1311
    always @ (posedge clk or posedge rst)
1312
    if (rst)
1313
        level1 <= 1'b0;
1314
    else
1315
    if (cke)
1316 29 unneback
    if (clear)
1317
        level1 <= 1'b0;
1318
    else if (q_next == level1_value)
1319 25 unneback
        level1 <= 1'b1;
1320
    else if (qi == level1_value & rew)
1321
        level1 <= 1'b0;
1322
endmodule
1323
//////////////////////////////////////////////////////////////////////
1324
////                                                              ////
1325
////  Versatile counter                                           ////
1326
////                                                              ////
1327
////  Description                                                 ////
1328
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1329
////  counter                                                     ////
1330
////                                                              ////
1331
////  To Do:                                                      ////
1332
////   - add LFSR with more taps                                  ////
1333
////                                                              ////
1334
////  Author(s):                                                  ////
1335
////      - Michael Unneback, unneback@opencores.org              ////
1336
////        ORSoC AB                                              ////
1337
////                                                              ////
1338
//////////////////////////////////////////////////////////////////////
1339
////                                                              ////
1340
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1341
////                                                              ////
1342
//// This source file may be used and distributed without         ////
1343
//// restriction provided that this copyright statement is not    ////
1344
//// removed from the file and that any derivative work contains  ////
1345
//// the original copyright notice and the associated disclaimer. ////
1346
////                                                              ////
1347
//// This source file is free software; you can redistribute it   ////
1348
//// and/or modify it under the terms of the GNU Lesser General   ////
1349
//// Public License as published by the Free Software Foundation; ////
1350
//// either version 2.1 of the License, or (at your option) any   ////
1351
//// later version.                                               ////
1352
////                                                              ////
1353
//// This source is distributed in the hope that it will be       ////
1354
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1355
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1356
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1357
//// details.                                                     ////
1358
////                                                              ////
1359
//// You should have received a copy of the GNU Lesser General    ////
1360
//// Public License along with this source; if not, download it   ////
1361
//// from http://www.opencores.org/lgpl.shtml                     ////
1362
////                                                              ////
1363
//////////////////////////////////////////////////////////////////////
1364
// binary counter
1365 40 unneback
module vl_cnt_bin_ce_rew_q_zq_l1 (
1366
 cke, rew, q, zq, level1, rst, clk);
1367 25 unneback
   parameter length = 4;
1368
   input cke;
1369
   input rew;
1370
   output [length:1] q;
1371
   output reg zq;
1372
   output reg level1;
1373
   input rst;
1374
   input clk;
1375
   parameter clear_value = 0;
1376
   parameter set_value = 1;
1377
   parameter wrap_value = 1;
1378
   parameter level1_value = 15;
1379 29 unneback
   wire clear;
1380 30 unneback
   assign clear = 1'b0;
1381 25 unneback
   reg  [length:1] qi;
1382
   wire  [length:1] q_next, q_next_fw, q_next_rew;
1383
   assign q_next_fw  = qi + {{length-1{1'b0}},1'b1};
1384
   assign q_next_rew = qi - {{length-1{1'b0}},1'b1};
1385
   assign q_next = rew ? q_next_rew : q_next_fw;
1386
   always @ (posedge clk or posedge rst)
1387
     if (rst)
1388
       qi <= {length{1'b0}};
1389
     else
1390
     if (cke)
1391
       qi <= q_next;
1392
   assign q = qi;
1393
   always @ (posedge clk or posedge rst)
1394
     if (rst)
1395
       zq <= 1'b1;
1396
     else
1397
     if (cke)
1398
       zq <= q_next == {length{1'b0}};
1399
    always @ (posedge clk or posedge rst)
1400
    if (rst)
1401
        level1 <= 1'b0;
1402
    else
1403
    if (cke)
1404 29 unneback
    if (clear)
1405
        level1 <= 1'b0;
1406
    else if (q_next == level1_value)
1407 25 unneback
        level1 <= 1'b1;
1408
    else if (qi == level1_value & rew)
1409
        level1 <= 1'b0;
1410
endmodule
1411
//////////////////////////////////////////////////////////////////////
1412
////                                                              ////
1413
////  Versatile counter                                           ////
1414
////                                                              ////
1415
////  Description                                                 ////
1416
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1417
////  counter                                                     ////
1418
////                                                              ////
1419
////  To Do:                                                      ////
1420
////   - add LFSR with more taps                                  ////
1421
////                                                              ////
1422
////  Author(s):                                                  ////
1423
////      - Michael Unneback, unneback@opencores.org              ////
1424
////        ORSoC AB                                              ////
1425
////                                                              ////
1426
//////////////////////////////////////////////////////////////////////
1427
////                                                              ////
1428
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1429
////                                                              ////
1430
//// This source file may be used and distributed without         ////
1431
//// restriction provided that this copyright statement is not    ////
1432
//// removed from the file and that any derivative work contains  ////
1433
//// the original copyright notice and the associated disclaimer. ////
1434
////                                                              ////
1435
//// This source file is free software; you can redistribute it   ////
1436
//// and/or modify it under the terms of the GNU Lesser General   ////
1437
//// Public License as published by the Free Software Foundation; ////
1438
//// either version 2.1 of the License, or (at your option) any   ////
1439
//// later version.                                               ////
1440
////                                                              ////
1441
//// This source is distributed in the hope that it will be       ////
1442
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1443
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1444
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1445
//// details.                                                     ////
1446
////                                                              ////
1447
//// You should have received a copy of the GNU Lesser General    ////
1448
//// Public License along with this source; if not, download it   ////
1449
//// from http://www.opencores.org/lgpl.shtml                     ////
1450
////                                                              ////
1451
//////////////////////////////////////////////////////////////////////
1452 75 unneback
// LFSR counter
1453 136 unneback
module vl_cnt_lfsr_zq (
1454
 zq, rst, clk);
1455
   parameter length = 4;
1456
   output reg zq;
1457
   input rst;
1458
   input clk;
1459
   parameter clear_value = 0;
1460
   parameter set_value = 1;
1461
   parameter wrap_value = 8;
1462
   parameter level1_value = 15;
1463
   reg  [length:1] qi;
1464
   reg lfsr_fb;
1465
   wire [length:1] q_next;
1466
   reg [32:1] polynom;
1467
   integer i;
1468
   always @ (qi)
1469
   begin
1470
        case (length)
1471
         2: polynom = 32'b11;                               // 0x3
1472
         3: polynom = 32'b110;                              // 0x6
1473
         4: polynom = 32'b1100;                             // 0xC
1474
         5: polynom = 32'b10100;                            // 0x14
1475
         6: polynom = 32'b110000;                           // 0x30
1476
         7: polynom = 32'b1100000;                          // 0x60
1477
         8: polynom = 32'b10111000;                         // 0xb8
1478
         9: polynom = 32'b100010000;                        // 0x110
1479
        10: polynom = 32'b1001000000;                       // 0x240
1480
        11: polynom = 32'b10100000000;                      // 0x500
1481
        12: polynom = 32'b100000101001;                     // 0x829
1482
        13: polynom = 32'b1000000001100;                    // 0x100C
1483
        14: polynom = 32'b10000000010101;                   // 0x2015
1484
        15: polynom = 32'b110000000000000;                  // 0x6000
1485
        16: polynom = 32'b1101000000001000;                 // 0xD008
1486
        17: polynom = 32'b10010000000000000;                // 0x12000
1487
        18: polynom = 32'b100000010000000000;               // 0x20400
1488
        19: polynom = 32'b1000000000000100011;              // 0x40023
1489
        20: polynom = 32'b10010000000000000000;             // 0x90000
1490
        21: polynom = 32'b101000000000000000000;            // 0x140000
1491
        22: polynom = 32'b1100000000000000000000;           // 0x300000
1492
        23: polynom = 32'b10000100000000000000000;          // 0x420000
1493
        24: polynom = 32'b111000010000000000000000;         // 0xE10000
1494
        25: polynom = 32'b1001000000000000000000000;        // 0x1200000
1495
        26: polynom = 32'b10000000000000000000100011;       // 0x2000023
1496
        27: polynom = 32'b100000000000000000000010011;      // 0x4000013
1497
        28: polynom = 32'b1100100000000000000000000000;     // 0xC800000
1498
        29: polynom = 32'b10100000000000000000000000000;    // 0x14000000
1499
        30: polynom = 32'b100000000000000000000000101001;   // 0x20000029
1500
        31: polynom = 32'b1001000000000000000000000000000;  // 0x48000000
1501
        32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
1502
        default: polynom = 32'b0;
1503
        endcase
1504
        lfsr_fb = qi[length];
1505
        for (i=length-1; i>=1; i=i-1) begin
1506
            if (polynom[i])
1507
                lfsr_fb = lfsr_fb  ~^ qi[i];
1508
        end
1509
    end
1510
   assign q_next = (qi == wrap_value) ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
1511
   always @ (posedge clk or posedge rst)
1512
     if (rst)
1513
       qi <= {length{1'b0}};
1514
     else
1515
       qi <= q_next;
1516
   always @ (posedge clk or posedge rst)
1517
     if (rst)
1518
       zq <= 1'b1;
1519
     else
1520
       zq <= q_next == {length{1'b0}};
1521
endmodule
1522
//////////////////////////////////////////////////////////////////////
1523
////                                                              ////
1524
////  Versatile counter                                           ////
1525
////                                                              ////
1526
////  Description                                                 ////
1527
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1528
////  counter                                                     ////
1529
////                                                              ////
1530
////  To Do:                                                      ////
1531
////   - add LFSR with more taps                                  ////
1532
////                                                              ////
1533
////  Author(s):                                                  ////
1534
////      - Michael Unneback, unneback@opencores.org              ////
1535
////        ORSoC AB                                              ////
1536
////                                                              ////
1537
//////////////////////////////////////////////////////////////////////
1538
////                                                              ////
1539
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1540
////                                                              ////
1541
//// This source file may be used and distributed without         ////
1542
//// restriction provided that this copyright statement is not    ////
1543
//// removed from the file and that any derivative work contains  ////
1544
//// the original copyright notice and the associated disclaimer. ////
1545
////                                                              ////
1546
//// This source file is free software; you can redistribute it   ////
1547
//// and/or modify it under the terms of the GNU Lesser General   ////
1548
//// Public License as published by the Free Software Foundation; ////
1549
//// either version 2.1 of the License, or (at your option) any   ////
1550
//// later version.                                               ////
1551
////                                                              ////
1552
//// This source is distributed in the hope that it will be       ////
1553
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1554
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1555
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1556
//// details.                                                     ////
1557
////                                                              ////
1558
//// You should have received a copy of the GNU Lesser General    ////
1559
//// Public License along with this source; if not, download it   ////
1560
//// from http://www.opencores.org/lgpl.shtml                     ////
1561
////                                                              ////
1562
//////////////////////////////////////////////////////////////////////
1563
// LFSR counter
1564 75 unneback
module vl_cnt_lfsr_ce (
1565
 cke, zq, rst, clk);
1566
   parameter length = 4;
1567
   input cke;
1568
   output reg zq;
1569
   input rst;
1570
   input clk;
1571
   parameter clear_value = 0;
1572
   parameter set_value = 1;
1573
   parameter wrap_value = 0;
1574
   parameter level1_value = 15;
1575
   reg  [length:1] qi;
1576
   reg lfsr_fb;
1577
   wire [length:1] q_next;
1578
   reg [32:1] polynom;
1579
   integer i;
1580
   always @ (qi)
1581
   begin
1582
        case (length)
1583
         2: polynom = 32'b11;                               // 0x3
1584
         3: polynom = 32'b110;                              // 0x6
1585
         4: polynom = 32'b1100;                             // 0xC
1586
         5: polynom = 32'b10100;                            // 0x14
1587
         6: polynom = 32'b110000;                           // 0x30
1588
         7: polynom = 32'b1100000;                          // 0x60
1589
         8: polynom = 32'b10111000;                         // 0xb8
1590
         9: polynom = 32'b100010000;                        // 0x110
1591
        10: polynom = 32'b1001000000;                       // 0x240
1592
        11: polynom = 32'b10100000000;                      // 0x500
1593
        12: polynom = 32'b100000101001;                     // 0x829
1594
        13: polynom = 32'b1000000001100;                    // 0x100C
1595
        14: polynom = 32'b10000000010101;                   // 0x2015
1596
        15: polynom = 32'b110000000000000;                  // 0x6000
1597
        16: polynom = 32'b1101000000001000;                 // 0xD008
1598
        17: polynom = 32'b10010000000000000;                // 0x12000
1599
        18: polynom = 32'b100000010000000000;               // 0x20400
1600
        19: polynom = 32'b1000000000000100011;              // 0x40023
1601
        20: polynom = 32'b10010000000000000000;             // 0x90000
1602
        21: polynom = 32'b101000000000000000000;            // 0x140000
1603
        22: polynom = 32'b1100000000000000000000;           // 0x300000
1604
        23: polynom = 32'b10000100000000000000000;          // 0x420000
1605
        24: polynom = 32'b111000010000000000000000;         // 0xE10000
1606
        25: polynom = 32'b1001000000000000000000000;        // 0x1200000
1607
        26: polynom = 32'b10000000000000000000100011;       // 0x2000023
1608
        27: polynom = 32'b100000000000000000000010011;      // 0x4000013
1609
        28: polynom = 32'b1100100000000000000000000000;     // 0xC800000
1610
        29: polynom = 32'b10100000000000000000000000000;    // 0x14000000
1611
        30: polynom = 32'b100000000000000000000000101001;   // 0x20000029
1612
        31: polynom = 32'b1001000000000000000000000000000;  // 0x48000000
1613
        32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
1614
        default: polynom = 32'b0;
1615
        endcase
1616
        lfsr_fb = qi[length];
1617
        for (i=length-1; i>=1; i=i-1) begin
1618
            if (polynom[i])
1619
                lfsr_fb = lfsr_fb  ~^ qi[i];
1620
        end
1621
    end
1622
   assign q_next = (qi == wrap_value) ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
1623
   always @ (posedge clk or posedge rst)
1624
     if (rst)
1625
       qi <= {length{1'b0}};
1626
     else
1627
     if (cke)
1628
       qi <= q_next;
1629
   always @ (posedge clk or posedge rst)
1630
     if (rst)
1631
       zq <= 1'b1;
1632
     else
1633
     if (cke)
1634
       zq <= q_next == {length{1'b0}};
1635
endmodule
1636
//////////////////////////////////////////////////////////////////////
1637
////                                                              ////
1638
////  Versatile counter                                           ////
1639
////                                                              ////
1640
////  Description                                                 ////
1641
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1642
////  counter                                                     ////
1643
////                                                              ////
1644
////  To Do:                                                      ////
1645
////   - add LFSR with more taps                                  ////
1646
////                                                              ////
1647
////  Author(s):                                                  ////
1648
////      - Michael Unneback, unneback@opencores.org              ////
1649
////        ORSoC AB                                              ////
1650
////                                                              ////
1651
//////////////////////////////////////////////////////////////////////
1652
////                                                              ////
1653
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1654
////                                                              ////
1655
//// This source file may be used and distributed without         ////
1656
//// restriction provided that this copyright statement is not    ////
1657
//// removed from the file and that any derivative work contains  ////
1658
//// the original copyright notice and the associated disclaimer. ////
1659
////                                                              ////
1660
//// This source file is free software; you can redistribute it   ////
1661
//// and/or modify it under the terms of the GNU Lesser General   ////
1662
//// Public License as published by the Free Software Foundation; ////
1663
//// either version 2.1 of the License, or (at your option) any   ////
1664
//// later version.                                               ////
1665
////                                                              ////
1666
//// This source is distributed in the hope that it will be       ////
1667
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1668
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1669
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1670
//// details.                                                     ////
1671
////                                                              ////
1672
//// You should have received a copy of the GNU Lesser General    ////
1673
//// Public License along with this source; if not, download it   ////
1674
//// from http://www.opencores.org/lgpl.shtml                     ////
1675
////                                                              ////
1676
//////////////////////////////////////////////////////////////////////
1677 139 unneback
// LFSR counter
1678
module vl_cnt_lfsr_ce_zq (
1679
 cke, zq, rst, clk);
1680
   parameter length = 4;
1681
   input cke;
1682
   output reg zq;
1683
   input rst;
1684
   input clk;
1685
   parameter clear_value = 0;
1686
   parameter set_value = 1;
1687
   parameter wrap_value = 8;
1688
   parameter level1_value = 15;
1689
   reg  [length:1] qi;
1690
   reg lfsr_fb;
1691
   wire [length:1] q_next;
1692
   reg [32:1] polynom;
1693
   integer i;
1694
   always @ (qi)
1695
   begin
1696
        case (length)
1697
         2: polynom = 32'b11;                               // 0x3
1698
         3: polynom = 32'b110;                              // 0x6
1699
         4: polynom = 32'b1100;                             // 0xC
1700
         5: polynom = 32'b10100;                            // 0x14
1701
         6: polynom = 32'b110000;                           // 0x30
1702
         7: polynom = 32'b1100000;                          // 0x60
1703
         8: polynom = 32'b10111000;                         // 0xb8
1704
         9: polynom = 32'b100010000;                        // 0x110
1705
        10: polynom = 32'b1001000000;                       // 0x240
1706
        11: polynom = 32'b10100000000;                      // 0x500
1707
        12: polynom = 32'b100000101001;                     // 0x829
1708
        13: polynom = 32'b1000000001100;                    // 0x100C
1709
        14: polynom = 32'b10000000010101;                   // 0x2015
1710
        15: polynom = 32'b110000000000000;                  // 0x6000
1711
        16: polynom = 32'b1101000000001000;                 // 0xD008
1712
        17: polynom = 32'b10010000000000000;                // 0x12000
1713
        18: polynom = 32'b100000010000000000;               // 0x20400
1714
        19: polynom = 32'b1000000000000100011;              // 0x40023
1715
        20: polynom = 32'b10010000000000000000;             // 0x90000
1716
        21: polynom = 32'b101000000000000000000;            // 0x140000
1717
        22: polynom = 32'b1100000000000000000000;           // 0x300000
1718
        23: polynom = 32'b10000100000000000000000;          // 0x420000
1719
        24: polynom = 32'b111000010000000000000000;         // 0xE10000
1720
        25: polynom = 32'b1001000000000000000000000;        // 0x1200000
1721
        26: polynom = 32'b10000000000000000000100011;       // 0x2000023
1722
        27: polynom = 32'b100000000000000000000010011;      // 0x4000013
1723
        28: polynom = 32'b1100100000000000000000000000;     // 0xC800000
1724
        29: polynom = 32'b10100000000000000000000000000;    // 0x14000000
1725
        30: polynom = 32'b100000000000000000000000101001;   // 0x20000029
1726
        31: polynom = 32'b1001000000000000000000000000000;  // 0x48000000
1727
        32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
1728
        default: polynom = 32'b0;
1729
        endcase
1730
        lfsr_fb = qi[length];
1731
        for (i=length-1; i>=1; i=i-1) begin
1732
            if (polynom[i])
1733
                lfsr_fb = lfsr_fb  ~^ qi[i];
1734
        end
1735
    end
1736
   assign q_next = (qi == wrap_value) ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
1737
   always @ (posedge clk or posedge rst)
1738
     if (rst)
1739
       qi <= {length{1'b0}};
1740
     else
1741
     if (cke)
1742
       qi <= q_next;
1743
   always @ (posedge clk or posedge rst)
1744
     if (rst)
1745
       zq <= 1'b1;
1746
     else
1747
     if (cke)
1748
       zq <= q_next == {length{1'b0}};
1749
endmodule
1750
//////////////////////////////////////////////////////////////////////
1751
////                                                              ////
1752
////  Versatile counter                                           ////
1753
////                                                              ////
1754
////  Description                                                 ////
1755
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1756
////  counter                                                     ////
1757
////                                                              ////
1758
////  To Do:                                                      ////
1759
////   - add LFSR with more taps                                  ////
1760
////                                                              ////
1761
////  Author(s):                                                  ////
1762
////      - Michael Unneback, unneback@opencores.org              ////
1763
////        ORSoC AB                                              ////
1764
////                                                              ////
1765
//////////////////////////////////////////////////////////////////////
1766
////                                                              ////
1767
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1768
////                                                              ////
1769
//// This source file may be used and distributed without         ////
1770
//// restriction provided that this copyright statement is not    ////
1771
//// removed from the file and that any derivative work contains  ////
1772
//// the original copyright notice and the associated disclaimer. ////
1773
////                                                              ////
1774
//// This source file is free software; you can redistribute it   ////
1775
//// and/or modify it under the terms of the GNU Lesser General   ////
1776
//// Public License as published by the Free Software Foundation; ////
1777
//// either version 2.1 of the License, or (at your option) any   ////
1778
//// later version.                                               ////
1779
////                                                              ////
1780
//// This source is distributed in the hope that it will be       ////
1781
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1782
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1783
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1784
//// details.                                                     ////
1785
////                                                              ////
1786
//// You should have received a copy of the GNU Lesser General    ////
1787
//// Public License along with this source; if not, download it   ////
1788
//// from http://www.opencores.org/lgpl.shtml                     ////
1789
////                                                              ////
1790
//////////////////////////////////////////////////////////////////////
1791
// LFSR counter
1792
module vl_cnt_lfsr_ce_q (
1793
 cke, q, rst, clk);
1794
   parameter length = 4;
1795
   input cke;
1796
   output [length:1] q;
1797
   input rst;
1798
   input clk;
1799
   parameter clear_value = 0;
1800
   parameter set_value = 1;
1801
   parameter wrap_value = 8;
1802
   parameter level1_value = 15;
1803
   reg  [length:1] qi;
1804
   reg lfsr_fb;
1805
   wire [length:1] q_next;
1806
   reg [32:1] polynom;
1807
   integer i;
1808
   always @ (qi)
1809
   begin
1810
        case (length)
1811
         2: polynom = 32'b11;                               // 0x3
1812
         3: polynom = 32'b110;                              // 0x6
1813
         4: polynom = 32'b1100;                             // 0xC
1814
         5: polynom = 32'b10100;                            // 0x14
1815
         6: polynom = 32'b110000;                           // 0x30
1816
         7: polynom = 32'b1100000;                          // 0x60
1817
         8: polynom = 32'b10111000;                         // 0xb8
1818
         9: polynom = 32'b100010000;                        // 0x110
1819
        10: polynom = 32'b1001000000;                       // 0x240
1820
        11: polynom = 32'b10100000000;                      // 0x500
1821
        12: polynom = 32'b100000101001;                     // 0x829
1822
        13: polynom = 32'b1000000001100;                    // 0x100C
1823
        14: polynom = 32'b10000000010101;                   // 0x2015
1824
        15: polynom = 32'b110000000000000;                  // 0x6000
1825
        16: polynom = 32'b1101000000001000;                 // 0xD008
1826
        17: polynom = 32'b10010000000000000;                // 0x12000
1827
        18: polynom = 32'b100000010000000000;               // 0x20400
1828
        19: polynom = 32'b1000000000000100011;              // 0x40023
1829
        20: polynom = 32'b10010000000000000000;             // 0x90000
1830
        21: polynom = 32'b101000000000000000000;            // 0x140000
1831
        22: polynom = 32'b1100000000000000000000;           // 0x300000
1832
        23: polynom = 32'b10000100000000000000000;          // 0x420000
1833
        24: polynom = 32'b111000010000000000000000;         // 0xE10000
1834
        25: polynom = 32'b1001000000000000000000000;        // 0x1200000
1835
        26: polynom = 32'b10000000000000000000100011;       // 0x2000023
1836
        27: polynom = 32'b100000000000000000000010011;      // 0x4000013
1837
        28: polynom = 32'b1100100000000000000000000000;     // 0xC800000
1838
        29: polynom = 32'b10100000000000000000000000000;    // 0x14000000
1839
        30: polynom = 32'b100000000000000000000000101001;   // 0x20000029
1840
        31: polynom = 32'b1001000000000000000000000000000;  // 0x48000000
1841
        32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
1842
        default: polynom = 32'b0;
1843
        endcase
1844
        lfsr_fb = qi[length];
1845
        for (i=length-1; i>=1; i=i-1) begin
1846
            if (polynom[i])
1847
                lfsr_fb = lfsr_fb  ~^ qi[i];
1848
        end
1849
    end
1850
   assign q_next = (qi == wrap_value) ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
1851
   always @ (posedge clk or posedge rst)
1852
     if (rst)
1853
       qi <= {length{1'b0}};
1854
     else
1855
     if (cke)
1856
       qi <= q_next;
1857
   assign q = qi;
1858
endmodule
1859
//////////////////////////////////////////////////////////////////////
1860
////                                                              ////
1861
////  Versatile counter                                           ////
1862
////                                                              ////
1863
////  Description                                                 ////
1864
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1865
////  counter                                                     ////
1866
////                                                              ////
1867
////  To Do:                                                      ////
1868
////   - add LFSR with more taps                                  ////
1869
////                                                              ////
1870
////  Author(s):                                                  ////
1871
////      - Michael Unneback, unneback@opencores.org              ////
1872
////        ORSoC AB                                              ////
1873
////                                                              ////
1874
//////////////////////////////////////////////////////////////////////
1875
////                                                              ////
1876
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1877
////                                                              ////
1878
//// This source file may be used and distributed without         ////
1879
//// restriction provided that this copyright statement is not    ////
1880
//// removed from the file and that any derivative work contains  ////
1881
//// the original copyright notice and the associated disclaimer. ////
1882
////                                                              ////
1883
//// This source file is free software; you can redistribute it   ////
1884
//// and/or modify it under the terms of the GNU Lesser General   ////
1885
//// Public License as published by the Free Software Foundation; ////
1886
//// either version 2.1 of the License, or (at your option) any   ////
1887
//// later version.                                               ////
1888
////                                                              ////
1889
//// This source is distributed in the hope that it will be       ////
1890
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1891
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1892
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1893
//// details.                                                     ////
1894
////                                                              ////
1895
//// You should have received a copy of the GNU Lesser General    ////
1896
//// Public License along with this source; if not, download it   ////
1897
//// from http://www.opencores.org/lgpl.shtml                     ////
1898
////                                                              ////
1899
//////////////////////////////////////////////////////////////////////
1900
// LFSR counter
1901
module vl_cnt_lfsr_ce_clear_q (
1902
 clear, cke, q, rst, clk);
1903
   parameter length = 4;
1904
   input clear;
1905
   input cke;
1906
   output [length:1] q;
1907
   input rst;
1908
   input clk;
1909
   parameter clear_value = 0;
1910
   parameter set_value = 1;
1911
   parameter wrap_value = 8;
1912
   parameter level1_value = 15;
1913
   reg  [length:1] qi;
1914
   reg lfsr_fb;
1915
   wire [length:1] q_next;
1916
   reg [32:1] polynom;
1917
   integer i;
1918
   always @ (qi)
1919
   begin
1920
        case (length)
1921
         2: polynom = 32'b11;                               // 0x3
1922
         3: polynom = 32'b110;                              // 0x6
1923
         4: polynom = 32'b1100;                             // 0xC
1924
         5: polynom = 32'b10100;                            // 0x14
1925
         6: polynom = 32'b110000;                           // 0x30
1926
         7: polynom = 32'b1100000;                          // 0x60
1927
         8: polynom = 32'b10111000;                         // 0xb8
1928
         9: polynom = 32'b100010000;                        // 0x110
1929
        10: polynom = 32'b1001000000;                       // 0x240
1930
        11: polynom = 32'b10100000000;                      // 0x500
1931
        12: polynom = 32'b100000101001;                     // 0x829
1932
        13: polynom = 32'b1000000001100;                    // 0x100C
1933
        14: polynom = 32'b10000000010101;                   // 0x2015
1934
        15: polynom = 32'b110000000000000;                  // 0x6000
1935
        16: polynom = 32'b1101000000001000;                 // 0xD008
1936
        17: polynom = 32'b10010000000000000;                // 0x12000
1937
        18: polynom = 32'b100000010000000000;               // 0x20400
1938
        19: polynom = 32'b1000000000000100011;              // 0x40023
1939
        20: polynom = 32'b10010000000000000000;             // 0x90000
1940
        21: polynom = 32'b101000000000000000000;            // 0x140000
1941
        22: polynom = 32'b1100000000000000000000;           // 0x300000
1942
        23: polynom = 32'b10000100000000000000000;          // 0x420000
1943
        24: polynom = 32'b111000010000000000000000;         // 0xE10000
1944
        25: polynom = 32'b1001000000000000000000000;        // 0x1200000
1945
        26: polynom = 32'b10000000000000000000100011;       // 0x2000023
1946
        27: polynom = 32'b100000000000000000000010011;      // 0x4000013
1947
        28: polynom = 32'b1100100000000000000000000000;     // 0xC800000
1948
        29: polynom = 32'b10100000000000000000000000000;    // 0x14000000
1949
        30: polynom = 32'b100000000000000000000000101001;   // 0x20000029
1950
        31: polynom = 32'b1001000000000000000000000000000;  // 0x48000000
1951
        32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
1952
        default: polynom = 32'b0;
1953
        endcase
1954
        lfsr_fb = qi[length];
1955
        for (i=length-1; i>=1; i=i-1) begin
1956
            if (polynom[i])
1957
                lfsr_fb = lfsr_fb  ~^ qi[i];
1958
        end
1959
    end
1960
   assign q_next =  clear ? {length{1'b0}} :(qi == wrap_value) ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
1961
   always @ (posedge clk or posedge rst)
1962
     if (rst)
1963
       qi <= {length{1'b0}};
1964
     else
1965
     if (cke)
1966
       qi <= q_next;
1967
   assign q = qi;
1968
endmodule
1969
//////////////////////////////////////////////////////////////////////
1970
////                                                              ////
1971
////  Versatile counter                                           ////
1972
////                                                              ////
1973
////  Description                                                 ////
1974
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1975
////  counter                                                     ////
1976
////                                                              ////
1977
////  To Do:                                                      ////
1978
////   - add LFSR with more taps                                  ////
1979
////                                                              ////
1980
////  Author(s):                                                  ////
1981
////      - Michael Unneback, unneback@opencores.org              ////
1982
////        ORSoC AB                                              ////
1983
////                                                              ////
1984
//////////////////////////////////////////////////////////////////////
1985
////                                                              ////
1986
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1987
////                                                              ////
1988
//// This source file may be used and distributed without         ////
1989
//// restriction provided that this copyright statement is not    ////
1990
//// removed from the file and that any derivative work contains  ////
1991
//// the original copyright notice and the associated disclaimer. ////
1992
////                                                              ////
1993
//// This source file is free software; you can redistribute it   ////
1994
//// and/or modify it under the terms of the GNU Lesser General   ////
1995
//// Public License as published by the Free Software Foundation; ////
1996
//// either version 2.1 of the License, or (at your option) any   ////
1997
//// later version.                                               ////
1998
////                                                              ////
1999
//// This source is distributed in the hope that it will be       ////
2000
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
2001
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
2002
//// PURPOSE.  See the GNU Lesser General Public License for more ////
2003
//// details.                                                     ////
2004
////                                                              ////
2005
//// You should have received a copy of the GNU Lesser General    ////
2006
//// Public License along with this source; if not, download it   ////
2007
//// from http://www.opencores.org/lgpl.shtml                     ////
2008
////                                                              ////
2009
//////////////////////////////////////////////////////////////////////
2010
// LFSR counter
2011
module vl_cnt_lfsr_ce_q_zq (
2012
 cke, q, zq, rst, clk);
2013
   parameter length = 4;
2014
   input cke;
2015
   output [length:1] q;
2016
   output reg zq;
2017
   input rst;
2018
   input clk;
2019
   parameter clear_value = 0;
2020
   parameter set_value = 1;
2021
   parameter wrap_value = 8;
2022
   parameter level1_value = 15;
2023
   reg  [length:1] qi;
2024
   reg lfsr_fb;
2025
   wire [length:1] q_next;
2026
   reg [32:1] polynom;
2027
   integer i;
2028
   always @ (qi)
2029
   begin
2030
        case (length)
2031
         2: polynom = 32'b11;                               // 0x3
2032
         3: polynom = 32'b110;                              // 0x6
2033
         4: polynom = 32'b1100;                             // 0xC
2034
         5: polynom = 32'b10100;                            // 0x14
2035
         6: polynom = 32'b110000;                           // 0x30
2036
         7: polynom = 32'b1100000;                          // 0x60
2037
         8: polynom = 32'b10111000;                         // 0xb8
2038
         9: polynom = 32'b100010000;                        // 0x110
2039
        10: polynom = 32'b1001000000;                       // 0x240
2040
        11: polynom = 32'b10100000000;                      // 0x500
2041
        12: polynom = 32'b100000101001;                     // 0x829
2042
        13: polynom = 32'b1000000001100;                    // 0x100C
2043
        14: polynom = 32'b10000000010101;                   // 0x2015
2044
        15: polynom = 32'b110000000000000;                  // 0x6000
2045
        16: polynom = 32'b1101000000001000;                 // 0xD008
2046
        17: polynom = 32'b10010000000000000;                // 0x12000
2047
        18: polynom = 32'b100000010000000000;               // 0x20400
2048
        19: polynom = 32'b1000000000000100011;              // 0x40023
2049
        20: polynom = 32'b10010000000000000000;             // 0x90000
2050
        21: polynom = 32'b101000000000000000000;            // 0x140000
2051
        22: polynom = 32'b1100000000000000000000;           // 0x300000
2052
        23: polynom = 32'b10000100000000000000000;          // 0x420000
2053
        24: polynom = 32'b111000010000000000000000;         // 0xE10000
2054
        25: polynom = 32'b1001000000000000000000000;        // 0x1200000
2055
        26: polynom = 32'b10000000000000000000100011;       // 0x2000023
2056
        27: polynom = 32'b100000000000000000000010011;      // 0x4000013
2057
        28: polynom = 32'b1100100000000000000000000000;     // 0xC800000
2058
        29: polynom = 32'b10100000000000000000000000000;    // 0x14000000
2059
        30: polynom = 32'b100000000000000000000000101001;   // 0x20000029
2060
        31: polynom = 32'b1001000000000000000000000000000;  // 0x48000000
2061
        32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
2062
        default: polynom = 32'b0;
2063
        endcase
2064
        lfsr_fb = qi[length];
2065
        for (i=length-1; i>=1; i=i-1) begin
2066
            if (polynom[i])
2067
                lfsr_fb = lfsr_fb  ~^ qi[i];
2068
        end
2069
    end
2070
   assign q_next = (qi == wrap_value) ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
2071
   always @ (posedge clk or posedge rst)
2072
     if (rst)
2073
       qi <= {length{1'b0}};
2074
     else
2075
     if (cke)
2076
       qi <= q_next;
2077
   assign q = qi;
2078
   always @ (posedge clk or posedge rst)
2079
     if (rst)
2080
       zq <= 1'b1;
2081
     else
2082
     if (cke)
2083
       zq <= q_next == {length{1'b0}};
2084
endmodule
2085
//////////////////////////////////////////////////////////////////////
2086
////                                                              ////
2087
////  Versatile counter                                           ////
2088
////                                                              ////
2089
////  Description                                                 ////
2090
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
2091
////  counter                                                     ////
2092
////                                                              ////
2093
////  To Do:                                                      ////
2094
////   - add LFSR with more taps                                  ////
2095
////                                                              ////
2096
////  Author(s):                                                  ////
2097
////      - Michael Unneback, unneback@opencores.org              ////
2098
////        ORSoC AB                                              ////
2099
////                                                              ////
2100
//////////////////////////////////////////////////////////////////////
2101
////                                                              ////
2102
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
2103
////                                                              ////
2104
//// This source file may be used and distributed without         ////
2105
//// restriction provided that this copyright statement is not    ////
2106
//// removed from the file and that any derivative work contains  ////
2107
//// the original copyright notice and the associated disclaimer. ////
2108
////                                                              ////
2109
//// This source file is free software; you can redistribute it   ////
2110
//// and/or modify it under the terms of the GNU Lesser General   ////
2111
//// Public License as published by the Free Software Foundation; ////
2112
//// either version 2.1 of the License, or (at your option) any   ////
2113
//// later version.                                               ////
2114
////                                                              ////
2115
//// This source is distributed in the hope that it will be       ////
2116
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
2117
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
2118
//// PURPOSE.  See the GNU Lesser General Public License for more ////
2119
//// details.                                                     ////
2120
////                                                              ////
2121
//// You should have received a copy of the GNU Lesser General    ////
2122
//// Public License along with this source; if not, download it   ////
2123
//// from http://www.opencores.org/lgpl.shtml                     ////
2124
////                                                              ////
2125
//////////////////////////////////////////////////////////////////////
2126
// LFSR counter
2127
module vl_cnt_lfsr_ce_rew_l1 (
2128
 cke, rew, level1, rst, clk);
2129
   parameter length = 4;
2130
   input cke;
2131
   input rew;
2132
   output reg level1;
2133
   input rst;
2134
   input clk;
2135
   parameter clear_value = 0;
2136
   parameter set_value = 1;
2137
   parameter wrap_value = 8;
2138
   parameter level1_value = 15;
2139
   wire clear;
2140
   assign clear = 1'b0;
2141
   reg  [length:1] qi;
2142
   reg lfsr_fb, lfsr_fb_rew;
2143
   wire  [length:1] q_next, q_next_fw, q_next_rew;
2144
   reg [32:1] polynom_rew;
2145
   integer j;
2146
   reg [32:1] polynom;
2147
   integer i;
2148
   always @ (qi)
2149
   begin
2150
        case (length)
2151
         2: polynom = 32'b11;                               // 0x3
2152
         3: polynom = 32'b110;                              // 0x6
2153
         4: polynom = 32'b1100;                             // 0xC
2154
         5: polynom = 32'b10100;                            // 0x14
2155
         6: polynom = 32'b110000;                           // 0x30
2156
         7: polynom = 32'b1100000;                          // 0x60
2157
         8: polynom = 32'b10111000;                         // 0xb8
2158
         9: polynom = 32'b100010000;                        // 0x110
2159
        10: polynom = 32'b1001000000;                       // 0x240
2160
        11: polynom = 32'b10100000000;                      // 0x500
2161
        12: polynom = 32'b100000101001;                     // 0x829
2162
        13: polynom = 32'b1000000001100;                    // 0x100C
2163
        14: polynom = 32'b10000000010101;                   // 0x2015
2164
        15: polynom = 32'b110000000000000;                  // 0x6000
2165
        16: polynom = 32'b1101000000001000;                 // 0xD008
2166
        17: polynom = 32'b10010000000000000;                // 0x12000
2167
        18: polynom = 32'b100000010000000000;               // 0x20400
2168
        19: polynom = 32'b1000000000000100011;              // 0x40023
2169
        20: polynom = 32'b10010000000000000000;             // 0x90000
2170
        21: polynom = 32'b101000000000000000000;            // 0x140000
2171
        22: polynom = 32'b1100000000000000000000;           // 0x300000
2172
        23: polynom = 32'b10000100000000000000000;          // 0x420000
2173
        24: polynom = 32'b111000010000000000000000;         // 0xE10000
2174
        25: polynom = 32'b1001000000000000000000000;        // 0x1200000
2175
        26: polynom = 32'b10000000000000000000100011;       // 0x2000023
2176
        27: polynom = 32'b100000000000000000000010011;      // 0x4000013
2177
        28: polynom = 32'b1100100000000000000000000000;     // 0xC800000
2178
        29: polynom = 32'b10100000000000000000000000000;    // 0x14000000
2179
        30: polynom = 32'b100000000000000000000000101001;   // 0x20000029
2180
        31: polynom = 32'b1001000000000000000000000000000;  // 0x48000000
2181
        32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
2182
        default: polynom = 32'b0;
2183
        endcase
2184
        lfsr_fb = qi[length];
2185
        for (i=length-1; i>=1; i=i-1) begin
2186
            if (polynom[i])
2187
                lfsr_fb = lfsr_fb  ~^ qi[i];
2188
        end
2189
    end
2190
   assign q_next_fw  = (qi == wrap_value) ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
2191
   always @ (qi)
2192
   begin
2193
        case (length)
2194
         2: polynom_rew = 32'b11;
2195
         3: polynom_rew = 32'b110;
2196
         4: polynom_rew = 32'b1100;
2197
         5: polynom_rew = 32'b10100;
2198
         6: polynom_rew = 32'b110000;
2199
         7: polynom_rew = 32'b1100000;
2200
         8: polynom_rew = 32'b10111000;
2201
         9: polynom_rew = 32'b100010000;
2202
        10: polynom_rew = 32'b1001000000;
2203
        11: polynom_rew = 32'b10100000000;
2204
        12: polynom_rew = 32'b100000101001;
2205
        13: polynom_rew = 32'b1000000001100;
2206
        14: polynom_rew = 32'b10000000010101;
2207
        15: polynom_rew = 32'b110000000000000;
2208
        16: polynom_rew = 32'b1101000000001000;
2209
        17: polynom_rew = 32'b10010000000000000;
2210
        18: polynom_rew = 32'b100000010000000000;
2211
        19: polynom_rew = 32'b1000000000000100011;
2212
        20: polynom_rew = 32'b10000010000000000000;
2213
        21: polynom_rew = 32'b101000000000000000000;
2214
        22: polynom_rew = 32'b1100000000000000000000;
2215
        23: polynom_rew = 32'b10000100000000000000000;
2216
        24: polynom_rew = 32'b111000010000000000000000;
2217
        25: polynom_rew = 32'b1001000000000000000000000;
2218
        26: polynom_rew = 32'b10000000000000000000100011;
2219
        27: polynom_rew = 32'b100000000000000000000010011;
2220
        28: polynom_rew = 32'b1100100000000000000000000000;
2221
        29: polynom_rew = 32'b10100000000000000000000000000;
2222
        30: polynom_rew = 32'b100000000000000000000000101001;
2223
        31: polynom_rew = 32'b1001000000000000000000000000000;
2224
        32: polynom_rew = 32'b10000000001000000000000000000011;
2225
        default: polynom_rew = 32'b0;
2226
        endcase
2227
        // rotate left
2228
        polynom_rew[length:1] = { polynom_rew[length-2:1],polynom_rew[length] };
2229
        lfsr_fb_rew = qi[length];
2230
        for (i=length-1; i>=1; i=i-1) begin
2231
            if (polynom_rew[i])
2232
                lfsr_fb_rew = lfsr_fb_rew  ~^ qi[i];
2233
        end
2234
    end
2235
   assign q_next_rew = (qi == wrap_value) ? {length{1'b0}} :{lfsr_fb_rew,qi[length:2]};
2236
   assign q_next = rew ? q_next_rew : q_next_fw;
2237
   always @ (posedge clk or posedge rst)
2238
     if (rst)
2239
       qi <= {length{1'b0}};
2240
     else
2241
     if (cke)
2242
       qi <= q_next;
2243
    always @ (posedge clk or posedge rst)
2244
    if (rst)
2245
        level1 <= 1'b0;
2246
    else
2247
    if (cke)
2248
    if (clear)
2249
        level1 <= 1'b0;
2250
    else if (q_next == level1_value)
2251
        level1 <= 1'b1;
2252
    else if (qi == level1_value & rew)
2253
        level1 <= 1'b0;
2254
endmodule
2255
//////////////////////////////////////////////////////////////////////
2256
////                                                              ////
2257
////  Versatile counter                                           ////
2258
////                                                              ////
2259
////  Description                                                 ////
2260
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
2261
////  counter                                                     ////
2262
////                                                              ////
2263
////  To Do:                                                      ////
2264
////   - add LFSR with more taps                                  ////
2265
////                                                              ////
2266
////  Author(s):                                                  ////
2267
////      - Michael Unneback, unneback@opencores.org              ////
2268
////        ORSoC AB                                              ////
2269
////                                                              ////
2270
//////////////////////////////////////////////////////////////////////
2271
////                                                              ////
2272
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
2273
////                                                              ////
2274
//// This source file may be used and distributed without         ////
2275
//// restriction provided that this copyright statement is not    ////
2276
//// removed from the file and that any derivative work contains  ////
2277
//// the original copyright notice and the associated disclaimer. ////
2278
////                                                              ////
2279
//// This source file is free software; you can redistribute it   ////
2280
//// and/or modify it under the terms of the GNU Lesser General   ////
2281
//// Public License as published by the Free Software Foundation; ////
2282
//// either version 2.1 of the License, or (at your option) any   ////
2283
//// later version.                                               ////
2284
////                                                              ////
2285
//// This source is distributed in the hope that it will be       ////
2286
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
2287
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
2288
//// PURPOSE.  See the GNU Lesser General Public License for more ////
2289
//// details.                                                     ////
2290
////                                                              ////
2291
//// You should have received a copy of the GNU Lesser General    ////
2292
//// Public License along with this source; if not, download it   ////
2293
//// from http://www.opencores.org/lgpl.shtml                     ////
2294
////                                                              ////
2295
//////////////////////////////////////////////////////////////////////
2296 6 unneback
// GRAY counter
2297 139 unneback
module vl_cnt_gray (
2298
 q, rst, clk);
2299
   parameter length = 4;
2300
   output reg [length:1] q;
2301
   input rst;
2302
   input clk;
2303
   parameter clear_value = 0;
2304
   parameter set_value = 1;
2305
   parameter wrap_value = 8;
2306
   parameter level1_value = 15;
2307
   reg  [length:1] qi;
2308
   wire [length:1] q_next;
2309
   assign q_next = qi + {{length-1{1'b0}},1'b1};
2310
   always @ (posedge clk or posedge rst)
2311
     if (rst)
2312
       qi <= {length{1'b0}};
2313
     else
2314
       qi <= q_next;
2315
   always @ (posedge clk or posedge rst)
2316
     if (rst)
2317
       q <= {length{1'b0}};
2318
     else
2319
         q <= (q_next>>1) ^ q_next;
2320
endmodule
2321
//////////////////////////////////////////////////////////////////////
2322
////                                                              ////
2323
////  Versatile counter                                           ////
2324
////                                                              ////
2325
////  Description                                                 ////
2326
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
2327
////  counter                                                     ////
2328
////                                                              ////
2329
////  To Do:                                                      ////
2330
////   - add LFSR with more taps                                  ////
2331
////                                                              ////
2332
////  Author(s):                                                  ////
2333
////      - Michael Unneback, unneback@opencores.org              ////
2334
////        ORSoC AB                                              ////
2335
////                                                              ////
2336
//////////////////////////////////////////////////////////////////////
2337
////                                                              ////
2338
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
2339
////                                                              ////
2340
//// This source file may be used and distributed without         ////
2341
//// restriction provided that this copyright statement is not    ////
2342
//// removed from the file and that any derivative work contains  ////
2343
//// the original copyright notice and the associated disclaimer. ////
2344
////                                                              ////
2345
//// This source file is free software; you can redistribute it   ////
2346
//// and/or modify it under the terms of the GNU Lesser General   ////
2347
//// Public License as published by the Free Software Foundation; ////
2348
//// either version 2.1 of the License, or (at your option) any   ////
2349
//// later version.                                               ////
2350
////                                                              ////
2351
//// This source is distributed in the hope that it will be       ////
2352
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
2353
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
2354
//// PURPOSE.  See the GNU Lesser General Public License for more ////
2355
//// details.                                                     ////
2356
////                                                              ////
2357
//// You should have received a copy of the GNU Lesser General    ////
2358
//// Public License along with this source; if not, download it   ////
2359
//// from http://www.opencores.org/lgpl.shtml                     ////
2360
////                                                              ////
2361
//////////////////////////////////////////////////////////////////////
2362
// GRAY counter
2363
module vl_cnt_gray_ce (
2364
 cke, q, rst, clk);
2365
   parameter length = 4;
2366
   input cke;
2367
   output reg [length:1] q;
2368
   input rst;
2369
   input clk;
2370
   parameter clear_value = 0;
2371
   parameter set_value = 1;
2372
   parameter wrap_value = 8;
2373
   parameter level1_value = 15;
2374
   reg  [length:1] qi;
2375
   wire [length:1] q_next;
2376
   assign q_next = qi + {{length-1{1'b0}},1'b1};
2377
   always @ (posedge clk or posedge rst)
2378
     if (rst)
2379
       qi <= {length{1'b0}};
2380
     else
2381
     if (cke)
2382
       qi <= q_next;
2383
   always @ (posedge clk or posedge rst)
2384
     if (rst)
2385
       q <= {length{1'b0}};
2386
     else
2387
       if (cke)
2388
         q <= (q_next>>1) ^ q_next;
2389
endmodule
2390
//////////////////////////////////////////////////////////////////////
2391
////                                                              ////
2392
////  Versatile counter                                           ////
2393
////                                                              ////
2394
////  Description                                                 ////
2395
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
2396
////  counter                                                     ////
2397
////                                                              ////
2398
////  To Do:                                                      ////
2399
////   - add LFSR with more taps                                  ////
2400
////                                                              ////
2401
////  Author(s):                                                  ////
2402
////      - Michael Unneback, unneback@opencores.org              ////
2403
////        ORSoC AB                                              ////
2404
////                                                              ////
2405
//////////////////////////////////////////////////////////////////////
2406
////                                                              ////
2407
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
2408
////                                                              ////
2409
//// This source file may be used and distributed without         ////
2410
//// restriction provided that this copyright statement is not    ////
2411
//// removed from the file and that any derivative work contains  ////
2412
//// the original copyright notice and the associated disclaimer. ////
2413
////                                                              ////
2414
//// This source file is free software; you can redistribute it   ////
2415
//// and/or modify it under the terms of the GNU Lesser General   ////
2416
//// Public License as published by the Free Software Foundation; ////
2417
//// either version 2.1 of the License, or (at your option) any   ////
2418
//// later version.                                               ////
2419
////                                                              ////
2420
//// This source is distributed in the hope that it will be       ////
2421
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
2422
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
2423
//// PURPOSE.  See the GNU Lesser General Public License for more ////
2424
//// details.                                                     ////
2425
////                                                              ////
2426
//// You should have received a copy of the GNU Lesser General    ////
2427
//// Public License along with this source; if not, download it   ////
2428
//// from http://www.opencores.org/lgpl.shtml                     ////
2429
////                                                              ////
2430
//////////////////////////////////////////////////////////////////////
2431
// GRAY counter
2432 40 unneback
module vl_cnt_gray_ce_bin (
2433
 cke, q, q_bin, rst, clk);
2434 6 unneback
   parameter length = 4;
2435
   input cke;
2436
   output reg [length:1] q;
2437
   output [length:1] q_bin;
2438
   input rst;
2439
   input clk;
2440
   parameter clear_value = 0;
2441
   parameter set_value = 1;
2442
   parameter wrap_value = 8;
2443
   parameter level1_value = 15;
2444
   reg  [length:1] qi;
2445
   wire [length:1] q_next;
2446
   assign q_next = qi + {{length-1{1'b0}},1'b1};
2447
   always @ (posedge clk or posedge rst)
2448
     if (rst)
2449
       qi <= {length{1'b0}};
2450
     else
2451
     if (cke)
2452
       qi <= q_next;
2453
   always @ (posedge clk or posedge rst)
2454
     if (rst)
2455
       q <= {length{1'b0}};
2456
     else
2457
       if (cke)
2458
         q <= (q_next>>1) ^ q_next;
2459
   assign q_bin = qi;
2460
endmodule
2461
//////////////////////////////////////////////////////////////////////
2462
////                                                              ////
2463
////  Versatile library, counters                                 ////
2464
////                                                              ////
2465
////  Description                                                 ////
2466
////  counters                                                    ////
2467
////                                                              ////
2468
////                                                              ////
2469
////  To Do:                                                      ////
2470
////   - add more counters                                        ////
2471
////                                                              ////
2472
////  Author(s):                                                  ////
2473
////      - Michael Unneback, unneback@opencores.org              ////
2474
////        ORSoC AB                                              ////
2475
////                                                              ////
2476
//////////////////////////////////////////////////////////////////////
2477
////                                                              ////
2478
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
2479
////                                                              ////
2480
//// This source file may be used and distributed without         ////
2481
//// restriction provided that this copyright statement is not    ////
2482
//// removed from the file and that any derivative work contains  ////
2483
//// the original copyright notice and the associated disclaimer. ////
2484
////                                                              ////
2485
//// This source file is free software; you can redistribute it   ////
2486
//// and/or modify it under the terms of the GNU Lesser General   ////
2487
//// Public License as published by the Free Software Foundation; ////
2488
//// either version 2.1 of the License, or (at your option) any   ////
2489
//// later version.                                               ////
2490
////                                                              ////
2491
//// This source is distributed in the hope that it will be       ////
2492
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
2493
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
2494
//// PURPOSE.  See the GNU Lesser General Public License for more ////
2495
//// details.                                                     ////
2496
////                                                              ////
2497
//// You should have received a copy of the GNU Lesser General    ////
2498
//// Public License along with this source; if not, download it   ////
2499
//// from http://www.opencores.org/lgpl.shtml                     ////
2500
////                                                              ////
2501
//////////////////////////////////////////////////////////////////////
2502 18 unneback
module vl_cnt_shreg_wrap ( q, rst, clk);
2503 6 unneback
   parameter length = 4;
2504
   output reg [0:length-1] q;
2505
   input rst;
2506
   input clk;
2507
    always @ (posedge clk or posedge rst)
2508
    if (rst)
2509
        q <= {1'b1,{length-1{1'b0}}};
2510
    else
2511
        q <= {q[length-1],q[0:length-2]};
2512
endmodule
2513 18 unneback
module vl_cnt_shreg_ce_wrap ( cke, q, rst, clk);
2514 6 unneback
   parameter length = 4;
2515
   input cke;
2516
   output reg [0:length-1] q;
2517
   input rst;
2518
   input clk;
2519
    always @ (posedge clk or posedge rst)
2520
    if (rst)
2521
        q <= {1'b1,{length-1{1'b0}}};
2522
    else
2523
        if (cke)
2524
            q <= {q[length-1],q[0:length-2]};
2525
endmodule
2526 105 unneback
module vl_cnt_shreg_clear ( clear, q, rst, clk);
2527
   parameter length = 4;
2528
   input clear;
2529
   output reg [0:length-1] q;
2530
   input rst;
2531
   input clk;
2532
    always @ (posedge clk or posedge rst)
2533
    if (rst)
2534
        q <= {1'b1,{length-1{1'b0}}};
2535
    else
2536
        if (clear)
2537
            q <= {1'b1,{length-1{1'b0}}};
2538
        else
2539
            q <= q >> 1;
2540
endmodule
2541 18 unneback
module vl_cnt_shreg_ce_clear ( cke, clear, q, rst, clk);
2542 6 unneback
   parameter length = 4;
2543
   input cke, clear;
2544
   output reg [0:length-1] q;
2545
   input rst;
2546
   input clk;
2547
    always @ (posedge clk or posedge rst)
2548
    if (rst)
2549
        q <= {1'b1,{length-1{1'b0}}};
2550
    else
2551
        if (cke)
2552
            if (clear)
2553
                q <= {1'b1,{length-1{1'b0}}};
2554
            else
2555
                q <= q >> 1;
2556
endmodule
2557 18 unneback
module vl_cnt_shreg_ce_clear_wrap ( cke, clear, q, rst, clk);
2558 6 unneback
   parameter length = 4;
2559
   input cke, clear;
2560
   output reg [0:length-1] q;
2561
   input rst;
2562
   input clk;
2563
    always @ (posedge clk or posedge rst)
2564
    if (rst)
2565
        q <= {1'b1,{length-1{1'b0}}};
2566
    else
2567
        if (cke)
2568
            if (clear)
2569
                q <= {1'b1,{length-1{1'b0}}};
2570
            else
2571
            q <= {q[length-1],q[0:length-2]};
2572
endmodule
2573
//////////////////////////////////////////////////////////////////////
2574
////                                                              ////
2575
////  Versatile library, memories                                 ////
2576
////                                                              ////
2577
////  Description                                                 ////
2578
////  memories                                                    ////
2579
////                                                              ////
2580
////                                                              ////
2581
////  To Do:                                                      ////
2582
////   - add more memory types                                    ////
2583
////                                                              ////
2584
////  Author(s):                                                  ////
2585
////      - Michael Unneback, unneback@opencores.org              ////
2586
////        ORSoC AB                                              ////
2587
////                                                              ////
2588
//////////////////////////////////////////////////////////////////////
2589
////                                                              ////
2590
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
2591
////                                                              ////
2592
//// This source file may be used and distributed without         ////
2593
//// restriction provided that this copyright statement is not    ////
2594
//// removed from the file and that any derivative work contains  ////
2595
//// the original copyright notice and the associated disclaimer. ////
2596
////                                                              ////
2597
//// This source file is free software; you can redistribute it   ////
2598
//// and/or modify it under the terms of the GNU Lesser General   ////
2599
//// Public License as published by the Free Software Foundation; ////
2600
//// either version 2.1 of the License, or (at your option) any   ////
2601
//// later version.                                               ////
2602
////                                                              ////
2603
//// This source is distributed in the hope that it will be       ////
2604
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
2605
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
2606
//// PURPOSE.  See the GNU Lesser General Public License for more ////
2607
//// details.                                                     ////
2608
////                                                              ////
2609
//// You should have received a copy of the GNU Lesser General    ////
2610
//// Public License along with this source; if not, download it   ////
2611
//// from http://www.opencores.org/lgpl.shtml                     ////
2612
////                                                              ////
2613
//////////////////////////////////////////////////////////////////////
2614
/// ROM
2615 7 unneback
module vl_rom_init ( adr, q, clk);
2616
   parameter data_width = 32;
2617
   parameter addr_width = 8;
2618 75 unneback
   parameter mem_size = 1<<addr_width;
2619 7 unneback
   input [(addr_width-1):0]       adr;
2620
   output reg [(data_width-1):0] q;
2621
   input                         clk;
2622 75 unneback
   reg [data_width-1:0] rom [mem_size-1:0];
2623 7 unneback
   parameter memory_file = "vl_rom.vmem";
2624
   initial
2625
     begin
2626
        $readmemh(memory_file, rom);
2627
     end
2628
   always @ (posedge clk)
2629
     q <= rom[adr];
2630
endmodule
2631 6 unneback
// Single port RAM
2632
module vl_ram ( d, adr, we, q, clk);
2633
   parameter data_width = 32;
2634
   parameter addr_width = 8;
2635 75 unneback
   parameter mem_size = 1<<addr_width;
2636 100 unneback
   parameter debug = 0;
2637 6 unneback
   input [(data_width-1):0]      d;
2638
   input [(addr_width-1):0]       adr;
2639
   input                         we;
2640 7 unneback
   output reg [(data_width-1):0] q;
2641 6 unneback
   input                         clk;
2642 98 unneback
   reg [data_width-1:0] ram [mem_size-1:0];
2643 100 unneback
    parameter memory_init = 0;
2644
    parameter memory_file = "vl_ram.vmem";
2645
    generate
2646
    if (memory_init == 1) begin : init_mem
2647
        initial
2648
            $readmemh(memory_file, ram);
2649
   end else if (memory_init == 2) begin : init_zero
2650
        integer k;
2651
        initial
2652
            for (k = 0; k < mem_size; k = k + 1)
2653
                ram[k] = 0;
2654 7 unneback
   end
2655
   endgenerate
2656 100 unneback
    generate
2657
    if (debug==1) begin : debug_we
2658
        always @ (posedge clk)
2659
        if (we)
2660
            $display ("Value %h written at address %h : time %t", d, adr, $time);
2661
    end
2662
    endgenerate
2663 6 unneback
   always @ (posedge clk)
2664
   begin
2665
   if (we)
2666
     ram[adr] <= d;
2667
   q <= ram[adr];
2668
   end
2669
endmodule
2670 91 unneback
module vl_ram_be ( d, adr, be, we, q, clk);
2671 7 unneback
   parameter data_width = 32;
2672 72 unneback
   parameter addr_width = 6;
2673 75 unneback
   parameter mem_size = 1<<addr_width;
2674 7 unneback
   input [(data_width-1):0]      d;
2675
   input [(addr_width-1):0]       adr;
2676 73 unneback
   input [(data_width/8)-1:0]    be;
2677 7 unneback
   input                         we;
2678
   output reg [(data_width-1):0] q;
2679
   input                         clk;
2680 65 unneback
`ifdef SYSTEMVERILOG
2681 95 unneback
    // use a multi-dimensional packed array
2682
    //t o model individual bytes within the word
2683
    logic [data_width/8-1:0][7:0] ram [0:mem_size-1];// # words = 1 << address width
2684 65 unneback
`else
2685 85 unneback
    reg [data_width-1:0] ram [mem_size-1:0];
2686
    wire [data_width/8-1:0] cke;
2687 65 unneback
`endif
2688 100 unneback
    parameter memory_init = 0;
2689
    parameter memory_file = "vl_ram.vmem";
2690
    generate
2691
    if (memory_init == 1) begin : init_mem
2692
        initial
2693
            $readmemh(memory_file, ram);
2694
    end else if (memory_init == 2) begin : init_zero
2695
        integer k;
2696
        initial
2697
            for (k = 0; k < mem_size; k = k + 1)
2698
                ram[k] = 0;
2699
    end
2700 7 unneback
   endgenerate
2701 60 unneback
`ifdef SYSTEMVERILOG
2702
always_ff@(posedge clk)
2703
begin
2704 95 unneback
    if(we) begin
2705 86 unneback
        if(be[3]) ram[adr][3] <= d[31:24];
2706
        if(be[2]) ram[adr][2] <= d[23:16];
2707
        if(be[1]) ram[adr][1] <= d[15:8];
2708
        if(be[0]) ram[adr][0] <= d[7:0];
2709 60 unneback
    end
2710 90 unneback
        q <= ram[adr];
2711 60 unneback
end
2712
`else
2713 85 unneback
assign cke = {data_width/8{we}} & be;
2714 7 unneback
   genvar i;
2715 85 unneback
   generate for (i=0;i<data_width/8;i=i+1) begin : be_ram
2716 7 unneback
      always @ (posedge clk)
2717 85 unneback
      if (cke[i])
2718 7 unneback
        ram[adr][(i+1)*8-1:i*8] <= d[(i+1)*8-1:i*8];
2719
   end
2720
   endgenerate
2721
   always @ (posedge clk)
2722
      q <= ram[adr];
2723 60 unneback
`endif
2724 93 unneback
`ifdef verilator
2725 85 unneback
   // Function to access RAM (for use by Verilator).
2726
   function [31:0] get_mem;
2727
      // verilator public
2728 90 unneback
      input [addr_width-1:0]             addr;
2729 85 unneback
      get_mem = ram[addr];
2730
   endfunction // get_mem
2731
   // Function to write RAM (for use by Verilator).
2732
   function set_mem;
2733
      // verilator public
2734 90 unneback
      input [addr_width-1:0]             addr;
2735
      input [data_width-1:0]             data;
2736 85 unneback
      ram[addr] = data;
2737
   endfunction // set_mem
2738 93 unneback
`endif
2739 7 unneback
endmodule
2740
module vl_dpram_1r1w ( d_a, adr_a, we_a, clk_a, q_b, adr_b, clk_b );
2741 6 unneback
   parameter data_width = 32;
2742
   parameter addr_width = 8;
2743 75 unneback
   parameter mem_size = 1<<addr_width;
2744 6 unneback
   input [(data_width-1):0]      d_a;
2745
   input [(addr_width-1):0]       adr_a;
2746
   input [(addr_width-1):0]       adr_b;
2747
   input                         we_a;
2748 118 unneback
   output reg [(data_width-1):0]          q_b;
2749 6 unneback
   input                         clk_a, clk_b;
2750 119 unneback
   reg [data_width-1:0] ram [0:mem_size-1] /*synthesis syn_ramstyle = "no_rw_check"*/;
2751 100 unneback
    parameter memory_init = 0;
2752
    parameter memory_file = "vl_ram.vmem";
2753
    parameter debug = 0;
2754
    generate
2755
    if (memory_init == 1) begin : init_mem
2756
        initial
2757
            $readmemh(memory_file, ram);
2758
    end else if (memory_init == 2) begin : init_zero
2759
        integer k;
2760
        initial
2761
            for (k = 0; k < mem_size; k = k + 1)
2762
                ram[k] = 0;
2763
    end
2764 7 unneback
   endgenerate
2765 100 unneback
    generate
2766
    if (debug==1) begin : debug_we
2767
        always @ (posedge clk_a)
2768
        if (we_a)
2769
            $display ("Debug: Value %h written at address %h : time %t", d_a, adr_a, $time);
2770
    end
2771
    endgenerate
2772 6 unneback
   always @ (posedge clk_a)
2773
   if (we_a)
2774
     ram[adr_a] <= d_a;
2775
   always @ (posedge clk_b)
2776 118 unneback
      q_b = ram[adr_b];
2777 6 unneback
endmodule
2778 7 unneback
module vl_dpram_2r1w ( d_a, q_a, adr_a, we_a, clk_a, q_b, adr_b, clk_b );
2779 6 unneback
   parameter data_width = 32;
2780
   parameter addr_width = 8;
2781 75 unneback
   parameter mem_size = 1<<addr_width;
2782 6 unneback
   input [(data_width-1):0]      d_a;
2783
   input [(addr_width-1):0]       adr_a;
2784
   input [(addr_width-1):0]       adr_b;
2785
   input                         we_a;
2786
   output [(data_width-1):0]      q_b;
2787
   output reg [(data_width-1):0] q_a;
2788
   input                         clk_a, clk_b;
2789
   reg [(data_width-1):0]         q_b;
2790 119 unneback
   reg [data_width-1:0] ram [0:mem_size-1] /*synthesis syn_ramstyle = "no_rw_check"*/;
2791 100 unneback
    parameter memory_init = 0;
2792
    parameter memory_file = "vl_ram.vmem";
2793
    parameter debug = 0;
2794
    generate
2795
    if (memory_init == 1) begin : init_mem
2796
        initial
2797
            $readmemh(memory_file, ram);
2798
    end else if (memory_init == 2) begin : init_zero
2799
        integer k;
2800
        initial
2801
            for (k = 0; k < mem_size; k = k + 1)
2802
                ram[k] = 0;
2803
    end
2804 7 unneback
   endgenerate
2805 100 unneback
    generate
2806
    if (debug==1) begin : debug_we
2807
        always @ (posedge clk_a)
2808
        if (we_a)
2809
            $display ("Debug: Value %h written at address %h : time %t", d_a, adr_a, $time);
2810
    end
2811
    endgenerate
2812 6 unneback
   always @ (posedge clk_a)
2813
     begin
2814
        q_a <= ram[adr_a];
2815
        if (we_a)
2816
             ram[adr_a] <= d_a;
2817
     end
2818
   always @ (posedge clk_b)
2819
          q_b <= ram[adr_b];
2820
endmodule
2821 100 unneback
module vl_dpram_1r2w ( d_a, q_a, adr_a, we_a, clk_a, d_b, adr_b, we_b, clk_b );
2822
   parameter data_width = 32;
2823
   parameter addr_width = 8;
2824
   parameter mem_size = 1<<addr_width;
2825
   input [(data_width-1):0]      d_a;
2826
   input [(addr_width-1):0]       adr_a;
2827
   input [(addr_width-1):0]       adr_b;
2828
   input                         we_a;
2829
   input [(data_width-1):0]       d_b;
2830
   output reg [(data_width-1):0] q_a;
2831
   input                         we_b;
2832
   input                         clk_a, clk_b;
2833
   reg [(data_width-1):0]         q_b;
2834 119 unneback
   reg [data_width-1:0] ram [0:mem_size-1] /*synthesis syn_ramstyle = "no_rw_check"*/;
2835 100 unneback
    parameter memory_init = 0;
2836
    parameter memory_file = "vl_ram.vmem";
2837
    parameter debug = 0;
2838
    generate
2839
    if (memory_init == 1) begin : init_mem
2840
        initial
2841
            $readmemh(memory_file, ram);
2842
    end else if (memory_init == 2) begin : init_zero
2843
        integer k;
2844
        initial
2845
            for (k = 0; k < mem_size; k = k + 1)
2846
                ram[k] = 0;
2847
    end
2848
   endgenerate
2849
    generate
2850
    if (debug==1) begin : debug_we
2851
        always @ (posedge clk_a)
2852
        if (we_a)
2853
            $display ("Debug: Value %h written at address %h : time %t", d_a, adr_a, $time);
2854
        always @ (posedge clk_b)
2855
        if (we_b)
2856
            $display ("Debug: Value %h written at address %h : time %t", d_b, adr_b, $time);
2857
    end
2858
    endgenerate
2859
   always @ (posedge clk_a)
2860
     begin
2861
        q_a <= ram[adr_a];
2862
        if (we_a)
2863
             ram[adr_a] <= d_a;
2864
     end
2865
   always @ (posedge clk_b)
2866
     begin
2867
        if (we_b)
2868
          ram[adr_b] <= d_b;
2869
     end
2870
endmodule
2871 7 unneback
module vl_dpram_2r2w ( d_a, q_a, adr_a, we_a, clk_a, d_b, q_b, adr_b, we_b, clk_b );
2872 6 unneback
   parameter data_width = 32;
2873
   parameter addr_width = 8;
2874 75 unneback
   parameter mem_size = 1<<addr_width;
2875 6 unneback
   input [(data_width-1):0]      d_a;
2876
   input [(addr_width-1):0]       adr_a;
2877
   input [(addr_width-1):0]       adr_b;
2878
   input                         we_a;
2879
   output [(data_width-1):0]      q_b;
2880
   input [(data_width-1):0]       d_b;
2881
   output reg [(data_width-1):0] q_a;
2882
   input                         we_b;
2883
   input                         clk_a, clk_b;
2884
   reg [(data_width-1):0]         q_b;
2885 119 unneback
   reg [data_width-1:0] ram [0:mem_size-1] /*synthesis syn_ramstyle = "no_rw_check"*/;
2886 100 unneback
    parameter memory_init = 0;
2887
    parameter memory_file = "vl_ram.vmem";
2888
    parameter debug = 0;
2889
    generate
2890
    if (memory_init) begin : init_mem
2891
        initial
2892
            $readmemh(memory_file, ram);
2893
    end else if (memory_init == 2) begin : init_zero
2894
        integer k;
2895
        initial
2896
            for (k = 0; k < mem_size; k = k + 1)
2897
                ram[k] = 0;
2898
    end
2899 7 unneback
   endgenerate
2900 100 unneback
    generate
2901
    if (debug==1) begin : debug_we
2902
        always @ (posedge clk_a)
2903
        if (we_a)
2904
            $display ("Debug: Value %h written at address %h : time %t", d_a, adr_a, $time);
2905
        always @ (posedge clk_b)
2906
        if (we_b)
2907
            $display ("Debug: Value %h written at address %h : time %t", d_b, adr_b, $time);
2908
    end
2909
    endgenerate
2910 6 unneback
   always @ (posedge clk_a)
2911
     begin
2912
        q_a <= ram[adr_a];
2913
        if (we_a)
2914
             ram[adr_a] <= d_a;
2915
     end
2916
   always @ (posedge clk_b)
2917
     begin
2918
        q_b <= ram[adr_b];
2919
        if (we_b)
2920
          ram[adr_b] <= d_b;
2921
     end
2922
endmodule
2923 92 unneback
module vl_dpram_be_2r2w ( d_a, q_a, adr_a, be_a, we_a, clk_a, d_b, q_b, adr_b, be_b, we_b, clk_b );
2924 75 unneback
   parameter a_data_width = 32;
2925
   parameter a_addr_width = 8;
2926 95 unneback
   parameter b_data_width = 64; //a_data_width;
2927 124 unneback
   //localparam b_addr_width = a_data_width * a_addr_width / b_data_width;
2928
   localparam b_addr_width =
2929 125 unneback
        (a_data_width==b_data_width) ? a_addr_width :
2930
        (a_data_width==b_data_width*2) ? a_addr_width+1 :
2931
        (a_data_width==b_data_width*4) ? a_addr_width+2 :
2932
        (a_data_width==b_data_width*8) ? a_addr_width+3 :
2933
        (a_data_width==b_data_width*16) ? a_addr_width+4 :
2934
        (a_data_width==b_data_width*32) ? a_addr_width+5 :
2935
        (a_data_width==b_data_width/2) ? a_addr_width-1 :
2936
        (a_data_width==b_data_width/4) ? a_addr_width-2 :
2937
        (a_data_width==b_data_width/8) ? a_addr_width-3 :
2938
        (a_data_width==b_data_width/16) ? a_addr_width-4 :
2939
        (a_data_width==b_data_width/32) ? a_addr_width-5 : 0;
2940 95 unneback
   localparam ratio = (a_addr_width>b_addr_width) ? (a_addr_width/b_addr_width) : (b_addr_width/a_addr_width);
2941
   parameter mem_size = (a_addr_width>b_addr_width) ? (1<<b_addr_width) : (1<<a_addr_width);
2942 100 unneback
   parameter memory_init = 0;
2943 95 unneback
   parameter memory_file = "vl_ram.vmem";
2944 100 unneback
   parameter debug = 0;
2945 75 unneback
   input [(a_data_width-1):0]      d_a;
2946 91 unneback
   input [(a_addr_width-1):0]       adr_a;
2947
   input [(a_data_width/8-1):0]    be_a;
2948
   input                           we_a;
2949 75 unneback
   output reg [(a_data_width-1):0] q_a;
2950 91 unneback
   input [(b_data_width-1):0]       d_b;
2951
   input [(b_addr_width-1):0]       adr_b;
2952 92 unneback
   input [(b_data_width/8-1):0]    be_b;
2953
   input                           we_b;
2954
   output reg [(b_data_width-1):0]          q_b;
2955 91 unneback
   input                           clk_a, clk_b;
2956 100 unneback
    generate
2957
    if (debug==1) begin : debug_we
2958
        always @ (posedge clk_a)
2959
        if (we_a)
2960 141 unneback
            $display ("Debug: Value %h written on port A at address %h : time %t", d_a, adr_a, $time);
2961 100 unneback
        always @ (posedge clk_b)
2962
        if (we_b)
2963 141 unneback
            $display ("Debug: Value %h written on port B at address %h : time %t", d_b, adr_b, $time);
2964 100 unneback
    end
2965
    endgenerate
2966 91 unneback
`ifdef SYSTEMVERILOG
2967
// use a multi-dimensional packed array
2968
//to model individual bytes within the word
2969 75 unneback
generate
2970 91 unneback
if (a_data_width==32 & b_data_width==32) begin : dpram_3232
2971 98 unneback
    logic [0:3][7:0] ram [0:mem_size-1] /*synthesis syn_ramstyle = "no_rw_check"*/;
2972 95 unneback
    initial
2973 100 unneback
        if (memory_init==1)
2974 95 unneback
            $readmemh(memory_file, ram);
2975 100 unneback
    integer k;
2976
    initial
2977
        if (memory_init==2)
2978
            for (k = 0; k < mem_size; k = k + 1)
2979
                ram[k] = 0;
2980 91 unneback
    always_ff@(posedge clk_a)
2981
    begin
2982
        if(we_a) begin
2983 100 unneback
            if(be_a[3]) ram[adr_a][0] <= d_a[31:24];
2984
            if(be_a[2]) ram[adr_a][1] <= d_a[23:16];
2985
            if(be_a[1]) ram[adr_a][2] <= d_a[15:8];
2986
            if(be_a[0]) ram[adr_a][3] <= d_a[7:0];
2987 91 unneback
        end
2988
    end
2989 92 unneback
    always@(posedge clk_a)
2990
        q_a = ram[adr_a];
2991 91 unneback
    always_ff@(posedge clk_b)
2992 92 unneback
    begin
2993
        if(we_b) begin
2994 100 unneback
            if(be_b[3]) ram[adr_b][0] <= d_b[31:24];
2995
            if(be_b[2]) ram[adr_b][1] <= d_b[23:16];
2996
            if(be_b[1]) ram[adr_b][2] <= d_b[15:8];
2997
            if(be_b[0]) ram[adr_b][3] <= d_b[7:0];
2998 92 unneback
        end
2999
    end
3000
    always@(posedge clk_b)
3001
        q_b = ram[adr_b];
3002 75 unneback
end
3003
endgenerate
3004 95 unneback
generate
3005
if (a_data_width==64 & b_data_width==64) begin : dpram_6464
3006 98 unneback
    logic [0:7][7:0] ram [0:mem_size-1] /*synthesis syn_ramstyle = "no_rw_check"*/;
3007 95 unneback
    initial
3008 100 unneback
        if (memory_init==1)
3009 95 unneback
            $readmemh(memory_file, ram);
3010 100 unneback
    integer k;
3011
    initial
3012
        if (memory_init==2)
3013
            for (k = 0; k < mem_size; k = k + 1)
3014
                ram[k] = 0;
3015 95 unneback
    always_ff@(posedge clk_a)
3016
    begin
3017
        if(we_a) begin
3018
            if(be_a[7]) ram[adr_a][7] <= d_a[63:56];
3019
            if(be_a[6]) ram[adr_a][6] <= d_a[55:48];
3020
            if(be_a[5]) ram[adr_a][5] <= d_a[47:40];
3021
            if(be_a[4]) ram[adr_a][4] <= d_a[39:32];
3022
            if(be_a[3]) ram[adr_a][3] <= d_a[31:24];
3023
            if(be_a[2]) ram[adr_a][2] <= d_a[23:16];
3024
            if(be_a[1]) ram[adr_a][1] <= d_a[15:8];
3025
            if(be_a[0]) ram[adr_a][0] <= d_a[7:0];
3026
        end
3027
    end
3028
    always@(posedge clk_a)
3029
        q_a = ram[adr_a];
3030
    always_ff@(posedge clk_b)
3031
    begin
3032
        if(we_b) begin
3033
            if(be_b[7]) ram[adr_b][7] <= d_b[63:56];
3034
            if(be_b[6]) ram[adr_b][6] <= d_b[55:48];
3035
            if(be_b[5]) ram[adr_b][5] <= d_b[47:40];
3036
            if(be_b[4]) ram[adr_b][4] <= d_b[39:32];
3037
            if(be_b[3]) ram[adr_b][3] <= d_b[31:24];
3038
            if(be_b[2]) ram[adr_b][2] <= d_b[23:16];
3039
            if(be_b[1]) ram[adr_b][1] <= d_b[15:8];
3040
            if(be_b[0]) ram[adr_b][0] <= d_b[7:0];
3041
        end
3042
    end
3043
    always@(posedge clk_b)
3044
        q_b = ram[adr_b];
3045
end
3046
endgenerate
3047
generate
3048
if (a_data_width==32 & b_data_width==16) begin : dpram_3216
3049
logic [31:0] temp;
3050 128 unneback
vl_dpram_be_2r2w # (.a_data_width(32), .b_data_width(32), .a_addr_width(a_addr_width), .mem_size(mem_size), .memory_init(memory_init), .memory_file(memory_file))
3051
dpram3232 (
3052 95 unneback
    .d_a(d_a),
3053
    .q_a(q_a),
3054
    .adr_a(adr_a),
3055
    .be_a(be_a),
3056
    .we_a(we_a),
3057
    .clk_a(clk_a),
3058
    .d_b({d_b,d_b}),
3059
    .q_b(temp),
3060 128 unneback
    .adr_b(adr_b[b_addr_width-1:1]),
3061 137 unneback
    .be_b({be_b,be_b} & {{2{!adr_b[0]}},{2{adr_b[0]}}}),
3062 95 unneback
    .we_b(we_b),
3063
    .clk_b(clk_b)
3064
);
3065 100 unneback
always @ (adr_b[0] or temp)
3066 95 unneback
    if (adr_b[0])
3067
        q_b = temp[31:16];
3068
    else
3069
        q_b = temp[15:0];
3070
end
3071
endgenerate
3072
generate
3073
if (a_data_width==32 & b_data_width==64) begin : dpram_3264
3074
logic [63:0] temp;
3075 128 unneback
vl_dpram_be_2r2w # (.a_data_width(32), .b_data_width(64), .a_addr_width(a_addr_width), .mem_size(mem_size), .memory_init(memory_init), .memory_file(memory_file))
3076 95 unneback
dpram6464 (
3077
    .d_a({d_a,d_a}),
3078
    .q_a(temp),
3079
    .adr_a(adr_a[a_addr_width-1:1]),
3080
    .be_a({be_a,be_a} & {{4{adr_a[0]}},{4{!adr_a[0]}}}),
3081
    .we_a(we_a),
3082
    .clk_a(clk_a),
3083
    .d_b(d_b),
3084
    .q_b(q_b),
3085
    .adr_b(adr_b),
3086
    .be_b(be_b),
3087
    .we_b(we_b),
3088
    .clk_b(clk_b)
3089
);
3090 100 unneback
always @ (adr_a[0] or temp)
3091 95 unneback
    if (adr_a[0])
3092
        q_a = temp[63:32];
3093
    else
3094
        q_a = temp[31:0];
3095
end
3096
endgenerate
3097 91 unneback
`else
3098 92 unneback
    // This modules requires SystemVerilog
3099 98 unneback
    // at this point anyway
3100 91 unneback
`endif
3101 75 unneback
endmodule
3102 6 unneback
// FIFO
3103 25 unneback
module vl_fifo_1r1w_fill_level_sync (
3104
    d, wr, fifo_full,
3105
    q, rd, fifo_empty,
3106
    fill_level,
3107
    clk, rst
3108
    );
3109
parameter data_width = 18;
3110
parameter addr_width = 4;
3111
// write side
3112
input  [data_width-1:0] d;
3113
input                   wr;
3114
output                  fifo_full;
3115
// read side
3116
output [data_width-1:0] q;
3117
input                   rd;
3118
output                  fifo_empty;
3119
// common
3120
output [addr_width:0]   fill_level;
3121
input rst, clk;
3122
wire [addr_width:1] wadr, radr;
3123
vl_cnt_bin_ce
3124
    # ( .length(addr_width))
3125
    fifo_wr_adr( .cke(wr), .q(wadr), .rst(rst), .clk(clk));
3126
vl_cnt_bin_ce
3127
    # (.length(addr_width))
3128
    fifo_rd_adr( .cke(rd), .q(radr), .rst(rst), .clk(clk));
3129
vl_dpram_1r1w
3130
    # (.data_width(data_width), .addr_width(addr_width))
3131
    dpram ( .d_a(d), .adr_a(wadr), .we_a(wr), .clk_a(clk), .q_b(q), .adr_b(radr), .clk_b(clk));
3132 31 unneback
vl_cnt_bin_ce_rew_q_zq_l1
3133 27 unneback
    # (.length(addr_width+1), .level1_value(1<<addr_width))
3134 25 unneback
    fill_level_cnt( .cke(rd ^ wr), .rew(rd), .q(fill_level), .zq(fifo_empty), .level1(fifo_full), .rst(rst), .clk(clk));
3135
endmodule
3136 27 unneback
// Intended use is two small FIFOs (RX and TX typically) in one FPGA RAM resource
3137
// RAM is supposed to be larger than the two FIFOs
3138
// LFSR counters used adr pointers
3139
module vl_fifo_2r2w_sync_simplex (
3140
    // a side
3141
    a_d, a_wr, a_fifo_full,
3142
    a_q, a_rd, a_fifo_empty,
3143
    a_fill_level,
3144
    // b side
3145
    b_d, b_wr, b_fifo_full,
3146
    b_q, b_rd, b_fifo_empty,
3147
    b_fill_level,
3148
    // common
3149
    clk, rst
3150
    );
3151
parameter data_width = 8;
3152
parameter addr_width = 5;
3153
parameter fifo_full_level = (1<<addr_width)-1;
3154
// a side
3155
input  [data_width-1:0] a_d;
3156
input                   a_wr;
3157
output                  a_fifo_full;
3158
output [data_width-1:0] a_q;
3159
input                   a_rd;
3160
output                  a_fifo_empty;
3161
output [addr_width-1:0] a_fill_level;
3162
// b side
3163
input  [data_width-1:0] b_d;
3164
input                   b_wr;
3165
output                  b_fifo_full;
3166
output [data_width-1:0] b_q;
3167
input                   b_rd;
3168
output                  b_fifo_empty;
3169
output [addr_width-1:0] b_fill_level;
3170
input                   clk;
3171
input                   rst;
3172
// adr_gen
3173
wire [addr_width:1] a_wadr, a_radr;
3174
wire [addr_width:1] b_wadr, b_radr;
3175
// dpram
3176
wire [addr_width:0] a_dpram_adr, b_dpram_adr;
3177
vl_cnt_lfsr_ce
3178
    # ( .length(addr_width))
3179
    fifo_a_wr_adr( .cke(a_wr), .q(a_wadr), .rst(rst), .clk(clk));
3180
vl_cnt_lfsr_ce
3181
    # (.length(addr_width))
3182
    fifo_a_rd_adr( .cke(a_rd), .q(a_radr), .rst(rst), .clk(clk));
3183
vl_cnt_lfsr_ce
3184
    # ( .length(addr_width))
3185
    fifo_b_wr_adr( .cke(b_wr), .q(b_wadr), .rst(rst), .clk(clk));
3186
vl_cnt_lfsr_ce
3187
    # (.length(addr_width))
3188
    fifo_b_rd_adr( .cke(b_rd), .q(b_radr), .rst(rst), .clk(clk));
3189
// mux read or write adr to DPRAM
3190
assign a_dpram_adr = (a_wr) ? {1'b0,a_wadr} : {1'b1,a_radr};
3191
assign b_dpram_adr = (b_wr) ? {1'b1,b_wadr} : {1'b0,b_radr};
3192
vl_dpram_2r2w
3193
    # (.data_width(data_width), .addr_width(addr_width+1))
3194
    dpram ( .d_a(a_d), .q_a(a_q), .adr_a(a_dpram_adr), .we_a(a_wr), .clk_a(a_clk),
3195
            .d_b(b_d), .q_b(b_q), .adr_b(b_dpram_adr), .we_b(b_wr), .clk_b(b_clk));
3196
vl_cnt_bin_ce_rew_zq_l1
3197 28 unneback
    # (.length(addr_width), .level1_value(fifo_full_level))
3198 27 unneback
    a_fill_level_cnt( .cke(a_rd ^ a_wr), .rew(a_rd), .q(a_fill_level), .zq(a_fifo_empty), .level1(a_fifo_full), .rst(rst), .clk(clk));
3199
vl_cnt_bin_ce_rew_zq_l1
3200 28 unneback
    # (.length(addr_width), .level1_value(fifo_full_level))
3201 27 unneback
    b_fill_level_cnt( .cke(b_rd ^ b_wr), .rew(b_rd), .q(b_fill_level), .zq(b_fifo_empty), .level1(b_fifo_full), .rst(rst), .clk(clk));
3202
endmodule
3203 6 unneback
module vl_fifo_cmp_async ( wptr, rptr, fifo_empty, fifo_full, wclk, rclk, rst );
3204 11 unneback
   parameter addr_width = 4;
3205
   parameter N = addr_width-1;
3206 6 unneback
   parameter Q1 = 2'b00;
3207
   parameter Q2 = 2'b01;
3208
   parameter Q3 = 2'b11;
3209
   parameter Q4 = 2'b10;
3210
   parameter going_empty = 1'b0;
3211
   parameter going_full  = 1'b1;
3212
   input [N:0]  wptr, rptr;
3213 14 unneback
   output       fifo_empty;
3214 6 unneback
   output       fifo_full;
3215
   input        wclk, rclk, rst;
3216
   wire direction;
3217
   reg  direction_set, direction_clr;
3218
   wire async_empty, async_full;
3219
   wire fifo_full2;
3220 14 unneback
   wire fifo_empty2;
3221 6 unneback
   // direction_set
3222
   always @ (wptr[N:N-1] or rptr[N:N-1])
3223
     case ({wptr[N:N-1],rptr[N:N-1]})
3224
       {Q1,Q2} : direction_set <= 1'b1;
3225
       {Q2,Q3} : direction_set <= 1'b1;
3226
       {Q3,Q4} : direction_set <= 1'b1;
3227
       {Q4,Q1} : direction_set <= 1'b1;
3228
       default : direction_set <= 1'b0;
3229
     endcase
3230
   // direction_clear
3231
   always @ (wptr[N:N-1] or rptr[N:N-1] or rst)
3232
     if (rst)
3233
       direction_clr <= 1'b1;
3234
     else
3235
       case ({wptr[N:N-1],rptr[N:N-1]})
3236
         {Q2,Q1} : direction_clr <= 1'b1;
3237
         {Q3,Q2} : direction_clr <= 1'b1;
3238
         {Q4,Q3} : direction_clr <= 1'b1;
3239
         {Q1,Q4} : direction_clr <= 1'b1;
3240
         default : direction_clr <= 1'b0;
3241
       endcase
3242 18 unneback
    vl_dff_sr dff_sr_dir( .aclr(direction_clr), .aset(direction_set), .clock(1'b1), .data(1'b1), .q(direction));
3243 6 unneback
   assign async_empty = (wptr == rptr) && (direction==going_empty);
3244
   assign async_full  = (wptr == rptr) && (direction==going_full);
3245 18 unneback
    vl_dff_sr dff_sr_empty0( .aclr(rst), .aset(async_full), .clock(wclk), .data(async_full), .q(fifo_full2));
3246
    vl_dff_sr dff_sr_empty1( .aclr(rst), .aset(async_full), .clock(wclk), .data(fifo_full2), .q(fifo_full));
3247 6 unneback
/*
3248
   always @ (posedge wclk or posedge rst or posedge async_full)
3249
     if (rst)
3250
       {fifo_full, fifo_full2} <= 2'b00;
3251
     else if (async_full)
3252
       {fifo_full, fifo_full2} <= 2'b11;
3253
     else
3254
       {fifo_full, fifo_full2} <= {fifo_full2, async_full};
3255
*/
3256 14 unneback
/*   always @ (posedge rclk or posedge async_empty)
3257 6 unneback
     if (async_empty)
3258
       {fifo_empty, fifo_empty2} <= 2'b11;
3259
     else
3260 14 unneback
       {fifo_empty,fifo_empty2} <= {fifo_empty2,async_empty}; */
3261 18 unneback
    vl_dff # ( .reset_value(1'b1)) dff0 ( .d(async_empty), .q(fifo_empty2), .clk(rclk), .rst(async_empty));
3262
    vl_dff # ( .reset_value(1'b1)) dff1 ( .d(fifo_empty2), .q(fifo_empty),  .clk(rclk), .rst(async_empty));
3263 27 unneback
endmodule // async_compb
3264 6 unneback
module vl_fifo_1r1w_async (
3265
    d, wr, fifo_full, wr_clk, wr_rst,
3266
    q, rd, fifo_empty, rd_clk, rd_rst
3267
    );
3268
parameter data_width = 18;
3269
parameter addr_width = 4;
3270
// write side
3271
input  [data_width-1:0] d;
3272
input                   wr;
3273
output                  fifo_full;
3274
input                   wr_clk;
3275
input                   wr_rst;
3276
// read side
3277
output [data_width-1:0] q;
3278
input                   rd;
3279
output                  fifo_empty;
3280
input                   rd_clk;
3281
input                   rd_rst;
3282
wire [addr_width:1] wadr, wadr_bin, radr, radr_bin;
3283 18 unneback
vl_cnt_gray_ce_bin
3284 6 unneback
    # ( .length(addr_width))
3285
    fifo_wr_adr( .cke(wr), .q(wadr), .q_bin(wadr_bin), .rst(wr_rst), .clk(wr_clk));
3286 18 unneback
vl_cnt_gray_ce_bin
3287 6 unneback
    # (.length(addr_width))
3288 23 unneback
    fifo_rd_adr( .cke(rd), .q(radr), .q_bin(radr_bin), .rst(rd_rst), .clk(rd_clk));
3289 7 unneback
vl_dpram_1r1w
3290 6 unneback
    # (.data_width(data_width), .addr_width(addr_width))
3291
    dpram ( .d_a(d), .adr_a(wadr_bin), .we_a(wr), .clk_a(wr_clk), .q_b(q), .adr_b(radr_bin), .clk_b(rd_clk));
3292
vl_fifo_cmp_async
3293
    # (.addr_width(addr_width))
3294
    cmp ( .wptr(wadr), .rptr(radr), .fifo_empty(fifo_empty), .fifo_full(fifo_full), .wclk(wr_clk), .rclk(rd_clk), .rst(wr_rst) );
3295
endmodule
3296 8 unneback
module vl_fifo_2r2w_async (
3297 6 unneback
    // a side
3298
    a_d, a_wr, a_fifo_full,
3299
    a_q, a_rd, a_fifo_empty,
3300
    a_clk, a_rst,
3301
    // b side
3302
    b_d, b_wr, b_fifo_full,
3303
    b_q, b_rd, b_fifo_empty,
3304
    b_clk, b_rst
3305
    );
3306
parameter data_width = 18;
3307
parameter addr_width = 4;
3308
// a side
3309
input  [data_width-1:0] a_d;
3310
input                   a_wr;
3311
output                  a_fifo_full;
3312
output [data_width-1:0] a_q;
3313
input                   a_rd;
3314
output                  a_fifo_empty;
3315
input                   a_clk;
3316
input                   a_rst;
3317
// b side
3318
input  [data_width-1:0] b_d;
3319
input                   b_wr;
3320
output                  b_fifo_full;
3321
output [data_width-1:0] b_q;
3322
input                   b_rd;
3323
output                  b_fifo_empty;
3324
input                   b_clk;
3325
input                   b_rst;
3326
vl_fifo_1r1w_async # (.data_width(data_width), .addr_width(addr_width))
3327
vl_fifo_1r1w_async_a (
3328
    .d(a_d), .wr(a_wr), .fifo_full(a_fifo_full), .wr_clk(a_clk), .wr_rst(a_rst),
3329
    .q(b_q), .rd(b_rd), .fifo_empty(b_fifo_empty), .rd_clk(b_clk), .rd_rst(b_rst)
3330
    );
3331
vl_fifo_1r1w_async # (.data_width(data_width), .addr_width(addr_width))
3332
vl_fifo_1r1w_async_b (
3333
    .d(b_d), .wr(b_wr), .fifo_full(b_fifo_full), .wr_clk(b_clk), .wr_rst(b_rst),
3334
    .q(a_q), .rd(a_rd), .fifo_empty(a_fifo_empty), .rd_clk(a_clk), .rd_rst(a_rst)
3335
    );
3336
endmodule
3337 8 unneback
module vl_fifo_2r2w_async_simplex (
3338 6 unneback
    // a side
3339
    a_d, a_wr, a_fifo_full,
3340
    a_q, a_rd, a_fifo_empty,
3341
    a_clk, a_rst,
3342
    // b side
3343
    b_d, b_wr, b_fifo_full,
3344
    b_q, b_rd, b_fifo_empty,
3345
    b_clk, b_rst
3346
    );
3347
parameter data_width = 18;
3348
parameter addr_width = 4;
3349
// a side
3350
input  [data_width-1:0] a_d;
3351
input                   a_wr;
3352
output                  a_fifo_full;
3353
output [data_width-1:0] a_q;
3354
input                   a_rd;
3355
output                  a_fifo_empty;
3356
input                   a_clk;
3357
input                   a_rst;
3358
// b side
3359
input  [data_width-1:0] b_d;
3360
input                   b_wr;
3361
output                  b_fifo_full;
3362
output [data_width-1:0] b_q;
3363
input                   b_rd;
3364
output                  b_fifo_empty;
3365
input                   b_clk;
3366
input                   b_rst;
3367
// adr_gen
3368
wire [addr_width:1] a_wadr, a_wadr_bin, a_radr, a_radr_bin;
3369
wire [addr_width:1] b_wadr, b_wadr_bin, b_radr, b_radr_bin;
3370
// dpram
3371
wire [addr_width:0] a_dpram_adr, b_dpram_adr;
3372 18 unneback
vl_cnt_gray_ce_bin
3373 6 unneback
    # ( .length(addr_width))
3374
    fifo_a_wr_adr( .cke(a_wr), .q(a_wadr), .q_bin(a_wadr_bin), .rst(a_rst), .clk(a_clk));
3375 18 unneback
vl_cnt_gray_ce_bin
3376 6 unneback
    # (.length(addr_width))
3377
    fifo_a_rd_adr( .cke(a_rd), .q(a_radr), .q_bin(a_radr_bin), .rst(a_rst), .clk(a_clk));
3378 18 unneback
vl_cnt_gray_ce_bin
3379 6 unneback
    # ( .length(addr_width))
3380
    fifo_b_wr_adr( .cke(b_wr), .q(b_wadr), .q_bin(b_wadr_bin), .rst(b_rst), .clk(b_clk));
3381 18 unneback
vl_cnt_gray_ce_bin
3382 6 unneback
    # (.length(addr_width))
3383
    fifo_b_rd_adr( .cke(b_rd), .q(b_radr), .q_bin(b_radr_bin), .rst(b_rst), .clk(b_clk));
3384
// mux read or write adr to DPRAM
3385
assign a_dpram_adr = (a_wr) ? {1'b0,a_wadr_bin} : {1'b1,a_radr_bin};
3386
assign b_dpram_adr = (b_wr) ? {1'b1,b_wadr_bin} : {1'b0,b_radr_bin};
3387 11 unneback
vl_dpram_2r2w
3388 6 unneback
    # (.data_width(data_width), .addr_width(addr_width+1))
3389
    dpram ( .d_a(a_d), .q_a(a_q), .adr_a(a_dpram_adr), .we_a(a_wr), .clk_a(a_clk),
3390
            .d_b(b_d), .q_b(b_q), .adr_b(b_dpram_adr), .we_b(b_wr), .clk_b(b_clk));
3391 11 unneback
vl_fifo_cmp_async
3392 6 unneback
    # (.addr_width(addr_width))
3393
    cmp1 ( .wptr(a_wadr), .rptr(b_radr), .fifo_empty(b_fifo_empty), .fifo_full(a_fifo_full), .wclk(a_clk), .rclk(b_clk), .rst(a_rst) );
3394 11 unneback
vl_fifo_cmp_async
3395 6 unneback
    # (.addr_width(addr_width))
3396
    cmp2 ( .wptr(b_wadr), .rptr(a_radr), .fifo_empty(a_fifo_empty), .fifo_full(b_fifo_full), .wclk(b_clk), .rclk(a_clk), .rst(b_rst) );
3397
endmodule
3398 48 unneback
module vl_reg_file (
3399 146 unneback
    a1, a2, a3, wd3, we3, rd1, rd2, clk, rst );
3400
parameter dw = 32;
3401
parameter aw = 5;
3402 143 unneback
parameter debug = 0;
3403 146 unneback
input [aw-1:0] a1, a2, a3;
3404
input [dw-1:0] wd3;
3405 48 unneback
input we3;
3406 146 unneback
output [dw-1:0] rd1, rd2;
3407 147 unneback
input clk, rst;
3408 146 unneback
wire [dw-1:0] rd1mem, rd2mem;
3409
reg [dw-1:0] wreg;
3410
reg sel1, sel2;
3411 143 unneback
generate
3412
if (debug==1) begin : debug_we
3413
    always @ (posedge clk)
3414 144 unneback
        if (we3)
3415 145 unneback
            $display ("Value %h written at register %h : time %t", wd3, a3, $time);
3416 143 unneback
end
3417
endgenerate
3418 146 unneback
vl_dpram_1r1w
3419
    # ( .data_width(dw), .addr_width(aw))
3420
    ram1 (
3421
        .d_a(wd3),
3422
        .adr_a(a3),
3423
        .we_a(we3),
3424
        .clk_a(clk),
3425
        .q_b(rd1mem),
3426
        .adr_b(a1),
3427
        .clk_b(clk) );
3428
vl_dpram_1r1w
3429
    # ( .data_width(dw), .addr_width(aw))
3430
    ram2 (
3431
        .d_a(wd3),
3432
        .adr_a(a3),
3433
        .we_a(we3),
3434
        .clk_a(clk),
3435
        .q_b(rd2mem),
3436
        .adr_b(a2),
3437
        .clk_b(clk) );
3438 48 unneback
always @ (posedge clk or posedge rst)
3439
if (rst)
3440 148 unneback
    {sel1, sel2, wreg} <= {1'b0,1'b0,{dw{1'b0}}};
3441 48 unneback
else
3442 146 unneback
    {sel1,sel2,wreg} <= {we3 & a1==a3, we3 & a2==a3,wd3};
3443
assign rd1 = (sel1) ? wreg : rd1mem;
3444
assign rd2 = (sel2) ? wreg : rd2mem;
3445 48 unneback
endmodule
3446 12 unneback
//////////////////////////////////////////////////////////////////////
3447
////                                                              ////
3448
////  Versatile library, wishbone stuff                           ////
3449
////                                                              ////
3450
////  Description                                                 ////
3451
////  Wishbone compliant modules                                  ////
3452
////                                                              ////
3453
////                                                              ////
3454
////  To Do:                                                      ////
3455
////   -                                                          ////
3456
////                                                              ////
3457
////  Author(s):                                                  ////
3458
////      - Michael Unneback, unneback@opencores.org              ////
3459
////        ORSoC AB                                              ////
3460
////                                                              ////
3461
//////////////////////////////////////////////////////////////////////
3462
////                                                              ////
3463
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
3464
////                                                              ////
3465
//// This source file may be used and distributed without         ////
3466
//// restriction provided that this copyright statement is not    ////
3467
//// removed from the file and that any derivative work contains  ////
3468
//// the original copyright notice and the associated disclaimer. ////
3469
////                                                              ////
3470
//// This source file is free software; you can redistribute it   ////
3471
//// and/or modify it under the terms of the GNU Lesser General   ////
3472
//// Public License as published by the Free Software Foundation; ////
3473
//// either version 2.1 of the License, or (at your option) any   ////
3474
//// later version.                                               ////
3475
////                                                              ////
3476
//// This source is distributed in the hope that it will be       ////
3477
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
3478
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
3479
//// PURPOSE.  See the GNU Lesser General Public License for more ////
3480
//// details.                                                     ////
3481
////                                                              ////
3482
//// You should have received a copy of the GNU Lesser General    ////
3483
//// Public License along with this source; if not, download it   ////
3484
//// from http://www.opencores.org/lgpl.shtml                     ////
3485
////                                                              ////
3486
//////////////////////////////////////////////////////////////////////
3487
`timescale 1ns/1ns
3488 85 unneback
module vl_wb_adr_inc ( cyc_i, stb_i, cti_i, bte_i, adr_i, we_i, ack_o, adr_o, clk, rst);
3489 83 unneback
parameter adr_width = 10;
3490
parameter max_burst_width = 4;
3491 85 unneback
input cyc_i, stb_i, we_i;
3492 83 unneback
input [2:0] cti_i;
3493
input [1:0] bte_i;
3494
input [adr_width-1:0] adr_i;
3495
output [adr_width-1:0] adr_o;
3496
output ack_o;
3497
input clk, rst;
3498
reg [adr_width-1:0] adr;
3499 90 unneback
wire [max_burst_width-1:0] to_adr;
3500 91 unneback
reg [max_burst_width-1:0] last_adr;
3501 92 unneback
reg last_cycle;
3502
localparam idle_or_eoc = 1'b0;
3503
localparam cyc_or_ws   = 1'b1;
3504 91 unneback
always @ (posedge clk or posedge rst)
3505
if (rst)
3506
    last_adr <= {max_burst_width{1'b0}};
3507
else
3508
    if (stb_i)
3509 92 unneback
        last_adr <=adr_o[max_burst_width-1:0];
3510 83 unneback
generate
3511
if (max_burst_width==0) begin : inst_0
3512 97 unneback
        reg ack_o;
3513
        assign adr_o = adr_i;
3514
        always @ (posedge clk or posedge rst)
3515
        if (rst)
3516
            ack_o <= 1'b0;
3517
        else
3518
            ack_o <= cyc_i & stb_i & !ack_o;
3519 83 unneback
end else begin
3520
    always @ (posedge clk or posedge rst)
3521
    if (rst)
3522 92 unneback
        last_cycle <= idle_or_eoc;
3523 83 unneback
    else
3524 92 unneback
        last_cycle <= (!cyc_i) ? idle_or_eoc : //idle
3525
                      (cyc_i & ack_o & (cti_i==3'b000 | cti_i==3'b111)) ? idle_or_eoc : // eoc
3526
                      (cyc_i & !stb_i) ? cyc_or_ws : //ws
3527
                      cyc_or_ws; // cyc
3528
    assign to_adr = (last_cycle==idle_or_eoc) ? adr_i[max_burst_width-1:0] : adr[max_burst_width-1:0];
3529 85 unneback
    assign adr_o[max_burst_width-1:0] = (we_i) ? adr_i[max_burst_width-1:0] :
3530 91 unneback
                                        (!stb_i) ? last_adr :
3531 92 unneback
                                        (last_cycle==idle_or_eoc) ? adr_i[max_burst_width-1:0] :
3532 85 unneback
                                        adr[max_burst_width-1:0];
3533 92 unneback
    assign ack_o = (last_cycle==cyc_or_ws) & stb_i;
3534 83 unneback
end
3535
endgenerate
3536
generate
3537
if (max_burst_width==2) begin : inst_2
3538
    always @ (posedge clk or posedge rst)
3539
    if (rst)
3540
        adr <= 2'h0;
3541
    else
3542
        if (cyc_i & stb_i)
3543
            adr[1:0] <= to_adr[1:0] + 2'd1;
3544
        else
3545
            adr <= to_adr[1:0];
3546
end
3547
endgenerate
3548
generate
3549
if (max_burst_width==3) begin : inst_3
3550
    always @ (posedge clk or posedge rst)
3551
    if (rst)
3552
        adr <= 3'h0;
3553
    else
3554
        if (cyc_i & stb_i)
3555
            case (bte_i)
3556
            2'b01: adr[2:0] <= {to_adr[2],to_adr[1:0] + 2'd1};
3557
            default: adr[3:0] <= to_adr[2:0] + 3'd1;
3558
            endcase
3559
        else
3560
            adr <= to_adr[2:0];
3561
end
3562
endgenerate
3563
generate
3564
if (max_burst_width==4) begin : inst_4
3565
    always @ (posedge clk or posedge rst)
3566
    if (rst)
3567
        adr <= 4'h0;
3568
    else
3569 91 unneback
        if (stb_i) // | (!stb_i & last_cycle!=ws)) // for !stb_i restart with adr_i +1, only inc once
3570 83 unneback
            case (bte_i)
3571
            2'b01: adr[3:0] <= {to_adr[3:2],to_adr[1:0] + 2'd1};
3572
            2'b10: adr[3:0] <= {to_adr[3],to_adr[2:0] + 3'd1};
3573
            default: adr[3:0] <= to_adr + 4'd1;
3574
            endcase
3575
        else
3576
            adr <= to_adr[3:0];
3577
end
3578
endgenerate
3579
generate
3580
if (adr_width > max_burst_width) begin : pass_through
3581
    assign adr_o[adr_width-1:max_burst_width] = adr_i[adr_width-1:max_burst_width];
3582
end
3583
endgenerate
3584
endmodule
3585
// async wb3 - wb3 bridge
3586
`timescale 1ns/1ns
3587 18 unneback
module vl_wb3wb3_bridge (
3588 12 unneback
        // wishbone slave side
3589
        wbs_dat_i, wbs_adr_i, wbs_sel_i, wbs_bte_i, wbs_cti_i, wbs_we_i, wbs_cyc_i, wbs_stb_i, wbs_dat_o, wbs_ack_o, wbs_clk, wbs_rst,
3590
        // wishbone master side
3591
        wbm_dat_o, wbm_adr_o, wbm_sel_o, wbm_bte_o, wbm_cti_o, wbm_we_o, wbm_cyc_o, wbm_stb_o, wbm_dat_i, wbm_ack_i, wbm_clk, wbm_rst);
3592 95 unneback
parameter style = "FIFO"; // valid: simple, FIFO
3593
parameter addr_width = 4;
3594 12 unneback
input [31:0] wbs_dat_i;
3595
input [31:2] wbs_adr_i;
3596
input [3:0]  wbs_sel_i;
3597
input [1:0]  wbs_bte_i;
3598
input [2:0]  wbs_cti_i;
3599
input wbs_we_i, wbs_cyc_i, wbs_stb_i;
3600
output [31:0] wbs_dat_o;
3601 14 unneback
output wbs_ack_o;
3602 12 unneback
input wbs_clk, wbs_rst;
3603
output [31:0] wbm_dat_o;
3604
output reg [31:2] wbm_adr_o;
3605
output [3:0]  wbm_sel_o;
3606
output reg [1:0]  wbm_bte_o;
3607
output reg [2:0]  wbm_cti_o;
3608 14 unneback
output reg wbm_we_o;
3609
output wbm_cyc_o;
3610 12 unneback
output wbm_stb_o;
3611
input [31:0]  wbm_dat_i;
3612
input wbm_ack_i;
3613
input wbm_clk, wbm_rst;
3614
// bte
3615
parameter linear       = 2'b00;
3616
parameter wrap4        = 2'b01;
3617
parameter wrap8        = 2'b10;
3618
parameter wrap16       = 2'b11;
3619
// cti
3620
parameter classic      = 3'b000;
3621
parameter incburst     = 3'b010;
3622
parameter endofburst   = 3'b111;
3623 95 unneback
localparam wbs_adr  = 1'b0;
3624
localparam wbs_data = 1'b1;
3625
localparam wbm_adr0      = 2'b00;
3626
localparam wbm_adr1      = 2'b01;
3627
localparam wbm_data      = 2'b10;
3628
localparam wbm_data_wait = 2'b11;
3629 12 unneback
reg [1:0] wbs_bte_reg;
3630
reg wbs;
3631
wire wbs_eoc_alert, wbm_eoc_alert;
3632
reg wbs_eoc, wbm_eoc;
3633
reg [1:0] wbm;
3634 14 unneback
wire [1:16] wbs_count, wbm_count;
3635 12 unneback
wire [35:0] a_d, a_q, b_d, b_q;
3636
wire a_wr, a_rd, a_fifo_full, a_fifo_empty, b_wr, b_rd, b_fifo_full, b_fifo_empty;
3637
reg a_rd_reg;
3638
wire b_rd_adr, b_rd_data;
3639 14 unneback
wire b_rd_data_reg;
3640
wire [35:0] temp;
3641 12 unneback
assign wbs_eoc_alert = (wbs_bte_reg==wrap4 & wbs_count[3]) | (wbs_bte_reg==wrap8 & wbs_count[7]) | (wbs_bte_reg==wrap16 & wbs_count[15]);
3642
always @ (posedge wbs_clk or posedge wbs_rst)
3643
if (wbs_rst)
3644
        wbs_eoc <= 1'b0;
3645
else
3646
        if (wbs==wbs_adr & wbs_stb_i & !a_fifo_full)
3647 78 unneback
                wbs_eoc <= (wbs_bte_i==linear) | (wbs_cti_i==3'b111);
3648 12 unneback
        else if (wbs_eoc_alert & (a_rd | a_wr))
3649
                wbs_eoc <= 1'b1;
3650 18 unneback
vl_cnt_shreg_ce_clear # ( .length(16))
3651 12 unneback
    cnt0 (
3652
        .cke(wbs_ack_o),
3653
        .clear(wbs_eoc),
3654
        .q(wbs_count),
3655
        .rst(wbs_rst),
3656
        .clk(wbs_clk));
3657
always @ (posedge wbs_clk or posedge wbs_rst)
3658
if (wbs_rst)
3659
        wbs <= wbs_adr;
3660
else
3661 75 unneback
        if ((wbs==wbs_adr) & wbs_cyc_i & wbs_stb_i & a_fifo_empty)
3662 12 unneback
                wbs <= wbs_data;
3663
        else if (wbs_eoc & wbs_ack_o)
3664
                wbs <= wbs_adr;
3665
// wbs FIFO
3666 75 unneback
assign a_d = (wbs==wbs_adr) ? {wbs_adr_i[31:2],wbs_we_i,((wbs_cti_i==3'b111) ? {2'b00,3'b000} : {wbs_bte_i,wbs_cti_i})} : {wbs_dat_i,wbs_sel_i};
3667
assign a_wr = (wbs==wbs_adr)  ? wbs_cyc_i & wbs_stb_i & a_fifo_empty :
3668 12 unneback
              (wbs==wbs_data) ? wbs_we_i  & wbs_stb_i & !a_fifo_full :
3669
              1'b0;
3670
assign a_rd = !a_fifo_empty;
3671
always @ (posedge wbs_clk or posedge wbs_rst)
3672
if (wbs_rst)
3673
        a_rd_reg <= 1'b0;
3674
else
3675
        a_rd_reg <= a_rd;
3676
assign wbs_ack_o = a_rd_reg | (a_wr & wbs==wbs_data);
3677
assign wbs_dat_o = a_q[35:4];
3678
always @ (posedge wbs_clk or posedge wbs_rst)
3679
if (wbs_rst)
3680 13 unneback
        wbs_bte_reg <= 2'b00;
3681 12 unneback
else
3682 13 unneback
        wbs_bte_reg <= wbs_bte_i;
3683 12 unneback
// wbm FIFO
3684
assign wbm_eoc_alert = (wbm_bte_o==wrap4 & wbm_count[3]) | (wbm_bte_o==wrap8 & wbm_count[7]) | (wbm_bte_o==wrap16 & wbm_count[15]);
3685
always @ (posedge wbm_clk or posedge wbm_rst)
3686
if (wbm_rst)
3687
        wbm_eoc <= 1'b0;
3688
else
3689
        if (wbm==wbm_adr0 & !b_fifo_empty)
3690
                wbm_eoc <= b_q[4:3] == linear;
3691
        else if (wbm_eoc_alert & wbm_ack_i)
3692
                wbm_eoc <= 1'b1;
3693
always @ (posedge wbm_clk or posedge wbm_rst)
3694
if (wbm_rst)
3695
        wbm <= wbm_adr0;
3696
else
3697 33 unneback
/*
3698 12 unneback
    if ((wbm==wbm_adr0 & !b_fifo_empty) |
3699
        (wbm==wbm_adr1 & !b_fifo_empty & wbm_we_o) |
3700
        (wbm==wbm_adr1 & !wbm_we_o) |
3701
        (wbm==wbm_data & wbm_ack_i & wbm_eoc))
3702
        wbm <= {wbm[0],!(wbm[1] ^ wbm[0])};  // count sequence 00,01,10
3703 33 unneback
*/
3704
    case (wbm)
3705
    wbm_adr0:
3706
        if (!b_fifo_empty)
3707
            wbm <= wbm_adr1;
3708
    wbm_adr1:
3709
        if (!wbm_we_o | (!b_fifo_empty & wbm_we_o))
3710
            wbm <= wbm_data;
3711
    wbm_data:
3712
        if (wbm_ack_i & wbm_eoc)
3713
            wbm <= wbm_adr0;
3714
        else if (b_fifo_empty & wbm_we_o & wbm_ack_i)
3715
            wbm <= wbm_data_wait;
3716
    wbm_data_wait:
3717
        if (!b_fifo_empty)
3718
            wbm <= wbm_data;
3719
    endcase
3720 12 unneback
assign b_d = {wbm_dat_i,4'b1111};
3721
assign b_wr = !wbm_we_o & wbm_ack_i;
3722
assign b_rd_adr  = (wbm==wbm_adr0 & !b_fifo_empty);
3723
assign b_rd_data = (wbm==wbm_adr1 & !b_fifo_empty & wbm_we_o) ? 1'b1 : // b_q[`WE]
3724
                   (wbm==wbm_data & !b_fifo_empty & wbm_we_o & wbm_ack_i & !wbm_eoc) ? 1'b1 :
3725 33 unneback
                   (wbm==wbm_data_wait & !b_fifo_empty) ? 1'b1 :
3726 12 unneback
                   1'b0;
3727
assign b_rd = b_rd_adr | b_rd_data;
3728 18 unneback
vl_dff dff1 ( .d(b_rd_data), .q(b_rd_data_reg), .clk(wbm_clk), .rst(wbm_rst));
3729
vl_dff_ce # ( .width(36)) dff2 ( .d(b_q), .ce(b_rd_data_reg), .q(temp), .clk(wbm_clk), .rst(wbm_rst));
3730 12 unneback
assign {wbm_dat_o,wbm_sel_o} = (b_rd_data_reg) ? b_q : temp;
3731 18 unneback
vl_cnt_shreg_ce_clear # ( .length(16))
3732 12 unneback
    cnt1 (
3733
        .cke(wbm_ack_i),
3734
        .clear(wbm_eoc),
3735
        .q(wbm_count),
3736
        .rst(wbm_rst),
3737
        .clk(wbm_clk));
3738 33 unneback
assign wbm_cyc_o = (wbm==wbm_data | wbm==wbm_data_wait);
3739
assign wbm_stb_o = (wbm==wbm_data);
3740 12 unneback
always @ (posedge wbm_clk or posedge wbm_rst)
3741
if (wbm_rst)
3742
        {wbm_adr_o,wbm_we_o,wbm_bte_o,wbm_cti_o} <= {30'h0,1'b0,linear,classic};
3743
else begin
3744
        if (wbm==wbm_adr0 & !b_fifo_empty)
3745
                {wbm_adr_o,wbm_we_o,wbm_bte_o,wbm_cti_o} <= b_q;
3746
        else if (wbm_eoc_alert & wbm_ack_i)
3747
                wbm_cti_o <= endofburst;
3748
end
3749
//async_fifo_dw_simplex_top
3750
vl_fifo_2r2w_async_simplex
3751
# ( .data_width(36), .addr_width(addr_width))
3752
fifo (
3753
    // a side
3754
    .a_d(a_d),
3755
    .a_wr(a_wr),
3756
    .a_fifo_full(a_fifo_full),
3757
    .a_q(a_q),
3758
    .a_rd(a_rd),
3759
    .a_fifo_empty(a_fifo_empty),
3760
    .a_clk(wbs_clk),
3761
    .a_rst(wbs_rst),
3762
    // b side
3763
    .b_d(b_d),
3764
    .b_wr(b_wr),
3765
    .b_fifo_full(b_fifo_full),
3766
    .b_q(b_q),
3767
    .b_rd(b_rd),
3768
    .b_fifo_empty(b_fifo_empty),
3769
    .b_clk(wbm_clk),
3770
    .b_rst(wbm_rst)
3771
    );
3772
endmodule
3773 75 unneback
module vl_wb3avalon_bridge (
3774
        // wishbone slave side
3775
        wbs_dat_i, wbs_adr_i, wbs_sel_i, wbs_bte_i, wbs_cti_i, wbs_we_i, wbs_cyc_i, wbs_stb_i, wbs_dat_o, wbs_ack_o, wbs_clk, wbs_rst,
3776 77 unneback
        // avalon master side
3777 75 unneback
        readdata, readdatavalid, address, read, be, write, burstcount, writedata, waitrequest, beginbursttransfer, clk, rst);
3778 85 unneback
parameter linewrapburst = 1'b0;
3779 75 unneback
input [31:0] wbs_dat_i;
3780
input [31:2] wbs_adr_i;
3781
input [3:0]  wbs_sel_i;
3782
input [1:0]  wbs_bte_i;
3783
input [2:0]  wbs_cti_i;
3784 83 unneback
input wbs_we_i;
3785
input wbs_cyc_i;
3786
input wbs_stb_i;
3787 75 unneback
output [31:0] wbs_dat_o;
3788
output wbs_ack_o;
3789
input wbs_clk, wbs_rst;
3790
input [31:0] readdata;
3791
output [31:0] writedata;
3792
output [31:2] address;
3793
output [3:0]  be;
3794
output write;
3795 81 unneback
output read;
3796 75 unneback
output beginbursttransfer;
3797
output [3:0] burstcount;
3798
input readdatavalid;
3799
input waitrequest;
3800
input clk;
3801
input rst;
3802
wire [1:0] wbm_bte_o;
3803
wire [2:0] wbm_cti_o;
3804
wire wbm_we_o, wbm_cyc_o, wbm_stb_o, wbm_ack_i;
3805
reg last_cyc;
3806 79 unneback
reg [3:0] counter;
3807 82 unneback
reg read_busy;
3808 75 unneback
always @ (posedge clk or posedge rst)
3809
if (rst)
3810
    last_cyc <= 1'b0;
3811
else
3812
    last_cyc <= wbm_cyc_o;
3813 79 unneback
always @ (posedge clk or posedge rst)
3814
if (rst)
3815 82 unneback
    read_busy <= 1'b0;
3816 79 unneback
else
3817 82 unneback
    if (read & !waitrequest)
3818
        read_busy <= 1'b1;
3819
    else if (wbm_ack_i & wbm_cti_o!=3'b010)
3820
        read_busy <= 1'b0;
3821
assign read = wbm_cyc_o & wbm_stb_o & !wbm_we_o & !read_busy;
3822 75 unneback
assign beginbursttransfer = (!last_cyc & wbm_cyc_o) & wbm_cti_o==3'b010;
3823
assign burstcount = (wbm_bte_o==2'b01) ? 4'd4 :
3824
                    (wbm_bte_o==2'b10) ? 4'd8 :
3825 78 unneback
                    (wbm_bte_o==2'b11) ? 4'd16:
3826
                    4'd1;
3827 82 unneback
assign wbm_ack_i = (readdatavalid) | (write & !waitrequest);
3828 79 unneback
always @ (posedge clk or posedge rst)
3829
if (rst) begin
3830
    counter <= 4'd0;
3831
end else
3832 80 unneback
    if (wbm_we_o) begin
3833
        if (!waitrequest & !last_cyc & wbm_cyc_o) begin
3834 85 unneback
            counter <= burstcount -4'd1;
3835 80 unneback
        end else if (waitrequest & !last_cyc & wbm_cyc_o) begin
3836
            counter <= burstcount;
3837
        end else if (!waitrequest & wbm_stb_o) begin
3838
            counter <= counter - 4'd1;
3839
        end
3840 82 unneback
    end
3841 81 unneback
assign write = wbm_cyc_o & wbm_stb_o & wbm_we_o & counter!=4'd0;
3842 77 unneback
vl_wb3wb3_bridge wbwb3inst (
3843 75 unneback
    // wishbone slave side
3844
    .wbs_dat_i(wbs_dat_i),
3845
    .wbs_adr_i(wbs_adr_i),
3846
    .wbs_sel_i(wbs_sel_i),
3847
    .wbs_bte_i(wbs_bte_i),
3848
    .wbs_cti_i(wbs_cti_i),
3849
    .wbs_we_i(wbs_we_i),
3850
    .wbs_cyc_i(wbs_cyc_i),
3851
    .wbs_stb_i(wbs_stb_i),
3852
    .wbs_dat_o(wbs_dat_o),
3853
    .wbs_ack_o(wbs_ack_o),
3854
    .wbs_clk(wbs_clk),
3855
    .wbs_rst(wbs_rst),
3856
    // wishbone master side
3857
    .wbm_dat_o(writedata),
3858 78 unneback
    .wbm_adr_o(address),
3859 75 unneback
    .wbm_sel_o(be),
3860
    .wbm_bte_o(wbm_bte_o),
3861
    .wbm_cti_o(wbm_cti_o),
3862
    .wbm_we_o(wbm_we_o),
3863
    .wbm_cyc_o(wbm_cyc_o),
3864
    .wbm_stb_o(wbm_stb_o),
3865
    .wbm_dat_i(readdata),
3866
    .wbm_ack_i(wbm_ack_i),
3867
    .wbm_clk(clk),
3868
    .wbm_rst(rst));
3869
endmodule
3870 49 unneback
// WB RAM with byte enable
3871 101 unneback
module vl_wb_ram (
3872 69 unneback
    wbs_dat_i, wbs_adr_i, wbs_cti_i, wbs_bte_i, wbs_sel_i, wbs_we_i, wbs_stb_i, wbs_cyc_i,
3873 101 unneback
    wbs_dat_o, wbs_ack_o, wbs_stall_o, wb_clk, wb_rst);
3874
parameter adr_width = 16;
3875
parameter mem_size = 1<<adr_width;
3876
parameter dat_width = 32;
3877
parameter max_burst_width = 4; // only used for B3
3878
parameter mode = "B3"; // valid options: B3, B4
3879 60 unneback
parameter memory_init = 1;
3880
parameter memory_file = "vl_ram.vmem";
3881 101 unneback
input [dat_width-1:0] wbs_dat_i;
3882
input [adr_width-1:0] wbs_adr_i;
3883
input [2:0] wbs_cti_i;
3884
input [1:0] wbs_bte_i;
3885
input [dat_width/8-1:0] wbs_sel_i;
3886 70 unneback
input wbs_we_i, wbs_stb_i, wbs_cyc_i;
3887 101 unneback
output [dat_width-1:0] wbs_dat_o;
3888 70 unneback
output wbs_ack_o;
3889 101 unneback
output wbs_stall_o;
3890 71 unneback
input wb_clk, wb_rst;
3891 101 unneback
wire [adr_width-1:0] adr;
3892
wire we;
3893
generate
3894
if (mode=="B3") begin : B3_inst
3895
vl_wb_adr_inc # ( .adr_width(adr_width), .max_burst_width(max_burst_width)) adr_inc0 (
3896 83 unneback
    .cyc_i(wbs_cyc_i),
3897
    .stb_i(wbs_stb_i),
3898
    .cti_i(wbs_cti_i),
3899
    .bte_i(wbs_bte_i),
3900
    .adr_i(wbs_adr_i),
3901 85 unneback
    .we_i(wbs_we_i),
3902 83 unneback
    .ack_o(wbs_ack_o),
3903
    .adr_o(adr),
3904
    .clk(wb_clk),
3905
    .rst(wb_rst));
3906 101 unneback
assign we = wbs_we_i & wbs_ack_o;
3907
end else if (mode=="B4") begin : B4_inst
3908
reg wbs_ack_o_reg;
3909
always @ (posedge wb_clk or posedge wb_rst)
3910
    if (wb_rst)
3911
        wbs_ack_o_reg <= 1'b0;
3912
    else
3913
        wbs_ack_o_reg <= wbs_stb_i & wbs_cyc_i;
3914
assign wbs_ack_o = wbs_ack_o_reg;
3915
assign wbs_stall_o = 1'b0;
3916
assign adr = wbs_adr_i;
3917
assign we = wbs_we_i & wbs_cyc_i & wbs_stb_i;
3918
end
3919
endgenerate
3920 100 unneback
vl_ram_be # (
3921
    .data_width(dat_width),
3922
    .addr_width(adr_width),
3923
    .mem_size(mem_size),
3924
    .memory_init(memory_init),
3925
    .memory_file(memory_file))
3926
ram0(
3927 101 unneback
    .d(wbs_dat_i),
3928
    .adr(adr),
3929
    .be(wbs_sel_i),
3930
    .we(we),
3931
    .q(wbs_dat_o),
3932 100 unneback
    .clk(wb_clk)
3933
);
3934 49 unneback
endmodule
3935 103 unneback
// A wishbone compliant RAM module that can be placed in front of other memory controllers
3936
module vl_wb_shadow_ram (
3937
    wbs_dat_i, wbs_adr_i, wbs_cti_i, wbs_bte_i, wbs_sel_i, wbs_we_i, wbs_stb_i, wbs_cyc_i,
3938
    wbs_dat_o, wbs_ack_o, wbs_stall_o,
3939
    wbm_dat_o, wbm_adr_o, wbm_cti_o, wbm_bte_o, wbm_sel_o, wbm_we_o, wbm_stb_o, wbm_cyc_o,
3940
    wbm_dat_i, wbm_ack_i, wbm_stall_i,
3941
    wb_clk, wb_rst);
3942
parameter dat_width = 32;
3943
parameter mode = "B4";
3944
parameter max_burst_width = 4; // only used for B3
3945
parameter shadow_mem_adr_width = 10;
3946
parameter shadow_mem_size = 1024;
3947
parameter shadow_mem_init = 2;
3948
parameter shadow_mem_file = "vl_ram.v";
3949
parameter main_mem_adr_width = 24;
3950
input [dat_width-1:0] wbs_dat_i;
3951
input [main_mem_adr_width-1:0] wbs_adr_i;
3952
input [2:0] wbs_cti_i;
3953
input [1:0] wbs_bte_i;
3954
input [dat_width/8-1:0] wbs_sel_i;
3955
input wbs_we_i, wbs_stb_i, wbs_cyc_i;
3956
output [dat_width-1:0] wbs_dat_o;
3957
output wbs_ack_o;
3958
output wbs_stall_o;
3959
output [dat_width-1:0] wbm_dat_o;
3960
output [main_mem_adr_width-1:0] wbm_adr_o;
3961
output [2:0] wbm_cti_o;
3962
output [1:0] wbm_bte_o;
3963
output [dat_width/8-1:0] wbm_sel_o;
3964
output wbm_we_o, wbm_stb_o, wbm_cyc_o;
3965
input [dat_width-1:0] wbm_dat_i;
3966
input wbm_ack_i, wbm_stall_i;
3967
input wb_clk, wb_rst;
3968
generate
3969
if (shadow_mem_size>0) begin : shadow_ram_inst
3970
wire cyc;
3971
wire [dat_width-1:0] dat;
3972
wire stall, ack;
3973
assign cyc = wbs_cyc_i & (wbs_adr_i<=shadow_mem_size);
3974
vl_wb_ram # (
3975
    .dat_width(dat_width),
3976
    .adr_width(shadow_mem_adr_width),
3977
    .mem_size(shadow_mem_size),
3978
    .memory_init(shadow_mem_init),
3979 117 unneback
    .memory_file(shadow_mem_file),
3980 103 unneback
    .mode(mode))
3981
shadow_mem0 (
3982
    .wbs_dat_i(wbs_dat_i),
3983
    .wbs_adr_i(wbs_adr_i[shadow_mem_adr_width-1:0]),
3984
    .wbs_sel_i(wbs_sel_i),
3985
    .wbs_we_i (wbs_we_i),
3986
    .wbs_bte_i(wbs_bte_i),
3987
    .wbs_cti_i(wbs_cti_i),
3988
    .wbs_stb_i(wbs_stb_i),
3989
    .wbs_cyc_i(cyc),
3990
    .wbs_dat_o(dat),
3991
    .wbs_stall_o(stall),
3992
    .wbs_ack_o(ack),
3993
    .wb_clk(wb_clk),
3994
    .wb_rst(wb_rst));
3995
assign {wbm_dat_o, wbm_adr_o, wbm_cti_o, wbm_bte_o, wbm_sel_o, wbm_we_o, wbm_stb_o} =
3996
       {wbs_dat_i, wbs_adr_i, wbs_cti_i, wbs_bte_i, wbs_sel_i, wbs_we_i, wbs_stb_i};
3997
assign wbm_cyc_o = wbs_cyc_i & (wbs_adr_i>shadow_mem_size);
3998
assign wbs_dat_o = (dat & {dat_width{cyc}}) | (wbm_dat_i & {dat_width{wbm_cyc_o}});
3999
assign wbs_ack_o = (ack & cyc) | (wbm_ack_i & wbm_cyc_o);
4000
assign wbs_stall_o = (stall & cyc) | (wbm_stall_i & wbm_cyc_o);
4001
end else begin : no_shadow_ram_inst
4002
assign {wbm_dat_o, wbm_adr_o, wbm_cti_o, wbm_bte_o, wbm_sel_o, wbm_we_o, wbm_stb_o, wbm_cyc_o} =
4003
       {wbs_dat_i, wbs_adr_i, wbs_cti_i, wbs_bte_i, wbs_sel_i, wbs_we_i, wbs_stb_i, wbs_cyc_i};
4004
assign {wbs_dat_o, wbs_ack_o, wbs_stall_o} = {wbm_dat_i, wbm_ack_i, wbm_stall_i};
4005
end
4006
endgenerate
4007
endmodule
4008 17 unneback
// WB ROM
4009 48 unneback
module vl_wb_b4_rom (
4010
    wb_adr_i, wb_stb_i, wb_cyc_i,
4011
    wb_dat_o, stall_o, wb_ack_o, wb_clk, wb_rst);
4012
    parameter dat_width = 32;
4013
    parameter dat_default = 32'h15000000;
4014
    parameter adr_width = 32;
4015
/*
4016
`ifndef ROM
4017
`define ROM "rom.v"
4018
`endif
4019
*/
4020
    input [adr_width-1:2]   wb_adr_i;
4021
    input                   wb_stb_i;
4022
    input                   wb_cyc_i;
4023
    output [dat_width-1:0]  wb_dat_o;
4024
    reg [dat_width-1:0]     wb_dat_o;
4025
    output                  wb_ack_o;
4026
    reg                     wb_ack_o;
4027
    output                  stall_o;
4028
    input                   wb_clk;
4029
    input                   wb_rst;
4030
always @ (posedge wb_clk or posedge wb_rst)
4031
    if (wb_rst)
4032
        wb_dat_o <= {dat_width{1'b0}};
4033
    else
4034
         case (wb_adr_i[adr_width-1:2])
4035
`ifdef ROM
4036
`include `ROM
4037
`endif
4038
           default:
4039
             wb_dat_o <= dat_default;
4040
         endcase // case (wb_adr_i)
4041
always @ (posedge wb_clk or posedge wb_rst)
4042
    if (wb_rst)
4043
        wb_ack_o <= 1'b0;
4044
    else
4045
        wb_ack_o <= wb_stb_i & wb_cyc_i;
4046
assign stall_o = 1'b0;
4047
endmodule
4048
// WB ROM
4049 18 unneback
module vl_wb_boot_rom (
4050 17 unneback
    wb_adr_i, wb_stb_i, wb_cyc_i,
4051 18 unneback
    wb_dat_o, wb_ack_o, hit_o, wb_clk, wb_rst);
4052
    parameter adr_hi = 31;
4053
    parameter adr_lo = 28;
4054
    parameter adr_sel = 4'hf;
4055
    parameter addr_width = 5;
4056 33 unneback
/*
4057 17 unneback
`ifndef BOOT_ROM
4058
`define BOOT_ROM "boot_rom.v"
4059
`endif
4060 33 unneback
*/
4061 18 unneback
    input [adr_hi:2]    wb_adr_i;
4062
    input               wb_stb_i;
4063
    input               wb_cyc_i;
4064
    output [31:0]        wb_dat_o;
4065
    output              wb_ack_o;
4066
    output              hit_o;
4067
    input               wb_clk;
4068
    input               wb_rst;
4069
    wire hit;
4070
    reg [31:0] wb_dat;
4071
    reg wb_ack;
4072
assign hit = wb_adr_i[adr_hi:adr_lo] == adr_sel;
4073 17 unneback
always @ (posedge wb_clk or posedge wb_rst)
4074
    if (wb_rst)
4075 18 unneback
        wb_dat <= 32'h15000000;
4076 17 unneback
    else
4077 18 unneback
         case (wb_adr_i[addr_width-1:2])
4078 33 unneback
`ifdef BOOT_ROM
4079 17 unneback
`include `BOOT_ROM
4080 33 unneback
`endif
4081 17 unneback
           /*
4082
            // Zero r0 and jump to 0x00000100
4083 18 unneback
 
4084
            1 : wb_dat <= 32'hA8200000;
4085
            2 : wb_dat <= 32'hA8C00100;
4086
            3 : wb_dat <= 32'h44003000;
4087
            4 : wb_dat <= 32'h15000000;
4088 17 unneback
            */
4089
           default:
4090 18 unneback
             wb_dat <= 32'h00000000;
4091 17 unneback
         endcase // case (wb_adr_i)
4092
always @ (posedge wb_clk or posedge wb_rst)
4093
    if (wb_rst)
4094 18 unneback
        wb_ack <= 1'b0;
4095 17 unneback
    else
4096 18 unneback
        wb_ack <= wb_stb_i & wb_cyc_i & hit & !wb_ack;
4097
assign hit_o = hit;
4098
assign wb_dat_o = wb_dat & {32{wb_ack}};
4099
assign wb_ack_o = wb_ack;
4100 17 unneback
endmodule
4101 106 unneback
module vl_wb_dpram (
4102
        // wishbone slave side a
4103
        wbsa_dat_i, wbsa_adr_i, wbsa_sel_i, wbsa_cti_i, wbsa_bte_i, wbsa_we_i, wbsa_cyc_i, wbsa_stb_i, wbsa_dat_o, wbsa_ack_o, wbsa_stall_o,
4104
        wbsa_clk, wbsa_rst,
4105
        // wishbone slave side b
4106
        wbsb_dat_i, wbsb_adr_i, wbsb_sel_i, wbsb_cti_i, wbsb_bte_i, wbsb_we_i, wbsb_cyc_i, wbsb_stb_i, wbsb_dat_o, wbsb_ack_o, wbsb_stall_o,
4107
        wbsb_clk, wbsb_rst);
4108
parameter data_width_a = 32;
4109
parameter data_width_b = data_width_a;
4110
parameter addr_width_a = 8;
4111
localparam addr_width_b = data_width_a * addr_width_a / data_width_b;
4112
parameter mem_size = (addr_width_a>addr_width_b) ? (1<<addr_width_a) : (1<<addr_width_b);
4113
parameter max_burst_width_a = 4;
4114
parameter max_burst_width_b = max_burst_width_a;
4115
parameter mode = "B3";
4116 109 unneback
parameter memory_init = 0;
4117
parameter memory_file = "vl_ram.v";
4118 142 unneback
parameter debug = 0;
4119 106 unneback
input [data_width_a-1:0] wbsa_dat_i;
4120
input [addr_width_a-1:0] wbsa_adr_i;
4121
input [data_width_a/8-1:0] wbsa_sel_i;
4122
input [2:0] wbsa_cti_i;
4123
input [1:0] wbsa_bte_i;
4124
input wbsa_we_i, wbsa_cyc_i, wbsa_stb_i;
4125
output [data_width_a-1:0] wbsa_dat_o;
4126 109 unneback
output wbsa_ack_o;
4127 106 unneback
output wbsa_stall_o;
4128
input wbsa_clk, wbsa_rst;
4129
input [data_width_b-1:0] wbsb_dat_i;
4130
input [addr_width_b-1:0] wbsb_adr_i;
4131
input [data_width_b/8-1:0] wbsb_sel_i;
4132
input [2:0] wbsb_cti_i;
4133
input [1:0] wbsb_bte_i;
4134
input wbsb_we_i, wbsb_cyc_i, wbsb_stb_i;
4135
output [data_width_b-1:0] wbsb_dat_o;
4136 109 unneback
output wbsb_ack_o;
4137 106 unneback
output wbsb_stall_o;
4138
input wbsb_clk, wbsb_rst;
4139
wire [addr_width_a-1:0] adr_a;
4140
wire [addr_width_b-1:0] adr_b;
4141
wire we_a, we_b;
4142
generate
4143
if (mode=="B3") begin : b3_inst
4144
vl_wb_adr_inc # ( .adr_width(addr_width_a), .max_burst_width(max_burst_width_a)) adr_inc0 (
4145
    .cyc_i(wbsa_cyc_i),
4146
    .stb_i(wbsa_stb_i),
4147
    .cti_i(wbsa_cti_i),
4148
    .bte_i(wbsa_bte_i),
4149
    .adr_i(wbsa_adr_i),
4150
    .we_i(wbsa_we_i),
4151
    .ack_o(wbsa_ack_o),
4152
    .adr_o(adr_a),
4153
    .clk(wbsa_clk),
4154
    .rst(wbsa_rst));
4155
assign we_a = wbsa_we_i & wbsa_ack_o;
4156
vl_wb_adr_inc # ( .adr_width(addr_width_b), .max_burst_width(max_burst_width_b)) adr_inc1 (
4157
    .cyc_i(wbsb_cyc_i),
4158
    .stb_i(wbsb_stb_i),
4159
    .cti_i(wbsb_cti_i),
4160
    .bte_i(wbsb_bte_i),
4161
    .adr_i(wbsb_adr_i),
4162
    .we_i(wbsb_we_i),
4163
    .ack_o(wbsb_ack_o),
4164
    .adr_o(adr_b),
4165
    .clk(wbsb_clk),
4166
    .rst(wbsb_rst));
4167
assign we_b = wbsb_we_i & wbsb_ack_o;
4168
end else if (mode=="B4") begin : b4_inst
4169 142 unneback
assign adr_a = wbsa_adr_i;
4170 109 unneback
vl_dff dffacka ( .d(wbsa_stb_i & wbsa_cyc_i), .q(wbsa_ack_o), .clk(wbsa_clk), .rst(wbsa_rst));
4171 106 unneback
assign wbsa_stall_o = 1'b0;
4172
assign we_a = wbsa_we_i & wbsa_cyc_i & wbsa_stb_i;
4173 142 unneback
assign adr_b = wbsb_adr_i;
4174 109 unneback
vl_dff dffackb ( .d(wbsb_stb_i & wbsb_cyc_i), .q(wbsb_ack_o), .clk(wbsb_clk), .rst(wbsb_rst));
4175 106 unneback
assign wbsb_stall_o = 1'b0;
4176
assign we_b = wbsb_we_i & wbsb_cyc_i & wbsb_stb_i;
4177
end
4178
endgenerate
4179 109 unneback
vl_dpram_be_2r2w # ( .a_data_width(data_width_a), .a_addr_width(addr_width_a), .mem_size(mem_size),
4180 110 unneback
                 .b_data_width(data_width_b),
4181 142 unneback
                 .memory_init(memory_init), .memory_file(memory_file),
4182
                 .debug(debug))
4183 106 unneback
ram_i (
4184
    .d_a(wbsa_dat_i),
4185
    .q_a(wbsa_dat_o),
4186
    .adr_a(adr_a),
4187
    .be_a(wbsa_sel_i),
4188
    .we_a(we_a),
4189
    .clk_a(wbsa_clk),
4190
    .d_b(wbsb_dat_i),
4191
    .q_b(wbsb_dat_o),
4192
    .adr_b(adr_b),
4193
    .be_b(wbsb_sel_i),
4194
    .we_b(we_b),
4195
    .clk_b(wbsb_clk) );
4196
endmodule
4197 101 unneback
module vl_wb_cache (
4198 103 unneback
    wbs_dat_i, wbs_adr_i, wbs_sel_i, wbs_cti_i, wbs_bte_i, wbs_we_i, wbs_stb_i, wbs_cyc_i, wbs_dat_o, wbs_ack_o, wbs_stall_o, wbs_clk, wbs_rst,
4199 98 unneback
    wbm_dat_o, wbm_adr_o, wbm_sel_o, wbm_cti_o, wbm_bte_o, wbm_we_o, wbm_stb_o, wbm_cyc_o, wbm_dat_i, wbm_ack_i, wbm_stall_i, wbm_clk, wbm_rst
4200 97 unneback
);
4201
parameter dw_s = 32;
4202
parameter aw_s = 24;
4203
parameter dw_m = dw_s;
4204 124 unneback
//localparam aw_m = dw_s * aw_s / dw_m;
4205
localparam aw_m =
4206 126 unneback
        (dw_s==dw_m) ? aw_s :
4207
        (dw_s==dw_m*2) ? aw_s+1 :
4208
        (dw_s==dw_m*4) ? aw_s+2 :
4209
        (dw_s==dw_m*8) ? aw_s+3 :
4210
        (dw_s==dw_m*16) ? aw_s+4 :
4211
        (dw_s==dw_m*32) ? aw_s+5 :
4212
        (dw_s==dw_m/2) ? aw_s-1 :
4213 127 unneback
        (dw_s==dw_m/4) ? aw_s-2 :
4214 126 unneback
        (dw_s==dw_m/8) ? aw_s-3 :
4215
        (dw_s==dw_m/16) ? aw_s-4 :
4216
        (dw_s==dw_m/32) ? aw_s-5 : 0;
4217 100 unneback
parameter wbs_max_burst_width = 4;
4218 103 unneback
parameter wbs_mode = "B3";
4219 97 unneback
parameter async = 1; // wbs_clk != wbm_clk
4220
parameter nr_of_ways = 1;
4221
parameter aw_offset = 4; // 4 => 16 words per cache line
4222
parameter aw_slot = 10;
4223 100 unneback
parameter valid_mem = 0;
4224
parameter debug = 0;
4225
localparam aw_b_offset = aw_offset * dw_s / dw_m;
4226 98 unneback
localparam aw_tag = aw_s - aw_slot - aw_offset;
4227 97 unneback
parameter wbm_burst_size = 4; // valid options 4,8,16
4228 98 unneback
localparam bte = (wbm_burst_size==4) ? 2'b01 : (wbm_burst_size==8) ? 2'b10 : 2'b11;
4229 100 unneback
localparam wbm_burst_width = (wbm_burst_size==1) ? 0 : (wbm_burst_size==2) ? 1 : (wbm_burst_size==4) ? 2 : (wbm_burst_size==8) ? 3 : (wbm_burst_size==16) ? 4 : (wbm_burst_size==32) ? 5 : (wbm_burst_size==64) ? 6 : (wbm_burst_size==128) ? 7 : 8;
4230 97 unneback
localparam nr_of_wbm_burst = ((1<<aw_offset)/wbm_burst_size) * dw_s / dw_m;
4231 100 unneback
localparam nr_of_wbm_burst_width = (nr_of_wbm_burst==1) ? 0 : (nr_of_wbm_burst==2) ? 1 : (nr_of_wbm_burst==4) ? 2 : (nr_of_wbm_burst==8) ? 3 : (nr_of_wbm_burst==16) ? 4 : (nr_of_wbm_burst==32) ? 5 : (nr_of_wbm_burst==64) ? 6 : (nr_of_wbm_burst==128) ? 7 : 8;
4232 97 unneback
input [dw_s-1:0] wbs_dat_i;
4233
input [aw_s-1:0] wbs_adr_i; // dont include a1,a0
4234 98 unneback
input [dw_s/8-1:0] wbs_sel_i;
4235 97 unneback
input [2:0] wbs_cti_i;
4236
input [1:0] wbs_bte_i;
4237 98 unneback
input wbs_we_i, wbs_stb_i, wbs_cyc_i;
4238 97 unneback
output [dw_s-1:0] wbs_dat_o;
4239
output wbs_ack_o;
4240 103 unneback
output wbs_stall_o;
4241 97 unneback
input wbs_clk, wbs_rst;
4242
output [dw_m-1:0] wbm_dat_o;
4243
output [aw_m-1:0] wbm_adr_o;
4244
output [dw_m/8-1:0] wbm_sel_o;
4245
output [2:0] wbm_cti_o;
4246
output [1:0] wbm_bte_o;
4247 98 unneback
output wbm_stb_o, wbm_cyc_o, wbm_we_o;
4248 97 unneback
input [dw_m-1:0] wbm_dat_i;
4249
input wbm_ack_i;
4250
input wbm_stall_i;
4251
input wbm_clk, wbm_rst;
4252 100 unneback
wire valid, dirty, hit;
4253 97 unneback
wire [aw_tag-1:0] tag;
4254
wire tag_mem_we;
4255
wire [aw_tag-1:0] wbs_adr_tag;
4256
wire [aw_slot-1:0] wbs_adr_slot;
4257 98 unneback
wire [aw_offset-1:0] wbs_adr_word;
4258
wire [aw_s-1:0] wbs_adr;
4259 97 unneback
reg [1:0] state;
4260
localparam idle = 2'h0;
4261
localparam rdwr = 2'h1;
4262
localparam push = 2'h2;
4263
localparam pull = 2'h3;
4264
wire eoc;
4265 103 unneback
wire we;
4266 97 unneback
// cdc
4267
wire done, mem_alert, mem_done;
4268 98 unneback
// wbm side
4269
reg [aw_m-1:0] wbm_radr;
4270
reg [aw_m-1:0] wbm_wadr;
4271 137 unneback
//wire [aw_slot-1:0] wbm_adr;
4272
wire [aw_m-1:0] wbm_adr;
4273 98 unneback
wire wbm_radr_cke, wbm_wadr_cke;
4274 100 unneback
reg [2:0] phase;
4275
// phase = {we,stb,cyc}
4276
localparam wbm_wait     = 3'b000;
4277
localparam wbm_wr       = 3'b111;
4278
localparam wbm_wr_drain = 3'b101;
4279
localparam wbm_rd       = 3'b011;
4280
localparam wbm_rd_drain = 3'b001;
4281 97 unneback
assign {wbs_adr_tag, wbs_adr_slot, wbs_adr_word} = wbs_adr_i;
4282 100 unneback
generate
4283
if (valid_mem==0) begin : no_valid_mem
4284
assign valid = 1'b1;
4285
end else begin : valid_mem_inst
4286
vl_dpram_1r1w
4287
    # ( .data_width(1), .addr_width(aw_slot), .memory_init(2), .debug(debug))
4288
    valid_mem ( .d_a(1'b1), .adr_a(wbs_adr_slot), .we_a(mem_done), .clk_a(wbm_clk),
4289
                .q_b(valid), .adr_b(wbs_adr_slot), .clk_b(wbs_clk));
4290
end
4291
endgenerate
4292
vl_dpram_1r1w
4293
    # ( .data_width(aw_tag), .addr_width(aw_slot), .memory_init(2), .debug(debug))
4294
    tag_mem ( .d_a(wbs_adr_tag), .adr_a(wbs_adr_slot), .we_a(mem_done), .clk_a(wbm_clk),
4295
              .q_b(tag), .adr_b(wbs_adr_slot), .clk_b(wbs_clk));
4296
assign hit = wbs_adr_tag == tag;
4297
vl_dpram_1r2w
4298
    # ( .data_width(1), .addr_width(aw_slot), .memory_init(2), .debug(debug))
4299
    dirty_mem (
4300
        .d_a(1'b1), .q_a(dirty), .adr_a(wbs_adr_slot), .we_a(wbs_cyc_i & wbs_we_i & wbs_ack_o), .clk_a(wbs_clk),
4301
        .d_b(1'b0), .adr_b(wbs_adr_slot), .we_b(mem_done), .clk_b(wbm_clk));
4302 103 unneback
generate
4303
if (wbs_mode=="B3") begin : inst_b3
4304 100 unneback
vl_wb_adr_inc # ( .adr_width(aw_s), .max_burst_width(wbs_max_burst_width)) adr_inc0 (
4305
    .cyc_i(wbs_cyc_i & (state==rdwr) & hit & valid),
4306
    .stb_i(wbs_stb_i & (state==rdwr) & hit & valid), // throttle depending on valid
4307 97 unneback
    .cti_i(wbs_cti_i),
4308
    .bte_i(wbs_bte_i),
4309
    .adr_i(wbs_adr_i),
4310
    .we_i (wbs_we_i),
4311
    .ack_o(wbs_ack_o),
4312
    .adr_o(wbs_adr),
4313 100 unneback
    .clk(wbs_clk),
4314
    .rst(wbs_rst));
4315 103 unneback
assign eoc = (wbs_cti_i==3'b000 | wbs_cti_i==3'b111) & wbs_ack_o;
4316
assign we = wbs_cyc_i &  wbs_we_i & wbs_ack_o;
4317
end else if (wbs_mode=="B4") begin : inst_b4
4318
end
4319
endgenerate
4320 131 unneback
localparam cache_mem_b_aw =
4321
    (dw_s==dw_m) ? aw_slot+aw_offset :
4322 133 unneback
    (dw_s==dw_m/2) ? aw_slot+aw_offset-1 :
4323
    (dw_s==dw_m/4) ? aw_slot+aw_offset-2 :
4324
    (dw_s==dw_m/8) ? aw_slot+aw_offset-3 :
4325
    (dw_s==dw_m/16) ? aw_slot+aw_offset-4 :
4326
    (dw_s==dw_m*2) ? aw_slot+aw_offset+1 :
4327
    (dw_s==dw_m*4) ? aw_slot+aw_offset+2 :
4328
    (dw_s==dw_m*8) ? aw_slot+aw_offset+3 :
4329
    (dw_s==dw_m*16) ? aw_slot+aw_offset+4 : 0;
4330 97 unneback
vl_dpram_be_2r2w
4331 100 unneback
    # ( .a_data_width(dw_s), .a_addr_width(aw_slot+aw_offset), .b_data_width(dw_m), .debug(debug))
4332 103 unneback
    cache_mem ( .d_a(wbs_dat_i), .adr_a(wbs_adr[aw_slot+aw_offset-1:0]),   .be_a(wbs_sel_i), .we_a(we), .q_a(wbs_dat_o), .clk_a(wbs_clk),
4333 136 unneback
                .d_b(wbm_dat_i), .adr_b(wbm_adr[cache_mem_b_aw-1:0]), .be_b(wbm_sel_o), .we_b(wbm_cyc_o & !wbm_we_o & wbm_ack_i), .q_b(wbm_dat_o), .clk_b(wbm_clk));
4334 97 unneback
always @ (posedge wbs_clk or posedge wbs_rst)
4335
if (wbs_rst)
4336 98 unneback
    state <= idle;
4337 97 unneback
else
4338
    case (state)
4339
    idle:
4340
        if (wbs_cyc_i)
4341
            state <= rdwr;
4342
    rdwr:
4343 100 unneback
        casex ({valid, hit, dirty, eoc})
4344
        4'b0xxx: state <= pull;
4345
        4'b11x1: state <= idle;
4346
        4'b101x: state <= push;
4347
        4'b100x: state <= pull;
4348
        endcase
4349 97 unneback
    push:
4350
        if (done)
4351
            state <= rdwr;
4352
    pull:
4353
        if (done)
4354
            state <= rdwr;
4355
    default: state <= idle;
4356
    endcase
4357
// cdc
4358
generate
4359
if (async==1) begin : cdc0
4360 100 unneback
vl_cdc cdc0 ( .start_pl(state==rdwr & (!valid | !hit)), .take_it_pl(mem_alert), .take_it_grant_pl(mem_done), .got_it_pl(done), .clk_src(wbs_clk), .rst_src(wbs_rst), .clk_dst(wbm_clk), .rst_dst(wbm_rst));
4361 97 unneback
end
4362
else begin : nocdc
4363 100 unneback
    assign mem_alert = state==rdwr & (!valid | !hit);
4364 97 unneback
    assign done = mem_done;
4365
end
4366
endgenerate
4367 136 unneback
// FSM generating a number of bursts 4 cycles
4368 97 unneback
// actual number depends on data width ratio
4369
// nr_of_wbm_burst
4370 101 unneback
reg [nr_of_wbm_burst_width+wbm_burst_width-1:0]       cnt_rw, cnt_ack;
4371 97 unneback
always @ (posedge wbm_clk or posedge wbm_rst)
4372
if (wbm_rst)
4373 100 unneback
    cnt_rw <= {wbm_burst_width{1'b0}};
4374 97 unneback
else
4375 100 unneback
    if (wbm_cyc_o & wbm_stb_o & !wbm_stall_i)
4376
        cnt_rw <= cnt_rw + 1;
4377 98 unneback
always @ (posedge wbm_clk or posedge wbm_rst)
4378
if (wbm_rst)
4379 100 unneback
    cnt_ack <= {wbm_burst_width{1'b0}};
4380 98 unneback
else
4381 100 unneback
    if (wbm_ack_i)
4382
        cnt_ack <= cnt_ack + 1;
4383
generate
4384 101 unneback
if (nr_of_wbm_burst==1) begin : one_burst
4385 98 unneback
always @ (posedge wbm_clk or posedge wbm_rst)
4386
if (wbm_rst)
4387
    phase <= wbm_wait;
4388
else
4389
    case (phase)
4390
    wbm_wait:
4391
        if (mem_alert)
4392 100 unneback
            if (state==push)
4393
                phase <= wbm_wr;
4394
            else
4395
                phase <= wbm_rd;
4396 98 unneback
    wbm_wr:
4397 100 unneback
        if (&cnt_rw)
4398
            phase <= wbm_wr_drain;
4399
    wbm_wr_drain:
4400
        if (&cnt_ack)
4401 98 unneback
            phase <= wbm_rd;
4402
    wbm_rd:
4403 100 unneback
        if (&cnt_rw)
4404
            phase <= wbm_rd_drain;
4405
    wbm_rd_drain:
4406
        if (&cnt_ack)
4407
            phase <= wbm_wait;
4408 98 unneback
    default: phase <= wbm_wait;
4409
    endcase
4410 100 unneback
end else begin : multiple_burst
4411 101 unneback
always @ (posedge wbm_clk or posedge wbm_rst)
4412
if (wbm_rst)
4413
    phase <= wbm_wait;
4414
else
4415
    case (phase)
4416
    wbm_wait:
4417
        if (mem_alert)
4418
            if (state==push)
4419
                phase <= wbm_wr;
4420
            else
4421
                phase <= wbm_rd;
4422
    wbm_wr:
4423
        if (&cnt_rw[wbm_burst_width-1:0])
4424
            phase <= wbm_wr_drain;
4425
    wbm_wr_drain:
4426
        if (&cnt_ack)
4427
            phase <= wbm_rd;
4428
        else if (&cnt_ack[wbm_burst_width-1:0])
4429
            phase <= wbm_wr;
4430
    wbm_rd:
4431
        if (&cnt_rw[wbm_burst_width-1:0])
4432
            phase <= wbm_rd_drain;
4433
    wbm_rd_drain:
4434
        if (&cnt_ack)
4435
            phase <= wbm_wait;
4436
        else if (&cnt_ack[wbm_burst_width-1:0])
4437
            phase <= wbm_rd;
4438
    default: phase <= wbm_wait;
4439
    endcase
4440 100 unneback
end
4441
endgenerate
4442 101 unneback
assign mem_done = phase==wbm_rd_drain & (&cnt_ack) & wbm_ack_i;
4443 100 unneback
assign wbm_adr_o = (phase[2]) ? {tag, wbs_adr_slot, cnt_rw} : {wbs_adr_tag, wbs_adr_slot, cnt_rw};
4444 137 unneback
assign wbm_adr   = (phase[2]) ? {wbs_adr_slot, cnt_rw} : {wbs_adr_slot, cnt_ack};
4445 100 unneback
assign wbm_sel_o = {dw_m/8{1'b1}};
4446
assign wbm_cti_o = (&cnt_rw | !wbm_stb_o) ? 3'b111 : 3'b010;
4447 98 unneback
assign wbm_bte_o = bte;
4448 100 unneback
assign {wbm_we_o, wbm_stb_o, wbm_cyc_o}  = phase;
4449 97 unneback
endmodule
4450 103 unneback
// Wishbone to avalon bridge supporting one type of burst transfer only
4451
// intended use is together with cache above
4452
// WB B4 -> pipelined avalon
4453
module vl_wb_avalon_bridge (
4454
        // wishbone slave side
4455
        wbs_dat_i, wbs_adr_i, wbs_sel_i, wbs_bte_i, wbs_cti_i, wbs_we_i, wbs_cyc_i, wbs_stb_i, wbs_dat_o, wbs_ack_o, wbs_stall_o,
4456
        // avalon master side
4457
        readdata, readdatavalid, address, read, be, write, burstcount, writedata, waitrequest, beginbursttransfer,
4458 136 unneback
        init_done,
4459 103 unneback
        // common
4460
        clk, rst);
4461
parameter adr_width = 30;
4462
parameter dat_width = 32;
4463
parameter burst_size = 4;
4464
input [dat_width-1:0] wbs_dat_i;
4465
input [adr_width-1:0] wbs_adr_i;
4466
input [dat_width/8-1:0]  wbs_sel_i;
4467
input [1:0]  wbs_bte_i;
4468
input [2:0]  wbs_cti_i;
4469
input wbs_we_i;
4470
input wbs_cyc_i;
4471
input wbs_stb_i;
4472 130 unneback
output [dat_width-1:0] wbs_dat_o;
4473 103 unneback
output wbs_ack_o;
4474
output wbs_stall_o;
4475
input [dat_width-1:0] readdata;
4476
input readdatavalid;
4477
output [dat_width-1:0] writedata;
4478
output [adr_width-1:0] address;
4479
output [dat_width/8-1:0]  be;
4480
output write;
4481
output read;
4482
output beginbursttransfer;
4483
output [3:0] burstcount;
4484
input waitrequest;
4485 136 unneback
input init_done;
4486 103 unneback
input clk, rst;
4487 136 unneback
// cnt1 - initiated read or writes
4488
// cnt2 - # of read or writes in pipeline
4489
reg [3:0] cnt1;
4490
reg [3:0] cnt2;
4491
reg next_state, state;
4492
localparam s0 = 1'b0;
4493
localparam s1 = 1'b1;
4494
wire eoc;
4495
always @ *
4496
begin
4497
    case (state)
4498
    s0: if (init_done & wbs_cyc_i) next_state <= s1;
4499
    s1:
4500
    default: next_state <= state;
4501
    end
4502
end
4503 103 unneback
always @ (posedge clk or posedge rst)
4504
if (rst)
4505 136 unneback
    state <= s0;
4506 103 unneback
else
4507 136 unneback
    state <= next_state;
4508
assign eoc = state==s1 & !(read | write) & (& !waitrequest & cnt2=;
4509
always @ (posedge clk or posedge rst)
4510
if (rst)
4511
    cnt1 <= 4'h0;
4512
else
4513
    if (read & !waitrequest & init_done)
4514
        cnt1 <= burst_size - 1;
4515
    else if (write & !waitrequest & init_done)
4516
        cnt1 <= cnt1 + 4'h1;
4517
    else if (next_state==idle)
4518
        cnt1 <= 4'h0;
4519
always @ (posedge clk or posedge rst)
4520
if (rst)
4521
    cnt2 <= 4'h0;
4522
else
4523
    if (read & !waitrequest & init_done)
4524
        cnt2 <= burst_size - 1;
4525
    else if (write & !waitrequest & init_done & )
4526
        cnt2 <= cnt1 + 4'h1;
4527
    else if (next_state==idle)
4528
        cnt2 <= 4'h0;
4529 103 unneback
reg wr_ack;
4530
always @ (posedge clk or posedge rst)
4531
if (rst)
4532
    wr_ack <= 1'b0;
4533
else
4534
    wr_ack <=  (wbs_we_i & wbs_cyc_i & wbs_stb_i & !wbs_stall_o);
4535
// to avalon
4536
assign writedata = wbs_dat_i;
4537
assign address = wbs_adr_i;
4538
assign be = wbs_sel_i;
4539 136 unneback
assign write = cnt!=4'h0 & wbs_cyc_i &  wbs_we_i;
4540
assign read  = cnt!=4'h0 & wbs_cyc_i & !wbs_we_i;
4541
assign beginbursttransfer = state==s0 & next_state==s1;
4542 103 unneback
assign burstcount = burst_size;
4543
// to wishbone
4544
assign wbs_dat_o = readdata;
4545
assign wbs_ack_o = wr_ack | readdatavalid;
4546
assign wbs_stall_o = waitrequest;
4547
endmodule
4548
module vl_wb_avalon_mem_cache (
4549
    wbs_dat_i, wbs_adr_i, wbs_sel_i, wbs_cti_i, wbs_bte_i, wbs_we_i, wbs_stb_i, wbs_cyc_i, wbs_dat_o, wbs_ack_o, wbs_stall_o, wbs_clk, wbs_rst,
4550
    readdata, readdatavalid, address, read, be, write, burstcount, writedata, waitrequest, beginbursttransfer, clk, rst
4551
);
4552
// wishbone
4553
parameter wb_dat_width = 32;
4554
parameter wb_adr_width = 22;
4555
parameter wb_max_burst_width = 4;
4556
parameter wb_mode = "B4";
4557
// avalon
4558
parameter avalon_dat_width = 32;
4559 121 unneback
//localparam avalon_adr_width = wb_dat_width * wb_adr_width / avalon_dat_width;
4560 122 unneback
localparam avalon_adr_width =
4561
        (wb_dat_width==avalon_dat_width) ? wb_adr_width :
4562
        (wb_dat_width==avalon_dat_width*2) ? wb_adr_width+1 :
4563
        (wb_dat_width==avalon_dat_width*4) ? wb_adr_width+2 :
4564
        (wb_dat_width==avalon_dat_width*8) ? wb_adr_width+3 :
4565
        (wb_dat_width==avalon_dat_width*16) ? wb_adr_width+4 :
4566
        (wb_dat_width==avalon_dat_width*32) ? wb_adr_width+5 :
4567
        (wb_dat_width==avalon_dat_width/2) ? wb_adr_width-1 :
4568
        (wb_dat_width==avalon_dat_width/4) ? wb_adr_width-2 :
4569
        (wb_dat_width==avalon_dat_width/8) ? wb_adr_width-3 :
4570
        (wb_dat_width==avalon_dat_width/16) ? wb_adr_width-4 :
4571 123 unneback
        (wb_dat_width==avalon_dat_width/32) ? wb_adr_width-5 : 0;
4572 103 unneback
parameter avalon_burst_size = 4;
4573
// cache
4574
parameter async = 1;
4575
parameter nr_of_ways = 1;
4576
parameter aw_offset = 4;
4577
parameter aw_slot = 10;
4578
parameter valid_mem = 1;
4579
// shadow RAM
4580
parameter shadow_ram = 0;
4581
parameter shadow_ram_adr_width = 10;
4582
parameter shadow_ram_size = 1024;
4583
parameter shadow_ram_init = 2; // 0: no init, 1: from file, 2: with zero
4584
parameter shadow_ram_file = "vl_ram.v";
4585
input [wb_dat_width-1:0] wbs_dat_i;
4586
input [wb_adr_width-1:0] wbs_adr_i; // dont include a1,a0
4587
input [wb_dat_width/8-1:0] wbs_sel_i;
4588
input [2:0] wbs_cti_i;
4589
input [1:0] wbs_bte_i;
4590
input wbs_we_i, wbs_stb_i, wbs_cyc_i;
4591
output [wb_dat_width-1:0] wbs_dat_o;
4592
output wbs_ack_o;
4593
output wbs_stall_o;
4594
input wbs_clk, wbs_rst;
4595
input [avalon_dat_width-1:0] readdata;
4596
input readdatavalid;
4597
output [avalon_dat_width-1:0] writedata;
4598
output [avalon_adr_width-1:0] address;
4599
output [avalon_dat_width/8-1:0]  be;
4600
output write;
4601
output read;
4602
output beginbursttransfer;
4603
output [3:0] burstcount;
4604
input waitrequest;
4605
input clk, rst;
4606
wire [wb_dat_width-1:0] wb1_dat_o;
4607
wire [wb_adr_width-1:0] wb1_adr_o;
4608
wire [wb_dat_width/8-1:0] wb1_sel_o;
4609
wire [2:0] wb1_cti_o;
4610
wire [1:0] wb1_bte_o;
4611
wire wb1_we_o;
4612
wire wb1_stb_o;
4613
wire wb1_cyc_o;
4614
wire wb1_stall_i;
4615
wire [wb_dat_width-1:0] wb1_dat_i;
4616
wire wb1_ack_i;
4617 129 unneback
wire [avalon_dat_width-1:0] wb2_dat_o;
4618
wire [avalon_adr_width-1:0] wb2_adr_o;
4619
wire [avalon_dat_width/8-1:0] wb2_sel_o;
4620 103 unneback
wire [2:0] wb2_cti_o;
4621
wire [1:0] wb2_bte_o;
4622
wire wb2_we_o;
4623
wire wb2_stb_o;
4624
wire wb2_cyc_o;
4625
wire wb2_stall_i;
4626 129 unneback
wire [avalon_dat_width-1:0] wb2_dat_i;
4627 103 unneback
wire wb2_ack_i;
4628
vl_wb_shadow_ram # ( .dat_width(wb_dat_width), .mode(wb_mode), .max_burst_width(wb_max_burst_width),
4629 120 unneback
                 .shadow_mem_adr_width(shadow_ram_adr_width), .shadow_mem_size(shadow_ram_size), .shadow_mem_init(shadow_ram_init), .shadow_mem_file(shadow_ram_file),
4630 103 unneback
                 .main_mem_adr_width(wb_adr_width))
4631
shadow_ram0 (
4632
    .wbs_dat_i(wbs_dat_i), .wbs_adr_i(wbs_adr_i), .wbs_cti_i(wbs_cti_i), .wbs_bte_i(wbs_bte_i), .wbs_sel_i(wbs_sel_i), .wbs_we_i(wbs_we_i), .wbs_stb_i(wbs_stb_i), .wbs_cyc_i(wbs_cyc_i),
4633
    .wbs_dat_o(wbs_dat_o), .wbs_ack_o(wbs_ack_o), .wbs_stall_o(wbs_stall_o),
4634
    .wbm_dat_o(wb1_dat_o), .wbm_adr_o(wb1_adr_o), .wbm_cti_o(wb1_cti_o), .wbm_bte_o(wb1_bte_o), .wbm_sel_o(wb1_sel_o), .wbm_we_o(wb1_we_o), .wbm_stb_o(wb1_stb_o), .wbm_cyc_o(wb1_cyc_o),
4635
    .wbm_dat_i(wb1_dat_i), .wbm_ack_i(wb1_ack_i), .wbm_stall_i(wb1_stall_i),
4636
    .wb_clk(wbs_clk), .wb_rst(wbs_rst));
4637
vl_wb_cache
4638
# ( .dw_s(wb_dat_width), .aw_s(wb_adr_width), .dw_m(avalon_dat_width), .wbs_mode(wb_mode), .wbs_max_burst_width(wb_max_burst_width), .async(async), .nr_of_ways(nr_of_ways), .aw_offset(aw_offset), .aw_slot(aw_slot), .valid_mem(valid_mem))
4639
cache0 (
4640
    .wbs_dat_i(wb1_dat_o), .wbs_adr_i(wb1_adr_o), .wbs_sel_i(wb1_sel_o), .wbs_cti_i(wb1_cti_o), .wbs_bte_i(wb1_bte_o), .wbs_we_i(wb1_we_o), .wbs_stb_i(wb1_stb_o), .wbs_cyc_i(wb1_cyc_o),
4641
    .wbs_dat_o(wb1_dat_i), .wbs_ack_o(wb1_ack_i), .wbs_stall_o(wb1_stall_i), .wbs_clk(wbs_clk), .wbs_rst(wbs_rst),
4642
    .wbm_dat_o(wb2_dat_o), .wbm_adr_o(wb2_adr_o), .wbm_sel_o(wb2_sel_o), .wbm_cti_o(wb2_cti_o), .wbm_bte_o(wb2_bte_o), .wbm_we_o(wb2_we_o), .wbm_stb_o(wb2_stb_o), .wbm_cyc_o(wb2_cyc_o),
4643
    .wbm_dat_i(wb2_dat_i), .wbm_ack_i(wb2_ack_i), .wbm_stall_i(wb2_stall_i), .wbm_clk(clk), .wbm_rst(rst));
4644
vl_wb_avalon_bridge # ( .adr_width(avalon_adr_width), .dat_width(avalon_dat_width), .burst_size(avalon_burst_size))
4645
bridge0 (
4646
        // wishbone slave side
4647
        .wbs_dat_i(wb2_dat_o), .wbs_adr_i(wb2_adr_o), .wbs_sel_i(wb2_sel_o), .wbs_bte_i(wb2_bte_o), .wbs_cti_i(wb2_cti_o), .wbs_we_i(wb2_we_o), .wbs_cyc_i(wb2_cyc_o), .wbs_stb_i(wb2_stb_o),
4648
        .wbs_dat_o(wb2_dat_i), .wbs_ack_o(wb2_ack_i), .wbs_stall_o(wb2_stall_i),
4649
        // avalon master side
4650
        .readdata(readdata), .readdatavalid(readdatavalid), .address(address), .read(read), .be(be), .write(write), .burstcount(burstcount), .writedata(writedata), .waitrequest(waitrequest), .beginbursttransfer(beginbursttransfer),
4651
        // common
4652
        .clk(clk), .rst(rst));
4653
endmodule
4654 136 unneback
module vl_wb_sdr_sdram (
4655
    // wisbone i/f
4656
    dat_i, adr_i, sel_i, we_i, cyc_i, stb_i, dat_o, ack_o, stall_o,
4657
    // SDR SDRAM
4658
    ba, a, cmd, cke, cs_n, dqm, dq_i, dq_o, dq_oe,
4659
    // system
4660
    clk, rst);
4661
    // external data bus size
4662
    parameter dat_size = 16;
4663
    // memory geometry parameters
4664
    parameter ba_size  = 2;
4665
    parameter row_size = 13;
4666
    parameter col_size = 9;
4667
    parameter cl = 2;
4668
    // memory timing parameters
4669
    parameter tRFC = 9;
4670
    parameter tRP  = 2;
4671
    parameter tRCD = 2;
4672
    parameter tMRD = 2;
4673
    // LMR
4674
    // [12:10] reserved
4675
    // [9]     WB, write burst; 0 - programmed burst length, 1 - single location
4676
    // [8:7]   OP Mode, 2'b00
4677
    // [6:4]   CAS Latency; 3'b010 - 2, 3'b011 - 3
4678
    // [3]     BT, Burst Type; 1'b0 - sequential, 1'b1 - interleaved
4679
    // [2:0]   Burst length; 3'b000 - 1, 3'b001 - 2, 3'b010 - 4, 3'b011 - 8, 3'b111 - full page
4680
    localparam init_wb = 1'b1;
4681
    localparam init_cl = (cl==2) ? 3'b010 : 3'b011;
4682
    localparam init_bt = 1'b0;
4683
    localparam init_bl = 3'b000;
4684
    input [dat_size-1:0] dat_i;
4685
    input [ba_size+col_size+row_size-1:0] adr_i;
4686
    input [dat_size/8-1:0] sel_i;
4687
    input we_i, cyc_i, stb_i;
4688
    output [dat_size-1:0] dat_o;
4689
    output ack_o;
4690
    output reg stall_o;
4691
    output [ba_size-1:0]    ba;
4692
    output reg [12:0]   a;
4693
    output reg [2:0]    cmd; // {ras,cas,we}
4694
    output cke, cs_n;
4695
    output reg [dat_size/8-1:0]    dqm;
4696
    output [dat_size-1:0]       dq_o;
4697
    output reg          dq_oe;
4698
    input  [dat_size-1:0]       dq_i;
4699
    input clk, rst;
4700
    wire [ba_size-1:0]   bank;
4701
    wire [row_size-1:0] row;
4702
    wire [col_size-1:0] col;
4703
    wire [0:31]  shreg;
4704
    wire                ref_cnt_zero;
4705
    reg                 refresh_req;
4706
    wire ack_rd, rd_ack_emptyflag;
4707
    wire ack_wr;
4708
    // to keep track of open rows per bank
4709
    reg [row_size-1:0]   open_row[0:3];
4710
    reg [0:3]            open_ba;
4711
    reg                 current_bank_closed, current_row_open;
4712
    parameter rfr_length = 10;
4713
    parameter rfr_wrap_value = 1010;
4714
    parameter [2:0] cmd_nop = 3'b111,
4715
                    cmd_act = 3'b011,
4716
                    cmd_rd  = 3'b101,
4717
                    cmd_wr  = 3'b100,
4718
                    cmd_pch = 3'b010,
4719
                    cmd_rfr = 3'b001,
4720
                    cmd_lmr = 3'b000;
4721
// ctrl FSM
4722
    assign cke = 1'b1;
4723
    assign cs_n = 1'b0;
4724
    reg [2:0] state, next;
4725
    function [12:0] a10_fix;
4726
        input [col_size-1:0] a;
4727
        integer i;
4728
    begin
4729
        for (i=0;i<13;i=i+1) begin
4730
            if (i<10)
4731
              if (i<col_size)
4732
                a10_fix[i] = a[i];
4733
              else
4734
                a10_fix[i] = 1'b0;
4735
            else if (i==10)
4736
              a10_fix[i] = 1'b0;
4737
            else
4738
              if (i<col_size)
4739
                a10_fix[i] = a[i-1];
4740
              else
4741
                a10_fix[i] = 1'b0;
4742
        end
4743
    end
4744
    endfunction
4745
    assign {bank,row,col} = adr_i;
4746
    always @ (posedge clk or posedge rst)
4747
    if (rst)
4748
       state <= 3'b000;
4749
    else
4750
       state <= next;
4751
    always @*
4752
    begin
4753
        next = state;
4754
        case (state)
4755
        3'b000:
4756
            if (shreg[3+tRP+tRFC+tRFC+tMRD]) next = 3'b001;
4757
        3'b001:
4758
            if (refresh_req) next = 3'b010;
4759
            else if (cyc_i & stb_i & rd_ack_emptyflag) next = 3'b011;
4760
        3'b010:
4761
            if (shreg[tRP+tRFC-2]) next = 3'b001; // take away two cycles because no cmd will be issued in idle and adr
4762
        3'b011:
4763
            if (current_bank_closed) next = 3'b101;
4764
            else if (current_row_open) next = 3'b111;
4765
            else next = 3'b100;
4766
        3'b100:
4767
            if (shreg[tRP]) next = 3'b101;
4768
        3'b101:
4769
            if (shreg[tRCD]) next = 3'b111;
4770
        3'b111:
4771
            if (!stb_i) next = 3'b001;
4772
        endcase
4773
    end
4774
    // counter
4775
    vl_cnt_shreg_clear # ( .length(32))
4776
        cnt0 (
4777
            .clear(state!=next),
4778
            .q(shreg),
4779
            .rst(rst),
4780
            .clk(clk));
4781
    // ba, a, cmd
4782
    // outputs dependent on state vector
4783
    always @ (*)
4784
        begin
4785
            {a,cmd} = {13'd0,cmd_nop};
4786
            dqm = 2'b11;
4787
            dq_oe = 1'b0;
4788
            stall_o = 1'b1;
4789
            case (state)
4790
            3'b000:
4791
                if (shreg[3]) begin
4792
                    {a,cmd} = {13'b0010000000000, cmd_pch};
4793
                end else if (shreg[3+tRP] | shreg[3+tRP+tRFC])
4794
                    {a,cmd} = {13'd0, cmd_rfr};
4795
                else if (shreg[3+tRP+tRFC+tRFC])
4796
                    {a,cmd} = {3'b000,init_wb,2'b00,init_cl,init_bt,init_bl,cmd_lmr};
4797
            3'b010:
4798
                if (shreg[0])
4799
                    {a,cmd} = {13'b0010000000000, cmd_pch};
4800
                else if (shreg[tRP])
4801
                    {a,cmd} = {13'd0, cmd_rfr};
4802
            3'b100:
4803
                if (shreg[0])
4804
                    {a,cmd} = {13'd0,cmd_pch};
4805
            3'b101:
4806
                if (shreg[0])
4807
                    {a[row_size-1:0],cmd} = {row,cmd_act};
4808
            3'b111:
4809
                begin
4810
                    if (we_i)
4811
                        cmd = cmd_wr;
4812
                    else
4813
                        cmd = cmd_rd;
4814
                    if (we_i)
4815
                        dqm = ~sel_i;
4816
                    else
4817
                        dqm = 2'b00;
4818
                    if (we_i)
4819
                        dq_oe = 1'b1;
4820
                    a = a10_fix(col);
4821
                    stall_o = 1'b0;
4822
                end
4823
            endcase
4824
        end
4825
    assign ba = bank;
4826
    // precharge individual bank A10=0
4827
    // precharge all bank A10=1
4828
    genvar i;
4829
    generate
4830
    for (i=0;i<2<<ba_size-1;i=i+1) begin : open_ba_logic
4831
        always @ (posedge clk or posedge rst)
4832
        if (rst)
4833
            {open_ba[i],open_row[i]} <= {1'b0,{row_size{1'b0}}};
4834
        else
4835
            if (cmd==cmd_pch & (a[10] | bank==i))
4836
                open_ba[i] <= 1'b0;
4837
            else if (cmd==cmd_act & bank==i)
4838
                {open_ba[i],open_row[i]} <= {1'b1,row};
4839
    end
4840
    endgenerate
4841
    // bank and row open ?
4842
    always @ (posedge clk or posedge rst)
4843
    if (rst)
4844
       {current_bank_closed, current_row_open} <= {1'b1, 1'b0};
4845
    else
4846
       {current_bank_closed, current_row_open} <= {!(open_ba[bank]), open_row[bank]==row};
4847
    // refresh counter
4848
    vl_cnt_lfsr_zq # ( .length(rfr_length), .wrap_value (rfr_wrap_value)) ref_counter0( .zq(ref_cnt_zero), .rst(rst), .clk(clk));
4849
    always @ (posedge clk or posedge rst)
4850
    if (rst)
4851
        refresh_req <= 1'b0;
4852
    else
4853
        if (ref_cnt_zero)
4854
            refresh_req <= 1'b1;
4855
        else if (state==3'b010)
4856
            refresh_req <= 1'b0;
4857
    assign dat_o = dq_i;
4858
    assign ack_wr = (state==3'b111 & we_i);
4859
    vl_delay_emptyflag # ( .depth(cl+2)) delay0 ( .d(state==3'b111 & stb_i & !we_i), .q(ack_rd), .emptyflag(rd_ack_emptyflag), .clk(clk), .rst(rst));
4860
    assign ack_o = ack_rd | ack_wr;
4861
    assign dq_o = dat_i;
4862
endmodule
4863
module vl_wb_sdr_sdram_ctrl (
4864
    // WB i/f
4865
    wbs_dat_i, wbs_adr_i, wbs_cti_i, wbs_bte_i, wbs_sel_i, wbs_we_i, wbs_stb_i, wbs_cyc_i,
4866
    wbs_dat_o, wbs_ack_o, wbs_stall_o,
4867
    // SDR SDRAM
4868
    mem_ba, mem_a, mem_cmd, mem_cke, mem_cs_n, mem_dqm, mem_dq_i, mem_dq_o, mem_dq_oe,
4869
    // system
4870
    wb_clk, wb_rst, mem_clk, mem_rst);
4871
    // WB slave
4872
    parameter wbs_dat_width = 32;
4873
    parameter wbs_adr_width = 24;
4874
    parameter wbs_mode = "B3";
4875
    parameter wbs_max_burst_width = 4;
4876
    // Shadow RAM
4877
    parameter shadow_mem_adr_width = 10;
4878
    parameter shadow_mem_size = 1024;
4879
    parameter shadow_mem_init = 2;
4880
    parameter shadow_mem_file = "vl_ram.v";
4881
    // Cache
4882
    parameter cache_async = 1; // wbs_clk != wbm_clk
4883
    parameter cache_nr_of_ways = 1;
4884
    parameter cache_aw_offset = 4; // 4 => 16 words per cache line
4885
    parameter cache_aw_slot = 10;
4886
    parameter cache_valid_mem = 0;
4887
    parameter cache_debug = 0;
4888
    // SDRAM parameters
4889
    parameter mem_dat_size = 16;
4890
    parameter mem_ba_size  = 2;
4891
    parameter mem_row_size = 13;
4892
    parameter mem_col_size = 9;
4893
    parameter mem_cl = 2;
4894
    parameter mem_tRFC = 9;
4895
    parameter mem_tRP  = 2;
4896
    parameter mem_tRCD = 2;
4897
    parameter mem_tMRD = 2;
4898
    parameter mem_rfr_length = 10;
4899
    parameter mem_rfr_wrap_value = 1010;
4900
    input [wbs_dat_width-1:0] wbs_dat_i;
4901
    input [wbs_adr_width-1:0] wbs_adr_i;
4902
    input [2:0] wbs_cti_i;
4903
    input [1:0] wbs_bte_i;
4904
    input [wbs_dat_width/8-1:0] wbs_sel_i;
4905
    input wbs_we_i, wbs_stb_i, wbs_cyc_i;
4906
    output [wbs_dat_width-1:0] wbs_dat_o;
4907
    output wbs_ack_o;
4908
    output wbs_stall_o;
4909
    output [mem_ba_size-1:0]    mem_ba;
4910
    output reg [12:0]           mem_a;
4911
    output reg [2:0]            mem_cmd; // {ras,cas,we}
4912
    output                      mem_cke, mem_cs_n;
4913
    output reg [mem_dat_size/8-1:0] mem_dqm;
4914
    output [mem_dat_size-1:0]       mem_dq_o;
4915
    output reg                  mem_dq_oe;
4916
    input  [mem_dat_size-1:0]       mem_dq_i;
4917
    input wb_clk, wb_rst, mem_clk, mem_rst;
4918
    // wbm1
4919
    wire [wbs_dat_width-1:0] wbm1_dat_o;
4920
    wire [wbs_adr_width-1:0] wbm1_adr_o;
4921
    wire [2:0] wbm1_cti_o;
4922
    wire [1:0] wbm1_bte_o;
4923
    wire [wbs_dat_width/8-1:0] wbm1_sel_o;
4924
    wire wbm1_we_o, wbm1_stb_o, wbm1_cyc_o;
4925
    wire [wbs_dat_width-1:0] wbm1_dat_i;
4926
    wire wbm1_ack_i, wbm1_stall_i;
4927
    // wbm2
4928
    wire [mem_dat_size-1:0] wbm2_dat_o;
4929
    wire [mem_ba_size+mem_row_size+mem_col_size-1:0] wbm2_adr_o;
4930
    wire [2:0] wbm2_cti_o;
4931
    wire [1:0] wbm2_bte_o;
4932
    wire [mem_dat_size/8-1:0] wbm2_sel_o;
4933
    wire wbm2_we_o, wbm2_stb_o, wbm2_cyc_o;
4934
    wire [mem_dat_size-1:0] wbm2_dat_i;
4935
    wire wbm2_ack_i, wbm2_stall_i;
4936
vl_wb_shadow_ram # (
4937
    .shadow_mem_adr_width(shadow_mem_adr_width), .shadow_mem_size(shadow_mem_size), .shadow_mem_init(shadow_mem_init), .shadow_mem_file(shadow_mem_file), .main_mem_adr_width(wbs_adr_width), .dat_width(wbs_dat_width), .mode(wbs_mode), .max_burst_width(wbs_max_burst_width) )
4938
shadow_ram0 (
4939
    .wbs_dat_i(wbs_dat_i),
4940
    .wbs_adr_i(wbs_adr_i),
4941
    .wbs_cti_i(wbs_cti_i),
4942
    .wbs_bte_i(wbs_bte_i),
4943
    .wbs_sel_i(wbs_sel_i),
4944
    .wbs_we_i (wbs_we_i),
4945
    .wbs_stb_i(wbs_stb_i),
4946
    .wbs_cyc_i(wbs_cyc_i),
4947
    .wbs_dat_o(wbs_dat_o),
4948
    .wbs_ack_o(wbs_ack_o),
4949
    .wbs_stall_o(wbs_stall_o),
4950
    .wbm_dat_o(wbm1_dat_o),
4951
    .wbm_adr_o(wbm1_adr_o),
4952
    .wbm_cti_o(wbm1_cti_o),
4953
    .wbm_bte_o(wbm1_bte_o),
4954
    .wbm_sel_o(wbm1_sel_o),
4955
    .wbm_we_o(wbm1_we_o),
4956
    .wbm_stb_o(wbm1_stb_o),
4957
    .wbm_cyc_o(wbm1_cyc_o),
4958
    .wbm_dat_i(wbm1_dat_i),
4959
    .wbm_ack_i(wbm1_ack_i),
4960
    .wbm_stall_i(wbm1_stall_i),
4961
    .wb_clk(wb_clk),
4962
    .wb_rst(wb_rst) );
4963
vl_wb_cache # (
4964
    .dw_s(wbs_dat_width), .aw_s(wbs_adr_width), .dw_m(mem_dat_size), .wbs_max_burst_width(cache_aw_offset), .wbs_mode(wbs_mode), .async(cache_async), .nr_of_ways(cache_nr_of_ways), .aw_offset(cache_aw_offset), .aw_slot(cache_aw_slot), .valid_mem(cache_valid_mem) )
4965
cache0 (
4966
    .wbs_dat_i(wbm1_dat_o),
4967
    .wbs_adr_i(wbm1_adr_o),
4968
    .wbs_sel_i(wbm1_sel_o),
4969
    .wbs_cti_i(wbm1_cti_o),
4970
    .wbs_bte_i(wbm1_bte_o),
4971
    .wbs_we_i (wbm1_we_o),
4972
    .wbs_stb_i(wbm1_stb_o),
4973
    .wbs_cyc_i(wbm1_cyc_o),
4974
    .wbs_dat_o(wbm1_dat_i),
4975
    .wbs_ack_o(wbm1_ack_i),
4976
    .wbs_stall_o(wbm1_stall_i),
4977
    .wbs_clk(wb_clk),
4978
    .wbs_rst(wb_rst),
4979
    .wbm_dat_o(wbm2_dat_o),
4980
    .wbm_adr_o(wbm2_adr_o),
4981
    .wbm_sel_o(wbm2_sel_o),
4982
    .wbm_cti_o(wbm2_cti_o),
4983
    .wbm_bte_o(wbm2_bte_o),
4984
    .wbm_we_o (wbm2_we_o),
4985
    .wbm_stb_o(wbm2_stb_o),
4986
    .wbm_cyc_o(wbm2_cyc_o),
4987
    .wbm_dat_i(wbm2_dat_i),
4988
    .wbm_ack_i(wbm2_ack_i),
4989
    .wbm_stall_i(wbm2_stall_i),
4990
    .wbm_clk(mem_clk),
4991
    .wbm_rst(mem_rst) );
4992
vl_wb_sdr_sdram # (
4993
    .dat_size(mem_dat_size), .ba_size(mem_ba_size), .row_size(mem_row_size), .col_size(mem_col_size), .cl(mem_cl), .tRFC(mem_tRFC), .tRP(mem_tRP), .tRCD(mem_tRCD), .tMRD(mem_tMRD), .rfr_length(mem_rfr_length), .rfr_wrap_value(mem_rfr_wrap_value) )
4994
ctrl0(
4995
    // wisbone i/f
4996
    .dat_i(wbm2_dat_o),
4997
    .adr_i(wbm2_adr_o),
4998
    .sel_i(wbm2_sel_o),
4999
    .we_i (wbm2_we_o),
5000
    .cyc_i(wbm2_cyc_o),
5001
    .stb_i(wbm2_stb_o),
5002
    .dat_o(wbm2_dat_i),
5003
    .ack_o(wbm2_ack_i),
5004
    .stall_o(wbm2_stall_i),
5005
    // SDR SDRAM
5006
    .ba(mem_ba),
5007
    .a(mem_a),
5008
    .cmd(mem_cmd),
5009
    .cke(mem_cke),
5010
    .cs_n(mem_cs_n),
5011
    .dqm(mem_dqm),
5012
    .dq_i(mem_dq_i),
5013
    .dq_o(mem_dq_o),
5014
    .dq_oe(mem_dq_oe),
5015
    // system
5016
    .clk(mem_clk),
5017
    .rst(mem_rst) );
5018
endmodule
5019 18 unneback
//////////////////////////////////////////////////////////////////////
5020
////                                                              ////
5021
////  Arithmetic functions                                        ////
5022
////                                                              ////
5023
////  Description                                                 ////
5024
////  Arithmetic functions for ALU and DSP                        ////
5025
////                                                              ////
5026
////                                                              ////
5027
////  To Do:                                                      ////
5028
////   -                                                          ////
5029
////                                                              ////
5030
////  Author(s):                                                  ////
5031
////      - Michael Unneback, unneback@opencores.org              ////
5032
////        ORSoC AB                                              ////
5033
////                                                              ////
5034
//////////////////////////////////////////////////////////////////////
5035
////                                                              ////
5036
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
5037
////                                                              ////
5038
//// This source file may be used and distributed without         ////
5039
//// restriction provided that this copyright statement is not    ////
5040
//// removed from the file and that any derivative work contains  ////
5041
//// the original copyright notice and the associated disclaimer. ////
5042
////                                                              ////
5043
//// This source file is free software; you can redistribute it   ////
5044
//// and/or modify it under the terms of the GNU Lesser General   ////
5045
//// Public License as published by the Free Software Foundation; ////
5046
//// either version 2.1 of the License, or (at your option) any   ////
5047
//// later version.                                               ////
5048
////                                                              ////
5049
//// This source is distributed in the hope that it will be       ////
5050
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
5051
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
5052
//// PURPOSE.  See the GNU Lesser General Public License for more ////
5053
//// details.                                                     ////
5054
////                                                              ////
5055
//// You should have received a copy of the GNU Lesser General    ////
5056
//// Public License along with this source; if not, download it   ////
5057
//// from http://www.opencores.org/lgpl.shtml                     ////
5058
////                                                              ////
5059
//////////////////////////////////////////////////////////////////////
5060
// signed multiplication
5061
module vl_mults (a,b,p);
5062
parameter operand_a_width = 18;
5063
parameter operand_b_width = 18;
5064
parameter result_hi = 35;
5065
parameter result_lo = 0;
5066
input [operand_a_width-1:0] a;
5067
input [operand_b_width-1:0] b;
5068
output [result_hi:result_lo] p;
5069
wire signed [operand_a_width-1:0] ai;
5070
wire signed [operand_b_width-1:0] bi;
5071
wire signed [operand_a_width+operand_b_width-1:0] result;
5072
    assign ai = a;
5073
    assign bi = b;
5074
    assign result = ai * bi;
5075
    assign p = result[result_hi:result_lo];
5076
endmodule
5077
module vl_mults18x18 (a,b,p);
5078
input [17:0] a,b;
5079
output [35:0] p;
5080
vl_mult
5081
    # (.operand_a_width(18), .operand_b_width(18))
5082
    mult0 (.a(a), .b(b), .p(p));
5083
endmodule
5084
// unsigned multiplication
5085
module vl_mult (a,b,p);
5086
parameter operand_a_width = 18;
5087
parameter operand_b_width = 18;
5088
parameter result_hi = 35;
5089
parameter result_lo = 0;
5090
input [operand_a_width-1:0] a;
5091
input [operand_b_width-1:0] b;
5092
output [result_hi:result_hi] p;
5093
wire [operand_a_width+operand_b_width-1:0] result;
5094
    assign result = a * b;
5095
    assign p = result[result_hi:result_lo];
5096
endmodule
5097
// shift unit
5098
// supporting the following shift functions
5099
//   SLL
5100
//   SRL
5101
//   SRA
5102
module vl_shift_unit_32( din, s, dout, opcode);
5103
input [31:0] din; // data in operand
5104
input [4:0] s; // shift operand
5105
input [1:0] opcode;
5106
output [31:0] dout;
5107
parameter opcode_sll = 2'b00;
5108 149 unneback
parameter opcode_srl = 2'b01;
5109 18 unneback
parameter opcode_sra = 2'b10;
5110 149 unneback
parameter opcode_ror = 2'b11;
5111
parameter mult=0; // if set to 1 implemented based on multipliers which saves LUT
5112
generate
5113
if (mult==1) begin : impl_mult
5114 18 unneback
wire sll, sra;
5115
assign sll = opcode == opcode_sll;
5116
assign sra = opcode == opcode_sra;
5117
wire [15:1] s1;
5118
wire [3:0] sign;
5119
wire [7:0] tmp [0:3];
5120
// first stage is multiplier based
5121
// shift operand as fractional 8.7
5122
assign s1[15] = sll & s[2:0]==3'd7;
5123
assign s1[14] = sll & s[2:0]==3'd6;
5124
assign s1[13] = sll & s[2:0]==3'd5;
5125
assign s1[12] = sll & s[2:0]==3'd4;
5126
assign s1[11] = sll & s[2:0]==3'd3;
5127
assign s1[10] = sll & s[2:0]==3'd2;
5128
assign s1[ 9] = sll & s[2:0]==3'd1;
5129
assign s1[ 8] = s[2:0]==3'd0;
5130
assign s1[ 7] = !sll & s[2:0]==3'd1;
5131
assign s1[ 6] = !sll & s[2:0]==3'd2;
5132
assign s1[ 5] = !sll & s[2:0]==3'd3;
5133
assign s1[ 4] = !sll & s[2:0]==3'd4;
5134
assign s1[ 3] = !sll & s[2:0]==3'd5;
5135
assign s1[ 2] = !sll & s[2:0]==3'd6;
5136
assign s1[ 1] = !sll & s[2:0]==3'd7;
5137
assign sign[3] = din[31] & sra;
5138
assign sign[2] = sign[3] & (&din[31:24]);
5139
assign sign[1] = sign[2] & (&din[23:16]);
5140
assign sign[0] = sign[1] & (&din[15:8]);
5141
vl_mults # ( .operand_a_width(25), .operand_b_width(16), .result_hi(14), .result_lo(7)) mult_byte3 ( .a({sign[3], {8{sign[3]}},din[31:24], din[23:16]}), .b({1'b0,s1}), .p(tmp[3]));
5142
vl_mults # ( .operand_a_width(25), .operand_b_width(16), .result_hi(14), .result_lo(7)) mult_byte2 ( .a({sign[2], din[31:24]  ,din[23:16],  din[15:8]}), .b({1'b0,s1}), .p(tmp[2]));
5143
vl_mults # ( .operand_a_width(25), .operand_b_width(16), .result_hi(14), .result_lo(7)) mult_byte1 ( .a({sign[1], din[23:16]  ,din[15:8],   din[7:0]}), .b({1'b0,s1}), .p(tmp[1]));
5144
vl_mults # ( .operand_a_width(25), .operand_b_width(16), .result_hi(14), .result_lo(7)) mult_byte0 ( .a({sign[0], din[15:8]   ,din[7:0],    8'h00}),      .b({1'b0,s1}), .p(tmp[0]));
5145
// second stage is multiplexer based
5146
// shift on byte level
5147
// mux byte 3
5148
assign dout[31:24] = (s[4:3]==2'b00) ? tmp[3] :
5149
                     (sll & s[4:3]==2'b01) ? tmp[2] :
5150
                     (sll & s[4:3]==2'b10) ? tmp[1] :
5151
                     (sll & s[4:3]==2'b11) ? tmp[0] :
5152
                     {8{sign[3]}};
5153
// mux byte 2
5154
assign dout[23:16] = (s[4:3]==2'b00) ? tmp[2] :
5155
                     (sll & s[4:3]==2'b01) ? tmp[1] :
5156
                     (sll & s[4:3]==2'b10) ? tmp[0] :
5157
                     (sll & s[4:3]==2'b11) ? {8{1'b0}} :
5158
                     (s[4:3]==2'b01) ? tmp[3] :
5159
                     {8{sign[3]}};
5160
// mux byte 1
5161
assign dout[15:8]  = (s[4:3]==2'b00) ? tmp[1] :
5162
                     (sll & s[4:3]==2'b01) ? tmp[0] :
5163
                     (sll & s[4:3]==2'b10) ? {8{1'b0}} :
5164
                     (sll & s[4:3]==2'b11) ? {8{1'b0}} :
5165
                     (s[4:3]==2'b01) ? tmp[2] :
5166
                     (s[4:3]==2'b10) ? tmp[3] :
5167
                     {8{sign[3]}};
5168
// mux byte 0
5169
assign dout[7:0]   = (s[4:3]==2'b00) ? tmp[0] :
5170
                     (sll) ?  {8{1'b0}}:
5171
                     (s[4:3]==2'b01) ? tmp[1] :
5172
                     (s[4:3]==2'b10) ? tmp[2] :
5173
                     tmp[3];
5174 149 unneback
end else begin : impl_classic
5175
reg [31:0] dout;
5176
`ifdef SYSTEMVERILOG
5177
always_comb
5178
`else
5179
always @ (din or s or opcode)
5180
`endif
5181
    case (opcode)
5182
    opcode_sll: dout = din << s;
5183
    opcode_srl: dout = din >> s;
5184 151 unneback
    opcode_sra: dout = (din >> s) | ({32{din[31]}} << (6'd32-{1'b0,s}));
5185 149 unneback
    //opcode_ror: dout = not yet implemented
5186
    default: dout = din << s;
5187
    endcase
5188
end
5189 152 unneback
endgenerate
5190 18 unneback
endmodule
5191
// logic unit
5192
// supporting the following logic functions
5193
//    a and b
5194
//    a or  b
5195
//    a xor b
5196
//    not b
5197
module vl_logic_unit( a, b, result, opcode);
5198
parameter width = 32;
5199
parameter opcode_and = 2'b00;
5200
parameter opcode_or  = 2'b01;
5201
parameter opcode_xor = 2'b10;
5202
input [width-1:0] a,b;
5203
output [width-1:0] result;
5204
input [1:0] opcode;
5205
assign result = (opcode==opcode_and) ? a & b :
5206
                (opcode==opcode_or)  ? a | b :
5207
                (opcode==opcode_xor) ? a ^ b :
5208
                b;
5209
endmodule
5210 140 unneback
module vl_arith_unit ( a, b, c_in, add_sub, sign, result, c_out, z, ovfl);
5211
parameter width = 32;
5212
parameter opcode_add = 1'b0;
5213
parameter opcode_sub = 1'b1;
5214
input [width-1:0] a,b;
5215
input c_in, add_sub, sign;
5216
output [width-1:0] result;
5217
output c_out, z, ovfl;
5218
assign {c_out,result} = {(a[width-1] & sign),a} + ({a[width-1] & sign,b} ^ {(width+1){(add_sub==opcode_sub)}}) + {{(width-1){1'b0}},(c_in | (add_sub==opcode_sub))};
5219
assign z = (result=={width{1'b0}});
5220
assign ovfl = ( a[width-1] &  b[width-1] & ~result[width-1]) |
5221
               (~a[width-1] & ~b[width-1] &  result[width-1]);
5222
endmodule
5223
module vl_count_unit (din, dout, opcode);
5224
parameter width = 32;
5225
input [width-1:0] din;
5226
output [width-1:0] dout;
5227
input opcode;
5228
integer i;
5229
wire [width/32+4:0] ff1, fl1;
5230
/*
5231
always @(din) begin
5232
    ff1 = 0; i = 0;
5233
    while (din[i] == 0 && i < width) begin // complex condition
5234
        ff1 = ff1 + 1;
5235
        i = i + 1;
5236
    end
5237
end
5238
always @(din) begin
5239
    fl1 = width; i = width-1;
5240
    while (din[i] == 0 && i >= width) begin // complex condition
5241
        fl1 = fl1 - 1;
5242
        i = i - 1;
5243
    end
5244
end
5245
*/
5246
generate
5247
if (width==32) begin
5248
    assign ff1 = din[0] ? 6'd1 :
5249
                 din[1] ? 6'd2 :
5250
                 din[2] ? 6'd3 :
5251
                 din[3] ? 6'd4 :
5252
                 din[4] ? 6'd5 :
5253
                 din[5] ? 6'd6 :
5254
                 din[6] ? 6'd7 :
5255
                 din[7] ? 6'd8 :
5256
                 din[8] ? 6'd9 :
5257
                 din[9] ? 6'd10 :
5258
                 din[10] ? 6'd11 :
5259
                 din[11] ? 6'd12 :
5260
                 din[12] ? 6'd13 :
5261
                 din[13] ? 6'd14 :
5262
                 din[14] ? 6'd15 :
5263
                 din[15] ? 6'd16 :
5264
                 din[16] ? 6'd17 :
5265
                 din[17] ? 6'd18 :
5266
                 din[18] ? 6'd19 :
5267
                 din[19] ? 6'd20 :
5268
                 din[20] ? 6'd21 :
5269
                 din[21] ? 6'd22 :
5270
                 din[22] ? 6'd23 :
5271
                 din[23] ? 6'd24 :
5272
                 din[24] ? 6'd25 :
5273
                 din[25] ? 6'd26 :
5274
                 din[26] ? 6'd27 :
5275
                 din[27] ? 6'd28 :
5276
                 din[28] ? 6'd29 :
5277
                 din[29] ? 6'd30 :
5278
                 din[30] ? 6'd31 :
5279
                 din[31] ? 6'd32 :
5280
                 6'd0;
5281
    assign fl1 = din[31] ? 6'd32 :
5282
                 din[30] ? 6'd31 :
5283
                 din[29] ? 6'd30 :
5284
                 din[28] ? 6'd29 :
5285
                 din[27] ? 6'd28 :
5286
                 din[26] ? 6'd27 :
5287
                 din[25] ? 6'd26 :
5288
                 din[24] ? 6'd25 :
5289
                 din[23] ? 6'd24 :
5290
                 din[22] ? 6'd23 :
5291
                 din[21] ? 6'd22 :
5292
                 din[20] ? 6'd21 :
5293
                 din[19] ? 6'd20 :
5294
                 din[18] ? 6'd19 :
5295
                 din[17] ? 6'd18 :
5296
                 din[16] ? 6'd17 :
5297
                 din[15] ? 6'd16 :
5298
                 din[14] ? 6'd15 :
5299
                 din[13] ? 6'd14 :
5300
                 din[12] ? 6'd13 :
5301
                 din[11] ? 6'd12 :
5302
                 din[10] ? 6'd11 :
5303
                 din[9] ? 6'd10 :
5304
                 din[8] ? 6'd9 :
5305
                 din[7] ? 6'd8 :
5306
                 din[6] ? 6'd7 :
5307
                 din[5] ? 6'd6 :
5308
                 din[4] ? 6'd5 :
5309
                 din[3] ? 6'd4 :
5310
                 din[2] ? 6'd3 :
5311
                 din[1] ? 6'd2 :
5312
                 din[0] ? 6'd1 :
5313
                 6'd0;
5314
    assign dout = (!opcode) ? {{26{1'b0}}, ff1} : {{26{1'b0}}, fl1};
5315
end
5316
endgenerate
5317
generate
5318
if (width==64) begin
5319
    assign ff1 = 7'd0;
5320
    assign fl1 = 7'd0;
5321
    assign dout = (!opcode) ? {{57{1'b0}}, ff1} : {{57{1'b0}}, fl1};
5322
end
5323
endgenerate
5324
endmodule
5325
module vl_ext_unit ( a, b, F, result, opcode);
5326
parameter width = 32;
5327
input [width-1:0] a, b;
5328
input F;
5329
output reg [width-1:0] result;
5330
input [2:0] opcode;
5331
generate
5332
if (width==32) begin
5333
always @ (a or b or F or opcode)
5334
begin
5335
    case (opcode)
5336
    3'b000: result = {{24{1'b0}},a[7:0]};
5337
    3'b001: result = {{24{a[7]}},a[7:0]};
5338
    3'b010: result = {{16{1'b0}},a[7:0]};
5339
    3'b011: result = {{16{a[15]}},a[15:0]};
5340
    3'b110: result = (F) ? a : b;
5341
    default: result = {b[15:0],16'h0000};
5342
    endcase
5343
end
5344
end
5345
endgenerate
5346
generate
5347
if (width==64) begin
5348
always @ (a or b or F or opcode)
5349
begin
5350
    case (opcode)
5351
    3'b000: result = {{56{1'b0}},a[7:0]};
5352
    3'b001: result = {{56{a[7]}},a[7:0]};
5353
    3'b010: result = {{48{1'b0}},a[7:0]};
5354
    3'b011: result = {{48{a[15]}},a[15:0]};
5355
    3'b110: result = (F) ? a : b;
5356
    default: result = {32'h00000000,b[15:0],16'h0000};
5357
    endcase
5358
end
5359
end
5360
endgenerate
5361
endmodule

powered by: WebSVN 2.1.0

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