📄 iquant_v.v
字号:
always @ (posedge CLK or posedge RST)
begin
if (RST)
begin
qdct_out_reg <= 12'b0; qdct_out_mag2 <= 1'b0;
qdct_out_mag3 <= 1'b0; qdct_out_mag4 <= 1'b0;
qdct_out_mag5 <= 1'b0; qdct_out_mag6 <= 1'b0;
qdct_out_mag7 <= 1'b0;
//macroblock_type_reg1 <= 1'b0;
macroblock_type_reg2 <= 1'b0; macroblock_type_reg3 <= 1'b0;
end
else
begin
qdct_out_reg <= qdct_out[11] ? (-qdct_out[10:0]) : qdct_out[10:0];
qdct_out_mag2 <= qdct_out[11];
qdct_out_mag3 <= qdct_out_mag2;
qdct_out_mag4 <= qdct_out_mag3;
qdct_out_mag5 <= qdct_out_mag4;
qdct_out_mag6 <= qdct_out_mag5;
qdct_out_mag7 <= qdct_out_mag6;
//macroblock_type_reg1 <= macroblock_type;
macroblock_type_reg2 <= macroblock_type_reg1;
macroblock_type_reg3 <= macroblock_type_reg2;
end
end
/*****************************************************************************/
assign case_wire = {macroblock_type_reg2,qdct_out_comp,qdct_out_mag2};
/* Of the 13 bits, 12 bits are magnitude and the msb is for sign */
/*if macroblock = intra ie., '0', quant shift = 2*QDCT + 0
if macroblock = non intra ie., '1', quant shift = 2*QDCT + k where
k = 0 if QDCT =0, k = 1 if QDCT is +ve and k = -1 if QDCT = -ve */
always @ (posedge CLK or posedge RST)
begin
if (RST)
quant_shift <= 13'b0;
else
begin
case (case_wire)
3'b000: quant_shift <= {qdct_out_reg,1'b0} ;
3'b001: quant_shift <= {qdct_out_reg,1'b0} ;
3'b010: quant_shift <= {qdct_out_reg,1'b0} ;
3'b011: quant_shift <= {qdct_out_reg,1'b0} ;
3'b110: quant_shift <= {qdct_out_reg,1'b0};
3'b111: quant_shift <= {qdct_out_reg,1'b0};
3'b100: quant_shift <= {qdct_out_reg,1'b1} ;
3'b101: quant_shift <= ({qdct_out_reg,1'b0} - 1'b1);
endcase
end
end
/*always @ (posedge CLK or posedge RST)
begin
if (RST)
begin
quant_shift_reg1 <= 13'b0;
quant_shift_reg2 <= 13'b0;
end
else
begin
quant_shift_reg1 <= quant_shift;
quant_shift_reg2 <= quant_shift_reg1;
end
end*/
/*****************************************************************************/
/* [Qmatrix*(qscale/32)] => 8bits * 10bits(2,8decimal) = 18bits (last 8 bits being decimal).
Since the last 3 digits of q_scale_mem are always '0', the multiplication and result
could also be looked at as 8bits * 7bits(2,5 decimal) = 15bits with the last 5 bits being decimal.
: pipe3 for q matrix and qscale. Prod1 registered once to match the 4 pipe stages of
quant_shift into the next multiplier*/
always @ (posedge CLK or posedge RST)
begin
if (RST)
begin
prod1 <= 15'b0;
end
else //if (rdy_in == 1'b1)
begin
if (load_intra_qmatrix_reg3 == 1'b0 && load_non_intra_qmatrix_reg3 == 1'b0)
begin
prod1 <= (def_q_mem_reg * q_scale_mem[9:3]);
end
else
begin
prod1 <= (q_value_new_out * q_scale_mem[9:3]) ;
end
end
end
always @ (posedge CLK or posedge RST)
begin
if (RST)
prod1_reg <= 15'b0;
else
prod1_reg <= prod1; /* last 5 bits decimal */
end
/*****************************************************************************/
/* (2*quantised input + k) * qscale/32 * Qmatrix .
13 bits * 18 bits = 31 bits with the last 8 bits being decimal
or 13 bits * 15 bits = 28 bits with last 5 bits being decimal.
Of the 13 bits, msb is sign bit. This 13 bits are sign extended to 17 bits.
Sign extension is done to retain the correct sign at the output of prod2
which is 28 bits wide. Sign extension is done only to 17 bits so that embedded
mulipliers can be used for Virtex family*/
always @ (posedge CLK or posedge RST)
begin
if (RST)
begin
prod2 <= 27'b0;
end
else if (rdy_in == 1'b1)
begin
prod2 <= (prod1 * quant_shift[11:0]) ;
/*15 bits * 12 bits = 27 bits with 5 decimal
msb of quant_shift is sign bit and is accounted for
in prod2_sign*/
end
else
begin
end
end
/*****************************************************************************/
/* rounding and saturation to 2047 (111,1111,1111) to -2048 (1000,0000,0000) */
always @ (posedge CLK or posedge RST)
begin
if (RST)
begin
prod2_rnd <= 22'b0;
end
else if (rdy_in == 1'b1)
begin
prod2_rnd <= prod2[4] ? (prod2[26:5] + 1'b1) : prod2[26:5];
/* rounding up decimal.(35:8) or (32:5) */
end
end
/*****************************************************************************/
always @ (posedge CLK or posedge RST)
begin
if (RST)
begin
prod2_sign <= 22'b0; prod2_rnd_pos <= 1'b0; prod2_rnd_neg <= 1'b0;
prod2_sign_reg <= 22'b0;
end
else
begin
prod2_sign <= (qdct_out_mag5) ? (-prod2_rnd) :prod2_rnd;
prod2_sign_reg <= prod2_sign;
prod2_rnd_pos <= (prod2_sign[20:11] == 10'b0) ? 1'b1 : 1'b0;//was25&15
prod2_rnd_neg <= (prod2_sign[20:11] == 10'b1111111111) ? 1'b1 : 1'b0;
end
end
/*****************************************************************************/
always @ (posedge CLK or posedge RST)
begin
if (RST)
begin
prod_sat <= 12'b0;
end
else
begin
case (prod2_sign_reg[21])// was 26
1'b1: prod_sat <= (prod2_rnd_neg) ? {1'b1,prod2_sign_reg[10:0]} :
12'b100000000000;
1'b0: prod_sat <= (prod2_rnd_pos) ? {1'b0,prod2_sign_reg[10:0]} :
12'b011111111111;
endcase
end
end
always @ (posedge CLK or posedge RST)
begin
if (RST)
begin
prod_sat_reg <= 12'b0;
end
else
begin
prod_sat_reg <= prod_sat;
end
end
/*****************************************************************************/
/* mismatch control. If sum of 64 coefficients is odd, no correction. If it
is even, then F[7,7] = (prod2[7,7] - 1 ) if prod2[7,7] is odd else
F[7,7] = (prod2[7,7] + 1 ) . The lsb of the sum can be xored to find out if the sum
of all coefficient is even or odd */
always @ (posedge CLK or posedge RST)
begin
if (RST)
begin
quant_sum <= 1'b0;
end
else if (rdy_in == 1'b1 && cnt64 == 7'd11)
begin
for (Q_cnt64 = 1 ; Q_cnt64 <= 63; Q_cnt64 = Q_cnt64 + 1)
begin
quant_sum <= quant_sum + prod2_sign_reg[0] ;
end
Q_cnt64 = 1;
end
end
/*****************************************************************************/
always @ (posedge CLK or posedge RST)
begin
if (RST)
begin
prod_mismatch<= 12'b0;
end
else if (rdy_in == 1'b1 && cnt64 == 7'd64)
begin
prod_mismatch <= (quant_sum) ? {prod_sat[11:1],prod_sat[0]} :
{prod_sat[11:1],~prod_sat[0]};
end
end
/*****************************************************************************/
always @ (posedge CLK or posedge RST)
begin
if (RST)
begin
q_out <= 12'b0;
end
else if (rdy_in == 1'b1)
begin
if (cnt64 == 7'b1000000)
q_out <= prod_mismatch;
else
q_out <= prod_sat_reg;
end
end
/*****************************************************************************/
always @ (posedge CLK or posedge RST)
begin
if (RST)
begin
cnt12 <= 4'b0;
end
else if (rdy_in == 1'b1)
begin
if (cnt12 < 4'b1011)
begin
cnt12 <= cnt12 + 1;
end
else
begin
cnt12 <= 4'b1011;
end
end
end
always @ (posedge CLK or posedge RST)
begin
if (RST)
iquant_rdy_out <= 1'b0;
else if (cnt12 == 4'b1011)
iquant_rdy_out <= 1'b1;
else
iquant_rdy_out <= iquant_rdy_out;
end
endmodule
//module ADSU8 (A, B, ADD,CI,S,OFL,CO); // synthesis syn_black_box
/*input[7:0] A,B;
input ADD,CI;
output[7:0] S;
output OFL,CO;
endmodule*/
//module MULT18X18 (A, B, P); // synthesis syn_black_box
/*input[17:0] A;
input[17:0] B;
output[35:0] P;
endmodule*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -