📄 deint_v2mult_4l.v
字号:
//
RAMB16_S18_S18 LB2_lo (
.DOA(LB2_lo_DOA),
.DOPA(),
.DOB(),
.DOPB(),
.ADDRA(lb_adr[10:1]),
.CLKA(clk),
.DIA(LB1_lo_DOA),
.DIPA(2'b00),
.ENA(ce_rg[1]),
.SSRA(1'b0),
.WEA(ce_rg[1]),
.ADDRB(10'h000),
.CLKB(clk),
.DIB(16'h0000),
.DIPB(2'b00),
.ENB(1'b1),
.SSRB(rst),
.WEB(1'b0)
);
//-----------------------------------------------------------------------
//
// Line Buffer LB3
//
// synthesis attribute WRITE_MODE_A of LB3_hi is "READ_FIRST"
// synthesis attribute WRITE_MODE_B of LB3_hi is "READ_FIRST"
// synthesis attribute INIT_A of LB3_hi is "000000000"
// synthesis attribute INIT_B of LB3_hi is "000000000"
// synthesis attribute SRVAL_A of LB3_hi is "000000000"
// synthesis attribute SRVAL_B of LB3_hi is "000000000"
//
RAMB16_S18_S18 LB3_hi (
.DOA(LB3_hi_DOA),
.DOPA(),
.DOB(),
.DOPB(),
.ADDRA(lb_adr[10:1]),
.CLKA(clk),
.DIA(LB2_hi_DOA),
.DIPA(2'b00),
.ENA(ce_rg[1]),
.SSRA(1'b0),
.WEA(ce_rg[1]),
.ADDRB(10'h000),
.CLKB(clk),
.DIB(16'h0000),
.DIPB(2'b00),
.ENB(1'b1),
.SSRB(rst),
.WEB(1'b0)
);
// synthesis attribute WRITE_MODE_A of LB3_lo is "READ_FIRST"
// synthesis attribute WRITE_MODE_B of LB3_lo is "READ_FIRST"
// synthesis attribute INIT_A of LB3_lo is "000000000"
// synthesis attribute INIT_B of LB3_lo is "000000000"
// synthesis attribute SRVAL_A of LB3_lo is "000000000"
// synthesis attribute SRVAL_B of LB3_lo is "000000000"
//
RAMB16_S18_S18 LB3_lo (
.DOA(LB3_lo_DOA),
.DOPA(),
.DOB(),
.DOPB(),
.ADDRA(lb_adr[10:1]),
.CLKA(clk),
.DIA(LB2_lo_DOA),
.DIPA(2'b00),
.ENA(ce_rg[1]),
.SSRA(1'b0),
.WEA(ce_rg[1]),
.ADDRB(10'h000),
.CLKB(clk),
.DIB(16'h0000),
.DIPB(2'b00),
.ENB(1'b1),
.SSRB(rst),
.WEB(1'b0)
);
//-----------------------------------------------------------------------
//
// Output from Line buffers into the filter math
//
always @ (posedge clk) begin
if (rst) begin for (i = 0; i <= 3; i = i+1) FR_rg[i] <= 0; end
else begin
FR_rg[0] <= R_rg;
FG_rg[0] <= G_rg;
FB_rg[0] <= B_rg;
FR_rg[1] <= {LB1_hi_DOA[14:10], LB1_lo_DOA[14:10]};
FG_rg[1] <= {LB1_hi_DOA[9:5], LB1_lo_DOA[9:5]};
FB_rg[1] <= {LB1_hi_DOA[4:0], LB1_lo_DOA[4:0]};
FR_rg[2] <= {LB2_hi_DOA[14:10], LB2_lo_DOA[14:10]};
FG_rg[2] <= {LB2_hi_DOA[9:5], LB2_lo_DOA[9:5]};
FB_rg[2] <= {LB2_hi_DOA[4:0], LB2_lo_DOA[4:0]};
FR_rg[3] <= {LB3_hi_DOA[14:10], LB3_lo_DOA[14:10]};
FG_rg[3] <= {LB3_hi_DOA[9:5], LB3_lo_DOA[9:5]};
FB_rg[3] <= {LB3_hi_DOA[4:0], LB3_lo_DOA[4:0]};
end
end
//-----------------------------------------------------------------------
//
// Registered pre-addition into the multipliers
//
/*
Filter registers contain incoming RGB where each 10 bit component is of
the format:
S[1]I[7].F[2]
The output of the pre adder format is:
S[1]I[7].F[2] + S[1]I[7].F[2] = S[1]I[8].F[2]
*/
always @ (posedge clk) begin
if (rst) begin
R_pre_add0 <= 0; G_pre_add0 <= 0; B_pre_add0 <= 0;
R_pre_add1 <= 0; G_pre_add1 <= 0; B_pre_add1 <= 0;
end
else begin
R_pre_add0 <= FR_rg[0] + FR_rg[3];
R_pre_add1 <= FR_rg[1] + FR_rg[2];
G_pre_add0 <= FG_rg[0] + FG_rg[3];
G_pre_add1 <= FG_rg[1] + FG_rg[2];
B_pre_add0 <= FB_rg[0] + FB_rg[3];
B_pre_add1 <= FB_rg[1] + FB_rg[2];
end
end
//-----------------------------------------------------------------------
//
// Filter multipliers
// initially use .25 as the coefficients
// later use 1/6, and 1/3
//
/*
The output of the pre adders above is in the format:
S[1]I[8].F[2]
The 36 bit multiplier output format will be:
S[1].F[17] * S[1]I[8].F[2] = S[8]I[9].F[19]
Notice that there are 19 fractional bits out of the multiplier. We only
need to carry two (bits 17 and 18 from the multiplier). Therefore the
bits we are interested in keeping from the multiply are the 12 bits
[28:17] which are formatted as:
S[1]I[9].F[2]
Note that a coregen multiplier would consume about 68 LUTs and 34
registers per constant multiplier replaced or 408 LUTs and 204 FFs for
all six multipliers. Of course, one only need generate an 11 bit input
multiplied by a 12 bit constant with a 12 bit result.
*/
// Red Multipliers
MULT18X18 MULT1 (.P(PR0), .A(18'h08000), .B({7'h00, R_pre_add0}));
MULT18X18 MULT2 (.P(PR1), .A(18'h08000), .B({7'h00, R_pre_add1}));
// Green Multipliers
MULT18X18 MULT3 (.P(PG0), .A(18'h08000), .B({7'h00, G_pre_add0}));
MULT18X18 MULT4 (.P(PG1), .A(18'h08000), .B({7'h00, G_pre_add1}));
// Blue Multipliers
MULT18X18 MULT5 (.P(PB0), .A(18'h08000), .B({7'h00, B_pre_add0}));
MULT18X18 MULT6 (.P(PB1), .A(18'h08000), .B({7'h00, B_pre_add1}));
//-----------------------------------------------------------------------
//
// Registered outputs of multiply
//
always @ (posedge clk) begin
if (rst) begin
PR0_rg <= 0; PR1_rg <= 0;
PG0_rg <= 0; PG1_rg <= 0;
PB0_rg <= 0; PB1_rg <= 0;
end
else if (ce_rg[1]) begin
PR0_rg <= PR0; PR1_rg <= PR1;
PG0_rg <= PG0; PG1_rg <= PG1;
PB0_rg <= PB0; PB1_rg <= PB1;
end
else begin
PR0_rg <= PR0_rg; PR1_rg <= PR1_rg;
PG0_rg <= PG0_rg; PG1_rg <= PG1_rg;
PB0_rg <= PB0_rg; PB1_rg <= PB1_rg;
end
end
//-----------------------------------------------------------------------
//
// Registered post-addition outputs of multiply
//
/*
The output of the multipliers above is in the format:
S[1]I[9].F[2]
Twelve bits gives us plenty of head room for the post addition, so the
same format is maintained.
*/
always @ (posedge clk) begin
if (rst) begin
R_filt <= 0; G_filt <= 0; B_filt <= 0;
end
else if (ce_rg[1]) begin
R_filt <= PR0_rg[28:17] + PR1_rg[28:17];
G_filt <= PG0_rg[28:17] + PG1_rg[28:17];
B_filt <= PB0_rg[28:17] + PB1_rg[28:17];
end
else begin
R_filt <= R_filt;
G_filt <= R_filt;
B_filt <= R_filt;
end
end
//-----------------------------------------------------------------------
//
// pipe delays to account for filter
//
always @ (posedge clk) begin
if (rst) begin
R_dld1 <= 0; G_dld1 <= 0; B_dld1 <= 0;
R_dld2 <= 0; G_dld2 <= 0; B_dld2 <= 0;
R_dld3 <= 0; G_dld3 <= 0; B_dld3 <= 0;
R_dld4 <= 0; G_dld4 <= 0; B_dld4 <= 0;
end
else if (ce_rg[1]) begin
R_dld1 <= FR_rg[2]; // Delay RGB to align filtered data with
G_dld1 <= FG_rg[2]; // non filtered data. Delays account for:
B_dld1 <= FB_rg[2]; // 1. pre-add register
R_dld2 <= R_dld1; // 2. multiplier output register
G_dld2 <= G_dld1; // 3. post-add register
B_dld2 <= B_dld1; // 4. correction register
R_dld3 <= R_dld2;
G_dld3 <= G_dld2;
B_dld3 <= B_dld2;
R_dld4 <= R_dld3;
G_dld4 <= G_dld3;
B_dld4 <= B_dld3;
end
else begin
R_dld1 <= R_dld1;
G_dld1 <= G_dld1;
B_dld1 <= B_dld1;
R_dld2 <= R_dld2;
G_dld2 <= G_dld2;
B_dld2 <= B_dld2;
R_dld3 <= R_dld3;
G_dld3 <= G_dld3;
B_dld3 <= B_dld3;
R_dld4 <= R_dld4;
G_dld4 <= G_dld4;
B_dld4 <= B_dld4;
end
end
//-----------------------------------------------------------------------
//
// Correct overflows and underflows coming out of the filter
//
always @ (posedge clk) begin
if (rst) R_correct <= 0;
else if (ce_rg[1] & (R_filt > 12'h3FC)) R_correct <= 10'h3FC; // max value = 255
else if (ce_rg[1]) R_correct <= R_filt; // otherwise pass
else R_correct <= R_correct;
end
always @ (posedge clk) begin
if (rst) G_correct <= 0;
else if (ce_rg[1] & (G_filt > 12'h3FC)) G_correct <= 10'h3FC; // max value = 255
else if (ce_rg[1]) G_correct <= G_filt; // otherwise pass
else G_correct <= G_correct;
end
always @ (posedge clk) begin
if (rst) B_correct <= 0;
else if (ce_rg[1] & (B_filt > 12'h3FC)) B_correct <= 10'h3FC; // max value = 255
else if (ce_rg[1]) B_correct <= B_filt; // otherwise pass
else B_correct <= B_correct;
end
//-----------------------------------------------------------------------
//
// The output registers are loaded every clock meaning data is cycled at
// 27 Mhz.
//
always @ (posedge clk) begin
if (rst) begin
R_out_real <= 0; G_out_real <= 0; B_out_real <= 0;
R_out_filt <= 0; G_out_filt <= 0; B_out_filt <= 0;
end
else if (ce_rg[1]) begin
R_out_real <= R_dld4; G_out_real <= G_dld4; B_out_real <= B_dld4;
R_out_filt <= R_correct; G_out_filt <= G_correct; B_out_filt <= B_correct;
end
else begin
R_out_real <= R_out_real; G_out_real <= G_out_real; B_out_real <= B_out_real;
R_out_filt <= R_out_filt; G_out_filt <= G_out_filt; B_out_filt <= B_out_filt;
end
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -