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

Subversion Repositories bilinear_demosaic

[/] [bilinear_demosaic/] [trunk/] [sim/] [rtl_sim/] [bilinearDemosaic.v.bak] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 tesla500
/*-----------------------------------------------------------------------------
2
 
3
                                                                Video Stream Scaler
4
 
5
                                                        Author: David Kronstein
6
 
7
 
8
 
9
Copyright 2011, David Kronstein, and individual contributors as indicated
10
by the @authors tag.
11
 
12
This is free software; you can redistribute it and/or modify it
13
under the terms of the GNU Lesser General Public License as
14
published by the Free Software Foundation; either version 2.1 of
15
the License, or (at your option) any later version.
16
 
17
This software is distributed in the hope that it will be useful,
18
but WITHOUT ANY WARRANTY; without even the implied warranty of
19
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
Lesser General Public License for more details.
21
 
22
You should have received a copy of the GNU Lesser General Public
23
License along with this software; if not, write to the Free
24
Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25
02110-1301 USA, or see the FSF site: http://www.fsf.org.
26
 
27
 
28
-------------------------------------------------------------------------------
29
 
30
Scales streaming video up or down in resolution. Bilinear and nearest neighbor
31
modes are supported.
32
 
33
Run-time adjustment of input and output resolution, scaling factors, and scale
34
type.
35
 
36
-------------------------------------------------------------------------------
37
 
38
Revisions
39
 
40
V1.0.0  Feb 21 2011             Initial Release         David Kronstein
41
Known bugs:
42
Very slight numerical errors (+0/-2 LSb) in output data due to coefficient arithmetic.
43
Impossible to notice without adjustment in video levels. Attempted to fix by setting
44
coeff11 to 1.0 - other coefficients, but this caused timing issues.
45
 
46
*/
47
`default_nettype none
48
 
49
module bilinearDemosaic #(
50
//---------------------------Parameters----------------------------------------
51
parameter       DATA_WIDTH =                    8,              //Width of input/output data
52
parameter       X_RES_WIDTH =                   11,             //Widths of input/output resolution control signals
53
parameter       Y_RES_WIDTH =                   11,
54
parameter       BUFFER_SIZE =                   5,              //Depth of RFIFO
55
//---------------------Non-user-definable parameters----------------------------
56
parameter       BUFFER_SIZE_WIDTH =             ((BUFFER_SIZE+1) <= 2) ? 1 :    //wide enough to hold value BUFFER_SIZE + 1
57
                                                                        ((BUFFER_SIZE+1) <= 4) ? 2 :
58
                                                                        ((BUFFER_SIZE+1) <= 8) ? 3 :
59
                                                                        ((BUFFER_SIZE+1) <= 16) ? 4 :
60
                                                                        ((BUFFER_SIZE+1) <= 32) ? 5 :
61
                                                                        ((BUFFER_SIZE+1) <= 64) ? 6 : 7
62
)(
63
//---------------------------Module IO-----------------------------------------
64
//Clock and reset
65
input wire                                                      clk,
66
input wire                                                      rst,
67
 
68
//User interface
69
//Input
70
input wire [DATA_WIDTH-1:0]                     dIn,
71
input wire                                                      dInValid,
72
output wire                                                     nextDin,
73
input wire                                                      start,
74
 
75
//Output
76
output reg [DATA_WIDTH-1:0]
77
                                                                        rOut,
78
output reg [DATA_WIDTH-1:0]
79
                                                                        gOut,
80
output reg [DATA_WIDTH-1:0]
81
                                                                        bOut,
82
output reg                                                      dOutValid,                      //latency of x clock cycles after nextDout is asserted
83
input wire                                                      nextDout,
84
 
85
//Control
86
input wire [X_RES_WIDTH-1:0]    xRes,                   //Resolution of input data minus 1
87
input wire [Y_RES_WIDTH-1:0]    yRes
88
 
89
);
90
//-----------------------Internal signals and registers------------------------
91
reg                                                             advanceRead1;
92
 
93
wire [DATA_WIDTH-1:0]   readData0;
94
wire [DATA_WIDTH-1:0]   readData1;
95
wire [DATA_WIDTH-1:0]   readData2;
96
 
97
wire [X_RES_WIDTH-1:0]                  readAddress;
98
 
99
reg                                                     readyForRead;           //Indicates two full lines have been put into the buffer
100
reg [Y_RES_WIDTH-1:0]   outputLine;                     //which output video line we're on
101
reg [X_RES_WIDTH-1:0]   outputColumn;           //which output video column we're on
102
wire [BUFFER_SIZE_WIDTH-1:0]    fillCount;                      //Numbers used rams in the ram fifo
103
reg                                     lineSwitchOutputDisable; //On the end of an output line, disable the output for one cycle to let the RAM data become valid
104
reg                                                             dOutValidInt;
105
 
106
wire                                                    allDataWritten;         //Indicates that all data from input has been read in
107
reg                                                     readState;
108
 
109
//States for read state machine
110
parameter RS_START = 0;
111
parameter RS_READ_LINE = 1;
112
 
113
//Read state machine
114
//Controls the RFIFO(ram FIFO) readout and generates output data valid signals
115
always @ (posedge clk or posedge rst or posedge start)
116
begin
117
        if(rst | start)
118
        begin
119
                outputLine <= 0;
120
                outputColumn <= 0;
121
                readState <= RS_START;
122
                dOutValidInt <= 0;
123
                lineSwitchOutputDisable <= 0;
124
                advanceRead1 <= 0;
125
        end
126
        else
127
        begin
128
                case (readState)
129
 
130
                        RS_START:
131
                        begin
132
                                if(readyForRead)
133
                                begin
134
                                        readState <= RS_READ_LINE;
135
                                        dOutValidInt <= 1;
136
                                end
137
                        end
138
 
139
                        RS_READ_LINE:
140
                        begin
141
 
142
                                //outputLine goes through all output lines, and the logic determines which input lines to read into the RRB and which ones to discard.
143
                                if(nextDout && dOutValidInt)
144
                                begin
145
                                        if(outputColumn == xRes)
146
                                        begin //On the last input pixel of the line
147
 
148
                                                advanceRead1 <= 1;
149
                                                if(fillCount < 3)               //If the RRB doesn't have enough data, stop reading it out
150
                                                        dOutValidInt <= 0;
151
 
152
 
153
                                                outputColumn <= 0;
154
                                                outputLine <= outputLine + 1;
155
                                                lineSwitchOutputDisable <= 1;
156
                                        end
157
                                        else
158
                                        begin
159
                                                //Advance the output pixel selection values except when waiting for the ram data to become valid
160
                                                if(lineSwitchOutputDisable == 0)
161
                                                begin
162
                                                        outputColumn <= outputColumn + 1;
163
                                                end
164
                                                advanceRead1 <= 0;
165
                                                lineSwitchOutputDisable <= 0;
166
                                        end
167
                                end
168
                                else //else from if(nextDout && dOutValidInt)
169
                                begin
170
                                        advanceRead1 <= 0;
171
                                        lineSwitchOutputDisable <= 0;
172
                                end
173
 
174
                                //Once the RRB has enough data, let data be read from it. If all input data has been written, always allow read
175
                                if(fillCount >= 3 && dOutValidInt == 0 || allDataWritten)
176
                                begin
177
                                        if(!advanceRead1)
178
                                        begin
179
                                                dOutValidInt <= 1;
180
                                                lineSwitchOutputDisable <= 0;
181
                                        end
182
                                end
183
                        end//state RS_READ_LINE:
184
                endcase
185
 
186
        end
187
end
188
 
189
assign readAddress = outputColumn;
190
 
191
//Generate dOutValid signal, delayed to account for delays in data path
192
reg dOutValid_1;
193
reg dOutValid_2;
194
reg dOutValid_3;
195
 
196
always @(posedge clk or posedge rst)
197
begin
198
        if(rst)
199
        begin
200
                dOutValid_1 <= 0;
201
                dOutValid_2 <= 0;
202
                dOutValid_3 <= 0;
203
                dOutValid <= 0;
204
        end
205
        else
206
        begin
207
                dOutValid_1 <= nextDout && dOutValidInt && !lineSwitchOutputDisable;
208
                dOutValid_2 <= dOutValid_1;
209
                dOutValid_3 <= dOutValid_2;
210
                dOutValid <= dOutValid_3;
211
        end
212
end
213
 
214
 
215
wire            advanceWrite;
216
 
217
reg [1:0]       writeState;
218
 
219
reg [X_RES_WIDTH-1:0] writeColCount;
220
reg [Y_RES_WIDTH-1:0] writeRowCount;
221
reg                     enableNextDin;
222
reg                     forceRead;
223
 
224
//Write state machine
225
//Controls writing scaler input data into the RRB
226
 
227
parameter       WS_START = 0;
228
parameter       WS_DISCARD = 1;
229
parameter       WS_READ = 2;
230
parameter       WS_DONE = 3;
231
 
232
//Control write and address signals to write data into ram FIFO
233
always @ (posedge clk or posedge rst or posedge start)
234
begin
235
        if(rst | start)
236
        begin
237
                writeState <= WS_START;
238
                enableNextDin <= 0;
239
                readyForRead <= 0;
240
                writeRowCount <= 0;
241
                writeColCount <= 0;
242
                forceRead <= 0;
243
        end
244
        else
245
        begin
246
                case (writeState)
247
 
248
                        WS_START:
249
                        begin
250
                                enableNextDin <= 1;
251
                                writeState <= WS_READ;
252
                        end
253
 
254
                        WS_READ:
255
                        begin
256
                                if(dInValid & nextDin)
257
                                begin
258
                                        if(writeColCount == xRes)
259
                                        begin   //Occurs on the last pixel in the line
260
 
261
                                                //Once writeRowCount is >= 3, data is ready to start being output.
262
                                                if(writeRowCount[1:0] == 2'h3)
263
                                                        readyForRead <= 1;
264
 
265
                                                if(writeRowCount == yRes)       //When all data has been read in, stop reading.
266
                                                begin
267
                                                        writeState <= WS_DONE;
268
                                                        enableNextDin <= 0;
269
                                                        forceRead <= 1;
270
                                                end
271
 
272
                                                writeColCount <= 0;
273
                                                writeRowCount <= writeRowCount + 1;
274
                                        end
275
                                        else
276
                                        begin
277
                                                writeColCount <= writeColCount + 1;
278
                                        end
279
                                end
280
                        end
281
 
282
                        WS_DONE:
283
                        begin
284
                                //do nothing, wait for reset
285
                        end
286
 
287
                endcase
288
        end
289
end
290
 
291
 
292
wire leftMask =         outputColumn == 0;
293
wire rightMask =        outputColumn == xRes;
294
wire topMask =          outputLine == 0;
295
wire bottomMask =       outputLine == yRes;
296
 
297
reg [DATA_WIDTH-1:0]    pixel [2:0][2:0];    //[y, x]
298
wire [DATA_WIDTH-1:0]    pixelMasked [2:0][2:0];    //[y, x]
299
 
300
always @ (posedge clk or posedge rst or posedge start)
301
begin
302
   if(rst | start)
303
   begin
304
       pixel[0][0] <= 0;
305
       pixel[0][1] <= 0;
306
       pixel[0][2] <= 0;
307
       pixel[1][0] <= 0;
308
       pixel[1][1] <= 0;
309
       pixel[1][2] <= 0;
310
       pixel[2][0] <= 0;
311
       pixel[2][1] <= 0;
312
       pixel[2][2] <= 0;
313
   end
314
   else
315
   begin
316
       pixel[0][0] <= readData0;
317
       pixel[0][1] <= pixel[0][0];
318
       pixel[0][2] <= pixel[0][1];
319
 
320
       pixel[1][0] <= readData1;
321
       pixel[1][1] <= pixel[1][0];
322
       pixel[1][2] <= pixel[1][1];
323
 
324
       pixel[2][0] <= readData2;
325
       pixel[2][1] <= pixel[2][0];
326
       pixel[2][2] <= pixel[2][1];
327
   end
328
end
329
 
330
assign pixelMasked[0][0] = pixel[0][0] & {DATA_WIDTH{leftMask}} & {DATA_WIDTH{topMask}};
331
assign pixelMasked[0][1] = pixel[0][1] & {DATA_WIDTH{topMask}};
332
assign pixelMasked[0][2] = pixel[0][2] & {DATA_WIDTH{rightMask}} & {DATA_WIDTH{topMask}};
333
assign pixelMasked[1][0] = pixel[1][0] & {DATA_WIDTH{leftMask}};
334
assign pixelMasked[1][1] = pixel[1][1];
335
assign pixelMasked[1][2] = pixel[1][2] & {DATA_WIDTH{rightMask}};
336
assign pixelMasked[2][0] = pixel[2][0] & {DATA_WIDTH{leftMask}} & {DATA_WIDTH{bottomMask}};
337
assign pixelMasked[2][1] = pixel[2][1] & {DATA_WIDTH{bottomMask}};
338
assign pixelMasked[2][2] = pixel[2][2] & {DATA_WIDTH{rightMask}} & {DATA_WIDTH{bottomMask}};
339
 
340
wire [2:0] sidesMasked = ~leftMask + ~rightMask + ~topMask + ~bottomMask;       //Number of sides masked, either 0, 1 or 2
341
 
342
 
343
 
344
wire [DATA_WIDTH+1:0] blend1Sum_1 = pixelMasked[1][0] + pixelMasked[1][2] + pixelMasked[0][1] + pixelMasked[2][1];
345
reg [DATA_WIDTH+1:0] blend1SumOver3;
346
reg [DATA_WIDTH+1:0] blend1, blend2, blend3, blend4, blend5, blend2_1, blend3_1, blend4_1, blend5_1;
347
 
348
always @ (posedge clk or posedge rst or posedge start)
349
begin
350
        if(rst | start)
351
        begin
352
                blend1SumOver3 <= 0;
353
                blend1Sum <= 0;
354
                blend1 <= 0;
355
                blend2 <= 0;
356
                blend3 <= 0;
357
                blend4 <= 0;
358
        end
359
        else
360
        begin
361
                blend1SumOver3 <= (blend1Sum_1 >> 2) + (blend1Sum_1 >> 4) + (blend1Sum_1 >> 6) + (blend1Sum_1 >> 10);    //Constant multiply by 1/3 (approximate, but close enough)
362
                blend1Sum <= blend1Sum_1;
363
                blend1 <= ((sidesMasked == 0) ? blend1Sum >> 2 : (sidesMasked == 1) ? blend1SumOver3 : blend1Sum >> 1);     // divide by 4, 3, 2
364
 
365
                blend2_1 <= (pixelMasked[0][0] + pixelMasked[2][2] + pixelMasked[0][2] + pixelMasked[2][0]) >> ((sidesMasked == 0) ? 2 : (sidesMasked == 1) ? 1 : 0);       // divide by 4, 2, 1
366
                blend3_1 <= (pixelMasked[1][0] + pixelMasked[1][2]) >> ((!leftMask || !rightMask) ? 1 : 2); //divide by 2, 1
367
                blend4_1 <= (pixelMasked[0][1] + pixelMasked[2][1]) >> ((!topMask || !bottomMask) ? 1 : 2); //divide by 2, 1
368
                blend5_1 <= pixelMasked[1][1];  //Straight through
369
 
370
                blend2 <= blend2_1;
371
                blend3 <= blend3_1;
372
                blend4 <= blend4_1;
373
                blend5 <= blend5_1;
374
 
375
        end
376
end
377
 
378
 
379
//0 = R, 1 = G, 2 = B
380
 
381
wire [1:0] pixel0 = 0;
382
wire [1:0] pixel1 = 1;
383
wire [1:0] pixel2 = 1;
384
wire [1:0] pixel3 = 2;
385
 
386
wire [1:0]      quadPosition = {outputLine[0], outputColumn[0]};
387
wire [1:0]      blendModeSelect =       quadPosition == 0 ? pixel0 :
388
                                                                quadPosition == 1 ? pixel1 :
389
                                                                quadPosition == 2 ? pixel2 :
390
                                                                                                        pixel3;
391
 
392
always @ (posedge clk or posedge rst or posedge start)
393
begin
394
        if(rst | start)
395
        begin
396
                rOut <= 0;
397
                gOut <= 0;
398
                bOut <= 0;
399
        end
400
        else
401
        begin
402
                case(blendModeSelect)
403
                0:      //Red filter
404
                begin
405
                        rOut <= blend5; // Straight through
406
                        gOut <= blend1; // +
407
                        bOut <= blend2; // X
408
                end
409
 
410
                1:      //Green filter
411
                begin
412
                        rOut <= blend4; // |
413
                        gOut <= blend5; // Straight through
414
                        bOut <= blend3; // --
415
                end
416
                2:      //Blue filter
417
                begin
418
                        rOut <= blend2; // X
419
                        gOut <= blend1; // +
420
                        bOut <= blend5; // Straight through
421
                end
422
 
423
 
424
                endcase
425
 
426
        end
427
end
428
 
429
 
430
 
431
 
432
 
433
 
434
 
435
//Advance write whenever we have just written a valid line (discardInput == 0)
436
//Generate this signal one earlier than discardInput above that uses the same conditions, to advance the buffer at the right time.
437
assign advanceWrite =   (writeColCount == xRes) & dInValid & nextDin;
438
assign allDataWritten = writeState == WS_DONE;
439
assign nextDin = (fillCount < BUFFER_SIZE) & enableNextDin;
440
 
441
ramFifo #(
442
        .DATA_WIDTH( DATA_WIDTH ),
443
        .ADDRESS_WIDTH( X_RES_WIDTH ),  //Controls width of RAMs
444
        .BUFFER_SIZE( BUFFER_SIZE )             //Number of RAMs
445
) ramRB (
446
        .clk( clk ),
447
        .rst( rst | start ),
448
        .advanceRead1( advanceRead1 ),
449
        .advanceRead2( 0 ),
450
        .advanceWrite( advanceWrite ),
451
 
452
        .writeData( dIn ),
453
        .writeAddress( writeColCount ),
454
        .writeEnable( dInValid & nextDin & enableNextDin & ~discardInput ),
455
        .fillCount( fillCount ),
456
 
457
        .readData0( readData0 ),
458
        .readData1( readData1 ),
459
        .readData2( readData2 ),
460
        .readAddress( readAddress )
461
);
462
 
463
endmodule       //scaler
464
 
465
 
466
 
467
//---------------------------Ram FIFO (RFIFO)-----------------------------
468
//FIFO buffer with rams as the elements, instead of data
469
//One ram is filled, while two others are simultaneously read out.
470
//Four neighboring pixels are read out at once, at the selected RAM and one line down, and at readAddress and readAddress + 1
471
module ramFifo #(
472
        parameter DATA_WIDTH = 8,
473
        parameter ADDRESS_WIDTH = 8,
474
        parameter BUFFER_SIZE = 3,
475
        parameter BUFFER_SIZE_WIDTH =   ((BUFFER_SIZE+1) <= 2) ? 1 :    //wide enough to hold value BUFFER_SIZE + 1
476
                                                                        ((BUFFER_SIZE+1) <= 4) ? 2 :
477
                                                                        ((BUFFER_SIZE+1) <= 8) ? 3 :
478
                                                                        ((BUFFER_SIZE+1) <= 16) ? 4 :
479
                                                                        ((BUFFER_SIZE+1) <= 32) ? 5 :
480
                                                                        ((BUFFER_SIZE+1) <= 64) ? 6 : 7
481
)(
482
        input wire                                              clk,
483
        input wire                                              rst,
484
        input wire                                              advanceRead1,   //Advance selected read RAM by one
485
        input wire                                              advanceRead2,   //Advance selected read RAM by two
486
        input wire                                              advanceWrite,   //Advance selected write RAM by one
487
 
488
        input wire [DATA_WIDTH-1:0]             writeData,
489
        input wire [ADDRESS_WIDTH-1:0]  writeAddress,
490
        input wire                                              writeEnable,
491
        output reg [BUFFER_SIZE_WIDTH-1:0]
492
                                                                        fillCount,
493
 
494
        //                                                                              yx
495
        output wire [DATA_WIDTH-1:0]    readData0,              //Read from deepest RAM (earliest data), at readAddress
496
        output wire [DATA_WIDTH-1:0]    readData1,              //Read from second deepest RAM (second earliest data), at readAddress
497
        output wire [DATA_WIDTH-1:0]    readData2,              //Read from second deepest RAM (second earliest data), at readAddress
498
        input wire [ADDRESS_WIDTH-1:0]  readAddress
499
);
500
 
501
reg [BUFFER_SIZE-1:0]           writeSelect;
502
reg [BUFFER_SIZE-1:0]           readSelect;
503
 
504
//Read select ring register
505
always @(posedge clk or posedge rst)
506
begin
507
        if(rst)
508
                readSelect <= 1;
509
        else
510
        begin
511
                if(advanceRead1)
512
                begin
513
                        readSelect <= {readSelect[BUFFER_SIZE-2 : 0], readSelect[BUFFER_SIZE-1]};
514
                end
515
                else if(advanceRead2)
516
                begin
517
                        readSelect <= {readSelect[BUFFER_SIZE-3 : 0], readSelect[BUFFER_SIZE-1:BUFFER_SIZE-2]};
518
                end
519
        end
520
end
521
 
522
//Write select ring register
523
always @(posedge clk or posedge rst)
524
begin
525
        if(rst)
526
                writeSelect <= 1;
527
        else
528
        begin
529
                if(advanceWrite)
530
                begin
531
                        writeSelect <= {writeSelect[BUFFER_SIZE-2 : 0], writeSelect[BUFFER_SIZE-1]};
532
                end
533
        end
534
end
535
 
536
wire [DATA_WIDTH-1:0] ramDataOut [2**BUFFER_SIZE-1:0];
537
 
538
//Generate to instantiate the RAMs
539
generate
540
genvar i;
541
        for(i = 0; i < BUFFER_SIZE; i = i + 1)
542
                begin : ram_generate
543
 
544
                        ramDualPort #(
545
                                .DATA_WIDTH( DATA_WIDTH ),
546
                                .ADDRESS_WIDTH( ADDRESS_WIDTH )
547
                        ) ram_inst_i(
548
                                .clk( clk ),
549
 
550
                                //Port A is written to as well as read from. When writing, this port cannot be read from.
551
                                //As long as the buffer is large enough, this will not cause any problem.
552
                                .addrA( writeAddress ),
553
                                .dataA( writeData ),
554
                                .weA( writeEnable ),
555
                                .qA(  ),
556
 
557
                                .addrB( readAddress ),
558
                                .dataB( 0 ),
559
                                .weB( 1'b0 ),
560
                                .qB( ramDataOut[2**i] )
561
                        );
562
                end
563
endgenerate
564
 
565
//Select which ram to read from
566
wire [BUFFER_SIZE-1:0]  readSelect0 = readSelect;
567
wire [BUFFER_SIZE-1:0]  readSelect1 = (readSelect << 1) | readSelect[BUFFER_SIZE-1];
568
wire [BUFFER_SIZE-1:0]  readSelect2 = (readSelect << 2) | readSelect[BUFFER_SIZE-2];
569
 
570
//Steer the output data to the right ports
571
assign readData0 = ramDataOut[readSelect0];
572
assign readData1 = ramDataOut[readSelect1];
573
assign readData2 = ramDataOut[readSelect2];
574
 
575
 
576
//Keep track of fill level
577
always @(posedge clk or posedge rst)
578
begin
579
        if(rst)
580
        begin
581
                fillCount <= 0;
582
        end
583
        else
584
        begin
585
                if(advanceWrite)
586
                begin
587
                        if(advanceRead1)
588
                                fillCount <= fillCount;
589
                        else if(advanceRead2)
590
                                fillCount <= fillCount - 1;
591
                        else
592
                                fillCount <= fillCount + 1;
593
                end
594
                else
595
                begin
596
                        if(advanceRead1)
597
                                fillCount <= fillCount - 1;
598
                        else if(advanceRead2)
599
                                fillCount <= fillCount - 2;
600
                        else
601
                                fillCount <= fillCount;
602
                end
603
        end
604
end
605
 
606
endmodule //ramFifo
607
 
608
 
609
//Dual port RAM
610
module ramDualPort #(
611
        parameter DATA_WIDTH = 8,
612
        parameter ADDRESS_WIDTH = 8
613
)(
614
        input wire [(DATA_WIDTH-1):0] dataA, dataB,
615
        input wire [(ADDRESS_WIDTH-1):0] addrA, addrB,
616
        input wire weA, weB, clk,
617
        output reg [(DATA_WIDTH-1):0] qA, qB
618
);
619
 
620
        // Declare the RAM variable
621
        reg [DATA_WIDTH-1:0] ram[2**ADDRESS_WIDTH-1:0];
622
 
623
        //Port A
624
        always @ (posedge clk)
625
        begin
626
                if (weA)
627
                begin
628
                        ram[addrA] <= dataA;
629
                        qA <= dataA;
630
                end
631
                else
632
                begin
633
                        qA <= ram[addrA];
634
                end
635
        end
636
 
637
        //Port B
638
        always @ (posedge clk)
639
        begin
640
                if (weB)
641
                begin
642
                        ram[addrB] <= dataB;
643
                        qB <= dataB;
644
                end
645
                else
646
                begin
647
                        qB <= ram[addrB];
648
                end
649
        end
650
 
651
endmodule //ramDualPort
652
 
653
`default_nettype wire

powered by: WebSVN 2.1.0

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