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

Subversion Repositories bilinear_demosaic

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 tesla500
/*-----------------------------------------------------------------------------
2
 
3
                                                                Bilinear Demosaic
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
Provides demosaicing of a streamign video source.
31
 
32
 
33
Bayer pattern codes for input bayerPattern:
34
0=R G
35
  G B
36
 
37
1=B G
38
  G R
39
 
40
2=G R
41
  B G
42
 
43
3=G B
44
  R G
45
 
46
-------------------------------------------------------------------------------
47
 
48
Revisions
49
 
50
V1.0.0  Nov 16 2012             Initial Release         David Kronstein
51
 
52
 
53
 
54
*/
55
`default_nettype none
56
 
57
module bilinearDemosaic #(
58
//---------------------------Parameters----------------------------------------
59
parameter       DATA_WIDTH =                    8,              //Width of input/output data
60
parameter       X_RES_WIDTH =                   11,             //Widths of input/output resolution control signals
61
parameter       Y_RES_WIDTH =                   11,
62
parameter       BUFFER_SIZE =                   4,              //Depth of RFIFO
63
//---------------------Non-user-definable parameters----------------------------
64
parameter       BUFFER_SIZE_WIDTH =             ((BUFFER_SIZE+1) <= 2) ? 1 :    //wide enough to hold value BUFFER_SIZE + 1
65
                                                                        ((BUFFER_SIZE+1) <= 4) ? 2 :
66
                                                                        ((BUFFER_SIZE+1) <= 8) ? 3 :
67
                                                                        ((BUFFER_SIZE+1) <= 16) ? 4 :
68
                                                                        ((BUFFER_SIZE+1) <= 32) ? 5 :
69
                                                                        ((BUFFER_SIZE+1) <= 64) ? 6 : 7
70
)(
71
//---------------------------Module IO-----------------------------------------
72
//Clock and reset
73
input wire                                              clk,
74
input wire                                              rst,
75
 
76
//User interface
77
//Video Input
78
input wire [DATA_WIDTH-1:0]              dIn,
79
input wire                                              dInValid,
80
output wire                                             nextDin,
81
input wire                                              start,
82
 
83
//Video Output
84
output reg [DATA_WIDTH-1:0]
85
                                                                rOut,
86
output reg [DATA_WIDTH-1:0]
87
                                                                gOut,
88
output reg [DATA_WIDTH-1:0]
89
                                                                bOut,
90
output reg                                              dOutValid,                      //latency of 1 clock cycle after nextDout is asserted
91
input wire                                              nextDout,
92
 
93
//Control
94
input wire [1:0]                         bayerPattern,           //Controls which of four bayer pixel patterns is used
95
input wire [X_RES_WIDTH-1:0]     xRes,                           //Resolution of input data minus 1
96
input wire [Y_RES_WIDTH-1:0]     yRes
97
 
98
);
99
//-----------------------Internal signals and registers------------------------
100
reg                                                             advanceRead;
101
 
102
wire [DATA_WIDTH-1:0]                    readData0;
103
wire [DATA_WIDTH-1:0]                    readData1;
104
wire [DATA_WIDTH-1:0]                    readData2;
105
 
106
wire [X_RES_WIDTH-1:0]                   readAddress;
107
 
108
reg                                                     readyForRead;           //Indicates two full lines have been put into the buffer
109
reg [Y_RES_WIDTH-1:0]                    outputLine;                     //which output video line we're on
110
reg [X_RES_WIDTH-1:0]                    outputColumn;           //which output video column we're on
111
wire [BUFFER_SIZE_WIDTH-1:0]     fillCount;                      //Numbers used rams in the ram fifo
112
reg                                                             dOutValidInt;
113
reg                                                             fillPipeline;
114
reg                                                             fillPipeline_1;
115
reg [2:0]                                                fillPipelineCount;
116
 
117
wire                                                    allDataWritten;         //Indicates that all data from input has been read in
118
reg                                                     readState;
119
 
120
//States for read state machine
121
parameter RS_START =            1'b0;
122
parameter RS_READ_LINE =        1'b1;
123
 
124
//Read state machine
125
//Controls the RFIFO(ram FIFO) readout and generates output data valid signals
126
always @ (posedge clk or posedge rst or posedge start)
127
begin
128
        if(rst | start)
129
        begin
130
                outputLine <= 0;
131
                outputColumn <= 0;
132
                readState <= RS_START;
133
                dOutValidInt <= 0;
134
                advanceRead <= 0;
135
                fillPipeline <= 0;
136
                fillPipeline_1 <= 0;
137
                fillPipelineCount <= 0;
138
        end
139
        else
140
        begin
141
                case (readState)
142
 
143
                        RS_START:
144
                        begin
145
                                if(readyForRead)
146
                                begin
147
                                        readState <= RS_READ_LINE;
148
                                        dOutValidInt <= 1;
149
                                        fillPipeline <= 1;
150
                                        fillPipelineCount <= 4;
151
                                end
152
                        end
153
 
154
                        RS_READ_LINE:
155
                        begin
156
                                if(nextDout && dOutValidInt || fillPipeline)
157
                                begin
158
                                        if(outputColumn == xRes)
159
                                        begin //On the last input pixel of the line
160
 
161
                                                advanceRead <= 1;
162
                                                if(fillCount < (3 + 1))         //If the RFIFO doesn't have enough data, stop reading it out (+1 to account for fill level after advancing the RRB)
163
                                                        dOutValidInt <= 0;
164
 
165
                                                outputColumn <= 0;
166
                                                outputLine <= outputLine + 1;
167
                                        end
168
                                        else
169
                                        begin
170
                                                //Advance the output pixel selection values
171
                                                outputColumn <= outputColumn + 1;
172
                                                advanceRead <= 0;
173
                                        end
174
                                end
175
                                else //else from if(nextDout && dOutValidInt || fillPipeline)
176
                                begin
177
                                        advanceRead <= 0;
178
                                end
179
 
180
                                //Once the RFIFO has enough data, let data be read from it.
181
                                if(fillCount >= 3 && dOutValidInt == 0 || allDataWritten)
182
                                begin
183
                                        if(!advanceRead)
184
                                        begin
185
                                                dOutValidInt <= 1;
186
                                        end
187
                                end
188
 
189
                                //Counter for pipeline fill time
190
                                if(fillPipelineCount > 0)
191
                                begin
192
                                        fillPipelineCount <= fillPipelineCount - 1;
193
                                end
194
                                else
195
                                begin
196
                                        fillPipeline <= 0;
197
                                end
198
 
199
                                fillPipeline_1 <= fillPipeline;
200
 
201
                        end//state RS_READ_LINE:
202
                endcase
203
 
204
        end
205
end
206
 
207
assign readAddress = outputColumn;
208
 
209
//Generate dOutValid signal, delayed to account for delays in data path
210
always @(posedge clk or posedge rst)
211
begin
212
        if(rst)
213
        begin
214
                dOutValid <= 0;
215
        end
216
        else
217
        begin
218
                dOutValid <= nextDout && dOutValidInt;
219
        end
220
end
221
 
222
 
223
wire                                    advanceWrite;
224
reg [1:0]                                writeState;
225
reg [X_RES_WIDTH-1:0]    writeColCount;
226
reg [Y_RES_WIDTH-1:0]    writeRowCount;
227
reg                                             enableNextDin;
228
reg                                             forceRead;
229
 
230
//Write state machine
231
//Controls writing scaler input data into the RFIFO
232
parameter       WS_START = 0;
233
parameter       WS_DISCARD = 1;
234
parameter       WS_READ = 2;
235
parameter       WS_DONE = 3;
236
 
237
//Control write and address signals to write data into ram FIFO
238
always @ (posedge clk or posedge rst or posedge start)
239
begin
240
        if(rst | start)
241
        begin
242
                writeState <= WS_START;
243
                enableNextDin <= 0;
244
                readyForRead <= 0;
245
                writeRowCount <= 0;
246
                writeColCount <= 0;
247
                forceRead <= 0;
248
        end
249
        else
250
        begin
251
                case (writeState)
252
 
253
                        WS_START:
254
                        begin
255
                                enableNextDin <= 1;
256
                                writeState <= WS_READ;
257
                        end
258
 
259
                        WS_READ:
260
                        begin
261
                                if(dInValid & nextDin)
262
                                begin
263
                                        if(writeColCount == xRes)
264
                                        begin   //Occurs on the last pixel in the line
265
 
266
                                                //Once writeRowCount is >= 3, data is ready to start being output.
267
                                                if(writeRowCount[1:0] == 2'h2)
268
                                                        readyForRead <= 1;
269
 
270
                                                if(writeRowCount == yRes)       //When all data has been read in, stop reading from input.
271
                                                begin
272
                                                        writeState <= WS_DONE;
273
                                                        enableNextDin <= 0;
274
                                                        forceRead <= 1;
275
                                                end
276
 
277
                                                writeColCount <= 0;
278
                                                writeRowCount <= writeRowCount + 1;
279
                                        end
280
                                        else
281
                                        begin
282
                                                writeColCount <= writeColCount + 1;
283
                                        end
284
                                end
285
                        end
286
 
287
                        WS_DONE:
288
                        begin
289
                                //do nothing, wait for reset
290
                        end
291
 
292
                endcase
293
        end
294
end
295
 
296
//Masks to disable blending of invalid data (when at edges of image and no data is available for some pixels)
297
wire leftMask, rightMask, topMask, bottomMask;
298
 
299
wire leftMask_1 =       ~(outputColumn == 0);
300
wire rightMask_1 =      ~(outputColumn == xRes);
301
wire topMask_1 =        ~(outputLine == 0);
302
wire bottomMask_1 =     ~(outputLine == yRes);
303
 
304
//delay mask signals as required
305
registerDelay #(
306
        .DATA_WIDTH( 4 ),
307
        .STAGES( 3 )
308
) rd_edgeMask (
309
        .clk( clk ),
310
        .rst( rst | start ),
311
        .enable( dOutValid || fillPipeline ),
312
        .d( {leftMask_1, rightMask_1, topMask_1, bottomMask_1} ),
313
        .q( {leftMask, rightMask, topMask, bottomMask} )
314
        );
315
 
316
 
317
reg [DATA_WIDTH-1:0]     pixel [2:0][2:0];    //[y, x] pixel da
318
wire [DATA_WIDTH-1:0]    pixelMasked [2:0][2:0];    //[y, x]
319
/*
320
Pixel data format
321
 
322
pixel[0][0]     pixel[0][1]     pixel[0][2]
323
pixel[1][0]     pixel[1][1]     pixel[1][2]
324
pixel[2][0]     pixel[2][1]     pixel[2][2]
325
 
326
*/
327
 
328
always @ (posedge clk or posedge rst or posedge start)
329
begin
330
   if(rst | start)
331
   begin
332
       pixel[0][0] <= 0;
333
       pixel[0][1] <= 0;
334
       pixel[0][2] <= 0;
335
       pixel[1][0] <= 0;
336
       pixel[1][1] <= 0;
337
       pixel[1][2] <= 0;
338
       pixel[2][0] <= 0;
339
       pixel[2][1] <= 0;
340
       pixel[2][2] <= 0;
341
   end
342
   else
343
   begin
344
           if( dOutValid || fillPipeline_1 )
345
           begin
346
                   pixel[0][2] <= readData0;     //Upper line
347
                   pixel[0][1] <= pixel[0][2];
348
                   pixel[0][0] <= pixel[0][1];
349
 
350
                   pixel[1][2] <= readData1;    //Middle line
351
                   pixel[1][1] <= pixel[1][2];
352
                   pixel[1][0] <= pixel[1][1];
353
 
354
                   pixel[2][2] <= readData2;    //Lower line
355
                   pixel[2][1] <= pixel[2][2];
356
                   pixel[2][0] <= pixel[2][1];
357
                end
358
        end
359
end
360
 
361
//Apply masking so invalid data at the edge of the image is not used
362
assign pixelMasked[0][0] = pixel[0][0] & {DATA_WIDTH{leftMask}} & {DATA_WIDTH{topMask}};
363
assign pixelMasked[0][1] = pixel[0][1] & {DATA_WIDTH{topMask}};
364
assign pixelMasked[0][2] = pixel[0][2] & {DATA_WIDTH{rightMask}} & {DATA_WIDTH{topMask}};
365
assign pixelMasked[1][0] = pixel[1][0] & {DATA_WIDTH{leftMask}};
366
assign pixelMasked[1][1] = pixel[1][1];
367
assign pixelMasked[1][2] = pixel[1][2] & {DATA_WIDTH{rightMask}};
368
assign pixelMasked[2][0] = pixel[2][0] & {DATA_WIDTH{leftMask}} & {DATA_WIDTH{bottomMask}};
369
assign pixelMasked[2][1] = pixel[2][1] & {DATA_WIDTH{bottomMask}};
370
assign pixelMasked[2][2] = pixel[2][2] & {DATA_WIDTH{rightMask}} & {DATA_WIDTH{bottomMask}};
371
 
372
wire [2:0]       sidesMasked = ~leftMask + ~rightMask + ~topMask + ~bottomMask;  //Number of sides masked, either 0, 1 or 2. Used for selecting how to divide during averaging
373
reg [2:0]        sidesMaskedReg;
374
 
375
/*
376
Perform demosaic blending
377
All possible blend modes are computed simultaneously, and
378
the proper ones are selected based on which color filter is being worked on
379
 
380
Blend modes:
381
blend1 = +      (average of four pixels N S E and W)
382
blend2 = X      (average of four pixels NE SE SW and NW)
383
blend3 = --     (average of pixels E and W)
384
blend4 = |      (average of pixels N and S)
385
blend5 = straight through
386
*/
387
 
388
wire [DATA_WIDTH+1:0]    blend1Sum_1 = pixelMasked[1][0] + pixelMasked[1][2] + pixelMasked[0][1] + pixelMasked[2][1];
389
reg [DATA_WIDTH+1:0]     blend1SumOver3, blend1Sum;
390
reg [DATA_WIDTH+1:0]     blend1, blend2, blend3, blend4, blend5, blend2_1, blend3_1, blend4_1, blend5_1;
391
 
392
always @ (posedge clk or posedge rst or posedge start)
393
begin
394
        if(rst | start)
395
        begin
396
                blend1SumOver3 <= 0;
397
                blend1Sum <= 0;
398
                blend1 <= 0;
399
                blend2 <= 0;
400
                blend3 <= 0;
401
                blend4 <= 0;
402
                sidesMaskedReg <= 0;
403
        end
404
        else
405
        begin
406
                if( dOutValid || fillPipeline_1 )
407
                begin
408
                        blend1SumOver3 <= (blend1Sum_1 >> 2) + (blend1Sum_1 >> 4) + (blend1Sum_1 >> 6) + (blend1Sum_1 >> 10);   //Constant multiply by 1/3 (approximate, but close enough)
409
                        blend1Sum <= blend1Sum_1;
410
                        blend1 <= ((sidesMaskedReg == 0) ? blend1Sum >> 2 : (sidesMaskedReg == 1) ? blend1SumOver3 : blend1Sum >> 1);    // divide by 4, 3, 2
411
 
412
                        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
413
                        blend3_1 <= (pixelMasked[1][0] + pixelMasked[1][2]) >> ((!leftMask || !rightMask) ? 0 : 1);       //divide by 2, 1
414
                        blend4_1 <= (pixelMasked[0][1] + pixelMasked[2][1]) >> ((!topMask || !bottomMask) ? 0 : 1);       //divide by 2, 1
415
                        blend5_1 <= pixelMasked[1][1];  //Straight through
416
 
417
                        blend2 <= blend2_1;
418
                        blend3 <= blend3_1;
419
                        blend4 <= blend4_1;
420
                        blend5 <= blend5_1;
421
 
422
                        sidesMaskedReg <= sidesMasked;
423
                end
424
 
425
        end
426
end
427
 
428
 
429
/*
430
Bayer pattern codes:
431
0=R G
432
  G B
433
 
434
1=B G
435
  G R
436
 
437
2=G R
438
  B G
439
 
440
3=G B
441
  R G
442
 
443
  Pixel codes
444
 
445
*/
446
reg [1:0] pixel0;
447
reg [1:0] pixel1;
448
reg [1:0] pixel2;
449
reg [1:0] pixel3;
450
 
451
always @(*)
452
begin
453
        case(bayerPattern)
454
        0:
455
        begin
456
                pixel0 = 0;
457
                pixel1 = 1;
458
                pixel2 = 2;
459
                pixel3 = 3;
460
        end
461
 
462
        1:
463
        begin
464
                pixel0 = 3;
465
                pixel1 = 2;
466
                pixel2 = 1;
467
                pixel3 = 0;
468
        end
469
 
470
        2:
471
        begin
472
                pixel0 = 1;
473
                pixel1 = 0;
474
                pixel2 = 3;
475
                pixel3 = 2;
476
        end
477
 
478
        3:
479
        begin
480
                pixel0 = 2;
481
                pixel1 = 3;
482
                pixel2 = 0;
483
                pixel3 = 1;
484
        end
485
        endcase
486
end
487
 
488
wire [1:0]       quadPosition = {outputLine[0], outputColumn[0]};
489
wire [1:0]       blendModeSelect_1 =     quadPosition == 0 ? pixel0 :
490
                                                                quadPosition == 1 ? pixel1 :
491
                                                                quadPosition == 2 ? pixel2 :
492
                                                                                                        pixel3;
493
wire [1:0]       blendModeSelect;
494
 
495
//Delay blend mode
496
registerDelay #(
497
        .DATA_WIDTH( 2 ),
498
        .STAGES( 5 )
499
) rd_blendMode (
500
        .clk( clk ),
501
        .rst( rst | start ),
502
        .enable( dOutValid || fillPipeline_1 ),
503
        .d( blendModeSelect_1 ),
504
        .q( blendModeSelect )
505
        );
506
 
507
//Select proper blend mode for each R G and B output
508
always @ (posedge clk or posedge rst or posedge start)
509
begin
510
        if(rst | start)
511
        begin
512
                rOut <= 0;
513
                gOut <= 0;
514
                bOut <= 0;
515
        end
516
        else
517
        begin
518
                if( dOutValid || fillPipeline_1 )
519
                begin
520
                        case(blendModeSelect)
521
                        0:       //Red filter
522
                        begin
523
                                rOut <= blend5; // Straight through
524
                                gOut <= blend1; // +
525
                                bOut <= blend2; // X
526
                        end
527
 
528
                        1:      //Green filter with blue above/below
529
                        begin
530
                                rOut <= blend3; // --
531
                                gOut <= blend5; // Straight through
532
                                bOut <= blend4; // |
533
                        end
534
 
535
                        2:      //Green filter with red above/below
536
                        begin
537
                                rOut <= blend4; // |
538
                                gOut <= blend5; // Straight through
539
                                bOut <= blend3; // --
540
                        end
541
 
542
                        3:      //Blue filter
543
                        begin
544
                                rOut <= blend2; // X
545
                                gOut <= blend1; // +
546
                                bOut <= blend5; // Straight through
547
                        end
548
                        endcase
549
                end
550
        end
551
end
552
 
553
 
554
//Advance write whenever we have just written a valid line (discardInput == 0)
555
//Generate this signal one earlier than discardInput above that uses the same conditions, to advance the buffer at the right time.
556
assign advanceWrite =   (writeColCount == xRes) & dInValid & nextDin;
557
assign allDataWritten = writeState == WS_DONE;
558
assign nextDin = (fillCount < BUFFER_SIZE) & enableNextDin;
559
 
560
ramFifo #(
561
        .DATA_WIDTH( DATA_WIDTH ),
562
        .ADDRESS_WIDTH( X_RES_WIDTH ),  //Controls width of RAMs
563
        .BUFFER_SIZE( BUFFER_SIZE )             //Number of RAMs
564
) ramRB (
565
        .clk( clk ),
566
        .rst( rst | start ),
567
        .advanceRead( advanceRead ),
568
        .advanceWrite( advanceWrite ),
569
 
570
        .writeData( dIn ),
571
        .writeAddress( writeColCount ),
572
        .writeEnable( dInValid & nextDin & enableNextDin ),
573
        .fillCount( fillCount ),
574
 
575
        .readData0( readData0 ),
576
        .readData1( readData1 ),
577
        .readData2( readData2 ),
578
        .readAddress( readAddress )
579
);
580
 
581
endmodule       //bilinearDemosaic
582
 
583
 
584
 
585
//---------------------------Ram FIFO (RFIFO)-----------------------------
586
//FIFO buffer with rams as the elements, instead of data
587
//One ram is filled, while three others are simultaneously read out.
588
module ramFifo #(
589
        parameter DATA_WIDTH = 8,
590
        parameter ADDRESS_WIDTH = 8,
591
        parameter BUFFER_SIZE = 3,
592
        parameter BUFFER_SIZE_WIDTH =   ((BUFFER_SIZE+1) <= 2) ? 1 :    //wide enough to hold value BUFFER_SIZE + 1
593
                                                                        ((BUFFER_SIZE+1) <= 4) ? 2 :
594
                                                                        ((BUFFER_SIZE+1) <= 8) ? 3 :
595
                                                                        ((BUFFER_SIZE+1) <= 16) ? 4 :
596
                                                                        ((BUFFER_SIZE+1) <= 32) ? 5 :
597
                                                                        ((BUFFER_SIZE+1) <= 64) ? 6 : 7
598
)(
599
        input wire                                              clk,
600
        input wire                                              rst,
601
        input wire                                              advanceRead,    //Advance selected read RAM by one
602
        input wire                                              advanceWrite,   //Advance selected write RAM by one     
603
 
604
        input wire [DATA_WIDTH-1:0]              writeData,
605
        input wire [ADDRESS_WIDTH-1:0]   writeAddress,
606
        input wire                                              writeEnable,
607
        output reg [BUFFER_SIZE_WIDTH-1:0]
608
                                                                        fillCount,
609
 
610
        output wire [DATA_WIDTH-1:0]     readData0,              //Read from deepest RAM (earliest data), at readAddress
611
        output wire [DATA_WIDTH-1:0]     readData1,              //Read from second deepest RAM (second earliest data), at readAddress
612
        output wire [DATA_WIDTH-1:0]     readData2,              //Read from third deepest RAM (third earliest data), at readAddress
613
        input wire [ADDRESS_WIDTH-1:0]   readAddress
614
);
615
 
616
reg [BUFFER_SIZE-1:0]                            writeSelect;
617
reg [BUFFER_SIZE-1:0]                            readSelect;
618
 
619
//Read select ring register
620
always @(posedge clk or posedge rst)
621
begin
622
        if(rst)
623
                readSelect <= {1'b1, {(BUFFER_SIZE-1){1'b0}}}; //Mod for demosaic, normally 1
624
        else
625
        begin
626
                if(advanceRead)
627
                begin
628
                        readSelect <= {readSelect[BUFFER_SIZE-2 : 0], readSelect[BUFFER_SIZE-1]};
629
                end
630
        end
631
end
632
 
633
//Write select ring register
634
always @(posedge clk or posedge rst)
635
begin
636
        if(rst)
637
                writeSelect <= 1;
638
        else
639
        begin
640
                if(advanceWrite)
641
                begin
642
                        writeSelect <= {writeSelect[BUFFER_SIZE-2 : 0], writeSelect[BUFFER_SIZE-1]};
643
                end
644
        end
645
end
646
 
647
wire [DATA_WIDTH-1:0] ramDataOut [2**BUFFER_SIZE-1:0];
648
 
649
//Generate to instantiate the RAMs
650
generate
651
genvar i;
652
        for(i = 0; i < BUFFER_SIZE; i = i + 1)
653
                begin : ram_generate
654
 
655
                        ramDualPort #(
656
                                .DATA_WIDTH( DATA_WIDTH ),
657
                                .ADDRESS_WIDTH( ADDRESS_WIDTH )
658
                        ) ram_inst_i(
659
                                .clk( clk ),
660
 
661
                                //Port A is written to, port B is read from
662
                                .addrA( writeAddress ),
663
                                .dataA( writeData ),
664
                                .weA( (writeSelect[i] == 1'b1) ? writeEnable : 1'b0 ),
665
                                .qA(  ),
666
 
667
                                .addrB( readAddress ),
668
                                .dataB( 0 ),
669
                                .weB( 1'b0 ),
670
                                .qB( ramDataOut[2**i] )
671
                        );
672
                end
673
endgenerate
674
 
675
//Select which ram to read from
676
wire [BUFFER_SIZE-1:0]   readSelect0 = readSelect;
677
wire [BUFFER_SIZE-1:0]   readSelect1 = (readSelect << 1) | readSelect[BUFFER_SIZE-1];
678
wire [BUFFER_SIZE-1:0]   readSelect2 = (readSelect << 2) | readSelect[BUFFER_SIZE-1:BUFFER_SIZE-2];
679
 
680
//Steer the output data to the right ports
681
assign readData0 = ramDataOut[readSelect0];
682
assign readData1 = ramDataOut[readSelect1];
683
assign readData2 = ramDataOut[readSelect2];
684
 
685
 
686
//Keep track of fill level
687
always @(posedge clk or posedge rst)
688
begin
689
        if(rst)
690
        begin
691
                fillCount <= 1;         //Mod for demosaic, normally 0. The first line has to come out of readData1, the invalid data from readData0 will be masked
692
        end
693
        else
694
        begin
695
                if(advanceWrite)
696
                begin
697
                        if(advanceRead)
698
                                fillCount <= fillCount;
699
                        else
700
                                fillCount <= fillCount + 1;
701
                end
702
                else
703
                begin
704
                        if(advanceRead)
705
                                fillCount <= fillCount - 1;
706
                        else
707
                                fillCount <= fillCount;
708
                end
709
        end
710
end
711
 
712
endmodule //ramFifo
713
 
714
 
715
//Dual port RAM
716
module ramDualPort #(
717
        parameter DATA_WIDTH = 8,
718
        parameter ADDRESS_WIDTH = 8
719
)(
720
        input wire [(DATA_WIDTH-1):0] dataA, dataB,
721
        input wire [(ADDRESS_WIDTH-1):0] addrA, addrB,
722
        input wire weA, weB, clk,
723
        output reg [(DATA_WIDTH-1):0] qA, qB
724
);
725
 
726
        // Declare the RAM variable
727
        reg [DATA_WIDTH-1:0] ram[2**ADDRESS_WIDTH-1:0];
728
 
729
        //Port A
730
        always @ (posedge clk)
731
        begin
732
                if (weA)
733
                begin
734
                        ram[addrA] <= dataA;
735
                        qA <= dataA;
736
                end
737
                else
738
                begin
739
                        qA <= ram[addrA];
740
                end
741
        end
742
 
743
        //Port B
744
        always @ (posedge clk)
745
        begin
746
                if (weB)
747
                begin
748
                        ram[addrB] <= dataB;
749
                        qB <= dataB;
750
                end
751
                else
752
                begin
753
                        qB <= ram[addrB];
754
                end
755
        end
756
 
757
endmodule //ramDualPort
758
 
759
`default_nettype wire

powered by: WebSVN 2.1.0

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