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

Subversion Repositories versatile_library

[/] [versatile_library/] [trunk/] [rtl/] [verilog/] [versatile_library_altera.v] - Blame information for rev 137

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

Line No. Rev Author Line
1 60 unneback
// default SYN_KEEP definition
2 136 unneback
///////////////////////////////////////
3
// dependencies
4
///////////////////////////////////////
5 97 unneback
// size to width
6 6 unneback
//////////////////////////////////////////////////////////////////////
7
////                                                              ////
8
////  Versatile library, clock and reset                          ////
9
////                                                              ////
10
////  Description                                                 ////
11
////  Logic related to clock and reset                            ////
12
////                                                              ////
13
////                                                              ////
14
////  To Do:                                                      ////
15
////   - add more different registers                             ////
16
////                                                              ////
17
////  Author(s):                                                  ////
18
////      - Michael Unneback, unneback@opencores.org              ////
19
////        ORSoC AB                                              ////
20
////                                                              ////
21
//////////////////////////////////////////////////////////////////////
22
////                                                              ////
23
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
24
////                                                              ////
25
//// This source file may be used and distributed without         ////
26
//// restriction provided that this copyright statement is not    ////
27
//// removed from the file and that any derivative work contains  ////
28
//// the original copyright notice and the associated disclaimer. ////
29
////                                                              ////
30
//// This source file is free software; you can redistribute it   ////
31
//// and/or modify it under the terms of the GNU Lesser General   ////
32
//// Public License as published by the Free Software Foundation; ////
33
//// either version 2.1 of the License, or (at your option) any   ////
34
//// later version.                                               ////
35
////                                                              ////
36
//// This source is distributed in the hope that it will be       ////
37
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
38
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
39
//// PURPOSE.  See the GNU Lesser General Public License for more ////
40
//// details.                                                     ////
41
////                                                              ////
42
//// You should have received a copy of the GNU Lesser General    ////
43
//// Public License along with this source; if not, download it   ////
44
//// from http://www.opencores.org/lgpl.shtml                     ////
45
////                                                              ////
46
//////////////////////////////////////////////////////////////////////
47 21 unneback
//altera
48 33 unneback
module vl_gbuf ( i, o);
49
input i;
50
output o;
51
assign o = i;
52
endmodule
53 6 unneback
 // ALTERA
54
 //ACTEL
55
// sync reset
56 17 unneback
// input active lo async reset, normally from external reset generator and/or switch
57 6 unneback
// output active high global reset sync with two DFFs 
58
`timescale 1 ns/100 ps
59
module vl_sync_rst ( rst_n_i, rst_o, clk);
60
input rst_n_i, clk;
61
output rst_o;
62 18 unneback
reg [1:0] tmp;
63 6 unneback
always @ (posedge clk or negedge rst_n_i)
64
if (!rst_n_i)
65 17 unneback
        tmp <= 2'b11;
66 6 unneback
else
67 33 unneback
        tmp <= {1'b0,tmp[1]};
68 17 unneback
vl_gbuf buf_i0( .i(tmp[0]), .o(rst_o));
69 6 unneback
endmodule
70
// vl_pll
71 32 unneback
///////////////////////////////////////////////////////////////////////////////
72
`timescale 1 ps/1 ps
73
module vl_pll ( clk_i, rst_n_i, lock, clk_o, rst_o);
74
parameter index = 0;
75
parameter number_of_clk = 1;
76
parameter period_time_0 = 20000;
77
parameter period_time_1 = 20000;
78
parameter period_time_2 = 20000;
79
parameter period_time_3 = 20000;
80
parameter period_time_4 = 20000;
81
parameter lock_delay = 2000000;
82
input clk_i, rst_n_i;
83
output lock;
84
output reg [0:number_of_clk-1] clk_o;
85
output [0:number_of_clk-1] rst_o;
86 33 unneback
`ifdef SIM_PLL
87 32 unneback
always
88
     #((period_time_0)/2) clk_o[0] <=  (!rst_n_i) ? 0 : ~clk_o[0];
89
generate if (number_of_clk > 1)
90
always
91
     #((period_time_1)/2) clk_o[1] <=  (!rst_n_i) ? 0 : ~clk_o[1];
92
endgenerate
93
generate if (number_of_clk > 2)
94
always
95
     #((period_time_2)/2) clk_o[2] <=  (!rst_n_i) ? 0 : ~clk_o[2];
96
endgenerate
97 33 unneback
generate if (number_of_clk > 3)
98 32 unneback
always
99
     #((period_time_3)/2) clk_o[3] <=  (!rst_n_i) ? 0 : ~clk_o[3];
100
endgenerate
101 33 unneback
generate if (number_of_clk > 4)
102 32 unneback
always
103
     #((period_time_4)/2) clk_o[4] <=  (!rst_n_i) ? 0 : ~clk_o[4];
104
endgenerate
105
genvar i;
106
generate for (i=0;i<number_of_clk;i=i+1) begin: clock
107
     vl_sync_rst rst_i0 ( .rst_n_i(rst_n_i | lock), .rst_o(rst_o[i]), .clk(clk_o[i]));
108
end
109
endgenerate
110 33 unneback
//assign #lock_delay lock = rst_n_i;
111
assign lock = rst_n_i;
112 32 unneback
endmodule
113 33 unneback
`else
114
`ifdef VL_PLL0
115
`ifdef VL_PLL0_CLK1
116
    pll0 pll0_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]));
117
`endif
118
`ifdef VL_PLL0_CLK2
119
    pll0 pll0_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]));
120
`endif
121
`ifdef VL_PLL0_CLK3
122
    pll0 pll0_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]), .c2(clk_o[2]));
123
`endif
124
`ifdef VL_PLL0_CLK4
125
    pll0 pll0_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]), .c2(clk_o[2]), .c3(clk_o[3]));
126
`endif
127
`ifdef VL_PLL0_CLK5
128
    pll0 pll0_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]), .c2(clk_o[2]), .c3(clk_o[3]), .c4(clk_o[4]));
129
`endif
130
`endif
131
`ifdef VL_PLL1
132
`ifdef VL_PLL1_CLK1
133
    pll1 pll1_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]));
134
`endif
135
`ifdef VL_PLL1_CLK2
136
    pll1 pll1_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]));
137
`endif
138
`ifdef VL_PLL1_CLK3
139
    pll1 pll1_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]), .c2(clk_o[2]));
140
`endif
141
`ifdef VL_PLL1_CLK4
142
    pll1 pll1_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]), .c2(clk_o[2]), .c3(clk_o[3]));
143
`endif
144
`ifdef VL_PLL1_CLK5
145
    pll1 pll1_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]), .c2(clk_o[2]), .c3(clk_o[3]), .c4(clk_o[4]));
146
`endif
147
`endif
148
`ifdef VL_PLL2
149
`ifdef VL_PLL2_CLK1
150
    pll2 pll2_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]));
151
`endif
152
`ifdef VL_PLL2_CLK2
153
    pll2 pll2_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]));
154
`endif
155
`ifdef VL_PLL2_CLK3
156
    pll2 pll2_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]), .c2(clk_o[2]));
157
`endif
158
`ifdef VL_PLL2_CLK4
159
    pll2 pll2_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]), .c2(clk_o[2]), .c3(clk_o[3]));
160
`endif
161
`ifdef VL_PLL2_CLK5
162
    pll2 pll2_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]), .c2(clk_o[2]), .c3(clk_o[3]), .c4(clk_o[4]));
163
`endif
164
`endif
165
`ifdef VL_PLL3
166
`ifdef VL_PLL3_CLK1
167
    pll3 pll3_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]));
168
`endif
169
`ifdef VL_PLL3_CLK2
170
    pll3 pll3_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]));
171
`endif
172
`ifdef VL_PLL3_CLK3
173
    pll3 pll3_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]), .c2(clk_o[2]));
174
`endif
175
`ifdef VL_PLL3_CLK4
176
    pll3 pll3_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]), .c2(clk_o[2]), .c3(clk_o[3]));
177
`endif
178
`ifdef VL_PLL3_CLK5
179
    pll3 pll3_i0 (.areset(rst_n_i), .inclk0(clk_i), .locked(lock), .c0(clk_o[0]), .c1(clk_o[1]), .c2(clk_o[2]), .c3(clk_o[3]), .c4(clk_o[4]));
180
`endif
181
`endif
182 32 unneback
genvar i;
183
generate for (i=0;i<number_of_clk;i=i+1) begin: clock
184 40 unneback
        vl_sync_rst rst_i0 ( .rst_n_i(rst_n_i | lock), .rst_o(rst_o[i]), .clk(clk_o[i]));
185 32 unneback
end
186
endgenerate
187
endmodule
188 33 unneback
`endif
189 32 unneback
///////////////////////////////////////////////////////////////////////////////
190 6 unneback
 //altera
191
 //actel
192
//////////////////////////////////////////////////////////////////////
193
////                                                              ////
194
////  Versatile library, registers                                ////
195
////                                                              ////
196
////  Description                                                 ////
197
////  Different type of registers                                 ////
198
////                                                              ////
199
////                                                              ////
200
////  To Do:                                                      ////
201
////   - add more different registers                             ////
202
////                                                              ////
203
////  Author(s):                                                  ////
204
////      - Michael Unneback, unneback@opencores.org              ////
205
////        ORSoC AB                                              ////
206
////                                                              ////
207
//////////////////////////////////////////////////////////////////////
208
////                                                              ////
209
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
210
////                                                              ////
211
//// This source file may be used and distributed without         ////
212
//// restriction provided that this copyright statement is not    ////
213
//// removed from the file and that any derivative work contains  ////
214
//// the original copyright notice and the associated disclaimer. ////
215
////                                                              ////
216
//// This source file is free software; you can redistribute it   ////
217
//// and/or modify it under the terms of the GNU Lesser General   ////
218
//// Public License as published by the Free Software Foundation; ////
219
//// either version 2.1 of the License, or (at your option) any   ////
220
//// later version.                                               ////
221
////                                                              ////
222
//// This source is distributed in the hope that it will be       ////
223
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
224
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
225
//// PURPOSE.  See the GNU Lesser General Public License for more ////
226
//// details.                                                     ////
227
////                                                              ////
228
//// You should have received a copy of the GNU Lesser General    ////
229
//// Public License along with this source; if not, download it   ////
230
//// from http://www.opencores.org/lgpl.shtml                     ////
231
////                                                              ////
232
//////////////////////////////////////////////////////////////////////
233 18 unneback
module vl_dff ( d, q, clk, rst);
234 6 unneback
        parameter width = 1;
235
        parameter reset_value = 0;
236
        input [width-1:0] d;
237
        input clk, rst;
238
        output reg [width-1:0] q;
239
        always @ (posedge clk or posedge rst)
240
        if (rst)
241
                q <= reset_value;
242
        else
243
                q <= d;
244
endmodule
245 18 unneback
module vl_dff_array ( d, q, clk, rst);
246 6 unneback
        parameter width = 1;
247
        parameter depth = 2;
248
        parameter reset_value = 1'b0;
249
        input [width-1:0] d;
250
        input clk, rst;
251
        output [width-1:0] q;
252
        reg  [0:depth-1] q_tmp [width-1:0];
253
        integer i;
254
        always @ (posedge clk or posedge rst)
255
        if (rst) begin
256
            for (i=0;i<depth;i=i+1)
257
                q_tmp[i] <= {width{reset_value}};
258
        end else begin
259
            q_tmp[0] <= d;
260
            for (i=1;i<depth;i=i+1)
261
                q_tmp[i] <= q_tmp[i-1];
262
        end
263
    assign q = q_tmp[depth-1];
264
endmodule
265 18 unneback
module vl_dff_ce ( d, ce, q, clk, rst);
266 6 unneback
        parameter width = 1;
267
        parameter reset_value = 0;
268
        input [width-1:0] d;
269
        input ce, clk, rst;
270
        output reg [width-1:0] q;
271
        always @ (posedge clk or posedge rst)
272
        if (rst)
273
                q <= reset_value;
274
        else
275
                if (ce)
276
                        q <= d;
277
endmodule
278 18 unneback
module vl_dff_ce_clear ( d, ce, clear, q, clk, rst);
279 8 unneback
        parameter width = 1;
280
        parameter reset_value = 0;
281
        input [width-1:0] d;
282 10 unneback
        input ce, clear, clk, rst;
283 8 unneback
        output reg [width-1:0] q;
284
        always @ (posedge clk or posedge rst)
285
        if (rst)
286
            q <= reset_value;
287
        else
288
            if (ce)
289
                if (clear)
290
                    q <= {width{1'b0}};
291
                else
292
                    q <= d;
293
endmodule
294 24 unneback
module vl_dff_ce_set ( d, ce, set, q, clk, rst);
295
        parameter width = 1;
296
        parameter reset_value = 0;
297
        input [width-1:0] d;
298
        input ce, set, clk, rst;
299
        output reg [width-1:0] q;
300
        always @ (posedge clk or posedge rst)
301
        if (rst)
302
            q <= reset_value;
303
        else
304
            if (ce)
305
                if (set)
306
                    q <= {width{1'b1}};
307
                else
308
                    q <= d;
309
endmodule
310 29 unneback
module vl_spr ( sp, r, q, clk, rst);
311 64 unneback
        //parameter width = 1;
312
        parameter reset_value = 1'b0;
313 29 unneback
        input sp, r;
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 (sp)
321
                q <= 1'b1;
322
            else if (r)
323
                q <= 1'b0;
324
endmodule
325
module vl_srp ( s, rp, q, clk, rst);
326
        parameter width = 1;
327
        parameter reset_value = 0;
328
        input s, rp;
329
        output reg q;
330
        input clk, rst;
331
        always @ (posedge clk or posedge rst)
332
        if (rst)
333
            q <= reset_value;
334
        else
335
            if (rp)
336
                q <= 1'b0;
337
            else if (s)
338
                q <= 1'b1;
339
endmodule
340 6 unneback
// megafunction wizard: %LPM_FF%
341
// GENERATION: STANDARD
342
// VERSION: WM1.0
343
// MODULE: lpm_ff 
344
// ============================================================
345
// File Name: dff_sr.v
346
// Megafunction Name(s):
347
//                      lpm_ff
348
//
349
// Simulation Library Files(s):
350
//                      lpm
351
// ============================================================
352
// ************************************************************
353
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
354
//
355
// 9.1 Build 304 01/25/2010 SP 1 SJ Full Version
356
// ************************************************************
357
//Copyright (C) 1991-2010 Altera Corporation
358
//Your use of Altera Corporation's design tools, logic functions 
359
//and other software and tools, and its AMPP partner logic 
360
//functions, and any output files from any of the foregoing 
361
//(including device programming or simulation files), and any 
362
//associated documentation or information are expressly subject 
363
//to the terms and conditions of the Altera Program License 
364
//Subscription Agreement, Altera MegaCore Function License 
365
//Agreement, or other applicable license agreement, including, 
366
//without limitation, that your use is for the sole purpose of 
367
//programming logic devices manufactured by Altera and sold by 
368
//Altera or its authorized distributors.  Please refer to the 
369
//applicable agreement for further details.
370
// synopsys translate_off
371
`timescale 1 ps / 1 ps
372
// synopsys translate_on
373 18 unneback
module vl_dff_sr (
374 6 unneback
        aclr,
375
        aset,
376
        clock,
377
        data,
378
        q);
379
        input     aclr;
380
        input     aset;
381
        input     clock;
382
        input     data;
383
        output    q;
384
        wire [0:0] sub_wire0;
385
        wire [0:0] sub_wire1 = sub_wire0[0:0];
386
        wire  q = sub_wire1;
387
        wire  sub_wire2 = data;
388
        wire  sub_wire3 = sub_wire2;
389
        lpm_ff  lpm_ff_component (
390
                                .aclr (aclr),
391
                                .clock (clock),
392
                                .data (sub_wire3),
393
                                .aset (aset),
394
                                .q (sub_wire0)
395
                                // synopsys translate_off
396
                                ,
397
                                .aload (),
398
                                .enable (),
399
                                .sclr (),
400
                                .sload (),
401
                                .sset ()
402
                                // synopsys translate_on
403
                                );
404
        defparam
405
                lpm_ff_component.lpm_fftype = "DFF",
406
                lpm_ff_component.lpm_type = "LPM_FF",
407
                lpm_ff_component.lpm_width = 1;
408
endmodule
409
// ============================================================
410
// CNX file retrieval info
411
// ============================================================
412
// Retrieval info: PRIVATE: ACLR NUMERIC "1"
413
// Retrieval info: PRIVATE: ALOAD NUMERIC "0"
414
// Retrieval info: PRIVATE: ASET NUMERIC "1"
415
// Retrieval info: PRIVATE: ASET_ALL1 NUMERIC "1"
416
// Retrieval info: PRIVATE: CLK_EN NUMERIC "0"
417
// Retrieval info: PRIVATE: DFF NUMERIC "1"
418
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
419
// Retrieval info: PRIVATE: SCLR NUMERIC "0"
420
// Retrieval info: PRIVATE: SLOAD NUMERIC "0"
421
// Retrieval info: PRIVATE: SSET NUMERIC "0"
422
// Retrieval info: PRIVATE: SSET_ALL1 NUMERIC "1"
423
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
424
// Retrieval info: PRIVATE: UseTFFdataPort NUMERIC "0"
425
// Retrieval info: PRIVATE: nBit NUMERIC "1"
426
// Retrieval info: CONSTANT: LPM_FFTYPE STRING "DFF"
427
// Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_FF"
428
// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "1"
429
// Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT NODEFVAL aclr
430
// Retrieval info: USED_PORT: aset 0 0 0 0 INPUT NODEFVAL aset
431
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
432
// Retrieval info: USED_PORT: data 0 0 0 0 INPUT NODEFVAL data
433
// Retrieval info: USED_PORT: q 0 0 0 0 OUTPUT NODEFVAL q
434
// Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
435
// Retrieval info: CONNECT: q 0 0 0 0 @q 0 0 1 0
436
// Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0
437
// Retrieval info: CONNECT: @aset 0 0 0 0 aset 0 0 0 0
438
// Retrieval info: CONNECT: @data 0 0 1 0 data 0 0 0 0
439
// Retrieval info: LIBRARY: lpm lpm.lpm_components.all
440
// Retrieval info: GEN_FILE: TYPE_NORMAL dff_sr.v TRUE
441
// Retrieval info: GEN_FILE: TYPE_NORMAL dff_sr.inc FALSE
442
// Retrieval info: GEN_FILE: TYPE_NORMAL dff_sr.cmp FALSE
443
// Retrieval info: GEN_FILE: TYPE_NORMAL dff_sr.bsf FALSE
444
// Retrieval info: GEN_FILE: TYPE_NORMAL dff_sr_inst.v FALSE
445
// Retrieval info: GEN_FILE: TYPE_NORMAL dff_sr_bb.v FALSE
446
// Retrieval info: LIB_FILE: lpm
447
// LATCH
448
// For targtes not supporting LATCH use dff_sr with clk=1 and data=1
449 18 unneback
module vl_latch ( d, le, q, clk);
450 6 unneback
input d, le;
451
output q;
452
input clk;
453
dff_sr i0 (.aclr(), .aset(), .clock(1'b1), .data(1'b1), .q(q));
454
endmodule
455 18 unneback
module vl_shreg ( d, q, clk, rst);
456 17 unneback
parameter depth = 10;
457
input d;
458
output q;
459
input clk, rst;
460
reg [1:depth] dffs;
461
always @ (posedge clk or posedge rst)
462
if (rst)
463
    dffs <= {depth{1'b0}};
464
else
465
    dffs <= {d,dffs[1:depth-1]};
466
assign q = dffs[depth];
467
endmodule
468 18 unneback
module vl_shreg_ce ( d, ce, q, clk, rst);
469 17 unneback
parameter depth = 10;
470
input d, ce;
471
output q;
472
input clk, rst;
473
reg [1:depth] dffs;
474
always @ (posedge clk or posedge rst)
475
if (rst)
476
    dffs <= {depth{1'b0}};
477
else
478
    if (ce)
479
        dffs <= {d,dffs[1:depth-1]};
480
assign q = dffs[depth];
481
endmodule
482 18 unneback
module vl_delay ( d, q, clk, rst);
483 15 unneback
parameter depth = 10;
484
input d;
485
output q;
486
input clk, rst;
487
reg [1:depth] dffs;
488
always @ (posedge clk or posedge rst)
489
if (rst)
490
    dffs <= {depth{1'b0}};
491
else
492
    dffs <= {d,dffs[1:depth-1]};
493
assign q = dffs[depth];
494
endmodule
495 18 unneback
module vl_delay_emptyflag ( d, q, emptyflag, clk, rst);
496 17 unneback
parameter depth = 10;
497
input d;
498
output q, emptyflag;
499
input clk, rst;
500
reg [1:depth] dffs;
501
always @ (posedge clk or posedge rst)
502
if (rst)
503
    dffs <= {depth{1'b0}};
504
else
505
    dffs <= {d,dffs[1:depth-1]};
506
assign q = dffs[depth];
507
assign emptyflag = !(|dffs);
508
endmodule
509 98 unneback
module vl_pulse2toggle ( pl, q, clk, rst);
510 94 unneback
input pl;
511 98 unneback
output reg q;
512 94 unneback
input clk, rst;
513
always @ (posedge clk or posedge rst)
514
if (rst)
515
    q <= 1'b0;
516
else
517
    q <= pl ^ q;
518
endmodule
519 98 unneback
module vl_toggle2pulse (d, pl, clk, rst);
520 94 unneback
input d;
521
output pl;
522
input clk, rst;
523
reg dff;
524
always @ (posedge clk or posedge rst)
525
if (rst)
526
    dff <= 1'b0;
527
else
528
    dff <= d;
529 98 unneback
assign pl = d ^ dff;
530 94 unneback
endmodule
531
module vl_synchronizer (d, q, clk, rst);
532
input d;
533
output reg q;
534 116 unneback
input clk, rst;
535 94 unneback
reg dff;
536
always @ (posedge clk or posedge rst)
537
if (rst)
538 100 unneback
    {q,dff} <= 2'b00;
539 94 unneback
else
540 100 unneback
    {q,dff} <= {dff,d};
541 94 unneback
endmodule
542 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);
543 94 unneback
input start_pl;
544
output take_it_pl;
545
input take_it_grant_pl; // note: connect to take_it_pl to generate automatic ack
546
output got_it_pl;
547
input clk_src, rst_src;
548
input clk_dst, rst_dst;
549
wire take_it_tg, take_it_tg_sync;
550
wire got_it_tg, got_it_tg_sync;
551
// src -> dst
552
vl_pulse2toggle p2t0 (
553
    .pl(start_pl),
554
    .q(take_it_tg),
555
    .clk(clk_src),
556
    .rst(rst_src));
557
vl_synchronizer sync0 (
558
    .d(take_it_tg),
559
    .q(take_it_tg_sync),
560
    .clk(clk_dst),
561
    .rst(rst_dst));
562
vl_toggle2pulse t2p0 (
563 100 unneback
    .d(take_it_tg_sync),
564 94 unneback
    .pl(take_it_pl),
565
    .clk(clk_dst),
566
    .rst(rst_dst));
567
// dst -> src
568 98 unneback
vl_pulse2toggle p2t1 (
569 94 unneback
    .pl(take_it_grant_pl),
570
    .q(got_it_tg),
571
    .clk(clk_dst),
572
    .rst(rst_dst));
573
vl_synchronizer sync1 (
574
    .d(got_it_tg),
575
    .q(got_it_tg_sync),
576
    .clk(clk_src),
577
    .rst(rst_src));
578
vl_toggle2pulse t2p1 (
579 100 unneback
    .d(got_it_tg_sync),
580 94 unneback
    .pl(got_it_pl),
581
    .clk(clk_src),
582
    .rst(rst_src));
583
endmodule
584 6 unneback
//////////////////////////////////////////////////////////////////////
585
////                                                              ////
586 18 unneback
////  Logic functions                                             ////
587
////                                                              ////
588
////  Description                                                 ////
589
////  Logic functions such as multiplexers                        ////
590
////                                                              ////
591
////                                                              ////
592
////  To Do:                                                      ////
593
////   -                                                          ////
594
////                                                              ////
595
////  Author(s):                                                  ////
596
////      - Michael Unneback, unneback@opencores.org              ////
597
////        ORSoC AB                                              ////
598
////                                                              ////
599
//////////////////////////////////////////////////////////////////////
600
////                                                              ////
601
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
602
////                                                              ////
603
//// This source file may be used and distributed without         ////
604
//// restriction provided that this copyright statement is not    ////
605
//// removed from the file and that any derivative work contains  ////
606
//// the original copyright notice and the associated disclaimer. ////
607
////                                                              ////
608
//// This source file is free software; you can redistribute it   ////
609
//// and/or modify it under the terms of the GNU Lesser General   ////
610
//// Public License as published by the Free Software Foundation; ////
611
//// either version 2.1 of the License, or (at your option) any   ////
612
//// later version.                                               ////
613
////                                                              ////
614
//// This source is distributed in the hope that it will be       ////
615
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
616
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
617
//// PURPOSE.  See the GNU Lesser General Public License for more ////
618
//// details.                                                     ////
619
////                                                              ////
620
//// You should have received a copy of the GNU Lesser General    ////
621
//// Public License along with this source; if not, download it   ////
622
//// from http://www.opencores.org/lgpl.shtml                     ////
623
////                                                              ////
624
//////////////////////////////////////////////////////////////////////
625 36 unneback
module vl_mux_andor ( a, sel, dout);
626
parameter width = 32;
627
parameter nr_of_ports = 4;
628
input [nr_of_ports*width-1:0] a;
629
input [nr_of_ports-1:0] sel;
630
output reg [width-1:0] dout;
631 38 unneback
integer i,j;
632 36 unneback
always @ (a, sel)
633
begin
634
    dout = a[width-1:0] & {width{sel[0]}};
635 42 unneback
    for (i=1;i<nr_of_ports;i=i+1)
636
        for (j=0;j<width;j=j+1)
637
            dout[j] = (a[i*width + j] & sel[i]) | dout[j];
638 36 unneback
end
639
endmodule
640 34 unneback
module vl_mux2_andor ( a1, a0, sel, dout);
641
parameter width = 32;
642 35 unneback
localparam nr_of_ports = 2;
643 34 unneback
input [width-1:0] a1, a0;
644
input [nr_of_ports-1:0] sel;
645
output [width-1:0] dout;
646 36 unneback
vl_mux_andor
647 38 unneback
    # ( .width(width), .nr_of_ports(nr_of_ports))
648 36 unneback
    mux0( .a({a1,a0}), .sel(sel), .dout(dout));
649 34 unneback
endmodule
650
module vl_mux3_andor ( a2, a1, a0, sel, dout);
651
parameter width = 32;
652 35 unneback
localparam nr_of_ports = 3;
653 34 unneback
input [width-1:0] a2, a1, a0;
654
input [nr_of_ports-1:0] sel;
655
output [width-1:0] dout;
656 36 unneback
vl_mux_andor
657 38 unneback
    # ( .width(width), .nr_of_ports(nr_of_ports))
658 36 unneback
    mux0( .a({a2,a1,a0}), .sel(sel), .dout(dout));
659 34 unneback
endmodule
660 18 unneback
module vl_mux4_andor ( a3, a2, a1, a0, sel, dout);
661
parameter width = 32;
662 35 unneback
localparam nr_of_ports = 4;
663 18 unneback
input [width-1:0] a3, a2, a1, a0;
664
input [nr_of_ports-1:0] sel;
665 22 unneback
output [width-1:0] dout;
666 36 unneback
vl_mux_andor
667 38 unneback
    # ( .width(width), .nr_of_ports(nr_of_ports))
668 36 unneback
    mux0( .a({a3,a2,a1,a0}), .sel(sel), .dout(dout));
669 18 unneback
endmodule
670
module vl_mux5_andor ( a4, a3, a2, a1, a0, sel, dout);
671
parameter width = 32;
672 35 unneback
localparam nr_of_ports = 5;
673 18 unneback
input [width-1:0] a4, a3, a2, a1, a0;
674
input [nr_of_ports-1:0] sel;
675 22 unneback
output [width-1:0] dout;
676 36 unneback
vl_mux_andor
677 38 unneback
    # ( .width(width), .nr_of_ports(nr_of_ports))
678 36 unneback
    mux0( .a({a4,a3,a2,a1,a0}), .sel(sel), .dout(dout));
679 18 unneback
endmodule
680
module vl_mux6_andor ( a5, a4, a3, a2, a1, a0, sel, dout);
681
parameter width = 32;
682 35 unneback
localparam nr_of_ports = 6;
683 18 unneback
input [width-1:0] a5, a4, a3, a2, a1, a0;
684
input [nr_of_ports-1:0] sel;
685 22 unneback
output [width-1:0] dout;
686 36 unneback
vl_mux_andor
687 38 unneback
    # ( .width(width), .nr_of_ports(nr_of_ports))
688 36 unneback
    mux0( .a({a5,a4,a3,a2,a1,a0}), .sel(sel), .dout(dout));
689 18 unneback
endmodule
690 43 unneback
module vl_parity_generate (data, parity);
691
parameter word_size = 32;
692
parameter chunk_size = 8;
693
parameter parity_type = 1'b0; // 0 - even, 1 - odd parity
694
input [word_size-1:0] data;
695
output reg [word_size/chunk_size-1:0] parity;
696
integer i,j;
697
always @ (data)
698
for (i=0;i<word_size/chunk_size;i=i+1) begin
699
    parity[i] = parity_type;
700
    for (j=0;j<chunk_size;j=j+1) begin
701 46 unneback
        parity[i] = data[i*chunk_size+j] ^ parity[i];
702 43 unneback
    end
703
end
704
endmodule
705
module vl_parity_check( data, parity, parity_error);
706
parameter word_size = 32;
707
parameter chunk_size = 8;
708
parameter parity_type = 1'b0; // 0 - even, 1 - odd parity
709
input [word_size-1:0] data;
710
input [word_size/chunk_size-1:0] parity;
711
output parity_error;
712 44 unneback
reg [word_size/chunk_size-1:0] error_flag;
713 43 unneback
integer i,j;
714
always @ (data or parity)
715
for (i=0;i<word_size/chunk_size;i=i+1) begin
716
    error_flag[i] = parity[i] ^ parity_type;
717
    for (j=0;j<chunk_size;j=j+1) begin
718 46 unneback
        error_flag[i] = data[i*chunk_size+j] ^ error_flag[i];
719 43 unneback
    end
720
end
721
assign parity_error = |error_flag;
722
endmodule
723 18 unneback
//////////////////////////////////////////////////////////////////////
724
////                                                              ////
725 44 unneback
////  IO functions                                                ////
726
////                                                              ////
727
////  Description                                                 ////
728
////  IO functions such as IOB flip-flops                         ////
729
////                                                              ////
730
////                                                              ////
731
////  To Do:                                                      ////
732
////   -                                                          ////
733
////                                                              ////
734
////  Author(s):                                                  ////
735
////      - Michael Unneback, unneback@opencores.org              ////
736
////        ORSoC AB                                              ////
737
////                                                              ////
738
//////////////////////////////////////////////////////////////////////
739
////                                                              ////
740
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
741
////                                                              ////
742
//// This source file may be used and distributed without         ////
743
//// restriction provided that this copyright statement is not    ////
744
//// removed from the file and that any derivative work contains  ////
745
//// the original copyright notice and the associated disclaimer. ////
746
////                                                              ////
747
//// This source file is free software; you can redistribute it   ////
748
//// and/or modify it under the terms of the GNU Lesser General   ////
749
//// Public License as published by the Free Software Foundation; ////
750
//// either version 2.1 of the License, or (at your option) any   ////
751
//// later version.                                               ////
752
////                                                              ////
753
//// This source is distributed in the hope that it will be       ////
754
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
755
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
756
//// PURPOSE.  See the GNU Lesser General Public License for more ////
757
//// details.                                                     ////
758
////                                                              ////
759
//// You should have received a copy of the GNU Lesser General    ////
760
//// Public License along with this source; if not, download it   ////
761
//// from http://www.opencores.org/lgpl.shtml                     ////
762
////                                                              ////
763
//////////////////////////////////////////////////////////////////////
764 45 unneback
`timescale 1ns/1ns
765 44 unneback
module vl_o_dff (d_i, o_pad, clk, rst);
766
parameter width = 1;
767 45 unneback
parameter reset_value = {width{1'b0}};
768
input  [width-1:0]  d_i;
769 44 unneback
output [width-1:0] o_pad;
770
input clk, rst;
771 60 unneback
wire [width-1:0] d_i_int /*synthesis syn_keep = 1*/;
772 45 unneback
reg  [width-1:0] o_pad_int;
773 44 unneback
assign d_i_int = d_i;
774
genvar i;
775 45 unneback
generate
776 136 unneback
for (i=0;i<width;i=i+1) begin : dffs
777 44 unneback
    always @ (posedge clk or posedge rst)
778
    if (rst)
779 45 unneback
        o_pad_int[i] <= reset_value[i];
780 44 unneback
    else
781 45 unneback
        o_pad_int[i] <= d_i_int[i];
782
    assign #1 o_pad[i] = o_pad_int[i];
783 44 unneback
end
784
endgenerate
785
endmodule
786 45 unneback
`timescale 1ns/1ns
787 44 unneback
module vl_io_dff_oe ( d_i, d_o, oe, io_pad, clk, rst);
788
parameter width = 1;
789
input  [width-1:0] d_o;
790
output reg [width-1:0] d_i;
791
input oe;
792
inout [width-1:0] io_pad;
793
input clk, rst;
794 60 unneback
wire [width-1:0] oe_d /*synthesis syn_keep = 1*/;
795 44 unneback
reg [width-1:0] oe_q;
796
reg [width-1:0] d_o_q;
797
assign oe_d = {width{oe}};
798
genvar i;
799
generate
800 136 unneback
for (i=0;i<width;i=i+1) begin : dffs
801 44 unneback
    always @ (posedge clk or posedge rst)
802
    if (rst)
803
        oe_q[i] <= 1'b0;
804
    else
805
        oe_q[i] <= oe_d[i];
806
    always @ (posedge clk or posedge rst)
807
    if (rst)
808
        d_o_q[i] <= 1'b0;
809
    else
810
        d_o_q[i] <= d_o[i];
811
    always @ (posedge clk or posedge rst)
812
    if (rst)
813
        d_i[i] <= 1'b0;
814
    else
815
        d_i[i] <= io_pad[i];
816 45 unneback
    assign #1 io_pad[i] = (oe_q[i]) ? d_o_q[i] : 1'bz;
817 44 unneback
end
818
endgenerate
819
endmodule
820 136 unneback
module vl_o_ddr (d_h_i, d_l_i, o_pad, clk, rst);
821
parameter width = 1;
822
input  [width-1:0] d_h_i, d_l_i;
823
output [width-1:0] o_pad;
824
input clk, rst;
825
genvar i;
826
generate
827
for (i=0;i<width;i=i+1) begin : ddr
828
    ddio_out ddio_out0( .aclr(rst), .datain_h(d_h_i[i]), .datain_l(d_l_i[i]), .outclock(clk), .dataout(o_pad[i]) );
829
end
830
endgenerate
831
endmodule
832
module vl_o_clk ( clk_o_pad, clk, rst);
833
input clk, rst;
834
output clk_o_pad;
835
vl_o_ddr o_ddr0( .d_h_i(1'b1), .d_l_i(1'b0), .o_pad(clk_o_pad), .clk(clk), .rst(rst));
836
endmodule
837 44 unneback
//////////////////////////////////////////////////////////////////////
838
////                                                              ////
839 6 unneback
////  Versatile counter                                           ////
840
////                                                              ////
841
////  Description                                                 ////
842
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
843
////  counter                                                     ////
844
////                                                              ////
845
////  To Do:                                                      ////
846
////   - add LFSR with more taps                                  ////
847
////                                                              ////
848
////  Author(s):                                                  ////
849
////      - Michael Unneback, unneback@opencores.org              ////
850
////        ORSoC AB                                              ////
851
////                                                              ////
852
//////////////////////////////////////////////////////////////////////
853
////                                                              ////
854
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
855
////                                                              ////
856
//// This source file may be used and distributed without         ////
857
//// restriction provided that this copyright statement is not    ////
858
//// removed from the file and that any derivative work contains  ////
859
//// the original copyright notice and the associated disclaimer. ////
860
////                                                              ////
861
//// This source file is free software; you can redistribute it   ////
862
//// and/or modify it under the terms of the GNU Lesser General   ////
863
//// Public License as published by the Free Software Foundation; ////
864
//// either version 2.1 of the License, or (at your option) any   ////
865
//// later version.                                               ////
866
////                                                              ////
867
//// This source is distributed in the hope that it will be       ////
868
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
869
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
870
//// PURPOSE.  See the GNU Lesser General Public License for more ////
871
//// details.                                                     ////
872
////                                                              ////
873
//// You should have received a copy of the GNU Lesser General    ////
874
//// Public License along with this source; if not, download it   ////
875
//// from http://www.opencores.org/lgpl.shtml                     ////
876
////                                                              ////
877
//////////////////////////////////////////////////////////////////////
878
// binary counter
879 40 unneback
module vl_cnt_bin_ce (
880
 cke, q, rst, clk);
881 22 unneback
   parameter length = 4;
882 6 unneback
   input cke;
883
   output [length:1] q;
884
   input rst;
885
   input clk;
886
   parameter clear_value = 0;
887
   parameter set_value = 1;
888
   parameter wrap_value = 0;
889
   parameter level1_value = 15;
890
   reg  [length:1] qi;
891
   wire [length:1] q_next;
892
   assign q_next = qi + {{length-1{1'b0}},1'b1};
893
   always @ (posedge clk or posedge rst)
894
     if (rst)
895
       qi <= {length{1'b0}};
896
     else
897
     if (cke)
898
       qi <= q_next;
899
   assign q = qi;
900
endmodule
901
//////////////////////////////////////////////////////////////////////
902
////                                                              ////
903
////  Versatile counter                                           ////
904
////                                                              ////
905
////  Description                                                 ////
906
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
907
////  counter                                                     ////
908
////                                                              ////
909
////  To Do:                                                      ////
910
////   - add LFSR with more taps                                  ////
911
////                                                              ////
912
////  Author(s):                                                  ////
913
////      - Michael Unneback, unneback@opencores.org              ////
914
////        ORSoC AB                                              ////
915
////                                                              ////
916
//////////////////////////////////////////////////////////////////////
917
////                                                              ////
918
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
919
////                                                              ////
920
//// This source file may be used and distributed without         ////
921
//// restriction provided that this copyright statement is not    ////
922
//// removed from the file and that any derivative work contains  ////
923
//// the original copyright notice and the associated disclaimer. ////
924
////                                                              ////
925
//// This source file is free software; you can redistribute it   ////
926
//// and/or modify it under the terms of the GNU Lesser General   ////
927
//// Public License as published by the Free Software Foundation; ////
928
//// either version 2.1 of the License, or (at your option) any   ////
929
//// later version.                                               ////
930
////                                                              ////
931
//// This source is distributed in the hope that it will be       ////
932
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
933
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
934
//// PURPOSE.  See the GNU Lesser General Public License for more ////
935
//// details.                                                     ////
936
////                                                              ////
937
//// You should have received a copy of the GNU Lesser General    ////
938
//// Public License along with this source; if not, download it   ////
939
//// from http://www.opencores.org/lgpl.shtml                     ////
940
////                                                              ////
941
//////////////////////////////////////////////////////////////////////
942
// binary counter
943 40 unneback
module vl_cnt_bin_ce_rew_zq_l1 (
944
 cke, rew, zq, level1, rst, clk);
945 6 unneback
   parameter length = 4;
946
   input cke;
947
   input rew;
948 25 unneback
   output reg zq;
949
   output reg level1;
950
   input rst;
951
   input clk;
952
   parameter clear_value = 0;
953
   parameter set_value = 1;
954
   parameter wrap_value = 1;
955
   parameter level1_value = 15;
956 29 unneback
   wire clear;
957 30 unneback
   assign clear = 1'b0;
958 25 unneback
   reg  [length:1] qi;
959
   wire  [length:1] q_next, q_next_fw, q_next_rew;
960
   assign q_next_fw  = qi + {{length-1{1'b0}},1'b1};
961
   assign q_next_rew = qi - {{length-1{1'b0}},1'b1};
962
   assign q_next = rew ? q_next_rew : q_next_fw;
963
   always @ (posedge clk or posedge rst)
964
     if (rst)
965
       qi <= {length{1'b0}};
966
     else
967
     if (cke)
968
       qi <= q_next;
969
   always @ (posedge clk or posedge rst)
970
     if (rst)
971
       zq <= 1'b1;
972
     else
973
     if (cke)
974
       zq <= q_next == {length{1'b0}};
975
    always @ (posedge clk or posedge rst)
976
    if (rst)
977
        level1 <= 1'b0;
978
    else
979
    if (cke)
980 29 unneback
    if (clear)
981
        level1 <= 1'b0;
982
    else if (q_next == level1_value)
983 25 unneback
        level1 <= 1'b1;
984
    else if (qi == level1_value & rew)
985
        level1 <= 1'b0;
986
endmodule
987
//////////////////////////////////////////////////////////////////////
988
////                                                              ////
989
////  Versatile counter                                           ////
990
////                                                              ////
991
////  Description                                                 ////
992
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
993
////  counter                                                     ////
994
////                                                              ////
995
////  To Do:                                                      ////
996
////   - add LFSR with more taps                                  ////
997
////                                                              ////
998
////  Author(s):                                                  ////
999
////      - Michael Unneback, unneback@opencores.org              ////
1000
////        ORSoC AB                                              ////
1001
////                                                              ////
1002
//////////////////////////////////////////////////////////////////////
1003
////                                                              ////
1004
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1005
////                                                              ////
1006
//// This source file may be used and distributed without         ////
1007
//// restriction provided that this copyright statement is not    ////
1008
//// removed from the file and that any derivative work contains  ////
1009
//// the original copyright notice and the associated disclaimer. ////
1010
////                                                              ////
1011
//// This source file is free software; you can redistribute it   ////
1012
//// and/or modify it under the terms of the GNU Lesser General   ////
1013
//// Public License as published by the Free Software Foundation; ////
1014
//// either version 2.1 of the License, or (at your option) any   ////
1015
//// later version.                                               ////
1016
////                                                              ////
1017
//// This source is distributed in the hope that it will be       ////
1018
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1019
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1020
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1021
//// details.                                                     ////
1022
////                                                              ////
1023
//// You should have received a copy of the GNU Lesser General    ////
1024
//// Public License along with this source; if not, download it   ////
1025
//// from http://www.opencores.org/lgpl.shtml                     ////
1026
////                                                              ////
1027
//////////////////////////////////////////////////////////////////////
1028
// binary counter
1029 40 unneback
module vl_cnt_bin_ce_rew_q_zq_l1 (
1030
 cke, rew, q, zq, level1, rst, clk);
1031 25 unneback
   parameter length = 4;
1032
   input cke;
1033
   input rew;
1034
   output [length:1] q;
1035
   output reg zq;
1036
   output reg level1;
1037
   input rst;
1038
   input clk;
1039
   parameter clear_value = 0;
1040
   parameter set_value = 1;
1041
   parameter wrap_value = 1;
1042
   parameter level1_value = 15;
1043 29 unneback
   wire clear;
1044 30 unneback
   assign clear = 1'b0;
1045 25 unneback
   reg  [length:1] qi;
1046
   wire  [length:1] q_next, q_next_fw, q_next_rew;
1047
   assign q_next_fw  = qi + {{length-1{1'b0}},1'b1};
1048
   assign q_next_rew = qi - {{length-1{1'b0}},1'b1};
1049
   assign q_next = rew ? q_next_rew : q_next_fw;
1050
   always @ (posedge clk or posedge rst)
1051
     if (rst)
1052
       qi <= {length{1'b0}};
1053
     else
1054
     if (cke)
1055
       qi <= q_next;
1056
   assign q = qi;
1057
   always @ (posedge clk or posedge rst)
1058
     if (rst)
1059
       zq <= 1'b1;
1060
     else
1061
     if (cke)
1062
       zq <= q_next == {length{1'b0}};
1063
    always @ (posedge clk or posedge rst)
1064
    if (rst)
1065
        level1 <= 1'b0;
1066
    else
1067
    if (cke)
1068 29 unneback
    if (clear)
1069
        level1 <= 1'b0;
1070
    else if (q_next == level1_value)
1071 25 unneback
        level1 <= 1'b1;
1072
    else if (qi == level1_value & rew)
1073
        level1 <= 1'b0;
1074
endmodule
1075
//////////////////////////////////////////////////////////////////////
1076
////                                                              ////
1077
////  Versatile counter                                           ////
1078
////                                                              ////
1079
////  Description                                                 ////
1080
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1081
////  counter                                                     ////
1082
////                                                              ////
1083
////  To Do:                                                      ////
1084
////   - add LFSR with more taps                                  ////
1085
////                                                              ////
1086
////  Author(s):                                                  ////
1087
////      - Michael Unneback, unneback@opencores.org              ////
1088
////        ORSoC AB                                              ////
1089
////                                                              ////
1090
//////////////////////////////////////////////////////////////////////
1091
////                                                              ////
1092
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1093
////                                                              ////
1094
//// This source file may be used and distributed without         ////
1095
//// restriction provided that this copyright statement is not    ////
1096
//// removed from the file and that any derivative work contains  ////
1097
//// the original copyright notice and the associated disclaimer. ////
1098
////                                                              ////
1099
//// This source file is free software; you can redistribute it   ////
1100
//// and/or modify it under the terms of the GNU Lesser General   ////
1101
//// Public License as published by the Free Software Foundation; ////
1102
//// either version 2.1 of the License, or (at your option) any   ////
1103
//// later version.                                               ////
1104
////                                                              ////
1105
//// This source is distributed in the hope that it will be       ////
1106
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1107
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1108
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1109
//// details.                                                     ////
1110
////                                                              ////
1111
//// You should have received a copy of the GNU Lesser General    ////
1112
//// Public License along with this source; if not, download it   ////
1113
//// from http://www.opencores.org/lgpl.shtml                     ////
1114
////                                                              ////
1115
//////////////////////////////////////////////////////////////////////
1116 75 unneback
// LFSR counter
1117 136 unneback
module vl_cnt_lfsr_zq (
1118
 zq, rst, clk);
1119
   parameter length = 4;
1120
   output reg zq;
1121
   input rst;
1122
   input clk;
1123
   parameter clear_value = 0;
1124
   parameter set_value = 1;
1125
   parameter wrap_value = 8;
1126
   parameter level1_value = 15;
1127
   reg  [length:1] qi;
1128
   reg lfsr_fb;
1129
   wire [length:1] q_next;
1130
   reg [32:1] polynom;
1131
   integer i;
1132
   always @ (qi)
1133
   begin
1134
        case (length)
1135
         2: polynom = 32'b11;                               // 0x3
1136
         3: polynom = 32'b110;                              // 0x6
1137
         4: polynom = 32'b1100;                             // 0xC
1138
         5: polynom = 32'b10100;                            // 0x14
1139
         6: polynom = 32'b110000;                           // 0x30
1140
         7: polynom = 32'b1100000;                          // 0x60
1141
         8: polynom = 32'b10111000;                         // 0xb8
1142
         9: polynom = 32'b100010000;                        // 0x110
1143
        10: polynom = 32'b1001000000;                       // 0x240
1144
        11: polynom = 32'b10100000000;                      // 0x500
1145
        12: polynom = 32'b100000101001;                     // 0x829
1146
        13: polynom = 32'b1000000001100;                    // 0x100C
1147
        14: polynom = 32'b10000000010101;                   // 0x2015
1148
        15: polynom = 32'b110000000000000;                  // 0x6000
1149
        16: polynom = 32'b1101000000001000;                 // 0xD008
1150
        17: polynom = 32'b10010000000000000;                // 0x12000
1151
        18: polynom = 32'b100000010000000000;               // 0x20400
1152
        19: polynom = 32'b1000000000000100011;              // 0x40023
1153
        20: polynom = 32'b10010000000000000000;             // 0x90000
1154
        21: polynom = 32'b101000000000000000000;            // 0x140000
1155
        22: polynom = 32'b1100000000000000000000;           // 0x300000
1156
        23: polynom = 32'b10000100000000000000000;          // 0x420000
1157
        24: polynom = 32'b111000010000000000000000;         // 0xE10000
1158
        25: polynom = 32'b1001000000000000000000000;        // 0x1200000
1159
        26: polynom = 32'b10000000000000000000100011;       // 0x2000023
1160
        27: polynom = 32'b100000000000000000000010011;      // 0x4000013
1161
        28: polynom = 32'b1100100000000000000000000000;     // 0xC800000
1162
        29: polynom = 32'b10100000000000000000000000000;    // 0x14000000
1163
        30: polynom = 32'b100000000000000000000000101001;   // 0x20000029
1164
        31: polynom = 32'b1001000000000000000000000000000;  // 0x48000000
1165
        32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
1166
        default: polynom = 32'b0;
1167
        endcase
1168
        lfsr_fb = qi[length];
1169
        for (i=length-1; i>=1; i=i-1) begin
1170
            if (polynom[i])
1171
                lfsr_fb = lfsr_fb  ~^ qi[i];
1172
        end
1173
    end
1174
   assign q_next = (qi == wrap_value) ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
1175
   always @ (posedge clk or posedge rst)
1176
     if (rst)
1177
       qi <= {length{1'b0}};
1178
     else
1179
       qi <= q_next;
1180
   always @ (posedge clk or posedge rst)
1181
     if (rst)
1182
       zq <= 1'b1;
1183
     else
1184
       zq <= q_next == {length{1'b0}};
1185
endmodule
1186
//////////////////////////////////////////////////////////////////////
1187
////                                                              ////
1188
////  Versatile counter                                           ////
1189
////                                                              ////
1190
////  Description                                                 ////
1191
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1192
////  counter                                                     ////
1193
////                                                              ////
1194
////  To Do:                                                      ////
1195
////   - add LFSR with more taps                                  ////
1196
////                                                              ////
1197
////  Author(s):                                                  ////
1198
////      - Michael Unneback, unneback@opencores.org              ////
1199
////        ORSoC AB                                              ////
1200
////                                                              ////
1201
//////////////////////////////////////////////////////////////////////
1202
////                                                              ////
1203
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1204
////                                                              ////
1205
//// This source file may be used and distributed without         ////
1206
//// restriction provided that this copyright statement is not    ////
1207
//// removed from the file and that any derivative work contains  ////
1208
//// the original copyright notice and the associated disclaimer. ////
1209
////                                                              ////
1210
//// This source file is free software; you can redistribute it   ////
1211
//// and/or modify it under the terms of the GNU Lesser General   ////
1212
//// Public License as published by the Free Software Foundation; ////
1213
//// either version 2.1 of the License, or (at your option) any   ////
1214
//// later version.                                               ////
1215
////                                                              ////
1216
//// This source is distributed in the hope that it will be       ////
1217
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1218
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1219
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1220
//// details.                                                     ////
1221
////                                                              ////
1222
//// You should have received a copy of the GNU Lesser General    ////
1223
//// Public License along with this source; if not, download it   ////
1224
//// from http://www.opencores.org/lgpl.shtml                     ////
1225
////                                                              ////
1226
//////////////////////////////////////////////////////////////////////
1227
// LFSR counter
1228 75 unneback
module vl_cnt_lfsr_ce (
1229
 cke, zq, rst, clk);
1230
   parameter length = 4;
1231
   input cke;
1232
   output reg zq;
1233
   input rst;
1234
   input clk;
1235
   parameter clear_value = 0;
1236
   parameter set_value = 1;
1237
   parameter wrap_value = 0;
1238
   parameter level1_value = 15;
1239
   reg  [length:1] qi;
1240
   reg lfsr_fb;
1241
   wire [length:1] q_next;
1242
   reg [32:1] polynom;
1243
   integer i;
1244
   always @ (qi)
1245
   begin
1246
        case (length)
1247
         2: polynom = 32'b11;                               // 0x3
1248
         3: polynom = 32'b110;                              // 0x6
1249
         4: polynom = 32'b1100;                             // 0xC
1250
         5: polynom = 32'b10100;                            // 0x14
1251
         6: polynom = 32'b110000;                           // 0x30
1252
         7: polynom = 32'b1100000;                          // 0x60
1253
         8: polynom = 32'b10111000;                         // 0xb8
1254
         9: polynom = 32'b100010000;                        // 0x110
1255
        10: polynom = 32'b1001000000;                       // 0x240
1256
        11: polynom = 32'b10100000000;                      // 0x500
1257
        12: polynom = 32'b100000101001;                     // 0x829
1258
        13: polynom = 32'b1000000001100;                    // 0x100C
1259
        14: polynom = 32'b10000000010101;                   // 0x2015
1260
        15: polynom = 32'b110000000000000;                  // 0x6000
1261
        16: polynom = 32'b1101000000001000;                 // 0xD008
1262
        17: polynom = 32'b10010000000000000;                // 0x12000
1263
        18: polynom = 32'b100000010000000000;               // 0x20400
1264
        19: polynom = 32'b1000000000000100011;              // 0x40023
1265
        20: polynom = 32'b10010000000000000000;             // 0x90000
1266
        21: polynom = 32'b101000000000000000000;            // 0x140000
1267
        22: polynom = 32'b1100000000000000000000;           // 0x300000
1268
        23: polynom = 32'b10000100000000000000000;          // 0x420000
1269
        24: polynom = 32'b111000010000000000000000;         // 0xE10000
1270
        25: polynom = 32'b1001000000000000000000000;        // 0x1200000
1271
        26: polynom = 32'b10000000000000000000100011;       // 0x2000023
1272
        27: polynom = 32'b100000000000000000000010011;      // 0x4000013
1273
        28: polynom = 32'b1100100000000000000000000000;     // 0xC800000
1274
        29: polynom = 32'b10100000000000000000000000000;    // 0x14000000
1275
        30: polynom = 32'b100000000000000000000000101001;   // 0x20000029
1276
        31: polynom = 32'b1001000000000000000000000000000;  // 0x48000000
1277
        32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
1278
        default: polynom = 32'b0;
1279
        endcase
1280
        lfsr_fb = qi[length];
1281
        for (i=length-1; i>=1; i=i-1) begin
1282
            if (polynom[i])
1283
                lfsr_fb = lfsr_fb  ~^ qi[i];
1284
        end
1285
    end
1286
   assign q_next = (qi == wrap_value) ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
1287
   always @ (posedge clk or posedge rst)
1288
     if (rst)
1289
       qi <= {length{1'b0}};
1290
     else
1291
     if (cke)
1292
       qi <= q_next;
1293
   always @ (posedge clk or posedge rst)
1294
     if (rst)
1295
       zq <= 1'b1;
1296
     else
1297
     if (cke)
1298
       zq <= q_next == {length{1'b0}};
1299
endmodule
1300
//////////////////////////////////////////////////////////////////////
1301
////                                                              ////
1302
////  Versatile counter                                           ////
1303
////                                                              ////
1304
////  Description                                                 ////
1305
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1306
////  counter                                                     ////
1307
////                                                              ////
1308
////  To Do:                                                      ////
1309
////   - add LFSR with more taps                                  ////
1310
////                                                              ////
1311
////  Author(s):                                                  ////
1312
////      - Michael Unneback, unneback@opencores.org              ////
1313
////        ORSoC AB                                              ////
1314
////                                                              ////
1315
//////////////////////////////////////////////////////////////////////
1316
////                                                              ////
1317
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1318
////                                                              ////
1319
//// This source file may be used and distributed without         ////
1320
//// restriction provided that this copyright statement is not    ////
1321
//// removed from the file and that any derivative work contains  ////
1322
//// the original copyright notice and the associated disclaimer. ////
1323
////                                                              ////
1324
//// This source file is free software; you can redistribute it   ////
1325
//// and/or modify it under the terms of the GNU Lesser General   ////
1326
//// Public License as published by the Free Software Foundation; ////
1327
//// either version 2.1 of the License, or (at your option) any   ////
1328
//// later version.                                               ////
1329
////                                                              ////
1330
//// This source is distributed in the hope that it will be       ////
1331
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1332
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1333
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1334
//// details.                                                     ////
1335
////                                                              ////
1336
//// You should have received a copy of the GNU Lesser General    ////
1337
//// Public License along with this source; if not, download it   ////
1338
//// from http://www.opencores.org/lgpl.shtml                     ////
1339
////                                                              ////
1340
//////////////////////////////////////////////////////////////////////
1341 6 unneback
// GRAY counter
1342 40 unneback
module vl_cnt_gray_ce_bin (
1343
 cke, q, q_bin, rst, clk);
1344 6 unneback
   parameter length = 4;
1345
   input cke;
1346
   output reg [length:1] q;
1347
   output [length:1] q_bin;
1348
   input rst;
1349
   input clk;
1350
   parameter clear_value = 0;
1351
   parameter set_value = 1;
1352
   parameter wrap_value = 8;
1353
   parameter level1_value = 15;
1354
   reg  [length:1] qi;
1355
   wire [length:1] q_next;
1356
   assign q_next = qi + {{length-1{1'b0}},1'b1};
1357
   always @ (posedge clk or posedge rst)
1358
     if (rst)
1359
       qi <= {length{1'b0}};
1360
     else
1361
     if (cke)
1362
       qi <= q_next;
1363
   always @ (posedge clk or posedge rst)
1364
     if (rst)
1365
       q <= {length{1'b0}};
1366
     else
1367
       if (cke)
1368
         q <= (q_next>>1) ^ q_next;
1369
   assign q_bin = qi;
1370
endmodule
1371
//////////////////////////////////////////////////////////////////////
1372
////                                                              ////
1373
////  Versatile library, counters                                 ////
1374
////                                                              ////
1375
////  Description                                                 ////
1376
////  counters                                                    ////
1377
////                                                              ////
1378
////                                                              ////
1379
////  To Do:                                                      ////
1380
////   - add more counters                                        ////
1381
////                                                              ////
1382
////  Author(s):                                                  ////
1383
////      - Michael Unneback, unneback@opencores.org              ////
1384
////        ORSoC AB                                              ////
1385
////                                                              ////
1386
//////////////////////////////////////////////////////////////////////
1387
////                                                              ////
1388
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
1389
////                                                              ////
1390
//// This source file may be used and distributed without         ////
1391
//// restriction provided that this copyright statement is not    ////
1392
//// removed from the file and that any derivative work contains  ////
1393
//// the original copyright notice and the associated disclaimer. ////
1394
////                                                              ////
1395
//// This source file is free software; you can redistribute it   ////
1396
//// and/or modify it under the terms of the GNU Lesser General   ////
1397
//// Public License as published by the Free Software Foundation; ////
1398
//// either version 2.1 of the License, or (at your option) any   ////
1399
//// later version.                                               ////
1400
////                                                              ////
1401
//// This source is distributed in the hope that it will be       ////
1402
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1403
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1404
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1405
//// details.                                                     ////
1406
////                                                              ////
1407
//// You should have received a copy of the GNU Lesser General    ////
1408
//// Public License along with this source; if not, download it   ////
1409
//// from http://www.opencores.org/lgpl.shtml                     ////
1410
////                                                              ////
1411
//////////////////////////////////////////////////////////////////////
1412 18 unneback
module vl_cnt_shreg_wrap ( q, rst, clk);
1413 6 unneback
   parameter length = 4;
1414
   output reg [0:length-1] q;
1415
   input rst;
1416
   input clk;
1417
    always @ (posedge clk or posedge rst)
1418
    if (rst)
1419
        q <= {1'b1,{length-1{1'b0}}};
1420
    else
1421
        q <= {q[length-1],q[0:length-2]};
1422
endmodule
1423 18 unneback
module vl_cnt_shreg_ce_wrap ( cke, q, rst, clk);
1424 6 unneback
   parameter length = 4;
1425
   input cke;
1426
   output reg [0:length-1] q;
1427
   input rst;
1428
   input clk;
1429
    always @ (posedge clk or posedge rst)
1430
    if (rst)
1431
        q <= {1'b1,{length-1{1'b0}}};
1432
    else
1433
        if (cke)
1434
            q <= {q[length-1],q[0:length-2]};
1435
endmodule
1436 105 unneback
module vl_cnt_shreg_clear ( clear, q, rst, clk);
1437
   parameter length = 4;
1438
   input clear;
1439
   output reg [0:length-1] q;
1440
   input rst;
1441
   input clk;
1442
    always @ (posedge clk or posedge rst)
1443
    if (rst)
1444
        q <= {1'b1,{length-1{1'b0}}};
1445
    else
1446
        if (clear)
1447
            q <= {1'b1,{length-1{1'b0}}};
1448
        else
1449
            q <= q >> 1;
1450
endmodule
1451 18 unneback
module vl_cnt_shreg_ce_clear ( cke, clear, q, rst, clk);
1452 6 unneback
   parameter length = 4;
1453
   input cke, clear;
1454
   output reg [0:length-1] q;
1455
   input rst;
1456
   input clk;
1457
    always @ (posedge clk or posedge rst)
1458
    if (rst)
1459
        q <= {1'b1,{length-1{1'b0}}};
1460
    else
1461
        if (cke)
1462
            if (clear)
1463
                q <= {1'b1,{length-1{1'b0}}};
1464
            else
1465
                q <= q >> 1;
1466
endmodule
1467 18 unneback
module vl_cnt_shreg_ce_clear_wrap ( cke, clear, q, rst, clk);
1468 6 unneback
   parameter length = 4;
1469
   input cke, clear;
1470
   output reg [0:length-1] q;
1471
   input rst;
1472
   input clk;
1473
    always @ (posedge clk or posedge rst)
1474
    if (rst)
1475
        q <= {1'b1,{length-1{1'b0}}};
1476
    else
1477
        if (cke)
1478
            if (clear)
1479
                q <= {1'b1,{length-1{1'b0}}};
1480
            else
1481
            q <= {q[length-1],q[0:length-2]};
1482
endmodule
1483
//////////////////////////////////////////////////////////////////////
1484
////                                                              ////
1485
////  Versatile library, memories                                 ////
1486
////                                                              ////
1487
////  Description                                                 ////
1488
////  memories                                                    ////
1489
////                                                              ////
1490
////                                                              ////
1491
////  To Do:                                                      ////
1492
////   - add more memory types                                    ////
1493
////                                                              ////
1494
////  Author(s):                                                  ////
1495
////      - Michael Unneback, unneback@opencores.org              ////
1496
////        ORSoC AB                                              ////
1497
////                                                              ////
1498
//////////////////////////////////////////////////////////////////////
1499
////                                                              ////
1500
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
1501
////                                                              ////
1502
//// This source file may be used and distributed without         ////
1503
//// restriction provided that this copyright statement is not    ////
1504
//// removed from the file and that any derivative work contains  ////
1505
//// the original copyright notice and the associated disclaimer. ////
1506
////                                                              ////
1507
//// This source file is free software; you can redistribute it   ////
1508
//// and/or modify it under the terms of the GNU Lesser General   ////
1509
//// Public License as published by the Free Software Foundation; ////
1510
//// either version 2.1 of the License, or (at your option) any   ////
1511
//// later version.                                               ////
1512
////                                                              ////
1513
//// This source is distributed in the hope that it will be       ////
1514
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1515
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1516
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1517
//// details.                                                     ////
1518
////                                                              ////
1519
//// You should have received a copy of the GNU Lesser General    ////
1520
//// Public License along with this source; if not, download it   ////
1521
//// from http://www.opencores.org/lgpl.shtml                     ////
1522
////                                                              ////
1523
//////////////////////////////////////////////////////////////////////
1524
/// ROM
1525 7 unneback
module vl_rom_init ( adr, q, clk);
1526
   parameter data_width = 32;
1527
   parameter addr_width = 8;
1528 75 unneback
   parameter mem_size = 1<<addr_width;
1529 7 unneback
   input [(addr_width-1):0]       adr;
1530
   output reg [(data_width-1):0] q;
1531
   input                         clk;
1532 75 unneback
   reg [data_width-1:0] rom [mem_size-1:0];
1533 7 unneback
   parameter memory_file = "vl_rom.vmem";
1534
   initial
1535
     begin
1536
        $readmemh(memory_file, rom);
1537
     end
1538
   always @ (posedge clk)
1539
     q <= rom[adr];
1540
endmodule
1541 6 unneback
// Single port RAM
1542
module vl_ram ( d, adr, we, q, clk);
1543
   parameter data_width = 32;
1544
   parameter addr_width = 8;
1545 75 unneback
   parameter mem_size = 1<<addr_width;
1546 100 unneback
   parameter debug = 0;
1547 6 unneback
   input [(data_width-1):0]      d;
1548
   input [(addr_width-1):0]       adr;
1549
   input                         we;
1550 7 unneback
   output reg [(data_width-1):0] q;
1551 6 unneback
   input                         clk;
1552 98 unneback
   reg [data_width-1:0] ram [mem_size-1:0];
1553 100 unneback
    parameter memory_init = 0;
1554
    parameter memory_file = "vl_ram.vmem";
1555
    generate
1556
    if (memory_init == 1) begin : init_mem
1557
        initial
1558
            $readmemh(memory_file, ram);
1559
   end else if (memory_init == 2) begin : init_zero
1560
        integer k;
1561
        initial
1562
            for (k = 0; k < mem_size; k = k + 1)
1563
                ram[k] = 0;
1564 7 unneback
   end
1565
   endgenerate
1566 100 unneback
    generate
1567
    if (debug==1) begin : debug_we
1568
        always @ (posedge clk)
1569
        if (we)
1570
            $display ("Value %h written at address %h : time %t", d, adr, $time);
1571
    end
1572
    endgenerate
1573 6 unneback
   always @ (posedge clk)
1574
   begin
1575
   if (we)
1576
     ram[adr] <= d;
1577
   q <= ram[adr];
1578
   end
1579
endmodule
1580 91 unneback
module vl_ram_be ( d, adr, be, we, q, clk);
1581 7 unneback
   parameter data_width = 32;
1582 72 unneback
   parameter addr_width = 6;
1583 75 unneback
   parameter mem_size = 1<<addr_width;
1584 7 unneback
   input [(data_width-1):0]      d;
1585
   input [(addr_width-1):0]       adr;
1586 73 unneback
   input [(data_width/8)-1:0]    be;
1587 7 unneback
   input                         we;
1588
   output reg [(data_width-1):0] q;
1589
   input                         clk;
1590 65 unneback
`ifdef SYSTEMVERILOG
1591 95 unneback
    // use a multi-dimensional packed array
1592
    //t o model individual bytes within the word
1593
    logic [data_width/8-1:0][7:0] ram [0:mem_size-1];// # words = 1 << address width
1594 65 unneback
`else
1595 85 unneback
    reg [data_width-1:0] ram [mem_size-1:0];
1596
    wire [data_width/8-1:0] cke;
1597 65 unneback
`endif
1598 100 unneback
    parameter memory_init = 0;
1599
    parameter memory_file = "vl_ram.vmem";
1600
    generate
1601
    if (memory_init == 1) begin : init_mem
1602
        initial
1603
            $readmemh(memory_file, ram);
1604
    end else if (memory_init == 2) begin : init_zero
1605
        integer k;
1606
        initial
1607
            for (k = 0; k < mem_size; k = k + 1)
1608
                ram[k] = 0;
1609
    end
1610 7 unneback
   endgenerate
1611 60 unneback
`ifdef SYSTEMVERILOG
1612
always_ff@(posedge clk)
1613
begin
1614 95 unneback
    if(we) begin
1615 86 unneback
        if(be[3]) ram[adr][3] <= d[31:24];
1616
        if(be[2]) ram[adr][2] <= d[23:16];
1617
        if(be[1]) ram[adr][1] <= d[15:8];
1618
        if(be[0]) ram[adr][0] <= d[7:0];
1619 60 unneback
    end
1620 90 unneback
        q <= ram[adr];
1621 60 unneback
end
1622
`else
1623 85 unneback
assign cke = {data_width/8{we}} & be;
1624 7 unneback
   genvar i;
1625 85 unneback
   generate for (i=0;i<data_width/8;i=i+1) begin : be_ram
1626 7 unneback
      always @ (posedge clk)
1627 85 unneback
      if (cke[i])
1628 7 unneback
        ram[adr][(i+1)*8-1:i*8] <= d[(i+1)*8-1:i*8];
1629
   end
1630
   endgenerate
1631
   always @ (posedge clk)
1632
      q <= ram[adr];
1633 60 unneback
`endif
1634 93 unneback
`ifdef verilator
1635 85 unneback
   // Function to access RAM (for use by Verilator).
1636
   function [31:0] get_mem;
1637
      // verilator public
1638 90 unneback
      input [addr_width-1:0]             addr;
1639 85 unneback
      get_mem = ram[addr];
1640
   endfunction // get_mem
1641
   // Function to write RAM (for use by Verilator).
1642
   function set_mem;
1643
      // verilator public
1644 90 unneback
      input [addr_width-1:0]             addr;
1645
      input [data_width-1:0]             data;
1646 85 unneback
      ram[addr] = data;
1647
   endfunction // set_mem
1648 93 unneback
`endif
1649 7 unneback
endmodule
1650
module vl_dpram_1r1w ( d_a, adr_a, we_a, clk_a, q_b, adr_b, clk_b );
1651 6 unneback
   parameter data_width = 32;
1652
   parameter addr_width = 8;
1653 75 unneback
   parameter mem_size = 1<<addr_width;
1654 6 unneback
   input [(data_width-1):0]      d_a;
1655
   input [(addr_width-1):0]       adr_a;
1656
   input [(addr_width-1):0]       adr_b;
1657
   input                         we_a;
1658 118 unneback
   output reg [(data_width-1):0]          q_b;
1659 6 unneback
   input                         clk_a, clk_b;
1660 119 unneback
   reg [data_width-1:0] ram [0:mem_size-1] ;
1661 100 unneback
    parameter memory_init = 0;
1662
    parameter memory_file = "vl_ram.vmem";
1663
    parameter debug = 0;
1664
    generate
1665
    if (memory_init == 1) begin : init_mem
1666
        initial
1667
            $readmemh(memory_file, ram);
1668
    end else if (memory_init == 2) begin : init_zero
1669
        integer k;
1670
        initial
1671
            for (k = 0; k < mem_size; k = k + 1)
1672
                ram[k] = 0;
1673
    end
1674 7 unneback
   endgenerate
1675 100 unneback
    generate
1676
    if (debug==1) begin : debug_we
1677
        always @ (posedge clk_a)
1678
        if (we_a)
1679
            $display ("Debug: Value %h written at address %h : time %t", d_a, adr_a, $time);
1680
    end
1681
    endgenerate
1682 6 unneback
   always @ (posedge clk_a)
1683
   if (we_a)
1684
     ram[adr_a] <= d_a;
1685
   always @ (posedge clk_b)
1686 118 unneback
      q_b = ram[adr_b];
1687 6 unneback
endmodule
1688 7 unneback
module vl_dpram_2r1w ( d_a, q_a, adr_a, we_a, clk_a, q_b, adr_b, clk_b );
1689 6 unneback
   parameter data_width = 32;
1690
   parameter addr_width = 8;
1691 75 unneback
   parameter mem_size = 1<<addr_width;
1692 6 unneback
   input [(data_width-1):0]      d_a;
1693
   input [(addr_width-1):0]       adr_a;
1694
   input [(addr_width-1):0]       adr_b;
1695
   input                         we_a;
1696
   output [(data_width-1):0]      q_b;
1697
   output reg [(data_width-1):0] q_a;
1698
   input                         clk_a, clk_b;
1699
   reg [(data_width-1):0]         q_b;
1700 119 unneback
   reg [data_width-1:0] ram [0:mem_size-1] ;
1701 100 unneback
    parameter memory_init = 0;
1702
    parameter memory_file = "vl_ram.vmem";
1703
    parameter debug = 0;
1704
    generate
1705
    if (memory_init == 1) begin : init_mem
1706
        initial
1707
            $readmemh(memory_file, ram);
1708
    end else if (memory_init == 2) begin : init_zero
1709
        integer k;
1710
        initial
1711
            for (k = 0; k < mem_size; k = k + 1)
1712
                ram[k] = 0;
1713
    end
1714 7 unneback
   endgenerate
1715 100 unneback
    generate
1716
    if (debug==1) begin : debug_we
1717
        always @ (posedge clk_a)
1718
        if (we_a)
1719
            $display ("Debug: Value %h written at address %h : time %t", d_a, adr_a, $time);
1720
    end
1721
    endgenerate
1722 6 unneback
   always @ (posedge clk_a)
1723
     begin
1724
        q_a <= ram[adr_a];
1725
        if (we_a)
1726
             ram[adr_a] <= d_a;
1727
     end
1728
   always @ (posedge clk_b)
1729
          q_b <= ram[adr_b];
1730
endmodule
1731 100 unneback
module vl_dpram_1r2w ( d_a, q_a, adr_a, we_a, clk_a, d_b, adr_b, we_b, clk_b );
1732
   parameter data_width = 32;
1733
   parameter addr_width = 8;
1734
   parameter mem_size = 1<<addr_width;
1735
   input [(data_width-1):0]      d_a;
1736
   input [(addr_width-1):0]       adr_a;
1737
   input [(addr_width-1):0]       adr_b;
1738
   input                         we_a;
1739
   input [(data_width-1):0]       d_b;
1740
   output reg [(data_width-1):0] q_a;
1741
   input                         we_b;
1742
   input                         clk_a, clk_b;
1743
   reg [(data_width-1):0]         q_b;
1744 119 unneback
   reg [data_width-1:0] ram [0:mem_size-1] ;
1745 100 unneback
    parameter memory_init = 0;
1746
    parameter memory_file = "vl_ram.vmem";
1747
    parameter debug = 0;
1748
    generate
1749
    if (memory_init == 1) begin : init_mem
1750
        initial
1751
            $readmemh(memory_file, ram);
1752
    end else if (memory_init == 2) begin : init_zero
1753
        integer k;
1754
        initial
1755
            for (k = 0; k < mem_size; k = k + 1)
1756
                ram[k] = 0;
1757
    end
1758
   endgenerate
1759
    generate
1760
    if (debug==1) begin : debug_we
1761
        always @ (posedge clk_a)
1762
        if (we_a)
1763
            $display ("Debug: Value %h written at address %h : time %t", d_a, adr_a, $time);
1764
        always @ (posedge clk_b)
1765
        if (we_b)
1766
            $display ("Debug: Value %h written at address %h : time %t", d_b, adr_b, $time);
1767
    end
1768
    endgenerate
1769
   always @ (posedge clk_a)
1770
     begin
1771
        q_a <= ram[adr_a];
1772
        if (we_a)
1773
             ram[adr_a] <= d_a;
1774
     end
1775
   always @ (posedge clk_b)
1776
     begin
1777
        if (we_b)
1778
          ram[adr_b] <= d_b;
1779
     end
1780
endmodule
1781 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 );
1782 6 unneback
   parameter data_width = 32;
1783
   parameter addr_width = 8;
1784 75 unneback
   parameter mem_size = 1<<addr_width;
1785 6 unneback
   input [(data_width-1):0]      d_a;
1786
   input [(addr_width-1):0]       adr_a;
1787
   input [(addr_width-1):0]       adr_b;
1788
   input                         we_a;
1789
   output [(data_width-1):0]      q_b;
1790
   input [(data_width-1):0]       d_b;
1791
   output reg [(data_width-1):0] q_a;
1792
   input                         we_b;
1793
   input                         clk_a, clk_b;
1794
   reg [(data_width-1):0]         q_b;
1795 119 unneback
   reg [data_width-1:0] ram [0:mem_size-1] ;
1796 100 unneback
    parameter memory_init = 0;
1797
    parameter memory_file = "vl_ram.vmem";
1798
    parameter debug = 0;
1799
    generate
1800
    if (memory_init) begin : init_mem
1801
        initial
1802
            $readmemh(memory_file, ram);
1803
    end else if (memory_init == 2) begin : init_zero
1804
        integer k;
1805
        initial
1806
            for (k = 0; k < mem_size; k = k + 1)
1807
                ram[k] = 0;
1808
    end
1809 7 unneback
   endgenerate
1810 100 unneback
    generate
1811
    if (debug==1) begin : debug_we
1812
        always @ (posedge clk_a)
1813
        if (we_a)
1814
            $display ("Debug: Value %h written at address %h : time %t", d_a, adr_a, $time);
1815
        always @ (posedge clk_b)
1816
        if (we_b)
1817
            $display ("Debug: Value %h written at address %h : time %t", d_b, adr_b, $time);
1818
    end
1819
    endgenerate
1820 6 unneback
   always @ (posedge clk_a)
1821
     begin
1822
        q_a <= ram[adr_a];
1823
        if (we_a)
1824
             ram[adr_a] <= d_a;
1825
     end
1826
   always @ (posedge clk_b)
1827
     begin
1828
        q_b <= ram[adr_b];
1829
        if (we_b)
1830
          ram[adr_b] <= d_b;
1831
     end
1832
endmodule
1833 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 );
1834 75 unneback
   parameter a_data_width = 32;
1835
   parameter a_addr_width = 8;
1836 95 unneback
   parameter b_data_width = 64; //a_data_width;
1837 124 unneback
   //localparam b_addr_width = a_data_width * a_addr_width / b_data_width;
1838
   localparam b_addr_width =
1839 125 unneback
        (a_data_width==b_data_width) ? a_addr_width :
1840
        (a_data_width==b_data_width*2) ? a_addr_width+1 :
1841
        (a_data_width==b_data_width*4) ? a_addr_width+2 :
1842
        (a_data_width==b_data_width*8) ? a_addr_width+3 :
1843
        (a_data_width==b_data_width*16) ? a_addr_width+4 :
1844
        (a_data_width==b_data_width*32) ? a_addr_width+5 :
1845
        (a_data_width==b_data_width/2) ? a_addr_width-1 :
1846
        (a_data_width==b_data_width/4) ? a_addr_width-2 :
1847
        (a_data_width==b_data_width/8) ? a_addr_width-3 :
1848
        (a_data_width==b_data_width/16) ? a_addr_width-4 :
1849
        (a_data_width==b_data_width/32) ? a_addr_width-5 : 0;
1850 95 unneback
   localparam ratio = (a_addr_width>b_addr_width) ? (a_addr_width/b_addr_width) : (b_addr_width/a_addr_width);
1851
   parameter mem_size = (a_addr_width>b_addr_width) ? (1<<b_addr_width) : (1<<a_addr_width);
1852 100 unneback
   parameter memory_init = 0;
1853 95 unneback
   parameter memory_file = "vl_ram.vmem";
1854 100 unneback
   parameter debug = 0;
1855 75 unneback
   input [(a_data_width-1):0]      d_a;
1856 91 unneback
   input [(a_addr_width-1):0]       adr_a;
1857
   input [(a_data_width/8-1):0]    be_a;
1858
   input                           we_a;
1859 75 unneback
   output reg [(a_data_width-1):0] q_a;
1860 91 unneback
   input [(b_data_width-1):0]       d_b;
1861
   input [(b_addr_width-1):0]       adr_b;
1862 92 unneback
   input [(b_data_width/8-1):0]    be_b;
1863
   input                           we_b;
1864
   output reg [(b_data_width-1):0]          q_b;
1865 91 unneback
   input                           clk_a, clk_b;
1866 100 unneback
    generate
1867
    if (debug==1) begin : debug_we
1868
        always @ (posedge clk_a)
1869
        if (we_a)
1870
            $display ("Debug: Value %h written at address %h : time %t", d_a, adr_a, $time);
1871
        always @ (posedge clk_b)
1872
        if (we_b)
1873
            $display ("Debug: Value %h written at address %h : time %t", d_b, adr_b, $time);
1874
    end
1875
    endgenerate
1876 91 unneback
`ifdef SYSTEMVERILOG
1877
// use a multi-dimensional packed array
1878
//to model individual bytes within the word
1879 75 unneback
generate
1880 91 unneback
if (a_data_width==32 & b_data_width==32) begin : dpram_3232
1881 98 unneback
    logic [0:3][7:0] ram [0:mem_size-1] ;
1882 95 unneback
    initial
1883 100 unneback
        if (memory_init==1)
1884 95 unneback
            $readmemh(memory_file, ram);
1885 100 unneback
    integer k;
1886
    initial
1887
        if (memory_init==2)
1888
            for (k = 0; k < mem_size; k = k + 1)
1889
                ram[k] = 0;
1890 91 unneback
    always_ff@(posedge clk_a)
1891
    begin
1892
        if(we_a) begin
1893 100 unneback
            if(be_a[3]) ram[adr_a][0] <= d_a[31:24];
1894
            if(be_a[2]) ram[adr_a][1] <= d_a[23:16];
1895
            if(be_a[1]) ram[adr_a][2] <= d_a[15:8];
1896
            if(be_a[0]) ram[adr_a][3] <= d_a[7:0];
1897 91 unneback
        end
1898
    end
1899 92 unneback
    always@(posedge clk_a)
1900
        q_a = ram[adr_a];
1901 91 unneback
    always_ff@(posedge clk_b)
1902 92 unneback
    begin
1903
        if(we_b) begin
1904 100 unneback
            if(be_b[3]) ram[adr_b][0] <= d_b[31:24];
1905
            if(be_b[2]) ram[adr_b][1] <= d_b[23:16];
1906
            if(be_b[1]) ram[adr_b][2] <= d_b[15:8];
1907
            if(be_b[0]) ram[adr_b][3] <= d_b[7:0];
1908 92 unneback
        end
1909
    end
1910
    always@(posedge clk_b)
1911
        q_b = ram[adr_b];
1912 75 unneback
end
1913
endgenerate
1914 95 unneback
generate
1915
if (a_data_width==64 & b_data_width==64) begin : dpram_6464
1916 98 unneback
    logic [0:7][7:0] ram [0:mem_size-1] ;
1917 95 unneback
    initial
1918 100 unneback
        if (memory_init==1)
1919 95 unneback
            $readmemh(memory_file, ram);
1920 100 unneback
    integer k;
1921
    initial
1922
        if (memory_init==2)
1923
            for (k = 0; k < mem_size; k = k + 1)
1924
                ram[k] = 0;
1925 95 unneback
    always_ff@(posedge clk_a)
1926
    begin
1927
        if(we_a) begin
1928
            if(be_a[7]) ram[adr_a][7] <= d_a[63:56];
1929
            if(be_a[6]) ram[adr_a][6] <= d_a[55:48];
1930
            if(be_a[5]) ram[adr_a][5] <= d_a[47:40];
1931
            if(be_a[4]) ram[adr_a][4] <= d_a[39:32];
1932
            if(be_a[3]) ram[adr_a][3] <= d_a[31:24];
1933
            if(be_a[2]) ram[adr_a][2] <= d_a[23:16];
1934
            if(be_a[1]) ram[adr_a][1] <= d_a[15:8];
1935
            if(be_a[0]) ram[adr_a][0] <= d_a[7:0];
1936
        end
1937
    end
1938
    always@(posedge clk_a)
1939
        q_a = ram[adr_a];
1940
    always_ff@(posedge clk_b)
1941
    begin
1942
        if(we_b) begin
1943
            if(be_b[7]) ram[adr_b][7] <= d_b[63:56];
1944
            if(be_b[6]) ram[adr_b][6] <= d_b[55:48];
1945
            if(be_b[5]) ram[adr_b][5] <= d_b[47:40];
1946
            if(be_b[4]) ram[adr_b][4] <= d_b[39:32];
1947
            if(be_b[3]) ram[adr_b][3] <= d_b[31:24];
1948
            if(be_b[2]) ram[adr_b][2] <= d_b[23:16];
1949
            if(be_b[1]) ram[adr_b][1] <= d_b[15:8];
1950
            if(be_b[0]) ram[adr_b][0] <= d_b[7:0];
1951
        end
1952
    end
1953
    always@(posedge clk_b)
1954
        q_b = ram[adr_b];
1955
end
1956
endgenerate
1957
generate
1958
if (a_data_width==32 & b_data_width==16) begin : dpram_3216
1959
logic [31:0] temp;
1960 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))
1961
dpram3232 (
1962 95 unneback
    .d_a(d_a),
1963
    .q_a(q_a),
1964
    .adr_a(adr_a),
1965
    .be_a(be_a),
1966
    .we_a(we_a),
1967
    .clk_a(clk_a),
1968
    .d_b({d_b,d_b}),
1969
    .q_b(temp),
1970 128 unneback
    .adr_b(adr_b[b_addr_width-1:1]),
1971 137 unneback
    .be_b({be_b,be_b} & {{2{!adr_b[0]}},{2{adr_b[0]}}}),
1972 95 unneback
    .we_b(we_b),
1973
    .clk_b(clk_b)
1974
);
1975 100 unneback
always @ (adr_b[0] or temp)
1976 95 unneback
    if (adr_b[0])
1977
        q_b = temp[31:16];
1978
    else
1979
        q_b = temp[15:0];
1980
end
1981
endgenerate
1982
generate
1983
if (a_data_width==32 & b_data_width==64) begin : dpram_3264
1984
logic [63:0] temp;
1985 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))
1986 95 unneback
dpram6464 (
1987
    .d_a({d_a,d_a}),
1988
    .q_a(temp),
1989
    .adr_a(adr_a[a_addr_width-1:1]),
1990
    .be_a({be_a,be_a} & {{4{adr_a[0]}},{4{!adr_a[0]}}}),
1991
    .we_a(we_a),
1992
    .clk_a(clk_a),
1993
    .d_b(d_b),
1994
    .q_b(q_b),
1995
    .adr_b(adr_b),
1996
    .be_b(be_b),
1997
    .we_b(we_b),
1998
    .clk_b(clk_b)
1999
);
2000 100 unneback
always @ (adr_a[0] or temp)
2001 95 unneback
    if (adr_a[0])
2002
        q_a = temp[63:32];
2003
    else
2004
        q_a = temp[31:0];
2005
end
2006
endgenerate
2007 91 unneback
`else
2008 92 unneback
    // This modules requires SystemVerilog
2009 98 unneback
    // at this point anyway
2010 91 unneback
`endif
2011 75 unneback
endmodule
2012 6 unneback
// FIFO
2013 25 unneback
module vl_fifo_1r1w_fill_level_sync (
2014
    d, wr, fifo_full,
2015
    q, rd, fifo_empty,
2016
    fill_level,
2017
    clk, rst
2018
    );
2019
parameter data_width = 18;
2020
parameter addr_width = 4;
2021
// write side
2022
input  [data_width-1:0] d;
2023
input                   wr;
2024
output                  fifo_full;
2025
// read side
2026
output [data_width-1:0] q;
2027
input                   rd;
2028
output                  fifo_empty;
2029
// common
2030
output [addr_width:0]   fill_level;
2031
input rst, clk;
2032
wire [addr_width:1] wadr, radr;
2033
vl_cnt_bin_ce
2034
    # ( .length(addr_width))
2035
    fifo_wr_adr( .cke(wr), .q(wadr), .rst(rst), .clk(clk));
2036
vl_cnt_bin_ce
2037
    # (.length(addr_width))
2038
    fifo_rd_adr( .cke(rd), .q(radr), .rst(rst), .clk(clk));
2039
vl_dpram_1r1w
2040
    # (.data_width(data_width), .addr_width(addr_width))
2041
    dpram ( .d_a(d), .adr_a(wadr), .we_a(wr), .clk_a(clk), .q_b(q), .adr_b(radr), .clk_b(clk));
2042 31 unneback
vl_cnt_bin_ce_rew_q_zq_l1
2043 27 unneback
    # (.length(addr_width+1), .level1_value(1<<addr_width))
2044 25 unneback
    fill_level_cnt( .cke(rd ^ wr), .rew(rd), .q(fill_level), .zq(fifo_empty), .level1(fifo_full), .rst(rst), .clk(clk));
2045
endmodule
2046 27 unneback
// Intended use is two small FIFOs (RX and TX typically) in one FPGA RAM resource
2047
// RAM is supposed to be larger than the two FIFOs
2048
// LFSR counters used adr pointers
2049
module vl_fifo_2r2w_sync_simplex (
2050
    // a side
2051
    a_d, a_wr, a_fifo_full,
2052
    a_q, a_rd, a_fifo_empty,
2053
    a_fill_level,
2054
    // b side
2055
    b_d, b_wr, b_fifo_full,
2056
    b_q, b_rd, b_fifo_empty,
2057
    b_fill_level,
2058
    // common
2059
    clk, rst
2060
    );
2061
parameter data_width = 8;
2062
parameter addr_width = 5;
2063
parameter fifo_full_level = (1<<addr_width)-1;
2064
// a side
2065
input  [data_width-1:0] a_d;
2066
input                   a_wr;
2067
output                  a_fifo_full;
2068
output [data_width-1:0] a_q;
2069
input                   a_rd;
2070
output                  a_fifo_empty;
2071
output [addr_width-1:0] a_fill_level;
2072
// b side
2073
input  [data_width-1:0] b_d;
2074
input                   b_wr;
2075
output                  b_fifo_full;
2076
output [data_width-1:0] b_q;
2077
input                   b_rd;
2078
output                  b_fifo_empty;
2079
output [addr_width-1:0] b_fill_level;
2080
input                   clk;
2081
input                   rst;
2082
// adr_gen
2083
wire [addr_width:1] a_wadr, a_radr;
2084
wire [addr_width:1] b_wadr, b_radr;
2085
// dpram
2086
wire [addr_width:0] a_dpram_adr, b_dpram_adr;
2087
vl_cnt_lfsr_ce
2088
    # ( .length(addr_width))
2089
    fifo_a_wr_adr( .cke(a_wr), .q(a_wadr), .rst(rst), .clk(clk));
2090
vl_cnt_lfsr_ce
2091
    # (.length(addr_width))
2092
    fifo_a_rd_adr( .cke(a_rd), .q(a_radr), .rst(rst), .clk(clk));
2093
vl_cnt_lfsr_ce
2094
    # ( .length(addr_width))
2095
    fifo_b_wr_adr( .cke(b_wr), .q(b_wadr), .rst(rst), .clk(clk));
2096
vl_cnt_lfsr_ce
2097
    # (.length(addr_width))
2098
    fifo_b_rd_adr( .cke(b_rd), .q(b_radr), .rst(rst), .clk(clk));
2099
// mux read or write adr to DPRAM
2100
assign a_dpram_adr = (a_wr) ? {1'b0,a_wadr} : {1'b1,a_radr};
2101
assign b_dpram_adr = (b_wr) ? {1'b1,b_wadr} : {1'b0,b_radr};
2102
vl_dpram_2r2w
2103
    # (.data_width(data_width), .addr_width(addr_width+1))
2104
    dpram ( .d_a(a_d), .q_a(a_q), .adr_a(a_dpram_adr), .we_a(a_wr), .clk_a(a_clk),
2105
            .d_b(b_d), .q_b(b_q), .adr_b(b_dpram_adr), .we_b(b_wr), .clk_b(b_clk));
2106
vl_cnt_bin_ce_rew_zq_l1
2107 28 unneback
    # (.length(addr_width), .level1_value(fifo_full_level))
2108 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));
2109
vl_cnt_bin_ce_rew_zq_l1
2110 28 unneback
    # (.length(addr_width), .level1_value(fifo_full_level))
2111 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));
2112
endmodule
2113 6 unneback
module vl_fifo_cmp_async ( wptr, rptr, fifo_empty, fifo_full, wclk, rclk, rst );
2114 11 unneback
   parameter addr_width = 4;
2115
   parameter N = addr_width-1;
2116 6 unneback
   parameter Q1 = 2'b00;
2117
   parameter Q2 = 2'b01;
2118
   parameter Q3 = 2'b11;
2119
   parameter Q4 = 2'b10;
2120
   parameter going_empty = 1'b0;
2121
   parameter going_full  = 1'b1;
2122
   input [N:0]  wptr, rptr;
2123 14 unneback
   output       fifo_empty;
2124 6 unneback
   output       fifo_full;
2125
   input        wclk, rclk, rst;
2126
   wire direction;
2127
   reg  direction_set, direction_clr;
2128
   wire async_empty, async_full;
2129
   wire fifo_full2;
2130 14 unneback
   wire fifo_empty2;
2131 6 unneback
   // direction_set
2132
   always @ (wptr[N:N-1] or rptr[N:N-1])
2133
     case ({wptr[N:N-1],rptr[N:N-1]})
2134
       {Q1,Q2} : direction_set <= 1'b1;
2135
       {Q2,Q3} : direction_set <= 1'b1;
2136
       {Q3,Q4} : direction_set <= 1'b1;
2137
       {Q4,Q1} : direction_set <= 1'b1;
2138
       default : direction_set <= 1'b0;
2139
     endcase
2140
   // direction_clear
2141
   always @ (wptr[N:N-1] or rptr[N:N-1] or rst)
2142
     if (rst)
2143
       direction_clr <= 1'b1;
2144
     else
2145
       case ({wptr[N:N-1],rptr[N:N-1]})
2146
         {Q2,Q1} : direction_clr <= 1'b1;
2147
         {Q3,Q2} : direction_clr <= 1'b1;
2148
         {Q4,Q3} : direction_clr <= 1'b1;
2149
         {Q1,Q4} : direction_clr <= 1'b1;
2150
         default : direction_clr <= 1'b0;
2151
       endcase
2152 18 unneback
    vl_dff_sr dff_sr_dir( .aclr(direction_clr), .aset(direction_set), .clock(1'b1), .data(1'b1), .q(direction));
2153 6 unneback
   assign async_empty = (wptr == rptr) && (direction==going_empty);
2154
   assign async_full  = (wptr == rptr) && (direction==going_full);
2155 18 unneback
    vl_dff_sr dff_sr_empty0( .aclr(rst), .aset(async_full), .clock(wclk), .data(async_full), .q(fifo_full2));
2156
    vl_dff_sr dff_sr_empty1( .aclr(rst), .aset(async_full), .clock(wclk), .data(fifo_full2), .q(fifo_full));
2157 6 unneback
/*
2158
   always @ (posedge wclk or posedge rst or posedge async_full)
2159
     if (rst)
2160
       {fifo_full, fifo_full2} <= 2'b00;
2161
     else if (async_full)
2162
       {fifo_full, fifo_full2} <= 2'b11;
2163
     else
2164
       {fifo_full, fifo_full2} <= {fifo_full2, async_full};
2165
*/
2166 14 unneback
/*   always @ (posedge rclk or posedge async_empty)
2167 6 unneback
     if (async_empty)
2168
       {fifo_empty, fifo_empty2} <= 2'b11;
2169
     else
2170 14 unneback
       {fifo_empty,fifo_empty2} <= {fifo_empty2,async_empty}; */
2171 18 unneback
    vl_dff # ( .reset_value(1'b1)) dff0 ( .d(async_empty), .q(fifo_empty2), .clk(rclk), .rst(async_empty));
2172
    vl_dff # ( .reset_value(1'b1)) dff1 ( .d(fifo_empty2), .q(fifo_empty),  .clk(rclk), .rst(async_empty));
2173 27 unneback
endmodule // async_compb
2174 6 unneback
module vl_fifo_1r1w_async (
2175
    d, wr, fifo_full, wr_clk, wr_rst,
2176
    q, rd, fifo_empty, rd_clk, rd_rst
2177
    );
2178
parameter data_width = 18;
2179
parameter addr_width = 4;
2180
// write side
2181
input  [data_width-1:0] d;
2182
input                   wr;
2183
output                  fifo_full;
2184
input                   wr_clk;
2185
input                   wr_rst;
2186
// read side
2187
output [data_width-1:0] q;
2188
input                   rd;
2189
output                  fifo_empty;
2190
input                   rd_clk;
2191
input                   rd_rst;
2192
wire [addr_width:1] wadr, wadr_bin, radr, radr_bin;
2193 18 unneback
vl_cnt_gray_ce_bin
2194 6 unneback
    # ( .length(addr_width))
2195
    fifo_wr_adr( .cke(wr), .q(wadr), .q_bin(wadr_bin), .rst(wr_rst), .clk(wr_clk));
2196 18 unneback
vl_cnt_gray_ce_bin
2197 6 unneback
    # (.length(addr_width))
2198 23 unneback
    fifo_rd_adr( .cke(rd), .q(radr), .q_bin(radr_bin), .rst(rd_rst), .clk(rd_clk));
2199 7 unneback
vl_dpram_1r1w
2200 6 unneback
    # (.data_width(data_width), .addr_width(addr_width))
2201
    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));
2202
vl_fifo_cmp_async
2203
    # (.addr_width(addr_width))
2204
    cmp ( .wptr(wadr), .rptr(radr), .fifo_empty(fifo_empty), .fifo_full(fifo_full), .wclk(wr_clk), .rclk(rd_clk), .rst(wr_rst) );
2205
endmodule
2206 8 unneback
module vl_fifo_2r2w_async (
2207 6 unneback
    // a side
2208
    a_d, a_wr, a_fifo_full,
2209
    a_q, a_rd, a_fifo_empty,
2210
    a_clk, a_rst,
2211
    // b side
2212
    b_d, b_wr, b_fifo_full,
2213
    b_q, b_rd, b_fifo_empty,
2214
    b_clk, b_rst
2215
    );
2216
parameter data_width = 18;
2217
parameter addr_width = 4;
2218
// a side
2219
input  [data_width-1:0] a_d;
2220
input                   a_wr;
2221
output                  a_fifo_full;
2222
output [data_width-1:0] a_q;
2223
input                   a_rd;
2224
output                  a_fifo_empty;
2225
input                   a_clk;
2226
input                   a_rst;
2227
// b side
2228
input  [data_width-1:0] b_d;
2229
input                   b_wr;
2230
output                  b_fifo_full;
2231
output [data_width-1:0] b_q;
2232
input                   b_rd;
2233
output                  b_fifo_empty;
2234
input                   b_clk;
2235
input                   b_rst;
2236
vl_fifo_1r1w_async # (.data_width(data_width), .addr_width(addr_width))
2237
vl_fifo_1r1w_async_a (
2238
    .d(a_d), .wr(a_wr), .fifo_full(a_fifo_full), .wr_clk(a_clk), .wr_rst(a_rst),
2239
    .q(b_q), .rd(b_rd), .fifo_empty(b_fifo_empty), .rd_clk(b_clk), .rd_rst(b_rst)
2240
    );
2241
vl_fifo_1r1w_async # (.data_width(data_width), .addr_width(addr_width))
2242
vl_fifo_1r1w_async_b (
2243
    .d(b_d), .wr(b_wr), .fifo_full(b_fifo_full), .wr_clk(b_clk), .wr_rst(b_rst),
2244
    .q(a_q), .rd(a_rd), .fifo_empty(a_fifo_empty), .rd_clk(a_clk), .rd_rst(a_rst)
2245
    );
2246
endmodule
2247 8 unneback
module vl_fifo_2r2w_async_simplex (
2248 6 unneback
    // a side
2249
    a_d, a_wr, a_fifo_full,
2250
    a_q, a_rd, a_fifo_empty,
2251
    a_clk, a_rst,
2252
    // b side
2253
    b_d, b_wr, b_fifo_full,
2254
    b_q, b_rd, b_fifo_empty,
2255
    b_clk, b_rst
2256
    );
2257
parameter data_width = 18;
2258
parameter addr_width = 4;
2259
// a side
2260
input  [data_width-1:0] a_d;
2261
input                   a_wr;
2262
output                  a_fifo_full;
2263
output [data_width-1:0] a_q;
2264
input                   a_rd;
2265
output                  a_fifo_empty;
2266
input                   a_clk;
2267
input                   a_rst;
2268
// b side
2269
input  [data_width-1:0] b_d;
2270
input                   b_wr;
2271
output                  b_fifo_full;
2272
output [data_width-1:0] b_q;
2273
input                   b_rd;
2274
output                  b_fifo_empty;
2275
input                   b_clk;
2276
input                   b_rst;
2277
// adr_gen
2278
wire [addr_width:1] a_wadr, a_wadr_bin, a_radr, a_radr_bin;
2279
wire [addr_width:1] b_wadr, b_wadr_bin, b_radr, b_radr_bin;
2280
// dpram
2281
wire [addr_width:0] a_dpram_adr, b_dpram_adr;
2282 18 unneback
vl_cnt_gray_ce_bin
2283 6 unneback
    # ( .length(addr_width))
2284
    fifo_a_wr_adr( .cke(a_wr), .q(a_wadr), .q_bin(a_wadr_bin), .rst(a_rst), .clk(a_clk));
2285 18 unneback
vl_cnt_gray_ce_bin
2286 6 unneback
    # (.length(addr_width))
2287
    fifo_a_rd_adr( .cke(a_rd), .q(a_radr), .q_bin(a_radr_bin), .rst(a_rst), .clk(a_clk));
2288 18 unneback
vl_cnt_gray_ce_bin
2289 6 unneback
    # ( .length(addr_width))
2290
    fifo_b_wr_adr( .cke(b_wr), .q(b_wadr), .q_bin(b_wadr_bin), .rst(b_rst), .clk(b_clk));
2291 18 unneback
vl_cnt_gray_ce_bin
2292 6 unneback
    # (.length(addr_width))
2293
    fifo_b_rd_adr( .cke(b_rd), .q(b_radr), .q_bin(b_radr_bin), .rst(b_rst), .clk(b_clk));
2294
// mux read or write adr to DPRAM
2295
assign a_dpram_adr = (a_wr) ? {1'b0,a_wadr_bin} : {1'b1,a_radr_bin};
2296
assign b_dpram_adr = (b_wr) ? {1'b1,b_wadr_bin} : {1'b0,b_radr_bin};
2297 11 unneback
vl_dpram_2r2w
2298 6 unneback
    # (.data_width(data_width), .addr_width(addr_width+1))
2299
    dpram ( .d_a(a_d), .q_a(a_q), .adr_a(a_dpram_adr), .we_a(a_wr), .clk_a(a_clk),
2300
            .d_b(b_d), .q_b(b_q), .adr_b(b_dpram_adr), .we_b(b_wr), .clk_b(b_clk));
2301 11 unneback
vl_fifo_cmp_async
2302 6 unneback
    # (.addr_width(addr_width))
2303
    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) );
2304 11 unneback
vl_fifo_cmp_async
2305 6 unneback
    # (.addr_width(addr_width))
2306
    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) );
2307
endmodule
2308 48 unneback
module vl_reg_file (
2309
    a1, a2, a3, wd3, we3, rd1, rd2, clk
2310
);
2311
parameter data_width = 32;
2312
parameter addr_width = 5;
2313
input [addr_width-1:0] a1, a2, a3;
2314
input [data_width-1:0] wd3;
2315
input we3;
2316
output [data_width-1:0] rd1, rd2;
2317
input clk;
2318
vl_dpram_1r1w
2319
    # ( .data_width(data_width), .addr_width(addr_width))
2320
    ram1 (
2321
        .d_a(wd3),
2322
        .adr_a(a3),
2323
        .we_a(we3),
2324
        .clk_a(clk),
2325
        .q_b(rd1),
2326
        .adr_b(a1),
2327
        .clk_b(clk) );
2328
vl_dpram_1r1w
2329
    # ( .data_width(data_width), .addr_width(addr_width))
2330
    ram2 (
2331
        .d_a(wd3),
2332
        .adr_a(a3),
2333
        .we_a(we3),
2334
        .clk_a(clk),
2335
        .q_b(rd2),
2336
        .adr_b(a2),
2337
        .clk_b(clk) );
2338
endmodule
2339 12 unneback
//////////////////////////////////////////////////////////////////////
2340
////                                                              ////
2341
////  Versatile library, wishbone stuff                           ////
2342
////                                                              ////
2343
////  Description                                                 ////
2344
////  Wishbone compliant modules                                  ////
2345
////                                                              ////
2346
////                                                              ////
2347
////  To Do:                                                      ////
2348
////   -                                                          ////
2349
////                                                              ////
2350
////  Author(s):                                                  ////
2351
////      - Michael Unneback, unneback@opencores.org              ////
2352
////        ORSoC AB                                              ////
2353
////                                                              ////
2354
//////////////////////////////////////////////////////////////////////
2355
////                                                              ////
2356
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
2357
////                                                              ////
2358
//// This source file may be used and distributed without         ////
2359
//// restriction provided that this copyright statement is not    ////
2360
//// removed from the file and that any derivative work contains  ////
2361
//// the original copyright notice and the associated disclaimer. ////
2362
////                                                              ////
2363
//// This source file is free software; you can redistribute it   ////
2364
//// and/or modify it under the terms of the GNU Lesser General   ////
2365
//// Public License as published by the Free Software Foundation; ////
2366
//// either version 2.1 of the License, or (at your option) any   ////
2367
//// later version.                                               ////
2368
////                                                              ////
2369
//// This source is distributed in the hope that it will be       ////
2370
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
2371
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
2372
//// PURPOSE.  See the GNU Lesser General Public License for more ////
2373
//// details.                                                     ////
2374
////                                                              ////
2375
//// You should have received a copy of the GNU Lesser General    ////
2376
//// Public License along with this source; if not, download it   ////
2377
//// from http://www.opencores.org/lgpl.shtml                     ////
2378
////                                                              ////
2379
//////////////////////////////////////////////////////////////////////
2380
`timescale 1ns/1ns
2381 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);
2382 83 unneback
parameter adr_width = 10;
2383
parameter max_burst_width = 4;
2384 85 unneback
input cyc_i, stb_i, we_i;
2385 83 unneback
input [2:0] cti_i;
2386
input [1:0] bte_i;
2387
input [adr_width-1:0] adr_i;
2388
output [adr_width-1:0] adr_o;
2389
output ack_o;
2390
input clk, rst;
2391
reg [adr_width-1:0] adr;
2392 90 unneback
wire [max_burst_width-1:0] to_adr;
2393 91 unneback
reg [max_burst_width-1:0] last_adr;
2394 92 unneback
reg last_cycle;
2395
localparam idle_or_eoc = 1'b0;
2396
localparam cyc_or_ws   = 1'b1;
2397 91 unneback
always @ (posedge clk or posedge rst)
2398
if (rst)
2399
    last_adr <= {max_burst_width{1'b0}};
2400
else
2401
    if (stb_i)
2402 92 unneback
        last_adr <=adr_o[max_burst_width-1:0];
2403 83 unneback
generate
2404
if (max_burst_width==0) begin : inst_0
2405 97 unneback
        reg ack_o;
2406
        assign adr_o = adr_i;
2407
        always @ (posedge clk or posedge rst)
2408
        if (rst)
2409
            ack_o <= 1'b0;
2410
        else
2411
            ack_o <= cyc_i & stb_i & !ack_o;
2412 83 unneback
end else begin
2413
    always @ (posedge clk or posedge rst)
2414
    if (rst)
2415 92 unneback
        last_cycle <= idle_or_eoc;
2416 83 unneback
    else
2417 92 unneback
        last_cycle <= (!cyc_i) ? idle_or_eoc : //idle
2418
                      (cyc_i & ack_o & (cti_i==3'b000 | cti_i==3'b111)) ? idle_or_eoc : // eoc
2419
                      (cyc_i & !stb_i) ? cyc_or_ws : //ws
2420
                      cyc_or_ws; // cyc
2421
    assign to_adr = (last_cycle==idle_or_eoc) ? adr_i[max_burst_width-1:0] : adr[max_burst_width-1:0];
2422 85 unneback
    assign adr_o[max_burst_width-1:0] = (we_i) ? adr_i[max_burst_width-1:0] :
2423 91 unneback
                                        (!stb_i) ? last_adr :
2424 92 unneback
                                        (last_cycle==idle_or_eoc) ? adr_i[max_burst_width-1:0] :
2425 85 unneback
                                        adr[max_burst_width-1:0];
2426 92 unneback
    assign ack_o = (last_cycle==cyc_or_ws) & stb_i;
2427 83 unneback
end
2428
endgenerate
2429
generate
2430
if (max_burst_width==2) begin : inst_2
2431
    always @ (posedge clk or posedge rst)
2432
    if (rst)
2433
        adr <= 2'h0;
2434
    else
2435
        if (cyc_i & stb_i)
2436
            adr[1:0] <= to_adr[1:0] + 2'd1;
2437
        else
2438
            adr <= to_adr[1:0];
2439
end
2440
endgenerate
2441
generate
2442
if (max_burst_width==3) begin : inst_3
2443
    always @ (posedge clk or posedge rst)
2444
    if (rst)
2445
        adr <= 3'h0;
2446
    else
2447
        if (cyc_i & stb_i)
2448
            case (bte_i)
2449
            2'b01: adr[2:0] <= {to_adr[2],to_adr[1:0] + 2'd1};
2450
            default: adr[3:0] <= to_adr[2:0] + 3'd1;
2451
            endcase
2452
        else
2453
            adr <= to_adr[2:0];
2454
end
2455
endgenerate
2456
generate
2457
if (max_burst_width==4) begin : inst_4
2458
    always @ (posedge clk or posedge rst)
2459
    if (rst)
2460
        adr <= 4'h0;
2461
    else
2462 91 unneback
        if (stb_i) // | (!stb_i & last_cycle!=ws)) // for !stb_i restart with adr_i +1, only inc once
2463 83 unneback
            case (bte_i)
2464
            2'b01: adr[3:0] <= {to_adr[3:2],to_adr[1:0] + 2'd1};
2465
            2'b10: adr[3:0] <= {to_adr[3],to_adr[2:0] + 3'd1};
2466
            default: adr[3:0] <= to_adr + 4'd1;
2467
            endcase
2468
        else
2469
            adr <= to_adr[3:0];
2470
end
2471
endgenerate
2472
generate
2473
if (adr_width > max_burst_width) begin : pass_through
2474
    assign adr_o[adr_width-1:max_burst_width] = adr_i[adr_width-1:max_burst_width];
2475
end
2476
endgenerate
2477
endmodule
2478
// async wb3 - wb3 bridge
2479
`timescale 1ns/1ns
2480 18 unneback
module vl_wb3wb3_bridge (
2481 12 unneback
        // wishbone slave side
2482
        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,
2483
        // wishbone master side
2484
        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);
2485 95 unneback
parameter style = "FIFO"; // valid: simple, FIFO
2486
parameter addr_width = 4;
2487 12 unneback
input [31:0] wbs_dat_i;
2488
input [31:2] wbs_adr_i;
2489
input [3:0]  wbs_sel_i;
2490
input [1:0]  wbs_bte_i;
2491
input [2:0]  wbs_cti_i;
2492
input wbs_we_i, wbs_cyc_i, wbs_stb_i;
2493
output [31:0] wbs_dat_o;
2494 14 unneback
output wbs_ack_o;
2495 12 unneback
input wbs_clk, wbs_rst;
2496
output [31:0] wbm_dat_o;
2497
output reg [31:2] wbm_adr_o;
2498
output [3:0]  wbm_sel_o;
2499
output reg [1:0]  wbm_bte_o;
2500
output reg [2:0]  wbm_cti_o;
2501 14 unneback
output reg wbm_we_o;
2502
output wbm_cyc_o;
2503 12 unneback
output wbm_stb_o;
2504
input [31:0]  wbm_dat_i;
2505
input wbm_ack_i;
2506
input wbm_clk, wbm_rst;
2507
// bte
2508
parameter linear       = 2'b00;
2509
parameter wrap4        = 2'b01;
2510
parameter wrap8        = 2'b10;
2511
parameter wrap16       = 2'b11;
2512
// cti
2513
parameter classic      = 3'b000;
2514
parameter incburst     = 3'b010;
2515
parameter endofburst   = 3'b111;
2516 95 unneback
localparam wbs_adr  = 1'b0;
2517
localparam wbs_data = 1'b1;
2518
localparam wbm_adr0      = 2'b00;
2519
localparam wbm_adr1      = 2'b01;
2520
localparam wbm_data      = 2'b10;
2521
localparam wbm_data_wait = 2'b11;
2522 12 unneback
reg [1:0] wbs_bte_reg;
2523
reg wbs;
2524
wire wbs_eoc_alert, wbm_eoc_alert;
2525
reg wbs_eoc, wbm_eoc;
2526
reg [1:0] wbm;
2527 14 unneback
wire [1:16] wbs_count, wbm_count;
2528 12 unneback
wire [35:0] a_d, a_q, b_d, b_q;
2529
wire a_wr, a_rd, a_fifo_full, a_fifo_empty, b_wr, b_rd, b_fifo_full, b_fifo_empty;
2530
reg a_rd_reg;
2531
wire b_rd_adr, b_rd_data;
2532 14 unneback
wire b_rd_data_reg;
2533
wire [35:0] temp;
2534 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]);
2535
always @ (posedge wbs_clk or posedge wbs_rst)
2536
if (wbs_rst)
2537
        wbs_eoc <= 1'b0;
2538
else
2539
        if (wbs==wbs_adr & wbs_stb_i & !a_fifo_full)
2540 78 unneback
                wbs_eoc <= (wbs_bte_i==linear) | (wbs_cti_i==3'b111);
2541 12 unneback
        else if (wbs_eoc_alert & (a_rd | a_wr))
2542
                wbs_eoc <= 1'b1;
2543 18 unneback
vl_cnt_shreg_ce_clear # ( .length(16))
2544 12 unneback
    cnt0 (
2545
        .cke(wbs_ack_o),
2546
        .clear(wbs_eoc),
2547
        .q(wbs_count),
2548
        .rst(wbs_rst),
2549
        .clk(wbs_clk));
2550
always @ (posedge wbs_clk or posedge wbs_rst)
2551
if (wbs_rst)
2552
        wbs <= wbs_adr;
2553
else
2554 75 unneback
        if ((wbs==wbs_adr) & wbs_cyc_i & wbs_stb_i & a_fifo_empty)
2555 12 unneback
                wbs <= wbs_data;
2556
        else if (wbs_eoc & wbs_ack_o)
2557
                wbs <= wbs_adr;
2558
// wbs FIFO
2559 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};
2560
assign a_wr = (wbs==wbs_adr)  ? wbs_cyc_i & wbs_stb_i & a_fifo_empty :
2561 12 unneback
              (wbs==wbs_data) ? wbs_we_i  & wbs_stb_i & !a_fifo_full :
2562
              1'b0;
2563
assign a_rd = !a_fifo_empty;
2564
always @ (posedge wbs_clk or posedge wbs_rst)
2565
if (wbs_rst)
2566
        a_rd_reg <= 1'b0;
2567
else
2568
        a_rd_reg <= a_rd;
2569
assign wbs_ack_o = a_rd_reg | (a_wr & wbs==wbs_data);
2570
assign wbs_dat_o = a_q[35:4];
2571
always @ (posedge wbs_clk or posedge wbs_rst)
2572
if (wbs_rst)
2573 13 unneback
        wbs_bte_reg <= 2'b00;
2574 12 unneback
else
2575 13 unneback
        wbs_bte_reg <= wbs_bte_i;
2576 12 unneback
// wbm FIFO
2577
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]);
2578
always @ (posedge wbm_clk or posedge wbm_rst)
2579
if (wbm_rst)
2580
        wbm_eoc <= 1'b0;
2581
else
2582
        if (wbm==wbm_adr0 & !b_fifo_empty)
2583
                wbm_eoc <= b_q[4:3] == linear;
2584
        else if (wbm_eoc_alert & wbm_ack_i)
2585
                wbm_eoc <= 1'b1;
2586
always @ (posedge wbm_clk or posedge wbm_rst)
2587
if (wbm_rst)
2588
        wbm <= wbm_adr0;
2589
else
2590 33 unneback
/*
2591 12 unneback
    if ((wbm==wbm_adr0 & !b_fifo_empty) |
2592
        (wbm==wbm_adr1 & !b_fifo_empty & wbm_we_o) |
2593
        (wbm==wbm_adr1 & !wbm_we_o) |
2594
        (wbm==wbm_data & wbm_ack_i & wbm_eoc))
2595
        wbm <= {wbm[0],!(wbm[1] ^ wbm[0])};  // count sequence 00,01,10
2596 33 unneback
*/
2597
    case (wbm)
2598
    wbm_adr0:
2599
        if (!b_fifo_empty)
2600
            wbm <= wbm_adr1;
2601
    wbm_adr1:
2602
        if (!wbm_we_o | (!b_fifo_empty & wbm_we_o))
2603
            wbm <= wbm_data;
2604
    wbm_data:
2605
        if (wbm_ack_i & wbm_eoc)
2606
            wbm <= wbm_adr0;
2607
        else if (b_fifo_empty & wbm_we_o & wbm_ack_i)
2608
            wbm <= wbm_data_wait;
2609
    wbm_data_wait:
2610
        if (!b_fifo_empty)
2611
            wbm <= wbm_data;
2612
    endcase
2613 12 unneback
assign b_d = {wbm_dat_i,4'b1111};
2614
assign b_wr = !wbm_we_o & wbm_ack_i;
2615
assign b_rd_adr  = (wbm==wbm_adr0 & !b_fifo_empty);
2616
assign b_rd_data = (wbm==wbm_adr1 & !b_fifo_empty & wbm_we_o) ? 1'b1 : // b_q[`WE]
2617
                   (wbm==wbm_data & !b_fifo_empty & wbm_we_o & wbm_ack_i & !wbm_eoc) ? 1'b1 :
2618 33 unneback
                   (wbm==wbm_data_wait & !b_fifo_empty) ? 1'b1 :
2619 12 unneback
                   1'b0;
2620
assign b_rd = b_rd_adr | b_rd_data;
2621 18 unneback
vl_dff dff1 ( .d(b_rd_data), .q(b_rd_data_reg), .clk(wbm_clk), .rst(wbm_rst));
2622
vl_dff_ce # ( .width(36)) dff2 ( .d(b_q), .ce(b_rd_data_reg), .q(temp), .clk(wbm_clk), .rst(wbm_rst));
2623 12 unneback
assign {wbm_dat_o,wbm_sel_o} = (b_rd_data_reg) ? b_q : temp;
2624 18 unneback
vl_cnt_shreg_ce_clear # ( .length(16))
2625 12 unneback
    cnt1 (
2626
        .cke(wbm_ack_i),
2627
        .clear(wbm_eoc),
2628
        .q(wbm_count),
2629
        .rst(wbm_rst),
2630
        .clk(wbm_clk));
2631 33 unneback
assign wbm_cyc_o = (wbm==wbm_data | wbm==wbm_data_wait);
2632
assign wbm_stb_o = (wbm==wbm_data);
2633 12 unneback
always @ (posedge wbm_clk or posedge wbm_rst)
2634
if (wbm_rst)
2635
        {wbm_adr_o,wbm_we_o,wbm_bte_o,wbm_cti_o} <= {30'h0,1'b0,linear,classic};
2636
else begin
2637
        if (wbm==wbm_adr0 & !b_fifo_empty)
2638
                {wbm_adr_o,wbm_we_o,wbm_bte_o,wbm_cti_o} <= b_q;
2639
        else if (wbm_eoc_alert & wbm_ack_i)
2640
                wbm_cti_o <= endofburst;
2641
end
2642
//async_fifo_dw_simplex_top
2643
vl_fifo_2r2w_async_simplex
2644
# ( .data_width(36), .addr_width(addr_width))
2645
fifo (
2646
    // a side
2647
    .a_d(a_d),
2648
    .a_wr(a_wr),
2649
    .a_fifo_full(a_fifo_full),
2650
    .a_q(a_q),
2651
    .a_rd(a_rd),
2652
    .a_fifo_empty(a_fifo_empty),
2653
    .a_clk(wbs_clk),
2654
    .a_rst(wbs_rst),
2655
    // b side
2656
    .b_d(b_d),
2657
    .b_wr(b_wr),
2658
    .b_fifo_full(b_fifo_full),
2659
    .b_q(b_q),
2660
    .b_rd(b_rd),
2661
    .b_fifo_empty(b_fifo_empty),
2662
    .b_clk(wbm_clk),
2663
    .b_rst(wbm_rst)
2664
    );
2665
endmodule
2666 75 unneback
module vl_wb3avalon_bridge (
2667
        // wishbone slave side
2668
        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,
2669 77 unneback
        // avalon master side
2670 75 unneback
        readdata, readdatavalid, address, read, be, write, burstcount, writedata, waitrequest, beginbursttransfer, clk, rst);
2671 85 unneback
parameter linewrapburst = 1'b0;
2672 75 unneback
input [31:0] wbs_dat_i;
2673
input [31:2] wbs_adr_i;
2674
input [3:0]  wbs_sel_i;
2675
input [1:0]  wbs_bte_i;
2676
input [2:0]  wbs_cti_i;
2677 83 unneback
input wbs_we_i;
2678
input wbs_cyc_i;
2679
input wbs_stb_i;
2680 75 unneback
output [31:0] wbs_dat_o;
2681
output wbs_ack_o;
2682
input wbs_clk, wbs_rst;
2683
input [31:0] readdata;
2684
output [31:0] writedata;
2685
output [31:2] address;
2686
output [3:0]  be;
2687
output write;
2688 81 unneback
output read;
2689 75 unneback
output beginbursttransfer;
2690
output [3:0] burstcount;
2691
input readdatavalid;
2692
input waitrequest;
2693
input clk;
2694
input rst;
2695
wire [1:0] wbm_bte_o;
2696
wire [2:0] wbm_cti_o;
2697
wire wbm_we_o, wbm_cyc_o, wbm_stb_o, wbm_ack_i;
2698
reg last_cyc;
2699 79 unneback
reg [3:0] counter;
2700 82 unneback
reg read_busy;
2701 75 unneback
always @ (posedge clk or posedge rst)
2702
if (rst)
2703
    last_cyc <= 1'b0;
2704
else
2705
    last_cyc <= wbm_cyc_o;
2706 79 unneback
always @ (posedge clk or posedge rst)
2707
if (rst)
2708 82 unneback
    read_busy <= 1'b0;
2709 79 unneback
else
2710 82 unneback
    if (read & !waitrequest)
2711
        read_busy <= 1'b1;
2712
    else if (wbm_ack_i & wbm_cti_o!=3'b010)
2713
        read_busy <= 1'b0;
2714
assign read = wbm_cyc_o & wbm_stb_o & !wbm_we_o & !read_busy;
2715 75 unneback
assign beginbursttransfer = (!last_cyc & wbm_cyc_o) & wbm_cti_o==3'b010;
2716
assign burstcount = (wbm_bte_o==2'b01) ? 4'd4 :
2717
                    (wbm_bte_o==2'b10) ? 4'd8 :
2718 78 unneback
                    (wbm_bte_o==2'b11) ? 4'd16:
2719
                    4'd1;
2720 82 unneback
assign wbm_ack_i = (readdatavalid) | (write & !waitrequest);
2721 79 unneback
always @ (posedge clk or posedge rst)
2722
if (rst) begin
2723
    counter <= 4'd0;
2724
end else
2725 80 unneback
    if (wbm_we_o) begin
2726
        if (!waitrequest & !last_cyc & wbm_cyc_o) begin
2727 85 unneback
            counter <= burstcount -4'd1;
2728 80 unneback
        end else if (waitrequest & !last_cyc & wbm_cyc_o) begin
2729
            counter <= burstcount;
2730
        end else if (!waitrequest & wbm_stb_o) begin
2731
            counter <= counter - 4'd1;
2732
        end
2733 82 unneback
    end
2734 81 unneback
assign write = wbm_cyc_o & wbm_stb_o & wbm_we_o & counter!=4'd0;
2735 77 unneback
vl_wb3wb3_bridge wbwb3inst (
2736 75 unneback
    // wishbone slave side
2737
    .wbs_dat_i(wbs_dat_i),
2738
    .wbs_adr_i(wbs_adr_i),
2739
    .wbs_sel_i(wbs_sel_i),
2740
    .wbs_bte_i(wbs_bte_i),
2741
    .wbs_cti_i(wbs_cti_i),
2742
    .wbs_we_i(wbs_we_i),
2743
    .wbs_cyc_i(wbs_cyc_i),
2744
    .wbs_stb_i(wbs_stb_i),
2745
    .wbs_dat_o(wbs_dat_o),
2746
    .wbs_ack_o(wbs_ack_o),
2747
    .wbs_clk(wbs_clk),
2748
    .wbs_rst(wbs_rst),
2749
    // wishbone master side
2750
    .wbm_dat_o(writedata),
2751 78 unneback
    .wbm_adr_o(address),
2752 75 unneback
    .wbm_sel_o(be),
2753
    .wbm_bte_o(wbm_bte_o),
2754
    .wbm_cti_o(wbm_cti_o),
2755
    .wbm_we_o(wbm_we_o),
2756
    .wbm_cyc_o(wbm_cyc_o),
2757
    .wbm_stb_o(wbm_stb_o),
2758
    .wbm_dat_i(readdata),
2759
    .wbm_ack_i(wbm_ack_i),
2760
    .wbm_clk(clk),
2761
    .wbm_rst(rst));
2762
endmodule
2763 49 unneback
// WB RAM with byte enable
2764 101 unneback
module vl_wb_ram (
2765 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,
2766 101 unneback
    wbs_dat_o, wbs_ack_o, wbs_stall_o, wb_clk, wb_rst);
2767
parameter adr_width = 16;
2768
parameter mem_size = 1<<adr_width;
2769
parameter dat_width = 32;
2770
parameter max_burst_width = 4; // only used for B3
2771
parameter mode = "B3"; // valid options: B3, B4
2772 60 unneback
parameter memory_init = 1;
2773
parameter memory_file = "vl_ram.vmem";
2774 101 unneback
input [dat_width-1:0] wbs_dat_i;
2775
input [adr_width-1:0] wbs_adr_i;
2776
input [2:0] wbs_cti_i;
2777
input [1:0] wbs_bte_i;
2778
input [dat_width/8-1:0] wbs_sel_i;
2779 70 unneback
input wbs_we_i, wbs_stb_i, wbs_cyc_i;
2780 101 unneback
output [dat_width-1:0] wbs_dat_o;
2781 70 unneback
output wbs_ack_o;
2782 101 unneback
output wbs_stall_o;
2783 71 unneback
input wb_clk, wb_rst;
2784 101 unneback
wire [adr_width-1:0] adr;
2785
wire we;
2786
generate
2787
if (mode=="B3") begin : B3_inst
2788
vl_wb_adr_inc # ( .adr_width(adr_width), .max_burst_width(max_burst_width)) adr_inc0 (
2789 83 unneback
    .cyc_i(wbs_cyc_i),
2790
    .stb_i(wbs_stb_i),
2791
    .cti_i(wbs_cti_i),
2792
    .bte_i(wbs_bte_i),
2793
    .adr_i(wbs_adr_i),
2794 85 unneback
    .we_i(wbs_we_i),
2795 83 unneback
    .ack_o(wbs_ack_o),
2796
    .adr_o(adr),
2797
    .clk(wb_clk),
2798
    .rst(wb_rst));
2799 101 unneback
assign we = wbs_we_i & wbs_ack_o;
2800
end else if (mode=="B4") begin : B4_inst
2801
reg wbs_ack_o_reg;
2802
always @ (posedge wb_clk or posedge wb_rst)
2803
    if (wb_rst)
2804
        wbs_ack_o_reg <= 1'b0;
2805
    else
2806
        wbs_ack_o_reg <= wbs_stb_i & wbs_cyc_i;
2807
assign wbs_ack_o = wbs_ack_o_reg;
2808
assign wbs_stall_o = 1'b0;
2809
assign adr = wbs_adr_i;
2810
assign we = wbs_we_i & wbs_cyc_i & wbs_stb_i;
2811
end
2812
endgenerate
2813 100 unneback
vl_ram_be # (
2814
    .data_width(dat_width),
2815
    .addr_width(adr_width),
2816
    .mem_size(mem_size),
2817
    .memory_init(memory_init),
2818
    .memory_file(memory_file))
2819
ram0(
2820 101 unneback
    .d(wbs_dat_i),
2821
    .adr(adr),
2822
    .be(wbs_sel_i),
2823
    .we(we),
2824
    .q(wbs_dat_o),
2825 100 unneback
    .clk(wb_clk)
2826
);
2827 49 unneback
endmodule
2828 103 unneback
// A wishbone compliant RAM module that can be placed in front of other memory controllers
2829
module vl_wb_shadow_ram (
2830
    wbs_dat_i, wbs_adr_i, wbs_cti_i, wbs_bte_i, wbs_sel_i, wbs_we_i, wbs_stb_i, wbs_cyc_i,
2831
    wbs_dat_o, wbs_ack_o, wbs_stall_o,
2832
    wbm_dat_o, wbm_adr_o, wbm_cti_o, wbm_bte_o, wbm_sel_o, wbm_we_o, wbm_stb_o, wbm_cyc_o,
2833
    wbm_dat_i, wbm_ack_i, wbm_stall_i,
2834
    wb_clk, wb_rst);
2835
parameter dat_width = 32;
2836
parameter mode = "B4";
2837
parameter max_burst_width = 4; // only used for B3
2838
parameter shadow_mem_adr_width = 10;
2839
parameter shadow_mem_size = 1024;
2840
parameter shadow_mem_init = 2;
2841
parameter shadow_mem_file = "vl_ram.v";
2842
parameter main_mem_adr_width = 24;
2843
input [dat_width-1:0] wbs_dat_i;
2844
input [main_mem_adr_width-1:0] wbs_adr_i;
2845
input [2:0] wbs_cti_i;
2846
input [1:0] wbs_bte_i;
2847
input [dat_width/8-1:0] wbs_sel_i;
2848
input wbs_we_i, wbs_stb_i, wbs_cyc_i;
2849
output [dat_width-1:0] wbs_dat_o;
2850
output wbs_ack_o;
2851
output wbs_stall_o;
2852
output [dat_width-1:0] wbm_dat_o;
2853
output [main_mem_adr_width-1:0] wbm_adr_o;
2854
output [2:0] wbm_cti_o;
2855
output [1:0] wbm_bte_o;
2856
output [dat_width/8-1:0] wbm_sel_o;
2857
output wbm_we_o, wbm_stb_o, wbm_cyc_o;
2858
input [dat_width-1:0] wbm_dat_i;
2859
input wbm_ack_i, wbm_stall_i;
2860
input wb_clk, wb_rst;
2861
generate
2862
if (shadow_mem_size>0) begin : shadow_ram_inst
2863
wire cyc;
2864
wire [dat_width-1:0] dat;
2865
wire stall, ack;
2866
assign cyc = wbs_cyc_i & (wbs_adr_i<=shadow_mem_size);
2867
vl_wb_ram # (
2868
    .dat_width(dat_width),
2869
    .adr_width(shadow_mem_adr_width),
2870
    .mem_size(shadow_mem_size),
2871
    .memory_init(shadow_mem_init),
2872 117 unneback
    .memory_file(shadow_mem_file),
2873 103 unneback
    .mode(mode))
2874
shadow_mem0 (
2875
    .wbs_dat_i(wbs_dat_i),
2876
    .wbs_adr_i(wbs_adr_i[shadow_mem_adr_width-1:0]),
2877
    .wbs_sel_i(wbs_sel_i),
2878
    .wbs_we_i (wbs_we_i),
2879
    .wbs_bte_i(wbs_bte_i),
2880
    .wbs_cti_i(wbs_cti_i),
2881
    .wbs_stb_i(wbs_stb_i),
2882
    .wbs_cyc_i(cyc),
2883
    .wbs_dat_o(dat),
2884
    .wbs_stall_o(stall),
2885
    .wbs_ack_o(ack),
2886
    .wb_clk(wb_clk),
2887
    .wb_rst(wb_rst));
2888
assign {wbm_dat_o, wbm_adr_o, wbm_cti_o, wbm_bte_o, wbm_sel_o, wbm_we_o, wbm_stb_o} =
2889
       {wbs_dat_i, wbs_adr_i, wbs_cti_i, wbs_bte_i, wbs_sel_i, wbs_we_i, wbs_stb_i};
2890
assign wbm_cyc_o = wbs_cyc_i & (wbs_adr_i>shadow_mem_size);
2891
assign wbs_dat_o = (dat & {dat_width{cyc}}) | (wbm_dat_i & {dat_width{wbm_cyc_o}});
2892
assign wbs_ack_o = (ack & cyc) | (wbm_ack_i & wbm_cyc_o);
2893
assign wbs_stall_o = (stall & cyc) | (wbm_stall_i & wbm_cyc_o);
2894
end else begin : no_shadow_ram_inst
2895
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} =
2896
       {wbs_dat_i, wbs_adr_i, wbs_cti_i, wbs_bte_i, wbs_sel_i, wbs_we_i, wbs_stb_i, wbs_cyc_i};
2897
assign {wbs_dat_o, wbs_ack_o, wbs_stall_o} = {wbm_dat_i, wbm_ack_i, wbm_stall_i};
2898
end
2899
endgenerate
2900
endmodule
2901 17 unneback
// WB ROM
2902 48 unneback
module vl_wb_b4_rom (
2903
    wb_adr_i, wb_stb_i, wb_cyc_i,
2904
    wb_dat_o, stall_o, wb_ack_o, wb_clk, wb_rst);
2905
    parameter dat_width = 32;
2906
    parameter dat_default = 32'h15000000;
2907
    parameter adr_width = 32;
2908
/*
2909
`ifndef ROM
2910
`define ROM "rom.v"
2911
`endif
2912
*/
2913
    input [adr_width-1:2]   wb_adr_i;
2914
    input                   wb_stb_i;
2915
    input                   wb_cyc_i;
2916
    output [dat_width-1:0]  wb_dat_o;
2917
    reg [dat_width-1:0]     wb_dat_o;
2918
    output                  wb_ack_o;
2919
    reg                     wb_ack_o;
2920
    output                  stall_o;
2921
    input                   wb_clk;
2922
    input                   wb_rst;
2923
always @ (posedge wb_clk or posedge wb_rst)
2924
    if (wb_rst)
2925
        wb_dat_o <= {dat_width{1'b0}};
2926
    else
2927
         case (wb_adr_i[adr_width-1:2])
2928
`ifdef ROM
2929
`include `ROM
2930
`endif
2931
           default:
2932
             wb_dat_o <= dat_default;
2933
         endcase // case (wb_adr_i)
2934
always @ (posedge wb_clk or posedge wb_rst)
2935
    if (wb_rst)
2936
        wb_ack_o <= 1'b0;
2937
    else
2938
        wb_ack_o <= wb_stb_i & wb_cyc_i;
2939
assign stall_o = 1'b0;
2940
endmodule
2941
// WB ROM
2942 18 unneback
module vl_wb_boot_rom (
2943 17 unneback
    wb_adr_i, wb_stb_i, wb_cyc_i,
2944 18 unneback
    wb_dat_o, wb_ack_o, hit_o, wb_clk, wb_rst);
2945
    parameter adr_hi = 31;
2946
    parameter adr_lo = 28;
2947
    parameter adr_sel = 4'hf;
2948
    parameter addr_width = 5;
2949 33 unneback
/*
2950
`ifndef BOOT_ROM
2951
`define BOOT_ROM "boot_rom.v"
2952
`endif
2953
*/
2954 18 unneback
    input [adr_hi:2]    wb_adr_i;
2955
    input               wb_stb_i;
2956
    input               wb_cyc_i;
2957
    output [31:0]        wb_dat_o;
2958
    output              wb_ack_o;
2959
    output              hit_o;
2960
    input               wb_clk;
2961
    input               wb_rst;
2962
    wire hit;
2963
    reg [31:0] wb_dat;
2964
    reg wb_ack;
2965
assign hit = wb_adr_i[adr_hi:adr_lo] == adr_sel;
2966 17 unneback
always @ (posedge wb_clk or posedge wb_rst)
2967
    if (wb_rst)
2968 18 unneback
        wb_dat <= 32'h15000000;
2969 17 unneback
    else
2970 18 unneback
         case (wb_adr_i[addr_width-1:2])
2971 33 unneback
`ifdef BOOT_ROM
2972
`include `BOOT_ROM
2973
`endif
2974 17 unneback
           /*
2975
            // Zero r0 and jump to 0x00000100
2976 18 unneback
 
2977
            1 : wb_dat <= 32'hA8200000;
2978
            2 : wb_dat <= 32'hA8C00100;
2979
            3 : wb_dat <= 32'h44003000;
2980
            4 : wb_dat <= 32'h15000000;
2981 17 unneback
            */
2982
           default:
2983 18 unneback
             wb_dat <= 32'h00000000;
2984 17 unneback
         endcase // case (wb_adr_i)
2985
always @ (posedge wb_clk or posedge wb_rst)
2986
    if (wb_rst)
2987 18 unneback
        wb_ack <= 1'b0;
2988 17 unneback
    else
2989 18 unneback
        wb_ack <= wb_stb_i & wb_cyc_i & hit & !wb_ack;
2990
assign hit_o = hit;
2991
assign wb_dat_o = wb_dat & {32{wb_ack}};
2992
assign wb_ack_o = wb_ack;
2993 17 unneback
endmodule
2994 106 unneback
module vl_wb_dpram (
2995
        // wishbone slave side a
2996
        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,
2997
        wbsa_clk, wbsa_rst,
2998
        // wishbone slave side b
2999
        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,
3000
        wbsb_clk, wbsb_rst);
3001
parameter data_width_a = 32;
3002
parameter data_width_b = data_width_a;
3003
parameter addr_width_a = 8;
3004
localparam addr_width_b = data_width_a * addr_width_a / data_width_b;
3005
parameter mem_size = (addr_width_a>addr_width_b) ? (1<<addr_width_a) : (1<<addr_width_b);
3006
parameter max_burst_width_a = 4;
3007
parameter max_burst_width_b = max_burst_width_a;
3008
parameter mode = "B3";
3009 109 unneback
parameter memory_init = 0;
3010
parameter memory_file = "vl_ram.v";
3011 106 unneback
input [data_width_a-1:0] wbsa_dat_i;
3012
input [addr_width_a-1:0] wbsa_adr_i;
3013
input [data_width_a/8-1:0] wbsa_sel_i;
3014
input [2:0] wbsa_cti_i;
3015
input [1:0] wbsa_bte_i;
3016
input wbsa_we_i, wbsa_cyc_i, wbsa_stb_i;
3017
output [data_width_a-1:0] wbsa_dat_o;
3018 109 unneback
output wbsa_ack_o;
3019 106 unneback
output wbsa_stall_o;
3020
input wbsa_clk, wbsa_rst;
3021
input [data_width_b-1:0] wbsb_dat_i;
3022
input [addr_width_b-1:0] wbsb_adr_i;
3023
input [data_width_b/8-1:0] wbsb_sel_i;
3024
input [2:0] wbsb_cti_i;
3025
input [1:0] wbsb_bte_i;
3026
input wbsb_we_i, wbsb_cyc_i, wbsb_stb_i;
3027
output [data_width_b-1:0] wbsb_dat_o;
3028 109 unneback
output wbsb_ack_o;
3029 106 unneback
output wbsb_stall_o;
3030
input wbsb_clk, wbsb_rst;
3031
wire [addr_width_a-1:0] adr_a;
3032
wire [addr_width_b-1:0] adr_b;
3033
wire we_a, we_b;
3034
generate
3035
if (mode=="B3") begin : b3_inst
3036
vl_wb_adr_inc # ( .adr_width(addr_width_a), .max_burst_width(max_burst_width_a)) adr_inc0 (
3037
    .cyc_i(wbsa_cyc_i),
3038
    .stb_i(wbsa_stb_i),
3039
    .cti_i(wbsa_cti_i),
3040
    .bte_i(wbsa_bte_i),
3041
    .adr_i(wbsa_adr_i),
3042
    .we_i(wbsa_we_i),
3043
    .ack_o(wbsa_ack_o),
3044
    .adr_o(adr_a),
3045
    .clk(wbsa_clk),
3046
    .rst(wbsa_rst));
3047
assign we_a = wbsa_we_i & wbsa_ack_o;
3048
vl_wb_adr_inc # ( .adr_width(addr_width_b), .max_burst_width(max_burst_width_b)) adr_inc1 (
3049
    .cyc_i(wbsb_cyc_i),
3050
    .stb_i(wbsb_stb_i),
3051
    .cti_i(wbsb_cti_i),
3052
    .bte_i(wbsb_bte_i),
3053
    .adr_i(wbsb_adr_i),
3054
    .we_i(wbsb_we_i),
3055
    .ack_o(wbsb_ack_o),
3056
    .adr_o(adr_b),
3057
    .clk(wbsb_clk),
3058
    .rst(wbsb_rst));
3059
assign we_b = wbsb_we_i & wbsb_ack_o;
3060
end else if (mode=="B4") begin : b4_inst
3061 109 unneback
vl_dff dffacka ( .d(wbsa_stb_i & wbsa_cyc_i), .q(wbsa_ack_o), .clk(wbsa_clk), .rst(wbsa_rst));
3062 106 unneback
assign wbsa_stall_o = 1'b0;
3063
assign we_a = wbsa_we_i & wbsa_cyc_i & wbsa_stb_i;
3064 109 unneback
vl_dff dffackb ( .d(wbsb_stb_i & wbsb_cyc_i), .q(wbsb_ack_o), .clk(wbsb_clk), .rst(wbsb_rst));
3065 106 unneback
assign wbsb_stall_o = 1'b0;
3066
assign we_b = wbsb_we_i & wbsb_cyc_i & wbsb_stb_i;
3067
end
3068
endgenerate
3069 109 unneback
vl_dpram_be_2r2w # ( .a_data_width(data_width_a), .a_addr_width(addr_width_a), .mem_size(mem_size),
3070 110 unneback
                 .b_data_width(data_width_b),
3071 109 unneback
                 .memory_init(memory_init), .memory_file(memory_file))
3072 106 unneback
ram_i (
3073
    .d_a(wbsa_dat_i),
3074
    .q_a(wbsa_dat_o),
3075
    .adr_a(adr_a),
3076
    .be_a(wbsa_sel_i),
3077
    .we_a(we_a),
3078
    .clk_a(wbsa_clk),
3079
    .d_b(wbsb_dat_i),
3080
    .q_b(wbsb_dat_o),
3081
    .adr_b(adr_b),
3082
    .be_b(wbsb_sel_i),
3083
    .we_b(we_b),
3084
    .clk_b(wbsb_clk) );
3085
endmodule
3086 101 unneback
module vl_wb_cache (
3087 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,
3088 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
3089 97 unneback
);
3090
parameter dw_s = 32;
3091
parameter aw_s = 24;
3092
parameter dw_m = dw_s;
3093 124 unneback
//localparam aw_m = dw_s * aw_s / dw_m;
3094
localparam aw_m =
3095 126 unneback
        (dw_s==dw_m) ? aw_s :
3096
        (dw_s==dw_m*2) ? aw_s+1 :
3097
        (dw_s==dw_m*4) ? aw_s+2 :
3098
        (dw_s==dw_m*8) ? aw_s+3 :
3099
        (dw_s==dw_m*16) ? aw_s+4 :
3100
        (dw_s==dw_m*32) ? aw_s+5 :
3101
        (dw_s==dw_m/2) ? aw_s-1 :
3102 127 unneback
        (dw_s==dw_m/4) ? aw_s-2 :
3103 126 unneback
        (dw_s==dw_m/8) ? aw_s-3 :
3104
        (dw_s==dw_m/16) ? aw_s-4 :
3105
        (dw_s==dw_m/32) ? aw_s-5 : 0;
3106 100 unneback
parameter wbs_max_burst_width = 4;
3107 103 unneback
parameter wbs_mode = "B3";
3108 97 unneback
parameter async = 1; // wbs_clk != wbm_clk
3109
parameter nr_of_ways = 1;
3110
parameter aw_offset = 4; // 4 => 16 words per cache line
3111
parameter aw_slot = 10;
3112 100 unneback
parameter valid_mem = 0;
3113
parameter debug = 0;
3114
localparam aw_b_offset = aw_offset * dw_s / dw_m;
3115 98 unneback
localparam aw_tag = aw_s - aw_slot - aw_offset;
3116 97 unneback
parameter wbm_burst_size = 4; // valid options 4,8,16
3117 98 unneback
localparam bte = (wbm_burst_size==4) ? 2'b01 : (wbm_burst_size==8) ? 2'b10 : 2'b11;
3118 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;
3119 97 unneback
localparam nr_of_wbm_burst = ((1<<aw_offset)/wbm_burst_size) * dw_s / dw_m;
3120 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;
3121 97 unneback
input [dw_s-1:0] wbs_dat_i;
3122
input [aw_s-1:0] wbs_adr_i; // dont include a1,a0
3123 98 unneback
input [dw_s/8-1:0] wbs_sel_i;
3124 97 unneback
input [2:0] wbs_cti_i;
3125
input [1:0] wbs_bte_i;
3126 98 unneback
input wbs_we_i, wbs_stb_i, wbs_cyc_i;
3127 97 unneback
output [dw_s-1:0] wbs_dat_o;
3128
output wbs_ack_o;
3129 103 unneback
output wbs_stall_o;
3130 97 unneback
input wbs_clk, wbs_rst;
3131
output [dw_m-1:0] wbm_dat_o;
3132
output [aw_m-1:0] wbm_adr_o;
3133
output [dw_m/8-1:0] wbm_sel_o;
3134
output [2:0] wbm_cti_o;
3135
output [1:0] wbm_bte_o;
3136 98 unneback
output wbm_stb_o, wbm_cyc_o, wbm_we_o;
3137 97 unneback
input [dw_m-1:0] wbm_dat_i;
3138
input wbm_ack_i;
3139
input wbm_stall_i;
3140
input wbm_clk, wbm_rst;
3141 100 unneback
wire valid, dirty, hit;
3142 97 unneback
wire [aw_tag-1:0] tag;
3143
wire tag_mem_we;
3144
wire [aw_tag-1:0] wbs_adr_tag;
3145
wire [aw_slot-1:0] wbs_adr_slot;
3146 98 unneback
wire [aw_offset-1:0] wbs_adr_word;
3147
wire [aw_s-1:0] wbs_adr;
3148 97 unneback
reg [1:0] state;
3149
localparam idle = 2'h0;
3150
localparam rdwr = 2'h1;
3151
localparam push = 2'h2;
3152
localparam pull = 2'h3;
3153
wire eoc;
3154 103 unneback
wire we;
3155 97 unneback
// cdc
3156
wire done, mem_alert, mem_done;
3157 98 unneback
// wbm side
3158
reg [aw_m-1:0] wbm_radr;
3159
reg [aw_m-1:0] wbm_wadr;
3160 137 unneback
//wire [aw_slot-1:0] wbm_adr;
3161
wire [aw_m-1:0] wbm_adr;
3162 98 unneback
wire wbm_radr_cke, wbm_wadr_cke;
3163 100 unneback
reg [2:0] phase;
3164
// phase = {we,stb,cyc}
3165
localparam wbm_wait     = 3'b000;
3166
localparam wbm_wr       = 3'b111;
3167
localparam wbm_wr_drain = 3'b101;
3168
localparam wbm_rd       = 3'b011;
3169
localparam wbm_rd_drain = 3'b001;
3170 97 unneback
assign {wbs_adr_tag, wbs_adr_slot, wbs_adr_word} = wbs_adr_i;
3171 100 unneback
generate
3172
if (valid_mem==0) begin : no_valid_mem
3173
assign valid = 1'b1;
3174
end else begin : valid_mem_inst
3175
vl_dpram_1r1w
3176
    # ( .data_width(1), .addr_width(aw_slot), .memory_init(2), .debug(debug))
3177
    valid_mem ( .d_a(1'b1), .adr_a(wbs_adr_slot), .we_a(mem_done), .clk_a(wbm_clk),
3178
                .q_b(valid), .adr_b(wbs_adr_slot), .clk_b(wbs_clk));
3179
end
3180
endgenerate
3181
vl_dpram_1r1w
3182
    # ( .data_width(aw_tag), .addr_width(aw_slot), .memory_init(2), .debug(debug))
3183
    tag_mem ( .d_a(wbs_adr_tag), .adr_a(wbs_adr_slot), .we_a(mem_done), .clk_a(wbm_clk),
3184
              .q_b(tag), .adr_b(wbs_adr_slot), .clk_b(wbs_clk));
3185
assign hit = wbs_adr_tag == tag;
3186
vl_dpram_1r2w
3187
    # ( .data_width(1), .addr_width(aw_slot), .memory_init(2), .debug(debug))
3188
    dirty_mem (
3189
        .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),
3190
        .d_b(1'b0), .adr_b(wbs_adr_slot), .we_b(mem_done), .clk_b(wbm_clk));
3191 103 unneback
generate
3192
if (wbs_mode=="B3") begin : inst_b3
3193 100 unneback
vl_wb_adr_inc # ( .adr_width(aw_s), .max_burst_width(wbs_max_burst_width)) adr_inc0 (
3194
    .cyc_i(wbs_cyc_i & (state==rdwr) & hit & valid),
3195
    .stb_i(wbs_stb_i & (state==rdwr) & hit & valid), // throttle depending on valid
3196 97 unneback
    .cti_i(wbs_cti_i),
3197
    .bte_i(wbs_bte_i),
3198
    .adr_i(wbs_adr_i),
3199
    .we_i (wbs_we_i),
3200
    .ack_o(wbs_ack_o),
3201
    .adr_o(wbs_adr),
3202 100 unneback
    .clk(wbs_clk),
3203
    .rst(wbs_rst));
3204 103 unneback
assign eoc = (wbs_cti_i==3'b000 | wbs_cti_i==3'b111) & wbs_ack_o;
3205
assign we = wbs_cyc_i &  wbs_we_i & wbs_ack_o;
3206
end else if (wbs_mode=="B4") begin : inst_b4
3207
end
3208
endgenerate
3209 131 unneback
localparam cache_mem_b_aw =
3210
    (dw_s==dw_m) ? aw_slot+aw_offset :
3211 133 unneback
    (dw_s==dw_m/2) ? aw_slot+aw_offset-1 :
3212
    (dw_s==dw_m/4) ? aw_slot+aw_offset-2 :
3213
    (dw_s==dw_m/8) ? aw_slot+aw_offset-3 :
3214
    (dw_s==dw_m/16) ? aw_slot+aw_offset-4 :
3215
    (dw_s==dw_m*2) ? aw_slot+aw_offset+1 :
3216
    (dw_s==dw_m*4) ? aw_slot+aw_offset+2 :
3217
    (dw_s==dw_m*8) ? aw_slot+aw_offset+3 :
3218
    (dw_s==dw_m*16) ? aw_slot+aw_offset+4 : 0;
3219 97 unneback
vl_dpram_be_2r2w
3220 100 unneback
    # ( .a_data_width(dw_s), .a_addr_width(aw_slot+aw_offset), .b_data_width(dw_m), .debug(debug))
3221 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),
3222 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));
3223 97 unneback
always @ (posedge wbs_clk or posedge wbs_rst)
3224
if (wbs_rst)
3225 98 unneback
    state <= idle;
3226 97 unneback
else
3227
    case (state)
3228
    idle:
3229
        if (wbs_cyc_i)
3230
            state <= rdwr;
3231
    rdwr:
3232 100 unneback
        casex ({valid, hit, dirty, eoc})
3233
        4'b0xxx: state <= pull;
3234
        4'b11x1: state <= idle;
3235
        4'b101x: state <= push;
3236
        4'b100x: state <= pull;
3237
        endcase
3238 97 unneback
    push:
3239
        if (done)
3240
            state <= rdwr;
3241
    pull:
3242
        if (done)
3243
            state <= rdwr;
3244
    default: state <= idle;
3245
    endcase
3246
// cdc
3247
generate
3248
if (async==1) begin : cdc0
3249 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));
3250 97 unneback
end
3251
else begin : nocdc
3252 100 unneback
    assign mem_alert = state==rdwr & (!valid | !hit);
3253 97 unneback
    assign done = mem_done;
3254
end
3255
endgenerate
3256 136 unneback
// FSM generating a number of bursts 4 cycles
3257 97 unneback
// actual number depends on data width ratio
3258
// nr_of_wbm_burst
3259 101 unneback
reg [nr_of_wbm_burst_width+wbm_burst_width-1:0]       cnt_rw, cnt_ack;
3260 97 unneback
always @ (posedge wbm_clk or posedge wbm_rst)
3261
if (wbm_rst)
3262 100 unneback
    cnt_rw <= {wbm_burst_width{1'b0}};
3263 97 unneback
else
3264 100 unneback
    if (wbm_cyc_o & wbm_stb_o & !wbm_stall_i)
3265
        cnt_rw <= cnt_rw + 1;
3266 98 unneback
always @ (posedge wbm_clk or posedge wbm_rst)
3267
if (wbm_rst)
3268 100 unneback
    cnt_ack <= {wbm_burst_width{1'b0}};
3269 98 unneback
else
3270 100 unneback
    if (wbm_ack_i)
3271
        cnt_ack <= cnt_ack + 1;
3272
generate
3273 101 unneback
if (nr_of_wbm_burst==1) begin : one_burst
3274 98 unneback
always @ (posedge wbm_clk or posedge wbm_rst)
3275
if (wbm_rst)
3276
    phase <= wbm_wait;
3277
else
3278
    case (phase)
3279
    wbm_wait:
3280
        if (mem_alert)
3281 100 unneback
            if (state==push)
3282
                phase <= wbm_wr;
3283
            else
3284
                phase <= wbm_rd;
3285 98 unneback
    wbm_wr:
3286 100 unneback
        if (&cnt_rw)
3287
            phase <= wbm_wr_drain;
3288
    wbm_wr_drain:
3289
        if (&cnt_ack)
3290 98 unneback
            phase <= wbm_rd;
3291
    wbm_rd:
3292 100 unneback
        if (&cnt_rw)
3293
            phase <= wbm_rd_drain;
3294
    wbm_rd_drain:
3295
        if (&cnt_ack)
3296
            phase <= wbm_wait;
3297 98 unneback
    default: phase <= wbm_wait;
3298
    endcase
3299 100 unneback
end else begin : multiple_burst
3300 101 unneback
always @ (posedge wbm_clk or posedge wbm_rst)
3301
if (wbm_rst)
3302
    phase <= wbm_wait;
3303
else
3304
    case (phase)
3305
    wbm_wait:
3306
        if (mem_alert)
3307
            if (state==push)
3308
                phase <= wbm_wr;
3309
            else
3310
                phase <= wbm_rd;
3311
    wbm_wr:
3312
        if (&cnt_rw[wbm_burst_width-1:0])
3313
            phase <= wbm_wr_drain;
3314
    wbm_wr_drain:
3315
        if (&cnt_ack)
3316
            phase <= wbm_rd;
3317
        else if (&cnt_ack[wbm_burst_width-1:0])
3318
            phase <= wbm_wr;
3319
    wbm_rd:
3320
        if (&cnt_rw[wbm_burst_width-1:0])
3321
            phase <= wbm_rd_drain;
3322
    wbm_rd_drain:
3323
        if (&cnt_ack)
3324
            phase <= wbm_wait;
3325
        else if (&cnt_ack[wbm_burst_width-1:0])
3326
            phase <= wbm_rd;
3327
    default: phase <= wbm_wait;
3328
    endcase
3329 100 unneback
end
3330
endgenerate
3331 101 unneback
assign mem_done = phase==wbm_rd_drain & (&cnt_ack) & wbm_ack_i;
3332 100 unneback
assign wbm_adr_o = (phase[2]) ? {tag, wbs_adr_slot, cnt_rw} : {wbs_adr_tag, wbs_adr_slot, cnt_rw};
3333 137 unneback
assign wbm_adr   = (phase[2]) ? {wbs_adr_slot, cnt_rw} : {wbs_adr_slot, cnt_ack};
3334 100 unneback
assign wbm_sel_o = {dw_m/8{1'b1}};
3335
assign wbm_cti_o = (&cnt_rw | !wbm_stb_o) ? 3'b111 : 3'b010;
3336 98 unneback
assign wbm_bte_o = bte;
3337 100 unneback
assign {wbm_we_o, wbm_stb_o, wbm_cyc_o}  = phase;
3338 97 unneback
endmodule
3339 103 unneback
// Wishbone to avalon bridge supporting one type of burst transfer only
3340
// intended use is together with cache above
3341
// WB B4 -> pipelined avalon
3342
module vl_wb_avalon_bridge (
3343
        // wishbone slave side
3344
        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,
3345
        // avalon master side
3346
        readdata, readdatavalid, address, read, be, write, burstcount, writedata, waitrequest, beginbursttransfer,
3347 136 unneback
        init_done,
3348 103 unneback
        // common
3349
        clk, rst);
3350
parameter adr_width = 30;
3351
parameter dat_width = 32;
3352
parameter burst_size = 4;
3353
input [dat_width-1:0] wbs_dat_i;
3354
input [adr_width-1:0] wbs_adr_i;
3355
input [dat_width/8-1:0]  wbs_sel_i;
3356
input [1:0]  wbs_bte_i;
3357
input [2:0]  wbs_cti_i;
3358
input wbs_we_i;
3359
input wbs_cyc_i;
3360
input wbs_stb_i;
3361 130 unneback
output [dat_width-1:0] wbs_dat_o;
3362 103 unneback
output wbs_ack_o;
3363
output wbs_stall_o;
3364
input [dat_width-1:0] readdata;
3365
input readdatavalid;
3366
output [dat_width-1:0] writedata;
3367
output [adr_width-1:0] address;
3368
output [dat_width/8-1:0]  be;
3369
output write;
3370
output read;
3371
output beginbursttransfer;
3372
output [3:0] burstcount;
3373
input waitrequest;
3374 136 unneback
input init_done;
3375 103 unneback
input clk, rst;
3376 136 unneback
// cnt1 - initiated read or writes
3377
// cnt2 - # of read or writes in pipeline
3378
reg [3:0] cnt1;
3379
reg [3:0] cnt2;
3380
reg next_state, state;
3381
localparam s0 = 1'b0;
3382
localparam s1 = 1'b1;
3383
wire eoc;
3384
always @ *
3385
begin
3386
    case (state)
3387
    s0: if (init_done & wbs_cyc_i) next_state <= s1;
3388
    s1:
3389
    default: next_state <= state;
3390
    end
3391
end
3392 103 unneback
always @ (posedge clk or posedge rst)
3393
if (rst)
3394 136 unneback
    state <= s0;
3395 103 unneback
else
3396 136 unneback
    state <= next_state;
3397
assign eoc = state==s1 & !(read | write) & (& !waitrequest & cnt2=;
3398
always @ (posedge clk or posedge rst)
3399
if (rst)
3400
    cnt1 <= 4'h0;
3401
else
3402
    if (read & !waitrequest & init_done)
3403
        cnt1 <= burst_size - 1;
3404
    else if (write & !waitrequest & init_done)
3405
        cnt1 <= cnt1 + 4'h1;
3406
    else if (next_state==idle)
3407
        cnt1 <= 4'h0;
3408
always @ (posedge clk or posedge rst)
3409
if (rst)
3410
    cnt2 <= 4'h0;
3411
else
3412
    if (read & !waitrequest & init_done)
3413
        cnt2 <= burst_size - 1;
3414
    else if (write & !waitrequest & init_done & )
3415
        cnt2 <= cnt1 + 4'h1;
3416
    else if (next_state==idle)
3417
        cnt2 <= 4'h0;
3418 103 unneback
reg wr_ack;
3419
always @ (posedge clk or posedge rst)
3420
if (rst)
3421
    wr_ack <= 1'b0;
3422
else
3423
    wr_ack <=  (wbs_we_i & wbs_cyc_i & wbs_stb_i & !wbs_stall_o);
3424
// to avalon
3425
assign writedata = wbs_dat_i;
3426
assign address = wbs_adr_i;
3427
assign be = wbs_sel_i;
3428 136 unneback
assign write = cnt!=4'h0 & wbs_cyc_i &  wbs_we_i;
3429
assign read  = cnt!=4'h0 & wbs_cyc_i & !wbs_we_i;
3430
assign beginbursttransfer = state==s0 & next_state==s1;
3431 103 unneback
assign burstcount = burst_size;
3432
// to wishbone
3433
assign wbs_dat_o = readdata;
3434
assign wbs_ack_o = wr_ack | readdatavalid;
3435
assign wbs_stall_o = waitrequest;
3436
endmodule
3437
module vl_wb_avalon_mem_cache (
3438
    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,
3439
    readdata, readdatavalid, address, read, be, write, burstcount, writedata, waitrequest, beginbursttransfer, clk, rst
3440
);
3441
// wishbone
3442
parameter wb_dat_width = 32;
3443
parameter wb_adr_width = 22;
3444
parameter wb_max_burst_width = 4;
3445
parameter wb_mode = "B4";
3446
// avalon
3447
parameter avalon_dat_width = 32;
3448 121 unneback
//localparam avalon_adr_width = wb_dat_width * wb_adr_width / avalon_dat_width;
3449 122 unneback
localparam avalon_adr_width =
3450
        (wb_dat_width==avalon_dat_width) ? wb_adr_width :
3451
        (wb_dat_width==avalon_dat_width*2) ? wb_adr_width+1 :
3452
        (wb_dat_width==avalon_dat_width*4) ? wb_adr_width+2 :
3453
        (wb_dat_width==avalon_dat_width*8) ? wb_adr_width+3 :
3454
        (wb_dat_width==avalon_dat_width*16) ? wb_adr_width+4 :
3455
        (wb_dat_width==avalon_dat_width*32) ? wb_adr_width+5 :
3456
        (wb_dat_width==avalon_dat_width/2) ? wb_adr_width-1 :
3457
        (wb_dat_width==avalon_dat_width/4) ? wb_adr_width-2 :
3458
        (wb_dat_width==avalon_dat_width/8) ? wb_adr_width-3 :
3459
        (wb_dat_width==avalon_dat_width/16) ? wb_adr_width-4 :
3460 123 unneback
        (wb_dat_width==avalon_dat_width/32) ? wb_adr_width-5 : 0;
3461 103 unneback
parameter avalon_burst_size = 4;
3462
// cache
3463
parameter async = 1;
3464
parameter nr_of_ways = 1;
3465
parameter aw_offset = 4;
3466
parameter aw_slot = 10;
3467
parameter valid_mem = 1;
3468
// shadow RAM
3469
parameter shadow_ram = 0;
3470
parameter shadow_ram_adr_width = 10;
3471
parameter shadow_ram_size = 1024;
3472
parameter shadow_ram_init = 2; // 0: no init, 1: from file, 2: with zero
3473
parameter shadow_ram_file = "vl_ram.v";
3474
input [wb_dat_width-1:0] wbs_dat_i;
3475
input [wb_adr_width-1:0] wbs_adr_i; // dont include a1,a0
3476
input [wb_dat_width/8-1:0] wbs_sel_i;
3477
input [2:0] wbs_cti_i;
3478
input [1:0] wbs_bte_i;
3479
input wbs_we_i, wbs_stb_i, wbs_cyc_i;
3480
output [wb_dat_width-1:0] wbs_dat_o;
3481
output wbs_ack_o;
3482
output wbs_stall_o;
3483
input wbs_clk, wbs_rst;
3484
input [avalon_dat_width-1:0] readdata;
3485
input readdatavalid;
3486
output [avalon_dat_width-1:0] writedata;
3487
output [avalon_adr_width-1:0] address;
3488
output [avalon_dat_width/8-1:0]  be;
3489
output write;
3490
output read;
3491
output beginbursttransfer;
3492
output [3:0] burstcount;
3493
input waitrequest;
3494
input clk, rst;
3495
wire [wb_dat_width-1:0] wb1_dat_o;
3496
wire [wb_adr_width-1:0] wb1_adr_o;
3497
wire [wb_dat_width/8-1:0] wb1_sel_o;
3498
wire [2:0] wb1_cti_o;
3499
wire [1:0] wb1_bte_o;
3500
wire wb1_we_o;
3501
wire wb1_stb_o;
3502
wire wb1_cyc_o;
3503
wire wb1_stall_i;
3504
wire [wb_dat_width-1:0] wb1_dat_i;
3505
wire wb1_ack_i;
3506 129 unneback
wire [avalon_dat_width-1:0] wb2_dat_o;
3507
wire [avalon_adr_width-1:0] wb2_adr_o;
3508
wire [avalon_dat_width/8-1:0] wb2_sel_o;
3509 103 unneback
wire [2:0] wb2_cti_o;
3510
wire [1:0] wb2_bte_o;
3511
wire wb2_we_o;
3512
wire wb2_stb_o;
3513
wire wb2_cyc_o;
3514
wire wb2_stall_i;
3515 129 unneback
wire [avalon_dat_width-1:0] wb2_dat_i;
3516 103 unneback
wire wb2_ack_i;
3517
vl_wb_shadow_ram # ( .dat_width(wb_dat_width), .mode(wb_mode), .max_burst_width(wb_max_burst_width),
3518 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),
3519 103 unneback
                 .main_mem_adr_width(wb_adr_width))
3520
shadow_ram0 (
3521
    .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),
3522
    .wbs_dat_o(wbs_dat_o), .wbs_ack_o(wbs_ack_o), .wbs_stall_o(wbs_stall_o),
3523
    .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),
3524
    .wbm_dat_i(wb1_dat_i), .wbm_ack_i(wb1_ack_i), .wbm_stall_i(wb1_stall_i),
3525
    .wb_clk(wbs_clk), .wb_rst(wbs_rst));
3526
vl_wb_cache
3527
# ( .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))
3528
cache0 (
3529
    .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),
3530
    .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),
3531
    .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),
3532
    .wbm_dat_i(wb2_dat_i), .wbm_ack_i(wb2_ack_i), .wbm_stall_i(wb2_stall_i), .wbm_clk(clk), .wbm_rst(rst));
3533
vl_wb_avalon_bridge # ( .adr_width(avalon_adr_width), .dat_width(avalon_dat_width), .burst_size(avalon_burst_size))
3534
bridge0 (
3535
        // wishbone slave side
3536
        .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),
3537
        .wbs_dat_o(wb2_dat_i), .wbs_ack_o(wb2_ack_i), .wbs_stall_o(wb2_stall_i),
3538
        // avalon master side
3539
        .readdata(readdata), .readdatavalid(readdatavalid), .address(address), .read(read), .be(be), .write(write), .burstcount(burstcount), .writedata(writedata), .waitrequest(waitrequest), .beginbursttransfer(beginbursttransfer),
3540
        // common
3541
        .clk(clk), .rst(rst));
3542
endmodule
3543 136 unneback
module vl_wb_sdr_sdram (
3544
    // wisbone i/f
3545
    dat_i, adr_i, sel_i, we_i, cyc_i, stb_i, dat_o, ack_o, stall_o,
3546
    // SDR SDRAM
3547
    ba, a, cmd, cke, cs_n, dqm, dq_i, dq_o, dq_oe,
3548
    // system
3549
    clk, rst);
3550
    // external data bus size
3551
    parameter dat_size = 16;
3552
    // memory geometry parameters
3553
    parameter ba_size  = 2;
3554
    parameter row_size = 13;
3555
    parameter col_size = 9;
3556
    parameter cl = 2;
3557
    // memory timing parameters
3558
    parameter tRFC = 9;
3559
    parameter tRP  = 2;
3560
    parameter tRCD = 2;
3561
    parameter tMRD = 2;
3562
    // LMR
3563
    // [12:10] reserved
3564
    // [9]     WB, write burst; 0 - programmed burst length, 1 - single location
3565
    // [8:7]   OP Mode, 2'b00
3566
    // [6:4]   CAS Latency; 3'b010 - 2, 3'b011 - 3
3567
    // [3]     BT, Burst Type; 1'b0 - sequential, 1'b1 - interleaved
3568
    // [2:0]   Burst length; 3'b000 - 1, 3'b001 - 2, 3'b010 - 4, 3'b011 - 8, 3'b111 - full page
3569
    localparam init_wb = 1'b1;
3570
    localparam init_cl = (cl==2) ? 3'b010 : 3'b011;
3571
    localparam init_bt = 1'b0;
3572
    localparam init_bl = 3'b000;
3573
    input [dat_size-1:0] dat_i;
3574
    input [ba_size+col_size+row_size-1:0] adr_i;
3575
    input [dat_size/8-1:0] sel_i;
3576
    input we_i, cyc_i, stb_i;
3577
    output [dat_size-1:0] dat_o;
3578
    output ack_o;
3579
    output reg stall_o;
3580
    output [ba_size-1:0]    ba;
3581
    output reg [12:0]   a;
3582
    output reg [2:0]    cmd; // {ras,cas,we}
3583
    output cke, cs_n;
3584
    output reg [dat_size/8-1:0]    dqm;
3585
    output [dat_size-1:0]       dq_o;
3586
    output reg          dq_oe;
3587
    input  [dat_size-1:0]       dq_i;
3588
    input clk, rst;
3589
    wire [ba_size-1:0]   bank;
3590
    wire [row_size-1:0] row;
3591
    wire [col_size-1:0] col;
3592
    wire [0:31]  shreg;
3593
    wire                ref_cnt_zero;
3594
    reg                 refresh_req;
3595
    wire ack_rd, rd_ack_emptyflag;
3596
    wire ack_wr;
3597
    // to keep track of open rows per bank
3598
    reg [row_size-1:0]   open_row[0:3];
3599
    reg [0:3]            open_ba;
3600
    reg                 current_bank_closed, current_row_open;
3601
    parameter rfr_length = 10;
3602
    parameter rfr_wrap_value = 1010;
3603
    parameter [2:0] cmd_nop = 3'b111,
3604
                    cmd_act = 3'b011,
3605
                    cmd_rd  = 3'b101,
3606
                    cmd_wr  = 3'b100,
3607
                    cmd_pch = 3'b010,
3608
                    cmd_rfr = 3'b001,
3609
                    cmd_lmr = 3'b000;
3610
// ctrl FSM
3611
    assign cke = 1'b1;
3612
    assign cs_n = 1'b0;
3613
    reg [2:0] state, next;
3614
    function [12:0] a10_fix;
3615
        input [col_size-1:0] a;
3616
        integer i;
3617
    begin
3618
        for (i=0;i<13;i=i+1) begin
3619
            if (i<10)
3620
              if (i<col_size)
3621
                a10_fix[i] = a[i];
3622
              else
3623
                a10_fix[i] = 1'b0;
3624
            else if (i==10)
3625
              a10_fix[i] = 1'b0;
3626
            else
3627
              if (i<col_size)
3628
                a10_fix[i] = a[i-1];
3629
              else
3630
                a10_fix[i] = 1'b0;
3631
        end
3632
    end
3633
    endfunction
3634
    assign {bank,row,col} = adr_i;
3635
    always @ (posedge clk or posedge rst)
3636
    if (rst)
3637
       state <= 3'b000;
3638
    else
3639
       state <= next;
3640
    always @*
3641
    begin
3642
        next = state;
3643
        case (state)
3644
        3'b000:
3645
            if (shreg[3+tRP+tRFC+tRFC+tMRD]) next = 3'b001;
3646
        3'b001:
3647
            if (refresh_req) next = 3'b010;
3648
            else if (cyc_i & stb_i & rd_ack_emptyflag) next = 3'b011;
3649
        3'b010:
3650
            if (shreg[tRP+tRFC-2]) next = 3'b001; // take away two cycles because no cmd will be issued in idle and adr
3651
        3'b011:
3652
            if (current_bank_closed) next = 3'b101;
3653
            else if (current_row_open) next = 3'b111;
3654
            else next = 3'b100;
3655
        3'b100:
3656
            if (shreg[tRP]) next = 3'b101;
3657
        3'b101:
3658
            if (shreg[tRCD]) next = 3'b111;
3659
        3'b111:
3660
            if (!stb_i) next = 3'b001;
3661
        endcase
3662
    end
3663
    // counter
3664
    vl_cnt_shreg_clear # ( .length(32))
3665
        cnt0 (
3666
            .clear(state!=next),
3667
            .q(shreg),
3668
            .rst(rst),
3669
            .clk(clk));
3670
    // ba, a, cmd
3671
    // outputs dependent on state vector
3672
    always @ (*)
3673
        begin
3674
            {a,cmd} = {13'd0,cmd_nop};
3675
            dqm = 2'b11;
3676
            dq_oe = 1'b0;
3677
            stall_o = 1'b1;
3678
            case (state)
3679
            3'b000:
3680
                if (shreg[3]) begin
3681
                    {a,cmd} = {13'b0010000000000, cmd_pch};
3682
                end else if (shreg[3+tRP] | shreg[3+tRP+tRFC])
3683
                    {a,cmd} = {13'd0, cmd_rfr};
3684
                else if (shreg[3+tRP+tRFC+tRFC])
3685
                    {a,cmd} = {3'b000,init_wb,2'b00,init_cl,init_bt,init_bl,cmd_lmr};
3686
            3'b010:
3687
                if (shreg[0])
3688
                    {a,cmd} = {13'b0010000000000, cmd_pch};
3689
                else if (shreg[tRP])
3690
                    {a,cmd} = {13'd0, cmd_rfr};
3691
            3'b100:
3692
                if (shreg[0])
3693
                    {a,cmd} = {13'd0,cmd_pch};
3694
            3'b101:
3695
                if (shreg[0])
3696
                    {a[row_size-1:0],cmd} = {row,cmd_act};
3697
            3'b111:
3698
                begin
3699
                    if (we_i)
3700
                        cmd = cmd_wr;
3701
                    else
3702
                        cmd = cmd_rd;
3703
                    if (we_i)
3704
                        dqm = ~sel_i;
3705
                    else
3706
                        dqm = 2'b00;
3707
                    if (we_i)
3708
                        dq_oe = 1'b1;
3709
                    a = a10_fix(col);
3710
                    stall_o = 1'b0;
3711
                end
3712
            endcase
3713
        end
3714
    assign ba = bank;
3715
    // precharge individual bank A10=0
3716
    // precharge all bank A10=1
3717
    genvar i;
3718
    generate
3719
    for (i=0;i<2<<ba_size-1;i=i+1) begin : open_ba_logic
3720
        always @ (posedge clk or posedge rst)
3721
        if (rst)
3722
            {open_ba[i],open_row[i]} <= {1'b0,{row_size{1'b0}}};
3723
        else
3724
            if (cmd==cmd_pch & (a[10] | bank==i))
3725
                open_ba[i] <= 1'b0;
3726
            else if (cmd==cmd_act & bank==i)
3727
                {open_ba[i],open_row[i]} <= {1'b1,row};
3728
    end
3729
    endgenerate
3730
    // bank and row open ?
3731
    always @ (posedge clk or posedge rst)
3732
    if (rst)
3733
       {current_bank_closed, current_row_open} <= {1'b1, 1'b0};
3734
    else
3735
       {current_bank_closed, current_row_open} <= {!(open_ba[bank]), open_row[bank]==row};
3736
    // refresh counter
3737
    vl_cnt_lfsr_zq # ( .length(rfr_length), .wrap_value (rfr_wrap_value)) ref_counter0( .zq(ref_cnt_zero), .rst(rst), .clk(clk));
3738
    always @ (posedge clk or posedge rst)
3739
    if (rst)
3740
        refresh_req <= 1'b0;
3741
    else
3742
        if (ref_cnt_zero)
3743
            refresh_req <= 1'b1;
3744
        else if (state==3'b010)
3745
            refresh_req <= 1'b0;
3746
    assign dat_o = dq_i;
3747
    assign ack_wr = (state==3'b111 & we_i);
3748
    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));
3749
    assign ack_o = ack_rd | ack_wr;
3750
    assign dq_o = dat_i;
3751
endmodule
3752
module vl_wb_sdr_sdram_ctrl (
3753
    // WB i/f
3754
    wbs_dat_i, wbs_adr_i, wbs_cti_i, wbs_bte_i, wbs_sel_i, wbs_we_i, wbs_stb_i, wbs_cyc_i,
3755
    wbs_dat_o, wbs_ack_o, wbs_stall_o,
3756
    // SDR SDRAM
3757
    mem_ba, mem_a, mem_cmd, mem_cke, mem_cs_n, mem_dqm, mem_dq_i, mem_dq_o, mem_dq_oe,
3758
    // system
3759
    wb_clk, wb_rst, mem_clk, mem_rst);
3760
    // WB slave
3761
    parameter wbs_dat_width = 32;
3762
    parameter wbs_adr_width = 24;
3763
    parameter wbs_mode = "B3";
3764
    parameter wbs_max_burst_width = 4;
3765
    // Shadow RAM
3766
    parameter shadow_mem_adr_width = 10;
3767
    parameter shadow_mem_size = 1024;
3768
    parameter shadow_mem_init = 2;
3769
    parameter shadow_mem_file = "vl_ram.v";
3770
    // Cache
3771
    parameter cache_async = 1; // wbs_clk != wbm_clk
3772
    parameter cache_nr_of_ways = 1;
3773
    parameter cache_aw_offset = 4; // 4 => 16 words per cache line
3774
    parameter cache_aw_slot = 10;
3775
    parameter cache_valid_mem = 0;
3776
    parameter cache_debug = 0;
3777
    // SDRAM parameters
3778
    parameter mem_dat_size = 16;
3779
    parameter mem_ba_size  = 2;
3780
    parameter mem_row_size = 13;
3781
    parameter mem_col_size = 9;
3782
    parameter mem_cl = 2;
3783
    parameter mem_tRFC = 9;
3784
    parameter mem_tRP  = 2;
3785
    parameter mem_tRCD = 2;
3786
    parameter mem_tMRD = 2;
3787
    parameter mem_rfr_length = 10;
3788
    parameter mem_rfr_wrap_value = 1010;
3789
    input [wbs_dat_width-1:0] wbs_dat_i;
3790
    input [wbs_adr_width-1:0] wbs_adr_i;
3791
    input [2:0] wbs_cti_i;
3792
    input [1:0] wbs_bte_i;
3793
    input [wbs_dat_width/8-1:0] wbs_sel_i;
3794
    input wbs_we_i, wbs_stb_i, wbs_cyc_i;
3795
    output [wbs_dat_width-1:0] wbs_dat_o;
3796
    output wbs_ack_o;
3797
    output wbs_stall_o;
3798
    output [mem_ba_size-1:0]    mem_ba;
3799
    output reg [12:0]           mem_a;
3800
    output reg [2:0]            mem_cmd; // {ras,cas,we}
3801
    output                      mem_cke, mem_cs_n;
3802
    output reg [mem_dat_size/8-1:0] mem_dqm;
3803
    output [mem_dat_size-1:0]       mem_dq_o;
3804
    output reg                  mem_dq_oe;
3805
    input  [mem_dat_size-1:0]       mem_dq_i;
3806
    input wb_clk, wb_rst, mem_clk, mem_rst;
3807
    // wbm1
3808
    wire [wbs_dat_width-1:0] wbm1_dat_o;
3809
    wire [wbs_adr_width-1:0] wbm1_adr_o;
3810
    wire [2:0] wbm1_cti_o;
3811
    wire [1:0] wbm1_bte_o;
3812
    wire [wbs_dat_width/8-1:0] wbm1_sel_o;
3813
    wire wbm1_we_o, wbm1_stb_o, wbm1_cyc_o;
3814
    wire [wbs_dat_width-1:0] wbm1_dat_i;
3815
    wire wbm1_ack_i, wbm1_stall_i;
3816
    // wbm2
3817
    wire [mem_dat_size-1:0] wbm2_dat_o;
3818
    wire [mem_ba_size+mem_row_size+mem_col_size-1:0] wbm2_adr_o;
3819
    wire [2:0] wbm2_cti_o;
3820
    wire [1:0] wbm2_bte_o;
3821
    wire [mem_dat_size/8-1:0] wbm2_sel_o;
3822
    wire wbm2_we_o, wbm2_stb_o, wbm2_cyc_o;
3823
    wire [mem_dat_size-1:0] wbm2_dat_i;
3824
    wire wbm2_ack_i, wbm2_stall_i;
3825
vl_wb_shadow_ram # (
3826
    .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) )
3827
shadow_ram0 (
3828
    .wbs_dat_i(wbs_dat_i),
3829
    .wbs_adr_i(wbs_adr_i),
3830
    .wbs_cti_i(wbs_cti_i),
3831
    .wbs_bte_i(wbs_bte_i),
3832
    .wbs_sel_i(wbs_sel_i),
3833
    .wbs_we_i (wbs_we_i),
3834
    .wbs_stb_i(wbs_stb_i),
3835
    .wbs_cyc_i(wbs_cyc_i),
3836
    .wbs_dat_o(wbs_dat_o),
3837
    .wbs_ack_o(wbs_ack_o),
3838
    .wbs_stall_o(wbs_stall_o),
3839
    .wbm_dat_o(wbm1_dat_o),
3840
    .wbm_adr_o(wbm1_adr_o),
3841
    .wbm_cti_o(wbm1_cti_o),
3842
    .wbm_bte_o(wbm1_bte_o),
3843
    .wbm_sel_o(wbm1_sel_o),
3844
    .wbm_we_o(wbm1_we_o),
3845
    .wbm_stb_o(wbm1_stb_o),
3846
    .wbm_cyc_o(wbm1_cyc_o),
3847
    .wbm_dat_i(wbm1_dat_i),
3848
    .wbm_ack_i(wbm1_ack_i),
3849
    .wbm_stall_i(wbm1_stall_i),
3850
    .wb_clk(wb_clk),
3851
    .wb_rst(wb_rst) );
3852
vl_wb_cache # (
3853
    .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) )
3854
cache0 (
3855
    .wbs_dat_i(wbm1_dat_o),
3856
    .wbs_adr_i(wbm1_adr_o),
3857
    .wbs_sel_i(wbm1_sel_o),
3858
    .wbs_cti_i(wbm1_cti_o),
3859
    .wbs_bte_i(wbm1_bte_o),
3860
    .wbs_we_i (wbm1_we_o),
3861
    .wbs_stb_i(wbm1_stb_o),
3862
    .wbs_cyc_i(wbm1_cyc_o),
3863
    .wbs_dat_o(wbm1_dat_i),
3864
    .wbs_ack_o(wbm1_ack_i),
3865
    .wbs_stall_o(wbm1_stall_i),
3866
    .wbs_clk(wb_clk),
3867
    .wbs_rst(wb_rst),
3868
    .wbm_dat_o(wbm2_dat_o),
3869
    .wbm_adr_o(wbm2_adr_o),
3870
    .wbm_sel_o(wbm2_sel_o),
3871
    .wbm_cti_o(wbm2_cti_o),
3872
    .wbm_bte_o(wbm2_bte_o),
3873
    .wbm_we_o (wbm2_we_o),
3874
    .wbm_stb_o(wbm2_stb_o),
3875
    .wbm_cyc_o(wbm2_cyc_o),
3876
    .wbm_dat_i(wbm2_dat_i),
3877
    .wbm_ack_i(wbm2_ack_i),
3878
    .wbm_stall_i(wbm2_stall_i),
3879
    .wbm_clk(mem_clk),
3880
    .wbm_rst(mem_rst) );
3881
vl_wb_sdr_sdram # (
3882
    .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) )
3883
ctrl0(
3884
    // wisbone i/f
3885
    .dat_i(wbm2_dat_o),
3886
    .adr_i(wbm2_adr_o),
3887
    .sel_i(wbm2_sel_o),
3888
    .we_i (wbm2_we_o),
3889
    .cyc_i(wbm2_cyc_o),
3890
    .stb_i(wbm2_stb_o),
3891
    .dat_o(wbm2_dat_i),
3892
    .ack_o(wbm2_ack_i),
3893
    .stall_o(wbm2_stall_i),
3894
    // SDR SDRAM
3895
    .ba(mem_ba),
3896
    .a(mem_a),
3897
    .cmd(mem_cmd),
3898
    .cke(mem_cke),
3899
    .cs_n(mem_cs_n),
3900
    .dqm(mem_dqm),
3901
    .dq_i(mem_dq_i),
3902
    .dq_o(mem_dq_o),
3903
    .dq_oe(mem_dq_oe),
3904
    // system
3905
    .clk(mem_clk),
3906
    .rst(mem_rst) );
3907
endmodule
3908 18 unneback
//////////////////////////////////////////////////////////////////////
3909
////                                                              ////
3910
////  Arithmetic functions                                        ////
3911
////                                                              ////
3912
////  Description                                                 ////
3913
////  Arithmetic functions for ALU and DSP                        ////
3914
////                                                              ////
3915
////                                                              ////
3916
////  To Do:                                                      ////
3917
////   -                                                          ////
3918
////                                                              ////
3919
////  Author(s):                                                  ////
3920
////      - Michael Unneback, unneback@opencores.org              ////
3921
////        ORSoC AB                                              ////
3922
////                                                              ////
3923
//////////////////////////////////////////////////////////////////////
3924
////                                                              ////
3925
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
3926
////                                                              ////
3927
//// This source file may be used and distributed without         ////
3928
//// restriction provided that this copyright statement is not    ////
3929
//// removed from the file and that any derivative work contains  ////
3930
//// the original copyright notice and the associated disclaimer. ////
3931
////                                                              ////
3932
//// This source file is free software; you can redistribute it   ////
3933
//// and/or modify it under the terms of the GNU Lesser General   ////
3934
//// Public License as published by the Free Software Foundation; ////
3935
//// either version 2.1 of the License, or (at your option) any   ////
3936
//// later version.                                               ////
3937
////                                                              ////
3938
//// This source is distributed in the hope that it will be       ////
3939
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
3940
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
3941
//// PURPOSE.  See the GNU Lesser General Public License for more ////
3942
//// details.                                                     ////
3943
////                                                              ////
3944
//// You should have received a copy of the GNU Lesser General    ////
3945
//// Public License along with this source; if not, download it   ////
3946
//// from http://www.opencores.org/lgpl.shtml                     ////
3947
////                                                              ////
3948
//////////////////////////////////////////////////////////////////////
3949
// signed multiplication
3950
module vl_mults (a,b,p);
3951
parameter operand_a_width = 18;
3952
parameter operand_b_width = 18;
3953
parameter result_hi = 35;
3954
parameter result_lo = 0;
3955
input [operand_a_width-1:0] a;
3956
input [operand_b_width-1:0] b;
3957
output [result_hi:result_lo] p;
3958
wire signed [operand_a_width-1:0] ai;
3959
wire signed [operand_b_width-1:0] bi;
3960
wire signed [operand_a_width+operand_b_width-1:0] result;
3961
    assign ai = a;
3962
    assign bi = b;
3963
    assign result = ai * bi;
3964
    assign p = result[result_hi:result_lo];
3965
endmodule
3966
module vl_mults18x18 (a,b,p);
3967
input [17:0] a,b;
3968
output [35:0] p;
3969
vl_mult
3970
    # (.operand_a_width(18), .operand_b_width(18))
3971
    mult0 (.a(a), .b(b), .p(p));
3972
endmodule
3973
// unsigned multiplication
3974
module vl_mult (a,b,p);
3975
parameter operand_a_width = 18;
3976
parameter operand_b_width = 18;
3977
parameter result_hi = 35;
3978
parameter result_lo = 0;
3979
input [operand_a_width-1:0] a;
3980
input [operand_b_width-1:0] b;
3981
output [result_hi:result_hi] p;
3982
wire [operand_a_width+operand_b_width-1:0] result;
3983
    assign result = a * b;
3984
    assign p = result[result_hi:result_lo];
3985
endmodule
3986
// shift unit
3987
// supporting the following shift functions
3988
//   SLL
3989
//   SRL
3990
//   SRA
3991
module vl_shift_unit_32( din, s, dout, opcode);
3992
input [31:0] din; // data in operand
3993
input [4:0] s; // shift operand
3994
input [1:0] opcode;
3995
output [31:0] dout;
3996
parameter opcode_sll = 2'b00;
3997
//parameter opcode_srl = 2'b01;
3998
parameter opcode_sra = 2'b10;
3999
//parameter opcode_ror = 2'b11;
4000
wire sll, sra;
4001
assign sll = opcode == opcode_sll;
4002
assign sra = opcode == opcode_sra;
4003
wire [15:1] s1;
4004
wire [3:0] sign;
4005
wire [7:0] tmp [0:3];
4006
// first stage is multiplier based
4007
// shift operand as fractional 8.7
4008
assign s1[15] = sll & s[2:0]==3'd7;
4009
assign s1[14] = sll & s[2:0]==3'd6;
4010
assign s1[13] = sll & s[2:0]==3'd5;
4011
assign s1[12] = sll & s[2:0]==3'd4;
4012
assign s1[11] = sll & s[2:0]==3'd3;
4013
assign s1[10] = sll & s[2:0]==3'd2;
4014
assign s1[ 9] = sll & s[2:0]==3'd1;
4015
assign s1[ 8] = s[2:0]==3'd0;
4016
assign s1[ 7] = !sll & s[2:0]==3'd1;
4017
assign s1[ 6] = !sll & s[2:0]==3'd2;
4018
assign s1[ 5] = !sll & s[2:0]==3'd3;
4019
assign s1[ 4] = !sll & s[2:0]==3'd4;
4020
assign s1[ 3] = !sll & s[2:0]==3'd5;
4021
assign s1[ 2] = !sll & s[2:0]==3'd6;
4022
assign s1[ 1] = !sll & s[2:0]==3'd7;
4023
assign sign[3] = din[31] & sra;
4024
assign sign[2] = sign[3] & (&din[31:24]);
4025
assign sign[1] = sign[2] & (&din[23:16]);
4026
assign sign[0] = sign[1] & (&din[15:8]);
4027
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]));
4028
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]));
4029
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]));
4030
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]));
4031
// second stage is multiplexer based
4032
// shift on byte level
4033
// mux byte 3
4034
assign dout[31:24] = (s[4:3]==2'b00) ? tmp[3] :
4035
                     (sll & s[4:3]==2'b01) ? tmp[2] :
4036
                     (sll & s[4:3]==2'b10) ? tmp[1] :
4037
                     (sll & s[4:3]==2'b11) ? tmp[0] :
4038
                     {8{sign[3]}};
4039
// mux byte 2
4040
assign dout[23:16] = (s[4:3]==2'b00) ? tmp[2] :
4041
                     (sll & s[4:3]==2'b01) ? tmp[1] :
4042
                     (sll & s[4:3]==2'b10) ? tmp[0] :
4043
                     (sll & s[4:3]==2'b11) ? {8{1'b0}} :
4044
                     (s[4:3]==2'b01) ? tmp[3] :
4045
                     {8{sign[3]}};
4046
// mux byte 1
4047
assign dout[15:8]  = (s[4:3]==2'b00) ? tmp[1] :
4048
                     (sll & s[4:3]==2'b01) ? tmp[0] :
4049
                     (sll & s[4:3]==2'b10) ? {8{1'b0}} :
4050
                     (sll & s[4:3]==2'b11) ? {8{1'b0}} :
4051
                     (s[4:3]==2'b01) ? tmp[2] :
4052
                     (s[4:3]==2'b10) ? tmp[3] :
4053
                     {8{sign[3]}};
4054
// mux byte 0
4055
assign dout[7:0]   = (s[4:3]==2'b00) ? tmp[0] :
4056
                     (sll) ?  {8{1'b0}}:
4057
                     (s[4:3]==2'b01) ? tmp[1] :
4058
                     (s[4:3]==2'b10) ? tmp[2] :
4059
                     tmp[3];
4060
endmodule
4061
// logic unit
4062
// supporting the following logic functions
4063
//    a and b
4064
//    a or  b
4065
//    a xor b
4066
//    not b
4067
module vl_logic_unit( a, b, result, opcode);
4068
parameter width = 32;
4069
parameter opcode_and = 2'b00;
4070
parameter opcode_or  = 2'b01;
4071
parameter opcode_xor = 2'b10;
4072
input [width-1:0] a,b;
4073
output [width-1:0] result;
4074
input [1:0] opcode;
4075
assign result = (opcode==opcode_and) ? a & b :
4076
                (opcode==opcode_or)  ? a | b :
4077
                (opcode==opcode_xor) ? a ^ b :
4078
                b;
4079
endmodule

powered by: WebSVN 2.1.0

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