源代码地址: https://github.com/openasic-org/xk265
帧内预测具体逻辑包含在代码xk265\rtl\rec\rec_intra\intra_pred.v 文件中。
module intra_pred() 看起来是每次计算某个4x4块的预测像素值。
以下代码用来算每个pred_angle的具体数值,每个mode_i对应的pred_angle参考下图所示:
module intra_pred( ... )
...
//lookup table to get pred_angle
always @( * ) begin
case (mode_i)
2 ,34:pred_angle=7'd32; 11,25:pred_angle=-7'd2;
3 ,33:pred_angle=7'd26; 12,24:pred_angle=-7'd5;
4 ,32:pred_angle=7'd21; 13,23:pred_angle=-7'd9;
5 ,31:pred_angle=7'd17; 14,22:pred_angle=-7'd13;
6 ,30:pred_angle=7'd13; 15,21:pred_angle=-7'd17;
7 ,29:pred_angle=7'd9; 16,20:pred_angle=-7'd21;
8 ,28:pred_angle=7'd5; 17,19:pred_angle=-7'd26;
9 ,27:pred_angle=7'd2; 18: pred_angle=-7'd32;
10,26:pred_angle=7'd0;
default:pred_angle=7'd0;
endcase
end
以下代码用于获取当前4x4块的第一行四个像素在大块中的水平位置,其中size_i用于表示大块的大小。
//********************************************************************************
//get the location information of current 4x4 block
always @( * ) begin//x
case(size_i)
2'b00:begin//4x4
x0='d0; x1='d1; x2='d2; x3='d3;
end
2'b01:begin//8x8
if(!i4x4_x_i[0]) begin
x0='d0; x1='d1; x2='d2; x3='d3;
end
else begin
x0='d4; x1='d5; x2='d6; x3='d7;
end
end
2'b10:begin//16x16
case(i4x4_x_i[1:0])
2'b00:begin
x0='d0; x1='d1; x2='d2; x3='d3;
end
2'b01:begin
x0='d4; x1='d5; x2='d6; x3='d7;
end
2'b10:begin
x0='d8; x1='d9; x2='d10; x3='d11;
end
2'b11:begin
x0='d12; x1='d13; x2='d14; x3='d15;
end
endcase
end
2'b11:begin//32x32
case(i4x4_x_i[2:0])
3'b000:begin
x0='d0; x1='d1; x2='d2; x3='d3;
end
3'b001:begin
x0='d4; x1='d5; x2='d6; x3='d7;
end
3'b010:begin
x0='d8; x1='d9; x2='d10; x3='d11;
end
3'b011:begin
x0='d12; x1='d13; x2='d14; x3='d15;
end
3'b100:begin
x0='d16; x1='d17; x2='d18; x3='d19;
end
3'b101:begin
x0='d20; x1='d21; x2='d22; x3='d23;
end
3'b110:begin
x0='d24; x1='d25; x2='d26; x3='d27;
end
3'b111:begin
x0='d28; x1='d29; x2='d30; x3='d31;
end
endcase
end
endcase
end
以下代码用于获取当前4x4块的第一列四个像素在大块中的垂直位置,其中size_i用于表示大块的大小。
always @( * ) begin//y
case(size_i)
2'b00:begin//4x4
y0='d0; y1='d1; y2='d2; y3='d3;
end
2'b01:begin//8x8
if(!i4x4_y_i[0]) begin
y0='d0; y1='d1; y2='d2; y3='d3;
end
else begin
y0='d4; y1='d5; y2='d6; y3='d7;
end
end
2'b10:begin//16x16
case(i4x4_y_i[1:0])
2'b00:begin
y0='d0; y1='d1; y2='d2; y3='d3;
end
2'b01:begin
y0='d4; y1='d5; y2='d6; y3='d7;
end
2'b10:begin
y0='d8; y1='d9; y2='d10; y3='d11;
end
2'b11:begin
y0='d12; y1='d13; y2='d14; y3='d15;
end
endcase
end
2'b11:begin//32x32
case(i4x4_y_i[2:0])
3'b000:begin
y0='d0; y1='d1; y2='d2; y3='d3;
end
3'b001:begin
y0='d4; y1='d5; y2='d6; y3='d7;
end
3'b010:begin
y0='d8; y1='d9; y2='d10; y3='d11;
end
3'b011:begin
y0='d12; y1='d13; y2='d14; y3='d15;
end
3'b100:begin
y0='d16; y1='d17; y2='d18; y3='d19;
end
3'b101:begin
y0='d20; y1='d21; y2='d22; y3='d23;
end
3'b110:begin
y0='d24; y1='d25; y2='d26; y3='d27;
end
3'b111:begin
y0='d28; y1='d29; y2='d30; y3='d31;
end
endcase
end
endcase
end
以下代码用于选择参考像素的位置: model_i >=18,则参考水平像素行,否则参考垂直像素列,具体细节可以参考下图。
always @(posedge clk or negedge rst_n) begin//help to choose the reference pixel
if(!rst_n) begin
delta_idx_r <= 'd0;
end
else begin
if(mode_i>=18)
delta_idx_r <= {1'b0,x0};
else
delta_idx_r <= {1'b0,y0};
end
end
以下代码用于计算加权factor和偏移量idx,原理可以参考HM或者论文Intra Coding of the HEVC Standard。
预测像素值P_{x,y}通过以下公式计算:
//*********************************************************************************
//calculate idx and ifact for intra prediction
// 将 x0~x3 和 y0~y3 的值进行符号扩展(sign extension),确保它们在后续计算中不会因为位宽不足而丢失精度。
assign x0_sign_w={1'b0,x0}; // 在x0最高位前添加一个0,变为无符号数;
assign x1_sign_w={1'b0,x1};
assign x2_sign_w={1'b0,x2};
assign x3_sign_w={1'b0,x3};
assign y0_sign_w={1'b0,y0};
assign y1_sign_w={1'b0,y1};
assign y2_sign_w={1'b0,y2};
assign y3_sign_w={1'b0,y3};
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
fact0<='d0; idx0<='d0;
fact1<='d0; idx1<='d0;
fact2<='d0; idx2<='d0;
fact3<='d0; idx3<='d0;
end
else begin
if (mode_i >= 18) begin
fact0<=((y0+1)*pred_angle);
fact1<=((y1+1)*pred_angle);
fact2<=((y2+1)*pred_angle);
fact3<=((y3+1)*pred_angle);
idx0<=((y0_sign_w+1)*pred_angle)>>>5;
idx1<=((y1_sign_w+1)*pred_angle)>>>5;
idx2<=((y2_sign_w+1)*pred_angle)>>>5;
idx3<=((y3_sign_w+1)*pred_angle)>>>5;
end
else begin
fact0<=((x0+1)*pred_angle);
fact1<=((x1+1)*pred_angle);
fact2<=((x2+1)*pred_angle);
fact3<=((x3+1)*pred_angle);
idx0<=((x0_sign_w+1)*pred_angle)>>>5;
idx1<=((x1_sign_w+1)*pred_angle)>>>5;
idx2<=((x2_sign_w+1)*pred_angle)>>>5;
idx3<=((x3_sign_w+1)*pred_angle)>>>5;
end
end
end
以下代码用于将输入的预测像素排到ref_lxx_w和ref_txx_w寄存器中。ref_l0_w到ref_lN-1_w 从输入的ref_lN-1_i中拷贝, ref_lN_w到ref_l2N-1_w 从输入的ref_b0N_i中拷贝,因为参考像素的行和列的宽度是块大小的两倍(如下图所示)。
//**********************************************************************************
//get the real reference pixel
always @( * ) begin
ref_l00_w = 'd0; ref_l04_w = 'd0; ref_l08_w = 'd0; ref_l12_w = 'd0; ref_l16_w = 'd0; ref_l20_w = 'd0; ref_l24_w = 'd0; ref_l28_w = 'd0;
ref_l01_w = 'd0; ref_l05_w = 'd0; ref_l09_w = 'd0; ref_l13_w = 'd0; ref_l17_w = 'd0; ref_l21_w = 'd0; ref_l25_w = 'd0; ref_l29_w = 'd0;
ref_l02_w = 'd0; ref_l06_w = 'd0; ref_l10_w = 'd0; ref_l14_w = 'd0; ref_l18_w = 'd0; ref_l22_w = 'd0; ref_l26_w = 'd0; ref_l30_w = 'd0;
ref_l03_w = 'd0; ref_l07_w = 'd0; ref_l11_w = 'd0; ref_l15_w = 'd0; ref_l19_w = 'd0; ref_l23_w = 'd0; ref_l27_w = 'd0; ref_l31_w = 'd0;
ref_l32_w = 'd0; ref_l36_w = 'd0; ref_l40_w = 'd0; ref_l44_w = 'd0; ref_l48_w = 'd0; ref_l52_w = 'd0; ref_l56_w = 'd0; ref_l60_w = 'd0;
ref_l33_w = 'd0; ref_l37_w = 'd0; ref_l41_w = 'd0; ref_l45_w = 'd0; ref_l49_w = 'd0; ref_l53_w = 'd0; ref_l57_w = 'd0; ref_l61_w = 'd0;
ref_l34_w = 'd0; ref_l38_w = 'd0; ref_l42_w = 'd0; ref_l46_w = 'd0; ref_l50_w = 'd0; ref_l54_w = 'd0; ref_l58_w = 'd0; ref_l62_w = 'd0;
ref_l35_w = 'd0; ref_l39_w = 'd0; ref_l43_w = 'd0; ref_l47_w = 'd0; ref_l51_w = 'd0; ref_l55_w = 'd0; ref_l59_w = 'd0; ref_l63_w = 'd0;
ref_t00_w = 'd0; ref_t04_w = 'd0; ref_t08_w = 'd0; ref_t12_w = 'd0; ref_t16_w = 'd0; ref_t20_w = 'd0; ref_t24_w = 'd0; ref_t28_w = 'd0;
ref_t01_w = 'd0; ref_t05_w = 'd0; ref_t09_w = 'd0; ref_t13_w = 'd0; ref_t17_w = 'd0; ref_t21_w = 'd0; ref_t25_w = 'd0; ref_t29_w = 'd0;
ref_t02_w = 'd0; ref_t06_w = 'd0; ref_t10_w = 'd0; ref_t14_w = 'd0; ref_t18_w = 'd0; ref_t22_w = 'd0; ref_t26_w = 'd0; ref_t30_w = 'd0;
ref_t03_w = 'd0; ref_t07_w = 'd0; ref_t11_w = 'd0; ref_t15_w = 'd0; ref_t19_w = 'd0; ref_t23_w = 'd0; ref_t27_w = 'd0; ref_t31_w = 'd0;
ref_t32_w = 'd0; ref_t36_w = 'd0; ref_t40_w = 'd0; ref_t44_w = 'd0; ref_t48_w = 'd0; ref_t52_w = 'd0; ref_t56_w = 'd0; ref_t60_w = 'd0;
ref_t33_w = 'd0; ref_t37_w = 'd0; ref_t41_w = 'd0; ref_t45_w = 'd0; ref_t49_w = 'd0; ref_t53_w = 'd0; ref_t57_w = 'd0; ref_t61_w = 'd0;
ref_t34_w = 'd0; ref_t38_w = 'd0; ref_t42_w = 'd0; ref_t46_w = 'd0; ref_t50_w = 'd0; ref_t54_w = 'd0; ref_t58_w = 'd0; ref_t62_w = 'd0;
ref_t35_w = 'd0; ref_t39_w = 'd0; ref_t43_w = 'd0; ref_t47_w = 'd0; ref_t51_w = 'd0; ref_t55_w = 'd0; ref_t59_w = 'd0; ref_t63_w = 'd0;
case(size_i)
2'b00:begin
ref_l00_w = ref_l00_i; ref_l04_w = ref_d00_i; ref_t00_w = ref_t00_i; ref_t04_w = ref_r00_i;
ref_l01_w = ref_l01_i; ref_l05_w = ref_d01_i; ref_t01_w = ref_t01_i; ref_t05_w = ref_r01_i;
ref_l02_w = ref_l02_i; ref_l06_w = ref_d02_i; ref_t02_w = ref_t02_i; ref_t06_w = ref_r02_i;
ref_l03_w = ref_l03_i; ref_l07_w = ref_d03_i; ref_t03_w = ref_t03_i; ref_t07_w = ref_r03_i;
end
2'b01:begin
ref_l00_w = ref_l00_i; ref_l04_w = ref_l04_i; ref_l08_w = ref_d00_i; ref_l12_w = ref_d04_i;
ref_l01_w = ref_l01_i; ref_l05_w = ref_l05_i; ref_l09_w = ref_d01_i; ref_l13_w = ref_d05_i;
ref_l02_w = ref_l02_i; ref_l06_w = ref_l06_i; ref_l10_w = ref_d02_i; ref_l14_w = ref_d06_i;
ref_l03_w = ref_l03_i; ref_l07_w = ref_l07_i; ref_l11_w = ref_d03_i; ref_l15_w = ref_d07_i;
ref_t00_w = ref_t00_i; ref_t04_w = ref_t04_i; ref_t08_w = ref_r00_i; ref_t12_w = ref_r04_i;
ref_t01_w = ref_t01_i; ref_t05_w = ref_t05_i; ref_t09_w = ref_r01_i; ref_t13_w = ref_r05_i;
ref_t02_w = ref_t02_i; ref_t06_w = ref_t06_i; ref_t10_w = ref_r02_i; ref_t14_w = ref_r06_i;
ref_t03_w = ref_t03_i; ref_t07_w = ref_t07_i; ref_t11_w = ref_r03_i; ref_t15_w = ref_r07_i;
end
2'b10:begin
ref_l00_w = ref_l00_i; ref_l04_w = ref_l04_i; ref_l08_w = ref_l08_i; ref_l12_w = ref_l12_i;
ref_l01_w = ref_l01_i; ref_l05_w = ref_l05_i; ref_l09_w = ref_l09_i; ref_l13_w = ref_l13_i;
ref_l02_w = ref_l02_i; ref_l06_w = ref_l06_i; ref_l10_w = ref_l10_i; ref_l14_w = ref_l14_i;
ref_l03_w = ref_l03_i; ref_l07_w = ref_l07_i; ref_l11_w = ref_l11_i; ref_l15_w = ref_l15_i;
ref_l16_w = ref_d00_i; ref_l20_w = ref_d04_i; ref_l24_w = ref_d08_i; ref_l28_w = ref_d12_i;
ref_l17_w = ref_d01_i; ref_l21_w = ref_d05_i; ref_l25_w = ref_d09_i; ref_l29_w = ref_d13_i;
ref_l18_w = ref_d02_i; ref_l22_w = ref_d06_i; ref_l26_w = ref_d10_i; ref_l30_w = ref_d14_i;
ref_l19_w = ref_d03_i; ref_l23_w = ref_d07_i; ref_l27_w = ref_d11_i; ref_l31_w = ref_d15_i;
ref_t00_w = ref_t00_i; ref_t04_w = ref_t04_i; ref_t08_w = ref_t08_i; ref_t12_w = ref_t12_i;
ref_t01_w = ref_t01_i; ref_t05_w = ref_t05_i; ref_t09_w = ref_t09_i; ref_t13_w = ref_t13_i;
ref_t02_w = ref_t02_i; ref_t06_w = ref_t06_i; ref_t10_w = ref_t10_i; ref_t14_w = ref_t14_i;
ref_t03_w = ref_t03_i; ref_t07_w = ref_t07_i; ref_t11_w = ref_t11_i; ref_t15_w = ref_t15_i;
ref_t16_w = ref_r00_i; ref_t20_w = ref_r04_i; ref_t24_w = ref_r08_i; ref_t28_w = ref_r12_i;
ref_t17_w = ref_r01_i; ref_t21_w = ref_r05_i; ref_t25_w = ref_r09_i; ref_t29_w = ref_r13_i;
ref_t18_w = ref_r02_i; ref_t22_w = ref_r06_i; ref_t26_w = ref_r10_i; ref_t30_w = ref_r14_i;
ref_t19_w = ref_r03_i; ref_t23_w = ref_r07_i; ref_t27_w = ref_r11_i; ref_t31_w = ref_r15_i;
end
2'b11:begin
ref_l00_w = ref_l00_i; ref_l04_w = ref_l04_i; ref_l08_w = ref_l08_i; ref_l12_w = ref_l12_i;
ref_l01_w = ref_l01_i; ref_l05_w = ref_l05_i; ref_l09_w = ref_l09_i; ref_l13_w = ref_l13_i;
ref_l02_w = ref_l02_i; ref_l06_w = ref_l06_i; ref_l10_w = ref_l10_i; ref_l14_w = ref_l14_i;
ref_l03_w = ref_l03_i; ref_l07_w = ref_l07_i; ref_l11_w = ref_l11_i; ref_l15_w = ref_l15_i;
ref_l16_w = ref_l16_i; ref_l20_w = ref_l20_i; ref_l24_w = ref_l24_i; ref_l28_w = ref_l28_i;
ref_l17_w = ref_l17_i; ref_l21_w = ref_l21_i; ref_l25_w = ref_l25_i; ref_l29_w = ref_l29_i;
ref_l18_w = ref_l18_i; ref_l22_w = ref_l22_i; ref_l26_w = ref_l26_i; ref_l30_w = ref_l30_i;
ref_l19_w = ref_l19_i; ref_l23_w = ref_l23_i; ref_l27_w = ref_l27_i; ref_l31_w = ref_l31_i;
ref_l32_w = ref_d00_i; ref_l36_w = ref_d04_i; ref_l40_w = ref_d08_i; ref_l44_w = ref_d12_i;
ref_l33_w = ref_d01_i; ref_l37_w = ref_d05_i; ref_l41_w = ref_d09_i; ref_l45_w = ref_d13_i;
ref_l34_w = ref_d02_i; ref_l38_w = ref_d06_i; ref_l42_w = ref_d10_i; ref_l46_w = ref_d14_i;
ref_l35_w = ref_d03_i; ref_l39_w = ref_d07_i; ref_l43_w = ref_d11_i; ref_l47_w = ref_d15_i;
ref_l48_w = ref_d16_i; ref_l52_w = ref_d20_i; ref_l56_w = ref_d24_i; ref_l60_w = ref_d28_i;
ref_l49_w = ref_d17_i; ref_l53_w = ref_d21_i; ref_l57_w = ref_d25_i; ref_l61_w = ref_d29_i;
ref_l50_w = ref_d18_i; ref_l54_w = ref_d22_i; ref_l58_w = ref_d26_i; ref_l62_w = ref_d30_i;
ref_l51_w = ref_d19_i; ref_l55_w = ref_d23_i; ref_l59_w = ref_d27_i; ref_l63_w = ref_d31_i;
ref_t00_w = ref_t00_i; ref_t04_w = ref_t04_i; ref_t08_w = ref_t08_i; ref_t12_w = ref_t12_i;
ref_t01_w = ref_t01_i; ref_t05_w = ref_t05_i; ref_t09_w = ref_t09_i; ref_t13_w = ref_t13_i;
ref_t02_w = ref_t02_i; ref_t06_w = ref_t06_i; ref_t10_w = ref_t10_i; ref_t14_w = ref_t14_i;
ref_t03_w = ref_t03_i; ref_t07_w = ref_t07_i; ref_t11_w = ref_t11_i; ref_t15_w = ref_t15_i;
ref_t16_w = ref_t16_i; ref_t20_w = ref_t20_i; ref_t24_w = ref_t24_i; ref_t28_w = ref_t28_i;
ref_t17_w = ref_t17_i; ref_t21_w = ref_t21_i; ref_t25_w = ref_t25_i; ref_t29_w = ref_t29_i;
ref_t18_w = ref_t18_i; ref_t22_w = ref_t22_i; ref_t26_w = ref_t26_i; ref_t30_w = ref_t30_i;
ref_t19_w = ref_t19_i; ref_t23_w = ref_t23_i; ref_t27_w = ref_t27_i; ref_t31_w = ref_t31_i;
ref_t32_w = ref_r00_i; ref_t36_w = ref_r04_i; ref_t40_w = ref_r08_i; ref_t44_w = ref_r12_i;
ref_t33_w = ref_r01_i; ref_t37_w = ref_r05_i; ref_t41_w = ref_r09_i; ref_t45_w = ref_r13_i;
ref_t34_w = ref_r02_i; ref_t38_w = ref_r06_i; ref_t42_w = ref_r10_i; ref_t46_w = ref_r14_i;
ref_t35_w = ref_r03_i; ref_t39_w = ref_r07_i; ref_t43_w = ref_r11_i; ref_t47_w = ref_r15_i;
ref_t48_w = ref_r16_i; ref_t52_w = ref_r20_i; ref_t56_w = ref_r24_i; ref_t60_w = ref_r28_i;
ref_t49_w = ref_r17_i; ref_t53_w = ref_r21_i; ref_t57_w = ref_r25_i; ref_t61_w = ref_r29_i;
ref_t50_w = ref_r18_i; ref_t54_w = ref_r22_i; ref_t58_w = ref_r26_i; ref_t62_w = ref_r30_i;
ref_t51_w = ref_r19_i; ref_t55_w = ref_r23_i; ref_t59_w = ref_r27_i; ref_t63_w = ref_r31_i;
end
endcase
end
以下代码是参考像素的投射过程。HEVC帧内预测的参考像素最终都是合并到一行像素中,不会再氛围上边行和左边列,左上角三种。合并过程根据预测角度分为两种:mode >= 18时,主体采用上边行像素预测,把左边列像素按照角度投射到上边行数组中(如下图所示);mode < 18时,主体采用左边列像素预测,把上边像素按角度投射到左边列中。
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin // 重置参考像素值,都设为0,清楚前面存储的数据
ref_00_r <= 'd0;
ref_01_r <= 'd0; ref_05_r <= 'd0; ref_09_r <= 'd0; ref_13_r <= 'd0; ref_17_r <= 'd0; ref_21_r <= 'd0; ref_25_r <= 'd0; ref_29_r <= 'd0;
ref_02_r <= 'd0; ref_06_r <= 'd0; ref_10_r <= 'd0; ref_14_r <= 'd0; ref_18_r <= 'd0; ref_22_r <= 'd0; ref_26_r <= 'd0; ref_30_r <= 'd0;
ref_03_r <= 'd0; ref_07_r <= 'd0; ref_11_r <= 'd0; ref_15_r <= 'd0; ref_19_r <= 'd0; ref_23_r <= 'd0; ref_27_r <= 'd0; ref_31_r <= 'd0;
ref_04_r <= 'd0; ref_08_r <= 'd0; ref_12_r <= 'd0; ref_16_r <= 'd0; ref_20_r <= 'd0; ref_24_r <= 'd0; ref_28_r <= 'd0; ref_32_r <= 'd0;
ref_33_r <= 'd0; ref_37_r <= 'd0; ref_41_r <= 'd0; ref_45_r <= 'd0; ref_49_r <= 'd0; ref_53_r <= 'd0; ref_57_r <= 'd0; ref_61_r <= 'd0;
ref_34_r <= 'd0; ref_38_r <= 'd0; ref_42_r <= 'd0; ref_46_r <= 'd0; ref_50_r <= 'd0; ref_54_r <= 'd0; ref_58_r <= 'd0; ref_62_r <= 'd0;
ref_35_r <= 'd0; ref_39_r <= 'd0; ref_43_r <= 'd0; ref_47_r <= 'd0; ref_51_r <= 'd0; ref_55_r <= 'd0; ref_59_r <= 'd0; ref_63_r <= 'd0;
ref_36_r <= 'd0; ref_40_r <= 'd0; ref_44_r <= 'd0; ref_48_r <= 'd0; ref_52_r <= 'd0; ref_56_r <= 'd0; ref_60_r <= 'd0; ref_64_r <= 'd0;
ref_x01_r <= 'd0; ref_x05_r <= 'd0; ref_x09_r <= 'd0; ref_x13_r <= 'd0; ref_x17_r <= 'd0; ref_x21_r <= 'd0; ref_x25_r <= 'd0; ref_x29_r <= 'd0;
ref_x02_r <= 'd0; ref_x06_r <= 'd0; ref_x10_r <= 'd0; ref_x14_r <= 'd0; ref_x18_r <= 'd0; ref_x22_r <= 'd0; ref_x26_r <= 'd0; ref_x30_r <= 'd0;
ref_x03_r <= 'd0; ref_x07_r <= 'd0; ref_x11_r <= 'd0; ref_x15_r <= 'd0; ref_x19_r <= 'd0; ref_x23_r <= 'd0; ref_x27_r <= 'd0; ref_x31_r <= 'd0;
ref_x04_r <= 'd0; ref_x08_r <= 'd0; ref_x12_r <= 'd0; ref_x16_r <= 'd0; ref_x20_r <= 'd0; ref_x24_r <= 'd0; ref_x28_r <= 'd0; ref_x32_r <= 'd0;
end
else begin
ref_00_r <= ref_tl_i; // 将左上角像素值存储到ref_00_r寄存器中
if(mode_i >= 18) begin // mode >= 18时,主体采用上边行像素预测,把左边列像素按照角度投射到上边行数组中
// 将上边行64个像素值存储到ref_01_r ...... ref_64_r 寄存器中。intra预测最大为32x32,采用非阻塞赋值,一次性将最大可能用到的参考像素进行赋值,囊括所有大小的CU
ref_01_r <= ref_t00_w; ref_05_r <= ref_t04_w; ref_09_r <= ref_t08_w; ref_13_r <= ref_t12_w;
ref_02_r <= ref_t01_w; ref_06_r <= ref_t05_w; ref_10_r <= ref_t09_w; ref_14_r <= ref_t13_w;
ref_03_r <= ref_t02_w; ref_07_r <= ref_t06_w; ref_11_r <= ref_t10_w; ref_15_r <= ref_t14_w;
ref_04_r <= ref_t03_w; ref_08_r <= ref_t07_w; ref_12_r <= ref_t11_w; ref_16_r <= ref_t15_w;
ref_17_r <= ref_t16_w; ref_21_r <= ref_t20_w; ref_25_r <= ref_t24_w; ref_29_r <= ref_t28_w;
ref_18_r <= ref_t17_w; ref_22_r <= ref_t21_w; ref_26_r <= ref_t25_w; ref_30_r <= ref_t29_w;
ref_19_r <= ref_t18_w; ref_23_r <= ref_t22_w; ref_27_r <= ref_t26_w; ref_31_r <= ref_t30_w;
ref_20_r <= ref_t19_w; ref_24_r <= ref_t23_w; ref_28_r <= ref_t27_w; ref_32_r <= ref_t31_w;
ref_33_r <= ref_t32_w; ref_37_r <= ref_t36_w; ref_41_r <= ref_t40_w; ref_45_r <= ref_t44_w;
ref_34_r <= ref_t33_w; ref_38_r <= ref_t37_w; ref_42_r <= ref_t41_w; ref_46_r <= ref_t45_w;
ref_35_r <= ref_t34_w; ref_39_r <= ref_t38_w; ref_43_r <= ref_t42_w; ref_47_r <= ref_t46_w;
ref_36_r <= ref_t35_w; ref_40_r <= ref_t39_w; ref_44_r <= ref_t43_w; ref_48_r <= ref_t47_w;
ref_49_r <= ref_t48_w; ref_53_r <= ref_t52_w; ref_57_r <= ref_t56_w; ref_61_r <= ref_t60_w;
ref_50_r <= ref_t49_w; ref_54_r <= ref_t53_w; ref_58_r <= ref_t57_w; ref_62_r <= ref_t61_w;
ref_51_r <= ref_t50_w; ref_55_r <= ref_t54_w; ref_59_r <= ref_t58_w; ref_63_r <= ref_t62_w;
ref_52_r <= ref_t51_w; ref_56_r <= ref_t55_w; ref_60_r <= ref_t59_w; ref_64_r <= ref_t63_w;
case (mode_i)
'd19:begin // mode 19是刚好大于45度角的预测
ref_x01_r <= ref_l00_w; ref_x05_r <= ref_l05_w; ref_x09_r <= ref_l10_w; ref_x13_r <= ref_l15_w;
ref_x02_r <= ref_l01_w; ref_x06_r <= ref_l06_w; ref_x10_r <= ref_l11_w; ref_x14_r <= ref_l16_w;
ref_x03_r <= ref_l03_w; ref_x07_r <= ref_l08_w; ref_x11_r <= ref_l13_w; ref_x15_r <= ref_l17_w;
ref_x04_r <= ref_l04_w; ref_x08_r <= ref_l09_w; ref_x12_r <= ref_l14_w; ref_x16_r <= ref_l19_w;
ref_x17_r <= ref_l20_w; ref_x21_r <= ref_l25_w; ref_x25_r <= ref_l30_w;
ref_x18_r <= ref_l21_w; ref_x22_r <= ref_l26_w; ref_x26_r <= ref_l31_w;
ref_x19_r <= ref_l22_w; ref_x23_r <= ref_l27_w;
ref_x20_r <= ref_l24_w; ref_x24_r <= ref_l29_w;
end
'd20:begin
ref_x01_r <= ref_l01_w; ref_x05_r <= ref_l07_w; ref_x09_r <= ref_l13_w; ref_x13_r <= ref_l19_w;
ref_x02_r <= ref_l02_w; ref_x06_r <= ref_l08_w; ref_x10_r <= ref_l14_w; ref_x14_r <= ref_l20_w;
ref_x03_r <= ref_l04_w; ref_x07_r <= ref_l10_w; ref_x11_r <= ref_l16_w; ref_x15_r <= ref_l22_w;
ref_x04_r <= ref_l05_w; ref_x08_r <= ref_l11_w; ref_x12_r <= ref_l17_w; ref_x16_r <= ref_l23_w;
ref_x17_r <= ref_l25_w; ref_x21_r <= ref_l31_w;
ref_x18_r <= ref_l26_w;
ref_x19_r <= ref_l28_w;
ref_x20_r <= ref_l29_w;
end
'd21:begin
ref_x01_r <= ref_l01_w; ref_x05_r <= ref_l08_w; ref_x09_r <= ref_l16_w; ref_x13_r <= ref_l23_w;
ref_x02_r <= ref_l03_w; ref_x06_r <= ref_l10_w; ref_x10_r <= ref_l18_w; ref_x14_r <= ref_l25_w;
ref_x03_r <= ref_l05_w; ref_x07_r <= ref_l12_w; ref_x11_r <= ref_l20_w; ref_x15_r <= ref_l27_w;
ref_x04_r <= ref_l07_w; ref_x08_r <= ref_l14_w; ref_x12_r <= ref_l22_w; ref_x16_r <= ref_l29_w;
ref_x17_r <= ref_l31_w;
end
'd22:begin
ref_x01_r <= ref_l01_w; ref_x05_r <= ref_l11_w; ref_x09_r <= ref_l21_w; ref_x13_r <= ref_l31_w;
ref_x02_r <= ref_l04_w; ref_x06_r <= ref_l14_w; ref_x10_r <= ref_l24_w;
ref_x03_r <= ref_l06_w; ref_x07_r <= ref_l16_w; ref_x11_r <= ref_l26_w;
ref_x04_r <= ref_l09_w; ref_x08_r <= ref_l19_w; ref_x12_r <= ref_l29_w;
end
'd23:begin
ref_x01_r <= ref_l03_w; ref_x05_r <= ref_l17_w; ref_x09_r <= ref_l31_w;
ref_x02_r <= ref_l06_w; ref_x06_r <= ref_l20_w;
ref_x03_r <= ref_l10_w; ref_x07_r <= ref_l24_w;
ref_x04_r <= ref_l13_w; ref_x08_r <= ref_l27_w;
end
'd24:begin
ref_x01_r <= ref_l05_w; ref_x05_r <= ref_l31_w;
ref_x02_r <= ref_l12_w;
ref_x03_r <= ref_l18_w;
ref_x04_r <= ref_l25_w;
end
'd25:begin
ref_x01_r <= ref_l15_w;
ref_x02_r <= ref_l31_w;
end
default begin // mode 18和 26-32,都是直接将左边列参考像素拷贝到ref_xN_r中
ref_x01_r <= ref_l00_w; ref_x05_r <= ref_l04_w; ref_x09_r <= ref_l08_w; ref_x13_r <= ref_l12_w;
ref_x02_r <= ref_l01_w; ref_x06_r <= ref_l05_w; ref_x10_r <= ref_l09_w; ref_x14_r <= ref_l13_w;
ref_x03_r <= ref_l02_w; ref_x07_r <= ref_l06_w; ref_x11_r <= ref_l10_w; ref_x15_r <= ref_l14_w;
ref_x04_r <= ref_l03_w; ref_x08_r <= ref_l07_w; ref_x12_r <= ref_l11_w; ref_x16_r <= ref_l15_w;
ref_x17_r <= ref_l16_w; ref_x21_r <= ref_l20_w; ref_x25_r <= ref_l24_w; ref_x29_r <= ref_l28_w;
ref_x18_r <= ref_l17_w; ref_x22_r <= ref_l21_w; ref_x26_r <= ref_l25_w; ref_x30_r <= ref_l29_w;
ref_x19_r <= ref_l18_w; ref_x23_r <= ref_l22_w; ref_x27_r <= ref_l26_w; ref_x31_r <= ref_l30_w;
ref_x20_r <= ref_l19_w; ref_x24_r <= ref_l23_w; ref_x28_r <= ref_l27_w; ref_x32_r <= ref_l31_w;
end
endcase
end
else begin // mode < 18时,主体采用左边列像素预测,把上边像素按角度投射到左边列中
ref_01_r <= ref_l00_w; ref_05_r <= ref_l04_w; ref_09_r <= ref_l08_w; ref_13_r <= ref_l12_w;
ref_02_r <= ref_l01_w; ref_06_r <= ref_l05_w; ref_10_r <= ref_l09_w; ref_14_r <= ref_l13_w;
ref_03_r <= ref_l02_w; ref_07_r <= ref_l06_w; ref_11_r <= ref_l10_w; ref_15_r <= ref_l14_w;
ref_04_r <= ref_l03_w; ref_08_r <= ref_l07_w; ref_12_r <= ref_l11_w; ref_16_r <= ref_l15_w;
ref_17_r <= ref_l16_w; ref_21_r <= ref_l20_w; ref_25_r <= ref_l24_w; ref_29_r <= ref_l28_w;
ref_18_r <= ref_l17_w; ref_22_r <= ref_l21_w; ref_26_r <= ref_l25_w; ref_30_r <= ref_l29_w;
ref_19_r <= ref_l18_w; ref_23_r <= ref_l22_w; ref_27_r <= ref_l26_w; ref_31_r <= ref_l30_w;
ref_20_r <= ref_l19_w; ref_24_r <= ref_l23_w; ref_28_r <= ref_l27_w; ref_32_r <= ref_l31_w;
ref_33_r <= ref_l32_w; ref_37_r <= ref_l36_w; ref_41_r <= ref_l40_w; ref_45_r <= ref_l44_w;
ref_34_r <= ref_l33_w; ref_38_r <= ref_l37_w; ref_42_r <= ref_l41_w; ref_46_r <= ref_l45_w;
ref_35_r <= ref_l34_w; ref_39_r <= ref_l38_w; ref_43_r <= ref_l42_w; ref_47_r <= ref_l46_w;
ref_36_r <= ref_l35_w; ref_40_r <= ref_l39_w; ref_44_r <= ref_l43_w; ref_48_r <= ref_l47_w;
ref_49_r <= ref_l48_w; ref_53_r <= ref_l52_w; ref_57_r <= ref_l56_w; ref_61_r <= ref_l60_w;
ref_50_r <= ref_l49_w; ref_54_r <= ref_l53_w; ref_58_r <= ref_l57_w; ref_62_r <= ref_l61_w;
ref_51_r <= ref_l50_w; ref_55_r <= ref_l54_w; ref_59_r <= ref_l58_w; ref_63_r <= ref_l62_w;
ref_52_r <= ref_l51_w; ref_56_r <= ref_l55_w; ref_60_r <= ref_l59_w; ref_64_r <= ref_l63_w;
case (mode_i)
'd17:begin
ref_x01_r <= ref_t00_w; ref_x05_r <= ref_t05_w; ref_x09_r <= ref_t10_w; ref_x13_r <= ref_t15_w;
ref_x02_r <= ref_t01_w; ref_x06_r <= ref_t06_w; ref_x10_r <= ref_t11_w; ref_x14_r <= ref_t16_w;
ref_x03_r <= ref_t03_w; ref_x07_r <= ref_t08_w; ref_x11_r <= ref_t13_w; ref_x15_r <= ref_t17_w;
ref_x04_r <= ref_t04_w; ref_x08_r <= ref_t09_w; ref_x12_r <= ref_t14_w; ref_x16_r <= ref_t19_w;
ref_x17_r <= ref_t20_w; ref_x21_r <= ref_t25_w; ref_x25_r <= ref_t30_w;
ref_x18_r <= ref_t21_w; ref_x22_r <= ref_t26_w; ref_x26_r <= ref_t31_w;
ref_x19_r <= ref_t22_w; ref_x23_r <= ref_t27_w;
ref_x20_r <= ref_t24_w; ref_x24_r <= ref_t29_w;
end
'd16:begin
ref_x01_r <= ref_t01_w; ref_x05_r <= ref_t07_w; ref_x09_r <= ref_t13_w; ref_x13_r <= ref_t19_w;
ref_x02_r <= ref_t02_w; ref_x06_r <= ref_t08_w; ref_x10_r <= ref_t14_w; ref_x14_r <= ref_t20_w;
ref_x03_r <= ref_t04_w; ref_x07_r <= ref_t10_w; ref_x11_r <= ref_t16_w; ref_x15_r <= ref_t22_w;
ref_x04_r <= ref_t05_w; ref_x08_r <= ref_t11_w; ref_x12_r <= ref_t17_w; ref_x16_r <= ref_t23_w;
ref_x17_r <= ref_t25_w; ref_x21_r <= ref_t31_w;
ref_x18_r <= ref_t26_w;
ref_x19_r <= ref_t28_w;
ref_x20_r <= ref_t29_w;
end
'd15:begin
ref_x01_r <= ref_t01_w; ref_x05_r <= ref_t08_w; ref_x09_r <= ref_t16_w; ref_x13_r <= ref_t23_w;
ref_x02_r <= ref_t03_w; ref_x06_r <= ref_t10_w; ref_x10_r <= ref_t18_w; ref_x14_r <= ref_t25_w;
ref_x03_r <= ref_t05_w; ref_x07_r <= ref_t12_w; ref_x11_r <= ref_t20_w; ref_x15_r <= ref_t27_w;
ref_x04_r <= ref_t07_w; ref_x08_r <= ref_t14_w; ref_x12_r <= ref_t22_w; ref_x16_r <= ref_t29_w;
ref_x17_r <= ref_t31_w;
end
'd14:begin
ref_x01_r <= ref_t01_w; ref_x05_r <= ref_t11_w; ref_x09_r <= ref_t21_w; ref_x13_r <= ref_t31_w;
ref_x02_r <= ref_t04_w; ref_x06_r <= ref_t14_w; ref_x10_r <= ref_t24_w;
ref_x03_r <= ref_t06_w; ref_x07_r <= ref_t16_w; ref_x11_r <= ref_t26_w;
ref_x04_r <= ref_t09_w; ref_x08_r <= ref_t19_w; ref_x12_r <= ref_t29_w;
end
'd13:begin
ref_x01_r <= ref_t03_w; ref_x05_r <= ref_t17_w; ref_x09_r <= ref_t31_w;
ref_x02_r <= ref_t06_w; ref_x06_r <= ref_t20_w;
ref_x03_r <= ref_t10_w; ref_x07_r <= ref_t24_w;
ref_x04_r <= ref_t13_w; ref_x08_r <= ref_t27_w;
end
'd12:begin
ref_x01_r <= ref_t05_w; ref_x05_r <= ref_t31_w;
ref_x02_r <= ref_t12_w;
ref_x03_r <= ref_t18_w;
ref_x04_r <= ref_t25_w;
end
'd11:begin
ref_x01_r <= ref_t15_w;
ref_x02_r <= ref_t31_w;
end
default begin
ref_x01_r <= ref_t00_w; ref_x05_r <= ref_t04_w; ref_x09_r <= ref_t08_w; ref_x13_r <= ref_t12_w;
ref_x02_r <= ref_t01_w; ref_x06_r <= ref_t05_w; ref_x10_r <= ref_t09_w; ref_x14_r <= ref_t13_w;
ref_x03_r <= ref_t02_w; ref_x07_r <= ref_t06_w; ref_x11_r <= ref_t10_w; ref_x15_r <= ref_t14_w;
ref_x04_r <= ref_t03_w; ref_x08_r <= ref_t07_w; ref_x12_r <= ref_t11_w; ref_x16_r <= ref_t15_w;
ref_x17_r <= ref_t16_w; ref_x21_r <= ref_t20_w; ref_x25_r <= ref_t24_w; ref_x29_r <= ref_t28_w;
ref_x18_r <= ref_t17_w; ref_x22_r <= ref_t21_w; ref_x26_r <= ref_t25_w; ref_x30_r <= ref_t29_w;
ref_x19_r <= ref_t18_w; ref_x23_r <= ref_t22_w; ref_x27_r <= ref_t26_w; ref_x31_r <= ref_t30_w;
ref_x20_r <= ref_t19_w; ref_x24_r <= ref_t23_w; ref_x28_r <= ref_t27_w; ref_x32_r <= ref_t31_w;
end
endcase
end
end
end
以下代码计算DC预测模式的中间值:
//**********************************************************************************
//calculate the middle value for DC
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
mid_t0_r <= 'd0; mid_l0_r <= 'd0;
mid_t2_r <= 'd0; mid_l2_r <= 'd0;
mid_t3_r <= 'd0; mid_l3_r <= 'd0;
mid_t4_r <= 'd0; mid_l4_r <= 'd0;
mid_t5_r <= 'd0; mid_l5_r <= 'd0;
end
else begin
mid_t0_r <= ref_t00_i+ref_t01_i+ref_t02_i+ref_t03_i; // 计算顶部4个像素(0-3)的和
// t2 - t5 分别计算8个像素的和(0-7, 8-15, 16-23, 24-31)
mid_t2_r <= ref_t00_i+ref_t01_i+ref_t02_i+ref_t03_i+ref_t04_i+ref_t05_i+ref_t06_i+ref_t07_i;
mid_t3_r <= ref_t08_i+ref_t09_i+ref_t10_i+ref_t11_i+ref_t12_i+ref_t13_i+ref_t14_i+ref_t15_i;
mid_t4_r <= ref_t16_i+ref_t17_i+ref_t18_i+ref_t19_i+ref_t20_i+ref_t21_i+ref_t22_i+ref_t23_i;
mid_t5_r <= ref_t24_i+ref_t25_i+ref_t26_i+ref_t27_i+ref_t28_i+ref_t29_i+ref_t30_i+ref_t31_i;
mid_l0_r <= ref_l00_i+ref_l01_i+ref_l02_i+ref_l03_i;
mid_l2_r <= ref_l00_i+ref_l01_i+ref_l02_i+ref_l03_i+ref_l04_i+ref_l05_i+ref_l06_i+ref_l07_i;
mid_l3_r <= ref_l08_i+ref_l09_i+ref_l10_i+ref_l11_i+ref_l12_i+ref_l13_i+ref_l14_i+ref_l15_i;
mid_l4_r <= ref_l16_i+ref_l17_i+ref_l18_i+ref_l19_i+ref_l20_i+ref_l21_i+ref_l22_i+ref_l23_i;
mid_l5_r <= ref_l24_i+ref_l25_i+ref_l26_i+ref_l27_i+ref_l28_i+ref_l29_i+ref_l30_i+ref_l31_i;
end
end
......
//**********************************************************************************
//calculate DC value for DC mode
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
dc_value_r <= 'd0;
else begin
case(size_r0)
2'b00:dc_value_r<=(mid_t0_r+mid_l0_r+4)>>3;
2'b01:dc_value_r<=(mid_t2_r+mid_l2_r+8)>>4;
2'b10:dc_value_r<=(mid_t2_r+mid_t3_r+mid_l2_r+mid_l3_r+16)>>5;
2'b11:dc_value_r<=(mid_t2_r+mid_t3_r+mid_t4_r+mid_t5_r+
mid_l2_r+mid_l3_r+mid_l4_r+mid_l5_r+32)>>6;
endcase
end
end
以下代码计算角度预测模式下,4x4块的预测值,基于ifact来加权两个整像素预测值。
//stage2
//***********************************************************************************
//predict process
//Angular
always @( * ) begin
if(ifact0) begin
pre_0_0_w = ( (32-ifact0)*ref_0_0 + ifact0*ref_0_1 + 16 ) >>5;
pre_0_1_w = ( (32-ifact0)*ref_0_1 + ifact0*ref_0_2 + 16 ) >>5;
pre_0_2_w = ( (32-ifact0)*ref_0_2 + ifact0*ref_0_3 + 16 ) >>5;
pre_0_3_w = ( (32-ifact0)*ref_0_3 + ifact0*ref_0_4 + 16 ) >>5;
end
else begin
pre_0_0_w = ref_0_0 ;
pre_0_1_w = ref_0_1 ;
pre_0_2_w = ref_0_2 ;
pre_0_3_w = ref_0_3 ;
end
end
always @( * ) begin
if(ifact0) begin
pre_1_0_w = ( (32-ifact1)*ref_1_0 + ifact1*ref_1_1 + 16 ) >>5;
pre_1_1_w = ( (32-ifact1)*ref_1_1 + ifact1*ref_1_2 + 16 ) >>5;
pre_1_2_w = ( (32-ifact1)*ref_1_2 + ifact1*ref_1_3 + 16 ) >>5;
pre_1_3_w = ( (32-ifact1)*ref_1_3 + ifact1*ref_1_4 + 16 ) >>5;
end
else begin
pre_1_0_w = ref_1_0 ;
pre_1_1_w = ref_1_1 ;
pre_1_2_w = ref_1_2 ;
pre_1_3_w = ref_1_3 ;
end
end
always @( * ) begin
if(ifact0) begin
pre_2_0_w = ( (32-ifact2)*ref_2_0 + ifact2*ref_2_1 + 16 ) >>5;
pre_2_1_w = ( (32-ifact2)*ref_2_1 + ifact2*ref_2_2 + 16 ) >>5;
pre_2_2_w = ( (32-ifact2)*ref_2_2 + ifact2*ref_2_3 + 16 ) >>5;
pre_2_3_w = ( (32-ifact2)*ref_2_3 + ifact2*ref_2_4 + 16 ) >>5;
end
else begin
pre_2_0_w = ref_2_0 ;
pre_2_1_w = ref_2_1 ;
pre_2_2_w = ref_2_2 ;
pre_2_3_w = ref_2_3 ;
end
end
always @( * ) begin
if(ifact0) begin
pre_3_0_w = ( (32-ifact3)*ref_3_0 + ifact3*ref_3_1 + 16 ) >>5;
pre_3_1_w = ( (32-ifact3)*ref_3_1 + ifact3*ref_3_2 + 16 ) >>5;
pre_3_2_w = ( (32-ifact3)*ref_3_2 + ifact3*ref_3_3 + 16 ) >>5;
pre_3_3_w = ( (32-ifact3)*ref_3_3 + ifact3*ref_3_4 + 16 ) >>5;
end
else begin
pre_3_0_w = ref_3_0 ;
pre_3_1_w = ref_3_1 ;
pre_3_2_w = ref_3_2 ;
pre_3_3_w = ref_3_3 ;
end
end
以下代码为Planar模式4x4块预测像素计算过程,基于Planar计算公式,容易理解。
//Planar
reg [`PIXEL_WIDTH-1:0] planar_00_w,planar_01_w,planar_02_w,planar_03_w;
reg [`PIXEL_WIDTH-1:0] planar_10_w,planar_11_w,planar_12_w,planar_13_w;
reg [`PIXEL_WIDTH-1:0] planar_20_w,planar_21_w,planar_22_w,planar_23_w;
reg [`PIXEL_WIDTH-1:0] planar_30_w,planar_31_w,planar_32_w,planar_33_w;
always @( * ) begin
case(size_r1)
2'b00:begin
planar_00_w=(3*left0_r+3*top0_r+planar_x0_r+planar_y0_r+4)>>3;
planar_01_w=(2*left0_r+3*top1_r+planar_x1_r+planar_y0_r+4)>>3;
planar_02_w=(1*left0_r+3*top2_r+planar_x2_r+planar_y0_r+4)>>3;
planar_03_w=(0*left0_r+3*top3_r+planar_x3_r+planar_y0_r+4)>>3;
planar_10_w=(3*left1_r+2*top0_r+planar_x0_r+planar_y1_r+4)>>3;
planar_11_w=(2*left1_r+2*top1_r+planar_x1_r+planar_y1_r+4)>>3;
planar_12_w=(1*left1_r+2*top2_r+planar_x2_r+planar_y1_r+4)>>3;
planar_13_w=(0*left1_r+2*top3_r+planar_x3_r+planar_y1_r+4)>>3;
planar_20_w=(3*left2_r+1*top0_r+planar_x0_r+planar_y2_r+4)>>3;
planar_21_w=(2*left2_r+1*top1_r+planar_x1_r+planar_y2_r+4)>>3;
planar_22_w=(1*left2_r+1*top2_r+planar_x2_r+planar_y2_r+4)>>3;
planar_23_w=(0*left2_r+1*top3_r+planar_x3_r+planar_y2_r+4)>>3;
planar_30_w=(3*left3_r+0*top0_r+planar_x0_r+planar_y3_r+4)>>3;
planar_31_w=(2*left3_r+0*top1_r+planar_x1_r+planar_y3_r+4)>>3;
planar_32_w=(1*left3_r+0*top2_r+planar_x2_r+planar_y3_r+4)>>3;
planar_33_w=(0*left3_r+0*top3_r+planar_x3_r+planar_y3_r+4)>>3;
end
2'b01:begin
planar_00_w=((7-x0_r1)*left0_r+(7-y0_r1)*top0_r+planar_x0_r+planar_y0_r+8)>>4;
planar_01_w=((7-x1_r1)*left0_r+(7-y0_r1)*top1_r+planar_x1_r+planar_y0_r+8)>>4;
planar_02_w=((7-x2_r1)*left0_r+(7-y0_r1)*top2_r+planar_x2_r+planar_y0_r+8)>>4;
planar_03_w=((7-x3_r1)*left0_r+(7-y0_r1)*top3_r+planar_x3_r+planar_y0_r+8)>>4;
planar_10_w=((7-x0_r1)*left1_r+(7-y1_r1)*top0_r+planar_x0_r+planar_y1_r+8)>>4;
planar_11_w=((7-x1_r1)*left1_r+(7-y1_r1)*top1_r+planar_x1_r+planar_y1_r+8)>>4;
planar_12_w=((7-x2_r1)*left1_r+(7-y1_r1)*top2_r+planar_x2_r+planar_y1_r+8)>>4;
planar_13_w=((7-x3_r1)*left1_r+(7-y1_r1)*top3_r+planar_x3_r+planar_y1_r+8)>>4;
planar_20_w=((7-x0_r1)*left2_r+(7-y2_r1)*top0_r+planar_x0_r+planar_y2_r+8)>>4;
planar_21_w=((7-x1_r1)*left2_r+(7-y2_r1)*top1_r+planar_x1_r+planar_y2_r+8)>>4;
planar_22_w=((7-x2_r1)*left2_r+(7-y2_r1)*top2_r+planar_x2_r+planar_y2_r+8)>>4;
planar_23_w=((7-x3_r1)*left2_r+(7-y2_r1)*top3_r+planar_x3_r+planar_y2_r+8)>>4;
planar_30_w=((7-x0_r1)*left3_r+(7-y3_r1)*top0_r+planar_x0_r+planar_y3_r+8)>>4;
planar_31_w=((7-x1_r1)*left3_r+(7-y3_r1)*top1_r+planar_x1_r+planar_y3_r+8)>>4;
planar_32_w=((7-x2_r1)*left3_r+(7-y3_r1)*top2_r+planar_x2_r+planar_y3_r+8)>>4;
planar_33_w=((7-x3_r1)*left3_r+(7-y3_r1)*top3_r+planar_x3_r+planar_y3_r+8)>>4;
end
2'b10:begin
planar_00_w=((15-x0_r1)*left0_r+(15-y0_r1)*top0_r+planar_x0_r+planar_y0_r+16)>>5;
planar_01_w=((15-x1_r1)*left0_r+(15-y0_r1)*top1_r+planar_x1_r+planar_y0_r+16)>>5;
planar_02_w=((15-x2_r1)*left0_r+(15-y0_r1)*top2_r+planar_x2_r+planar_y0_r+16)>>5;
planar_03_w=((15-x3_r1)*left0_r+(15-y0_r1)*top3_r+planar_x3_r+planar_y0_r+16)>>5;
planar_10_w=((15-x0_r1)*left1_r+(15-y1_r1)*top0_r+planar_x0_r+planar_y1_r+16)>>5;
planar_11_w=((15-x1_r1)*left1_r+(15-y1_r1)*top1_r+planar_x1_r+planar_y1_r+16)>>5;
planar_12_w=((15-x2_r1)*left1_r+(15-y1_r1)*top2_r+planar_x2_r+planar_y1_r+16)>>5;
planar_13_w=((15-x3_r1)*left1_r+(15-y1_r1)*top3_r+planar_x3_r+planar_y1_r+16)>>5;
planar_20_w=((15-x0_r1)*left2_r+(15-y2_r1)*top0_r+planar_x0_r+planar_y2_r+16)>>5;
planar_21_w=((15-x1_r1)*left2_r+(15-y2_r1)*top1_r+planar_x1_r+planar_y2_r+16)>>5;
planar_22_w=((15-x2_r1)*left2_r+(15-y2_r1)*top2_r+planar_x2_r+planar_y2_r+16)>>5;
planar_23_w=((15-x3_r1)*left2_r+(15-y2_r1)*top3_r+planar_x3_r+planar_y2_r+16)>>5;
planar_30_w=((15-x0_r1)*left3_r+(15-y3_r1)*top0_r+planar_x0_r+planar_y3_r+16)>>5;
planar_31_w=((15-x1_r1)*left3_r+(15-y3_r1)*top1_r+planar_x1_r+planar_y3_r+16)>>5;
planar_32_w=((15-x2_r1)*left3_r+(15-y3_r1)*top2_r+planar_x2_r+planar_y3_r+16)>>5;
planar_33_w=((15-x3_r1)*left3_r+(15-y3_r1)*top3_r+planar_x3_r+planar_y3_r+16)>>5;
end
2'b11:begin
planar_00_w=((31-x0_r1)*left0_r+(31-y0_r1)*top0_r+planar_x0_r+planar_y0_r+32)>>6;
planar_01_w=((31-x1_r1)*left0_r+(31-y0_r1)*top1_r+planar_x1_r+planar_y0_r+32)>>6;
planar_02_w=((31-x2_r1)*left0_r+(31-y0_r1)*top2_r+planar_x2_r+planar_y0_r+32)>>6;
planar_03_w=((31-x3_r1)*left0_r+(31-y0_r1)*top3_r+planar_x3_r+planar_y0_r+32)>>6;
planar_10_w=((31-x0_r1)*left1_r+(31-y1_r1)*top0_r+planar_x0_r+planar_y1_r+32)>>6;
planar_11_w=((31-x1_r1)*left1_r+(31-y1_r1)*top1_r+planar_x1_r+planar_y1_r+32)>>6;
planar_12_w=((31-x2_r1)*left1_r+(31-y1_r1)*top2_r+planar_x2_r+planar_y1_r+32)>>6;
planar_13_w=((31-x3_r1)*left1_r+(31-y1_r1)*top3_r+planar_x3_r+planar_y1_r+32)>>6;
planar_20_w=((31-x0_r1)*left2_r+(31-y2_r1)*top0_r+planar_x0_r+planar_y2_r+32)>>6;
planar_21_w=((31-x1_r1)*left2_r+(31-y2_r1)*top1_r+planar_x1_r+planar_y2_r+32)>>6;
planar_22_w=((31-x2_r1)*left2_r+(31-y2_r1)*top2_r+planar_x2_r+planar_y2_r+32)>>6;
planar_23_w=((31-x3_r1)*left2_r+(31-y2_r1)*top3_r+planar_x3_r+planar_y2_r+32)>>6;
planar_30_w=((31-x0_r1)*left3_r+(31-y3_r1)*top0_r+planar_x0_r+planar_y3_r+32)>>6;
planar_31_w=((31-x1_r1)*left3_r+(31-y3_r1)*top1_r+planar_x1_r+planar_y3_r+32)>>6;
planar_32_w=((31-x2_r1)*left3_r+(31-y3_r1)*top2_r+planar_x2_r+planar_y3_r+32)>>6;
planar_33_w=((31-x3_r1)*left3_r+(31-y3_r1)*top3_r+planar_x3_r+planar_y3_r+32)>>6;
end
endcase
end
以下代码为对DC、水平预测和垂直预测三种模式预测像素进行边界滤波代码。对DC,垂直预测和水平预测 三种模式,HEVC定义了边界滤波算法。
//DC
reg [`PIXEL_WIDTH-1:0] DC_00_w,DC_01_w,DC_02_w,DC_03_w;
reg [`PIXEL_WIDTH-1:0] DC_10_w;
reg [`PIXEL_WIDTH-1:0] DC_20_w;
reg [`PIXEL_WIDTH-1:0] DC_30_w;
always @( * ) begin
if(pre_sel_i==2'b00) begin
if((x0_r1==0) && (y0_r1==0) && size_r1!=2'b11)
DC_00_w = (top0_r+left0_r+(dc_value_r<<1)+2)>>2;
else if((x0_r1==0) && size_r1!=2'b11)
DC_00_w = (left0_r+(dc_value_r*3)+2)>>2;
else if((y0_r1==0) && size_r1!=2'b11)
DC_00_w = (top0_r +(dc_value_r*3)+2)>>2;
else begin
DC_00_w = dc_value_r;
end
end
else begin
DC_00_w = dc_value_r;
end
end
always @( * ) begin
if((x0_r1==0) && size_r1!=2'b11 && (pre_sel_i==2'b00) ) begin
DC_10_w = (left1_r+(dc_value_r*3)+2)>>2;
DC_20_w = (left2_r+(dc_value_r*3)+2)>>2;
DC_30_w = (left3_r+(dc_value_r*3)+2)>>2;
end
else begin
DC_10_w = dc_value_r;
DC_20_w = dc_value_r;
DC_30_w = dc_value_r;
end
end
always @( * ) begin
if((y0_r1==0) && size_r1!=2'b11 && (pre_sel_i==2'b00) ) begin
DC_01_w = (top1_r+(dc_value_r*3)+2)>>2;
DC_02_w = (top2_r+(dc_value_r*3)+2)>>2;
DC_03_w = (top3_r+(dc_value_r*3)+2)>>2;
end
else begin
DC_01_w = dc_value_r;
DC_02_w = dc_value_r;
DC_03_w = dc_value_r;
end
end
//Angular26 and Angular10 filter
wire signed [`PIXEL_WIDTH:0] top0_w, top1_w, top2_w, top3_w;
wire signed [`PIXEL_WIDTH:0] left0_w,left1_w,left2_w,left3_w;
wire signed [`PIXEL_WIDTH:0] ref_tl;
assign top0_w={1'b0,top0_r}; assign left0_w={1'b0,left0_r};
assign top1_w={1'b0,top1_r}; assign left1_w={1'b0,left1_r};
assign top2_w={1'b0,top2_r}; assign left2_w={1'b0,left2_r};
assign top3_w={1'b0,top3_r}; assign left3_w={1'b0,left3_r};
assign ref_tl={1'b0,ref_tl_i};
wire signed [`PIXEL_WIDTH+1:0] ver_0_w, ver_1_w, ver_2_w, ver_3_w;
wire signed [`PIXEL_WIDTH+1:0] hor_0_w, hor_1_w, hor_2_w, hor_3_w;
reg [`PIXEL_WIDTH-1:0] ver_00_w,ver_10_w,ver_20_w,ver_30_w;
reg [`PIXEL_WIDTH-1:0] hor_00_w,hor_01_w,hor_02_w,hor_03_w;
assign ver_0_w=top0_w+((left0_w-ref_tl)>>>1);
assign ver_1_w=top0_w+((left1_w-ref_tl)>>>1);
assign ver_2_w=top0_w+((left2_w-ref_tl)>>>1);
assign ver_3_w=top0_w+((left3_w-ref_tl)>>>1);
assign hor_0_w=left0_w+((top0_w-ref_tl)>>>1);
assign hor_1_w=left0_w+((top1_w-ref_tl)>>>1);
assign hor_2_w=left0_w+((top2_w-ref_tl)>>>1);
assign hor_3_w=left0_w+((top3_w-ref_tl)>>>1);
//Angular26
always @( * ) begin
if((x0_r1==0) && size_r1!=2'b11 && (pre_sel_i==2'b00) ) begin
ver_00_w=(ver_0_w[9] ? 'd0 : ( ver_0_w[8] ? 'd255 : ver_0_w[7:0] ));
ver_10_w=(ver_1_w[9] ? 'd0 : ( ver_1_w[8] ? 'd255 : ver_1_w[7:0] ));
ver_20_w=(ver_2_w[9] ? 'd0 : ( ver_2_w[8] ? 'd255 : ver_2_w[7:0] ));
ver_30_w=(ver_3_w[9] ? 'd0 : ( ver_3_w[8] ? 'd255 : ver_3_w[7:0] ));
end
else begin
ver_00_w=top0_r;
ver_10_w=top0_r;
ver_20_w=top0_r;
ver_30_w=top0_r;
end
end
//Angular10
always @( * ) begin
if((y0_r1==0) && size_r1!=2'b11 && (pre_sel_i==2'b00) ) begin
hor_00_w=(hor_0_w[9] ? 'd0 : ( hor_0_w[8] ? 'd255 : hor_0_w[7:0] ));
hor_01_w=(hor_1_w[9] ? 'd0 : ( hor_1_w[8] ? 'd255 : hor_1_w[7:0] ));
hor_02_w=(hor_2_w[9] ? 'd0 : ( hor_2_w[8] ? 'd255 : hor_2_w[7:0] ));
hor_03_w=(hor_3_w[9] ? 'd0 : ( hor_3_w[8] ? 'd255 : hor_3_w[7:0] ));
end
else begin
hor_00_w=left0_r;
hor_01_w=left0_r;
hor_02_w=left0_r;
hor_03_w=left0_r;
end
end
最后,将预测结果输出到输出变量
//***************************************************************************
//output
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
pred_00_o<='d0; pred_01_o<='d0; pred_02_o<='d0; pred_03_o<='d0;
pred_10_o<='d0; pred_11_o<='d0; pred_12_o<='d0; pred_13_o<='d0;
pred_20_o<='d0; pred_21_o<='d0; pred_22_o<='d0; pred_23_o<='d0;
pred_30_o<='d0; pred_31_o<='d0; pred_32_o<='d0; pred_33_o<='d0;
end
else begin
case(mode_r1)
'd0:begin
pred_00_o<=planar_00_w; pred_01_o<=planar_01_w; pred_02_o<=planar_02_w; pred_03_o<=planar_03_w;
pred_10_o<=planar_10_w; pred_11_o<=planar_11_w; pred_12_o<=planar_12_w; pred_13_o<=planar_13_w;
pred_20_o<=planar_20_w; pred_21_o<=planar_21_w; pred_22_o<=planar_22_w; pred_23_o<=planar_23_w;
pred_30_o<=planar_30_w; pred_31_o<=planar_31_w; pred_32_o<=planar_32_w; pred_33_o<=planar_33_w;
end
'd1:begin
pred_00_o<=DC_00_w; pred_01_o<=DC_01_w; pred_02_o<=DC_02_w; pred_03_o<=DC_03_w;
pred_10_o<=DC_10_w; pred_11_o<=dc_value_r; pred_12_o<=dc_value_r; pred_13_o<=dc_value_r;
pred_20_o<=DC_20_w; pred_21_o<=dc_value_r; pred_22_o<=dc_value_r; pred_23_o<=dc_value_r;
pred_30_o<=DC_30_w; pred_31_o<=dc_value_r; pred_32_o<=dc_value_r; pred_33_o<=dc_value_r;
end
'd10:begin
pred_00_o<=hor_00_w; pred_01_o<=hor_01_w; pred_02_o<=hor_02_w; pred_03_o<=hor_03_w;
pred_10_o<=left1_r; pred_11_o<=left1_r; pred_12_o<=left1_r; pred_13_o<=left1_r;
pred_20_o<=left2_r; pred_21_o<=left2_r; pred_22_o<=left2_r; pred_23_o<=left2_r;
pred_30_o<=left3_r; pred_31_o<=left3_r; pred_32_o<=left3_r; pred_33_o<=left3_r;
end
'd26:begin
pred_00_o<=ver_00_w; pred_01_o<=top1_r; pred_02_o<=top2_r; pred_03_o<=top3_r;
pred_10_o<=ver_10_w; pred_11_o<=top1_r; pred_12_o<=top2_r; pred_13_o<=top3_r;
pred_20_o<=ver_20_w; pred_21_o<=top1_r; pred_22_o<=top2_r; pred_23_o<=top3_r;
pred_30_o<=ver_30_w; pred_31_o<=top1_r; pred_32_o<=top2_r; pred_33_o<=top3_r;
end
default:begin
if(mode_r1>=18)begin
pred_00_o<=pre_0_0_w; pred_01_o<=pre_0_1_w; pred_02_o<=pre_0_2_w; pred_03_o<=pre_0_3_w;
pred_10_o<=pre_1_0_w; pred_11_o<=pre_1_1_w; pred_12_o<=pre_1_2_w; pred_13_o<=pre_1_3_w;
pred_20_o<=pre_2_0_w; pred_21_o<=pre_2_1_w; pred_22_o<=pre_2_2_w; pred_23_o<=pre_2_3_w;
pred_30_o<=pre_3_0_w; pred_31_o<=pre_3_1_w; pred_32_o<=pre_3_2_w; pred_33_o<=pre_3_3_w;
end
else begin
pred_00_o<=pre_0_0_w; pred_01_o<=pre_1_0_w; pred_02_o<=pre_2_0_w; pred_03_o<=pre_3_0_w;
pred_10_o<=pre_0_1_w; pred_11_o<=pre_1_1_w; pred_12_o<=pre_2_1_w; pred_13_o<=pre_3_1_w;
pred_20_o<=pre_0_2_w; pred_21_o<=pre_1_2_w; pred_22_o<=pre_2_2_w; pred_23_o<=pre_3_2_w;
pred_30_o<=pre_0_3_w; pred_31_o<=pre_1_3_w; pred_32_o<=pre_2_3_w; pred_33_o<=pre_3_3_w;
end
end
endcase
end
end