📄 dve_ccir_dph.v
字号:
// Only a quarter of a SINe table is used instead of two full SIN and COS tables
// 1:8 size reduction
// First table containes values from 0 to Pi/4-2Pi/2^DDS_resolution)
// Second table containes values from Pi/4 to Pi/2-2Pi/2^DDS_resolution)
// Additional BYPASS signals are generated in order to bypass chroma precisely without
// multiplication it by 0.99(9). Depending on the SINE/COSINE value, it is either 0 or 1
// Command decoder for BYPASS/NEGATE datapath
assign quadrature_axe = ~|fsc_tbl_addr[SUBCARRIER_INTEGER_PRECISION-4 : 0];
always @(fsc_tbl_addr[SUBCARRIER_INTEGER_PRECISION-1 : SUBCARRIER_INTEGER_PRECISION-3]
or lut_sin_out or lut_cos_out or quadrature_axe)
begin
case (fsc_tbl_addr[SUBCARRIER_INTEGER_PRECISION-1 : SUBCARRIER_INTEGER_PRECISION-3])
// ..... Sine is taken from 0 to 45 degrees table ..... Cosine from 45 to 90 degrees table
3'b000 : begin
sin_wt_mux = lut_sin_out; // will be multiplied by U component
negate_u_product = 1'b0; // sign of multiplication: positive, sin(x) positive
bypass_u_component = 1'b0;
cos_wt_mux = lut_cos_out; // will be multiplied by V component
negate_v_product = 1'b0; // positive sign of multiplication
bypass_v_component = quadrature_axe; // cos(PI/2) = 1, bypass
end
// ..... Sine is taken from 45 to 90 degrees table ..... Cosine from 0 to 45 degrees table
3'b001 : begin
// Special case: 45 degrees. Fetch a different value for SIN(x)/COS(x)
if (quadrature_axe)
begin
sin_wt_mux = `SIN_45_VALUE;
cos_wt_mux = `SIN_45_VALUE;
end
else
begin
sin_wt_mux = lut_cos_out; // will be multiplied by U component
cos_wt_mux = lut_sin_out; // by V component
end
negate_u_product = 1'b0; // SIN(X)>0
bypass_u_component = 1'b0; // SIN(PI/4)=1
negate_v_product = 1'b0;
bypass_v_component = 1'b0;
end
3'b010 : begin
sin_wt_mux = lut_cos_out;
cos_wt_mux = lut_sin_out;
negate_u_product = 1'b0; // SIN(X)>0
bypass_u_component = quadrature_axe; // SIN(PI/4)=1
negate_v_product = 1'b1;
bypass_v_component = 1'b0;
end
// ..... Sine is taken from 45 to 90 degrees table ..... Cosine from 0 to 45 degrees table
3'b011 : begin
if (quadrature_axe)
begin
sin_wt_mux = `SIN_45_VALUE;
cos_wt_mux = `SIN_45_VALUE;
end
else
begin
sin_wt_mux = lut_sin_out;
cos_wt_mux = lut_cos_out;
end
negate_u_product = 1'b0; // SIN(X)>0
bypass_u_component = 1'b0; //
negate_v_product = 1'b1;
bypass_v_component = 1'b0;
end
3'b100 : begin
sin_wt_mux = lut_sin_out; // will be multiplied by U component
negate_u_product = 1'b1; // sign of multiplication: positive, sin(x) positive
bypass_u_component = 1'b0;
cos_wt_mux = lut_cos_out; // will be multiplied by V component
negate_v_product = 1'b1; // positive sign of multiplication
bypass_v_component = quadrature_axe; // cos(PI/2) = 1, bypass
end
3'b101 : begin
if (quadrature_axe)
begin
sin_wt_mux = `SIN_45_VALUE;
cos_wt_mux = `SIN_45_VALUE;
end
else
begin
sin_wt_mux = lut_cos_out; // will be multiplied by U component
cos_wt_mux = lut_sin_out; // by V component
end
negate_u_product = 1'b1; // SIN(X)<0
bypass_u_component = 1'b0; //
negate_v_product = 1'b1;
bypass_v_component = 1'b0;
end
3'b110 : begin
sin_wt_mux = lut_cos_out;
cos_wt_mux = lut_sin_out;
negate_u_product = 1'b1; // SIN(X)>0
bypass_u_component = quadrature_axe; // SIN(PI/4)=1
negate_v_product = 1'b0;
bypass_v_component = 1'b0;
end
3'b111 : begin
if (quadrature_axe)
begin
sin_wt_mux = `SIN_45_VALUE;
cos_wt_mux = `SIN_45_VALUE;
end
else
begin
sin_wt_mux = lut_sin_out;
cos_wt_mux = lut_cos_out;
end
negate_u_product = 1'b1; // SIN(X)<0
bypass_u_component = 1'b0; // SIN(PI/4)=1
negate_v_product = 1'b0;
bypass_v_component = 1'b0;
end
endcase
end
always @(posedge sclk)
begin
if (!srst_n)
begin
negate_u_reg <= 1'b0;
bypass_u_reg <= 1'b0;
negate_v_reg <= 1'b0;
bypass_v_reg <= 1'b0;
negate_del_u_reg <= 1'b0;
bypass_del_u_reg <= 1'b0;
negate_del_v_reg <= 1'b0;
bypass_del_v_reg <= 1'b0;
end
else
begin
// In the PAL mode, PAL V flag reflects whether the
// the result of multiplication has to be inverted or not
negate_v_reg <= negate_v_product^(~pal_v_flag);
negate_u_reg <= negate_u_product;
bypass_u_reg <= bypass_u_component;
bypass_v_reg <= bypass_v_component;
bypass_del_u_reg <= bypass_u_reg;
bypass_del_v_reg <= bypass_v_reg;
negate_del_u_reg <= negate_u_reg;
negate_del_v_reg <= negate_v_reg;
end
end
always @(posedge sclk)
begin
sin_wt_reg <= sin_wt_mux;
cos_wt_reg <= cos_wt_mux;
end
always @(posedge sclk)
begin
u_bypass_reg <= u_oversampling_reg;
v_bypass_reg <= v_oversampling_reg;
end
// -----------------------------------------------------------------------------
//
// !!! CONFIGURATION FORK !!!!
// Either 8x8 or 8x9 multipliers are selected
// -----------------------------------------------------------------------------
`ifdef MODULATOR_CONFIGURATION_8BIT
// -----------------------------------------------------------------------------
// 8 bit datapath configuration case
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
// U COMPONENT MULTIPLIER
//
// -----------------------------------------------------------------------------
dve_ccir_mlt u_mult (.sclk(sclk),
.srst_n(srst_n),
.a_in({1'b0, sin_wt_reg}),
.b_in(u_oversampling_reg),
.p_out(u_by_sin_wt_out));
// -----------------------------------------------------------------------------
//
// V COMPONENT MULTIPLIER
//
// -----------------------------------------------------------------------------
dve_ccir_mlt v_mult (.sclk(sclk),
.srst_n(srst_n),
.a_in({1'b0, cos_wt_reg}),
.b_in(v_oversampling_reg),
.p_out(v_by_cos_wt_out));
always @(posedge sclk)
begin
u_by_sin_wt_reg <= {u_by_sin_wt_out[14 : 0],1'b0};
v_by_cos_wt_reg <= {v_by_cos_wt_out[14 : 0],1'b0};
end
`else
// -----------------------------------------------------------------------------
// 9 bit datapath configuration case
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
// U COMPONENT MULTIPLIER
//
// -----------------------------------------------------------------------------
dve_ccir_mlt8x9 u_mult (.sclk(sclk),
.srst_n(srst_n),
.a_in(u_oversampling_reg),
.b_in({1'b0, sin_wt_reg}),
.p_out(u_by_sin_wt_out));
// -----------------------------------------------------------------------------
//
// V COMPONENT MULTIPLIER
//
// -----------------------------------------------------------------------------
dve_ccir_mlt8x9 v_mult (.sclk(sclk),
.srst_n(srst_n),
.a_in(v_oversampling_reg),
.b_in({1'b0, cos_wt_reg}),
.p_out(v_by_cos_wt_out));
always @(posedge sclk)
begin
u_by_sin_wt_reg <= u_by_sin_wt_out;
v_by_cos_wt_reg <= v_by_cos_wt_out;
end
// -----------------------------------------------------------------------------
// ..... End of configuration fork .....
// -----------------------------------------------------------------------------
`endif
// -----------------------------------------------------------------------------
//
// CHROMA OUTPUT MIXER
//
// -----------------------------------------------------------------------------
assign u_by_sin_wt_final = (bypass_del_u_reg) ? {u_bypass_reg,8'b0} : u_by_sin_wt_reg;
assign v_by_cos_wt_final = (bypass_del_v_reg) ? {v_bypass_reg,8'b0} : v_by_cos_wt_reg;
always @(u_by_sin_wt_final or v_by_cos_wt_final or negate_del_v_reg or negate_del_u_reg)
begin
case ({negate_del_v_reg,negate_del_u_reg})
2'b00 : chroma_adder_out = u_by_sin_wt_final + v_by_cos_wt_final;
2'b01 : chroma_adder_out = v_by_cos_wt_final + ~u_by_sin_wt_final + 8'd1;
2'b10 : chroma_adder_out = u_by_sin_wt_final + ~v_by_cos_wt_final + 8'd1;
2'b11 : chroma_adder_out = ~u_by_sin_wt_final + ~v_by_cos_wt_final + 8'd2;
endcase
end
assign lut_adr_mux = (fsc_tbl_addr[SUBCARRIER_INTEGER_PRECISION-3]) ?
((~fsc_tbl_addr[SUBCARRIER_INTEGER_PRECISION-4 : 0])
+ {{SUBCARRIER_INTEGER_PRECISION-4{1'b0}},1'b1})
: fsc_tbl_addr[SUBCARRIER_INTEGER_PRECISION-4 : 0];
// -----------------------------------------------------------------------------
//
// OUTPUT STAGE
//
// -----------------------------------------------------------------------------
always @(posedge sclk)
begin
chroma_reg <= chroma_adder_out[15 : 16-OUTPUT_PRECISION];
end
`ifdef SIGNED_DAC_STAGE
//Signed DAC output
assign chroma_out = chroma_reg;
assign luma_out = {~luma_reg[OUTPUT_PRECISION-1],luma_reg[OUTPUT_PRECISION-2 : 0]}; //
assign fcbs_out = (chroma_reg + luma_reg) ^ {1'b1,{{OUTPUT_PRECISION-1{1'b0}}};
`else
// unsigned DAC output
assign chroma_out = {~chroma_reg[OUTPUT_PRECISION-1],chroma_reg[OUTPUT_PRECISION-2 : 0]}; //
assign fcbs_out = chroma_reg + luma_reg; //
assign luma_out = luma_reg; //
`endif
// -----------------------------------------------------------------------------
//
// SINUS LOOK-UP TABLE for argument values from 0 to 90 (excluding PI/8, 0)
//
// -----------------------------------------------------------------------------
`ifdef MODULATOR_CONFIGURATION_8BIT
dve_ccir_lut7b SIN_COS_LUT (.addr_lut(lut_adr_mux),
.sin_lut(lut_sin_out),
.cos_lut(lut_cos_out));
`else
dve_ccir_lut SIN_COS_LUT (.addr_lut(lut_adr_mux),
.sin_lut(lut_sin_out),
.cos_lut(lut_cos_out));
`endif
// -----------------------------------------------------------------------------
//
// add_halfa_halfb = 0.5*a + 0.5*b
//
// -----------------------------------------------------------------------------
function [15:0] add_halfa_halfb;
input [7:0] a;
input [7:0] b;
begin
add_halfa_halfb = {1'b1,~a[7],a[6:0],7'b0} + {1'b0,~b[7],b[6:0],7'b0};
end
endfunction
// -----------------------------------------------------------------------------
//
// add_threea_quartb = 0.75*a + 0.25*b
//
// -----------------------------------------------------------------------------
function [15:0] add_threea_quartb;
input [7:0] a;
input [7:0] b;
begin
add_threea_quartb = {1'b1,~a[7],a[6:0],7'b0} + {2'b0,~a[7],a[6:0],6'b0} +
{2'b0,~b[7],b[6:0],6'b0};
end
endfunction
// -----------------------------------------------------------------------------
//
// add_quarta_halfb_quartc = 0.25*a + 0.5*b + 0.25c
// !!! All three values are not signed values !!!
// -----------------------------------------------------------------------------
function [15:0] add_quarta_halfb_quartc;
input [15 : 0] a;
input [15 : 0] b;
input [15 : 0] c;
begin
// add_quarta_halfb_quartc = {2'b0,a,6'b0} + {1'b0,b,7'b0} + {2'b0,c,6'b0};
add_quarta_halfb_quartc = {2'b0,a[15 : 2]} + {1'b0,b[15 : 1]} + {2'b0,c[15 : 2]};
end
endfunction
// -----------------------------------------------------------------------------
//
// range_halfa_halfb = 0.5*a + 0.5*b
// !!! UNSIGNED OPERATION !!!
// -----------------------------------------------------------------------------
function [15:0] range_halfa_halfb;
input [10 : 0] a;
input [10 : 0] b;
begin
// range_halfa_halfb = {1'b0,a,7'b0} + {1'b0,b,7'b0};
range_halfa_halfb = {1'b0,a,4'b0} + {1'b0,b,4'b0};
end
endfunction
endmodule // dve_ccir_dph
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -