• JPEG解码:反DCT变换(二)


    1:矩阵与矩阵的乘法运算。

    8*8与8*8的矩阵相乘,第一次来的8个数据依次与矩阵的A的第i列相乘的结果相加作为第一行的第i个数,第二次来的8个数与矩阵A的第i列相乘的结果相加做为第二行的第i 个数。依次类推,直到64个数全部都运算结束。由于每次来一个数,所以需要一个8位的移位寄存器来保存每次来的数,直到8个数都来齐,才开始于矩阵A相称,由于乘法涉及到有符号乘法,解决的办法为放缩的方法,把矩阵A的系数全部房贷2^16倍,就是把A的系数向右移16位,转化为整数,但是结果也要还原,即向左移16位。

    代码如下:

    shift
     1 //----------------------------------------------------------------
    2 //移位寄存器
    3 reg[11:0] shift0,
    4 shift1,
    5 shift2,
    6 shift3,
    7 shift4,
    8 shift5,
    9 shift6,
    10 shift7;
    11
    12 always@(posedge clk or negedge rst_n)
    13 begin
    14 if(!rst_n)
    15 begin
    16 shift0<=12'b0;
    17 shift1<=12'b0;
    18 shift2<=12'b0;
    19 shift3<=12'b0;
    20 shift4<=12'b0;
    21 shift5<=12'b0;
    22 shift6<=12'b0;
    23 shift7<=12'b0;
    24 end
    25 else if(datain_en==1'b1)
    26 begin
    27 shift0<=datain;
    28 shift1<=shift0;
    29 shift2<=shift1;
    30 shift3<=shift2;
    31 shift4<=shift3;
    32 shift5<=shift4;
    33 shift6<=shift5;
    34 shift7<=shift6;
    35 end
    36
    37 end

    移位寄存器模块,用于保存每次进来的数据,一个保存8个。

    reg
     1 //-----------------------------------------------------------
    2 //数据保存
    3 reg [11:0]data0_reg,
    4 data1_reg,
    5 data2_reg,
    6 data3_reg,
    7 data4_reg,
    8 data5_reg,
    9 data6_reg,
    10 data7_reg;
    11
    12
    13 always@(posedge clk or negedge rst_n)
    14 begin
    15 if(!rst_n)
    16 begin
    17 data0_reg<=12'b0;
    18 data1_reg<=12'b0;
    19 data2_reg<=12'b0;
    20 data3_reg<=12'b0;
    21 data4_reg<=12'b0;
    22 data5_reg<=12'b0;
    23 data6_reg<=12'b0;
    24 data7_reg<=12'b0;
    25 end
    26
    27 else if(f1==1'b1) //
    28 begin
    29 data0_reg<=shift7;
    30 data1_reg<=shift6;
    31 data2_reg<=shift5;
    32 data3_reg<=shift4;
    33 data4_reg<=shift3;
    34 data5_reg<=shift2;
    35 data6_reg<=shift1;
    36 data7_reg<=shift0;
    37 end
    38
    39 else
    40 begin
    41 data0_reg<=data0_reg;
    42 data1_reg<=data1_reg;
    43 data2_reg<=data2_reg;
    44 data3_reg<=data3_reg;
    45 data4_reg<=data4_reg;
    46 data5_reg<=data5_reg;
    47 data6_reg<=data6_reg;
    48 data7_reg<=data7_reg;
    49 end
    50
    51
    52 end

    数据寄存器模块,当8个数据输入完毕,把移位寄存器中的数据转入寄存器中,释放移位寄存器,以便接受接下来传来的数据。在转入的时候注意数据的顺序,由于移位寄存器的的操作时每次来的数据都依次推移,所以第一个数据就保存到了shift7中,而最后一个数据却保存到shift0中,所以转入数据寄存器的时候需要顺序颠倒下。

    value
     1 //---------------------------------------------------------
    2 //把输入的数据进行符号和数值分离。
    3 reg [10:0]data0_value;
    4 reg [10:0]data1_value;
    5 reg [10:0]data2_value;
    6 reg [10:0]data3_value;
    7 reg [10:0]data4_value;
    8 reg [10:0]data5_value;
    9 reg [10:0]data6_value;
    10 reg [10:0]data7_value;
    11 reg data0_sign,
    12 data1_sign,
    13 data2_sign,
    14 data3_sign,
    15 data4_sign,
    16 data5_sign,
    17 data6_sign,
    18 data7_sign;
    19
    20 always@(posedge clk or negedge rst_n)
    21 begin
    22 if(!rst_n)
    23 begin
    24 data0_sign<=1'b0; data0_value<=11'b0;
    25 data1_sign<=1'b0; data1_value<=11'b0;
    26 data2_sign<=1'b0; data2_value<=11'b0;
    27 data3_sign<=1'b0; data3_value<=11'b0;
    28 data4_sign<=1'b0; data4_value<=11'b0;
    29 data5_sign<=1'b0; data5_value<=11'b0;
    30 data6_sign<=1'b0; data6_value<=11'b0;
    31 data7_sign<=1'b0; data7_value<=11'b0;
    32 end
    33
    34 else if(f2==1'b1)
    35 begin
    36 data0_sign<=data0_reg[11];
    37 data0_value[10:0]<=(data0_reg[11])?((-data0_reg)+1'b1):(data0_reg[10:0]);
    38
    39 data1_sign<=data1_reg[11];
    40 data1_value[10:0]<=(data1_reg[11])?((-data1_reg)+1'b1):(data1_reg[10:0]);
    41
    42 data2_sign<=data2_reg[11];
    43 data2_value[10:0]<=(data2_reg[11])?((-data2_reg)+1'b1):(data2_reg[10:0]);
    44
    45 data3_sign<=data3_reg[11];
    46 data3_value[10:0]<=(data3_reg[11])?((-data3_reg)+1'b1):(data3_reg[10:0]);
    47
    48 data4_sign<=data4_reg[11];
    49 data4_value[10:0]<=(data4_reg[11])?((-data4_reg)+1'b1):(data4_reg[10:0]);
    50
    51 data5_sign<=data5_reg[11];
    52 data5_value[10:0]<=(data5_reg[11])?((-data5_reg)+1'b1):(data5_reg[10:0]);
    53
    54 data6_sign<=data6_reg[11];
    55 data6_value[10:0]<=(data6_reg[11])?((-data6_reg)+1'b1):(data6_reg[10:0]);
    56
    57 data7_sign<=data7_reg[11];
    58 data7_value[10:0]<=(data7_reg[11])?((-data7_reg)+1'b1):(data7_reg[10:0]);
    59 end
    60
    61
    62 end

    进行数据的正负判断,把符号位提取出来。

    A
      1 //----------------------------------------------------------------------
    2 //设置矩阵A的系数,扩大2^16倍,右移16位。
    3 /*
    4 a a a a a a a a
    5 b d e g -g -e -d -b
    6 c f -f -c -c -f f c
    7 A= d -g -b -e e b g -d
    8 a -a -a a a -a -a a
    9 e -b g d -d -g b -c
    10 f -c c -f -f c -c f
    11 g -e d -b b -d e -g
    12
    13 */
    14 reg [2:0]state;
    15 reg[15:0] x0,
    16 x1,
    17 x2,
    18 x3,
    19 x4,
    20 x5,
    21 x6,
    22 x7;
    23 always@(posedge clk or negedge rst_n)
    24 begin
    25 if(!rst_n)
    26 begin
    27 x0<=16'b0;
    28 x1<=16'b0;
    29 x2<=16'b0;
    30 x3<=16'b0;
    31 x4<=16'b0;
    32 x5<=16'b0;
    33 x6<=16'b0;
    34 x7<=16'b0;
    35 state<=3'd0;
    36 end
    37
    38 else
    39
    40 begin
    41 case(state)
    42
    43 3'b000:if(f2==1'b1)
    44 begin
    45 x0<=16'd23170; //a
    46 x1<=16'd32138; //b
    47 x2<=16'd30274; //c
    48 x3<=16'd27246; //d
    49 x4<=16'd23170; //a
    50 x5<=16'd18205; //e
    51 x6<=16'd12540; //f
    52 x7<=16'd6393;
    53 state<=3'b001; //g
    54 end
    55
    56 3'b001:
    57 begin
    58 x0<=16'd23170; //a
    59 x1<=16'd27246; //d
    60 x2<=16'd12540; //f
    61 x3[15]<=1'd1;x3[14:0]<=15'd6393; //-g
    62 x4[15]<=1'd1;x4[14:0]<=15'd23170; //-a
    63 x5[15]<=1'd1;x5[14:0]<=15'd32138; //-b
    64 x6[15]<=1'd1;x6[14:0]<=15'd30274; //-c
    65 x7[15]<=1'd1;x7[14:0]<=15'd18205; //-e
    66 state<=3'b010;
    67 end
    68
    69 3'b010:
    70 begin
    71 x0<=16'd23170; //a
    72 x1<=16'd18205; //e
    73 x2[15]<=1'd1;x2[14:0]<=15'd12540; //-f
    74 x3[15]<=1'd1;x3[14:0]<=15'd32138; //-b
    75 x4[15]<=1'd1;x4[14:0]<=15'd23170; //-a
    76 x5<=16'd6393; //g
    77 x6<=16'd30274; //c
    78 x7<=16'd27246; //d
    79 state<=3'b011;
    80 end
    81
    82 3'b011:
    83 begin
    84 x0<=16'd23170; //a
    85 x1<=16'd6393; //g
    86 x2[15]<=1'd1;x2[14:0]<=15'd30274; //-c
    87 x3[15]<=1'd1;x3[14:0]<=15'd18205; //-e
    88 x4<=16'd23170; //a
    89 x5<=16'd27246; //d
    90 x6[15]<=1'd1;x6[14:0]<=15'd12540; //-f
    91 x7[15]<=1'd1;x7[14:0]<=15'd32138; //-b
    92 state<=3'b100;
    93 end
    94
    95 3'b100:
    96 begin
    97 x0<=16'd23170; //a
    98 x1[15]<=1'd1;x1[14:0]<=15'd6393; //-g
    99 x2[15]<=1'd1;x2[14:0]<=15'd30274; //-c
    100 x3<=16'd18205; //e
    101 x4<=16'd23170; //a
    102 x5[15]<=1'd1;x5[14:0]<=15'd27246; //-d
    103 x6[15]<=1'd1;x6[14:0]<=15'd12540; //-f
    104 x7<=16'd32138; //b
    105 state<=3'b101;
    106 end
    107
    108 3'b101:
    109 begin
    110 x0<=16'd23170; //a
    111 x1[15]<=1'd1;x1[14:0]<=15'd18205; //-e
    112 x2[15]<=1'd1;x2[14:0]<=15'd12540; //-f
    113 x3<=16'd32138; //b
    114 x4[15]<=1'd1;x4[14:0]<=15'd23170; //-a
    115 x5[15]<=1'd1;x5[14:0]<=15'd6393; //-g
    116 x6<=16'd30274; //c
    117 x7[15]<=1'd1;x7[14:0]<=15'd27246; //-d
    118 state<=3'b110;
    119 end
    120
    121 3'b110:
    122 begin
    123 x0<=16'd23170; //a
    124 x1[15]<=1'd1;x1[14:0]<=15'd27246; //-d
    125 x2<=16'd12540; //f
    126 x3<=16'd6393; //g
    127 x4[15]<=1'd1;x4[14:0]<=15'd23170; //-a
    128 x5<=16'd32138; //b
    129 x6[15]<=1'd1;x6[14:0]<=15'd30274; //-c
    130 x7<=16'd18205; //e
    131 state<=3'b111;
    132 end
    133
    134 3'b111:
    135 begin
    136 x0<=16'd23170; //a
    137 x1[15]<=1'd1;x1[14:0]<=15'd32138; //-b
    138 x2<=16'd30274; //c
    139 x3[15]<=1'd1;x3[14:0]<=15'd27246; //-d
    140 x4<=16'd23170; //a
    141 x5[15]<=1'd1;x5[14:0]<=15'd18205; //-e
    142 x6<=16'd12540; //f
    143 x7[15]<=1'd1;x7[14:0]<=15'd6393; //-g
    144 state<=3'b000;
    145 end
    146 endcase
    147 end
    148
    149
    150 end

    设置矩阵A的系数,这里的数值都是扩大了2^16倍之后的结果。

    mul
     1 //----------------------------------------------------------------------------
    2 //与矩阵相乘
    3 wire [35:0] r0;
    4 wire [35:0] r1;
    5 wire [35:0] r2;
    6 wire [35:0] r3;
    7 wire [35:0] r4;
    8 wire [35:0] r5;
    9 wire [35:0] r6;
    10 wire [35:0] r7;
    11
    12 MULT18_18 m0(.dataa({7'b0,data0_value}),.datab({3'b0,x0[14:0]}),.result(r0));
    13 MULT18_18 m1(.dataa({7'b0,data1_value}),.datab({3'b0,x1[14:0]}),.result(r1));
    14 MULT18_18 m2(.dataa({7'b0,data2_value}),.datab({3'b0,x2[14:0]}),.result(r2));
    15 MULT18_18 m3(.dataa({7'b0,data3_value}),.datab({3'b0,x3[14:0]}),.result(r3));
    16 MULT18_18 m4(.dataa({7'b0,data4_value}),.datab({3'b0,x4[14:0]}),.result(r4));
    17 MULT18_18 m5(.dataa({7'b0,data5_value}),.datab({3'b0,x5[14:0]}),.result(r5));
    18 MULT18_18 m6(.dataa({7'b0,data6_value}),.datab({3'b0,x6[14:0]}),.result(r6));
    19 MULT18_18 m7(.dataa({7'b0,data7_value}),.datab({3'b0,x7[14:0]}),.result(r7));

    两个矩阵系数相乘,只是一行与一列的相乘,这里例化一个乘法器,18_18位的乘法器,结果为36位。

    data
     1 //--------------------------------------------------------------------------------
    2 //取有效的长度
    3 reg [29:0]p0;
    4 reg [29:0]p1;
    5 reg [29:0]p2;
    6 reg [29:0]p3;
    7 reg [29:0]p4;
    8 reg [29:0]p5;
    9 reg [29:0]p6;
    10 reg [29:0]p7;
    11
    12 always@(posedge clk or negedge rst_n)
    13 begin
    14 if(!rst_n)
    15 begin
    16 p0<=30'b0;
    17 p1<=30'b0;
    18 p2<=30'b0;
    19 p3<=30'b0;
    20 p4<=30'b0;
    21 p5<=30'b0;
    22 p6<=30'b0;
    23 p7<=30'b0;
    24 end
    25 else //
    26 begin
    27 p0<=(data0_sign^x0[15])?((-r0[25:0])+1'b1):(r0[25:0]);
    28 p1<=(data1_sign^x1[15])?((-r1[25:0])+1'b1):(r1[25:0]);
    29 p2<=(data2_sign^x2[15])?((-r2[25:0])+1'b1):(r2[25:0]);
    30 p3<=(data3_sign^x3[15])?((-r3[25:0])+1'b1):(r3[25:0]);
    31 p4<=(data4_sign^x4[15])?((-r4[25:0])+1'b1):(r4[25:0]);
    32 p5<=(data5_sign^x5[15])?((-r5[25:0])+1'b1):(r5[25:0]);
    33 p6<=(data6_sign^x6[15])?((-r6[25:0])+1'b1):(r6[25:0]);
    34 p7<=(data7_sign^x7[15])?((-r7[25:0])+1'b1):(r7[25:0]);
    35 end
    36
    37 end

    对结果的36位取26位的有效长度。同时对结果的符号做判断,方法为乘数的符号与被乘数的符号做异或操作。

    View Code
    //-----------------------------------------------------------------------------
    //累加
    reg[29:0] suma1_reg,suma2_reg,suma3_reg,suma4_reg;
    reg[29:0] suma_out;

    always@(posedge clk or negedge rst_n)
    begin
    if(~rst_n)
    begin
    suma1_reg<=30'b0;suma2_reg<=30'b0;suma3_reg<=30'b0;suma4_reg<=30'b0;
    end

    else
    begin
    suma1_reg<=(p0+p1);
    suma2_reg<=(p2+p3);
    suma3_reg<=(p4+p5);
    suma4_reg<=(p6+p7);
    end
    end
    //------------------------------------------------------------------------------
    //计算结果
    always@(posedge clk or negedge rst_n)
    if(~rst_n)
    suma_out<=30'b0;
    else
    suma_out<=(suma1_reg+suma2_reg)+(suma3_reg+suma4_reg);


    assign dataout=suma_out[29:16]; //14位


    计算最终的结果,上个模块的8个结果做加法操作作为最后的结果。结果要右移16位,然后取高14位。


    对于64(8_8)个输入数据,要做64次上述操作。

    总代码如下:

    View Code
    `timescale 1ps / 1ps
    module idct_1d(
    clk,
    rst_n,
    datain_en,
    datain,
    dataout_en,
    dataout
    );


    input clk;
    input rst_n;
    input datain_en;
    input [11:0]datain;

    output dataout_en;
    output [13:0]dataout;
    //------------------------------------------------
    //输入数据计数,8个为一组
    reg [2:0] count_in;
    always @(posedge clk or negedge rst_n)
    if (!rst_n)
    count_in<=1'b0;
    else if (datain_en==1'b1)
    count_in<=count_in+1'b1;


    reg dataout_en;
    reg rdy0,rdy1,rdy2,rdy3,rdy4;
    //---------------------------------------------------------
    //输出数据计数,64个输出使能之后输出无效
    reg [5:0]cnt_64;
    always @(posedge clk or negedge rst_n)
    if (!rst_n)
    cnt_64<=1'b0;
    else if (rdy0==1'b1)
    cnt_64<=cnt_64+1'b1;

    //---------------------------------------------------------
    //设置输出使能,8个数据输入完毕之后有效,64个数据输出后无效
    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
    rdy0<=1'b0;
    else
    begin
    if (count_in==3'b111 )
    rdy0<=1'b1;
    if (cnt_64==6'b111111)
    rdy0<=1'b0;
    end
    //-----------------------------------------------------------
    //输出使能缓存
    always @ (posedge clk or negedge rst_n)
    if (!rst_n)
    begin
    rdy1<=1'b0;
    rdy2<=1'b0;
    rdy3<=1'b0;
    rdy4<=1'b0;
    dataout_en<=1'b0;
    end
    else
    begin
    rdy1<=rdy0;
    rdy2<=rdy1;
    rdy3<=rdy2;
    rdy4<=rdy3;
    dataout_en<=rdy4;
    end

    //--------------------------------------------------------------
    //设置控制使能
    reg f1,f2,f3;
    always @(posedge clk or negedge rst_n)
    if (!rst_n)
    f1<=1'b0;
    else if (count_in==3'b111)
    f1<=datain_en;
    else f1<=1'b0;
    always @(posedge clk or negedge rst_n)
    if (!rst_n)
    begin
    f2<=1'b0;
    f3<=1'b0;
    end
    else
    begin
    f2<=f1;
    f3<=f2;
    end

    //----------------------------------------------------------------
    //移位寄存器
    reg[11:0] shift0,
    shift1,
    shift2,
    shift3,
    shift4,
    shift5,
    shift6,
    shift7;

    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    begin
    shift0<=12'b0;
    shift1<=12'b0;
    shift2<=12'b0;
    shift3<=12'b0;
    shift4<=12'b0;
    shift5<=12'b0;
    shift6<=12'b0;
    shift7<=12'b0;
    end
    else if(datain_en==1'b1)
    begin
    shift0<=datain;
    shift1<=shift0;
    shift2<=shift1;
    shift3<=shift2;
    shift4<=shift3;
    shift5<=shift4;
    shift6<=shift5;
    shift7<=shift6;
    end

    end

    //-----------------------------------------------------------
    //数据保存
    reg [11:0]data0_reg,
    data1_reg,
    data2_reg,
    data3_reg,
    data4_reg,
    data5_reg,
    data6_reg,
    data7_reg;


    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    begin
    data0_reg<=12'b0;
    data1_reg<=12'b0;
    data2_reg<=12'b0;
    data3_reg<=12'b0;
    data4_reg<=12'b0;
    data5_reg<=12'b0;
    data6_reg<=12'b0;
    data7_reg<=12'b0;
    end

    else if(f1==1'b1) //
    begin
    data0_reg<=shift7;
    data1_reg<=shift6;
    data2_reg<=shift5;
    data3_reg<=shift4;
    data4_reg<=shift3;
    data5_reg<=shift2;
    data6_reg<=shift1;
    data7_reg<=shift0;
    end

    else
    begin
    data0_reg<=data0_reg;
    data1_reg<=data1_reg;
    data2_reg<=data2_reg;
    data3_reg<=data3_reg;
    data4_reg<=data4_reg;
    data5_reg<=data5_reg;
    data6_reg<=data6_reg;
    data7_reg<=data7_reg;
    end


    end
    //---------------------------------------------------------
    //把输入的数据进行符号和数值分离。
    reg [10:0]data0_value;
    reg [10:0]data1_value;
    reg [10:0]data2_value;
    reg [10:0]data3_value;
    reg [10:0]data4_value;
    reg [10:0]data5_value;
    reg [10:0]data6_value;
    reg [10:0]data7_value;
    reg data0_sign,
    data1_sign,
    data2_sign,
    data3_sign,
    data4_sign,
    data5_sign,
    data6_sign,
    data7_sign;

    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    begin
    data0_sign<=1'b0; data0_value<=11'b0;
    data1_sign<=1'b0; data1_value<=11'b0;
    data2_sign<=1'b0; data2_value<=11'b0;
    data3_sign<=1'b0; data3_value<=11'b0;
    data4_sign<=1'b0; data4_value<=11'b0;
    data5_sign<=1'b0; data5_value<=11'b0;
    data6_sign<=1'b0; data6_value<=11'b0;
    data7_sign<=1'b0; data7_value<=11'b0;
    end

    else if(f2==1'b1)
    begin
    data0_sign<=data0_reg[11];
    data0_value[10:0]<=(data0_reg[11])?(-data0_reg):(data0_reg[10:0]);

    data1_sign<=data1_reg[11];
    data1_value[10:0]<=(data1_reg[11])?(-data1_reg):(data1_reg[10:0]);

    data2_sign<=data2_reg[11];
    data2_value[10:0]<=(data2_reg[11])?(-data2_reg):(data2_reg[10:0]);

    data3_sign<=data3_reg[11];
    data3_value[10:0]<=(data3_reg[11])?(-data3_reg):(data3_reg[10:0]);

    data4_sign<=data4_reg[11];
    data4_value[10:0]<=(data4_reg[11])?(-data4_reg):(data4_reg[10:0]);

    data5_sign<=data5_reg[11];
    data5_value[10:0]<=(data5_reg[11])?(-data5_reg):(data5_reg[10:0]);

    data6_sign<=data6_reg[11];
    data6_value[10:0]<=(data6_reg[11])?(-data6_reg):(data6_reg[10:0]);

    data7_sign<=data7_reg[11];
    data7_value[10:0]<=(data7_reg[11])?(-data7_reg):(data7_reg[10:0]);
    end


    end
    //----------------------------------------------------------------------
    //设置矩阵A的系数,扩大2^16倍,右移16位。
    /*

    a a a a a a a a
    b d e g -g -e -d -b
    c f -f -c -c -f f c
    A= d -g -b -e e b g -d
    a -a -a a a -a -a a
    e -b g d -d -g b -c
    f -c c -f -f c -c f
    g -e d -b b -d e -g

    */
    reg [2:0]state;
    reg[15:0] x0,
    x1,
    x2,
    x3,
    x4,
    x5,
    x6,
    x7;
    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    begin
    x0<=16'b0;
    x1<=16'b0;
    x2<=16'b0;
    x3<=16'b0;
    x4<=16'b0;
    x5<=16'b0;
    x6<=16'b0;
    x7<=16'b0;
    state<=3'd0;
    end

    else

    begin
    case(state)

    3'b000:if(f2==1'b1)
    begin
    x0<=16'd23170; //a
    x1<=16'd32138; //b
    x2<=16'd30274; //c
    x3<=16'd27246; //d
    x4<=16'd23170; //a
    x5<=16'd18205; //e
    x6<=16'd12540; //f
    x7<=16'd6393;
    state<=3'b001; //g
    end

    3'b001:
    begin
    x0<=16'd23170; //a
    x1<=16'd27246; //d
    x2<=16'd12540; //f
    x3[15]<=1'd1;x3[14:0]<=15'd6393; //-g
    x4[15]<=1'd1;x4[14:0]<=15'd23170; //-a
    x5[15]<=1'd1;x5[14:0]<=15'd32138; //-b
    x6[15]<=1'd1;x6[14:0]<=15'd30274; //-c
    x7[15]<=1'd1;x7[14:0]<=15'd18205; //-e
    state<=3'b010;
    end

    3'b010:
    begin
    x0<=16'd23170; //a
    x1<=16'd18205; //e
    x2[15]<=1'd1;x2[14:0]<=15'd12540; //-f
    x3[15]<=1'd1;x3[14:0]<=15'd32138; //-b
    x4[15]<=1'd1;x4[14:0]<=15'd23170; //-a
    x5<=16'd6393; //g
    x6<=16'd30274; //c
    x7<=16'd27246; //d
    state<=3'b011;
    end

    3'b011:
    begin
    x0<=16'd23170; //a
    x1<=16'd6393; //g
    x2[15]<=1'd1;x2[14:0]<=15'd30274; //-c
    x3[15]<=1'd1;x3[14:0]<=15'd18205; //-e
    x4<=16'd23170; //a
    x5<=16'd27246; //d
    x6[15]<=1'd1;x6[14:0]<=15'd12540; //-f
    x7[15]<=1'd1;x7[14:0]<=15'd32138; //-b
    state<=3'b100;
    end

    3'b100:
    begin
    x0<=16'd23170; //a
    x1[15]<=1'd1;x1[14:0]<=15'd6393; //-g
    x2[15]<=1'd1;x2[14:0]<=15'd30274; //-c
    x3<=16'd18205; //e
    x4<=16'd23170; //a
    x5[15]<=1'd1;x5[14:0]<=15'd27246; //-d
    x6[15]<=1'd1;x6[14:0]<=15'd12540; //-f
    x7<=16'd32138; //b
    state<=3'b101;
    end

    3'b101:
    begin
    x0<=16'd23170; //a
    x1[15]<=1'd1;x1[14:0]<=15'd18205; //-e
    x2[15]<=1'd1;x2[14:0]<=15'd12540; //-f
    x3<=16'd32138; //b
    x4[15]<=1'd1;x4[14:0]<=15'd23170; //-a
    x5[15]<=1'd1;x5[14:0]<=15'd6393; //-g
    x6<=16'd30274; //c
    x7[15]<=1'd1;x7[14:0]<=15'd27246; //-d
    state<=3'b110;
    end

    3'b110:
    begin
    x0<=16'd23170; //a
    x1[15]<=1'd1;x1[14:0]<=15'd27246; //-d
    x2<=16'd12540; //f
    x3<=16'd6393; //g
    x4[15]<=1'd1;x4[14:0]<=15'd23170; //-a
    x5<=16'd32138; //b
    x6[15]<=1'd1;x6[14:0]<=15'd30274; //-c
    x7<=16'd18205; //e
    state<=3'b111;
    end

    3'b111:
    begin
    x0<=16'd23170; //a
    x1[15]<=1'd1;x1[14:0]<=15'd32138; //-b
    x2<=16'd30274; //c
    x3[15]<=1'd1;x3[14:0]<=15'd27246; //-d
    x4<=16'd23170; //a
    x5[15]<=1'd1;x5[14:0]<=15'd18205; //-e
    x6<=16'd12540; //f
    x7[15]<=1'd1;x7[14:0]<=15'd6393; //-g
    state<=3'b000;
    end
    endcase
    end


    end

    //----------------------------------------------------------------------------
    //与矩阵相乘
    wire [35:0] r0;
    wire [35:0] r1;
    wire [35:0] r2;
    wire [35:0] r3;
    wire [35:0] r4;
    wire [35:0] r5;
    wire [35:0] r6;
    wire [35:0] r7;

    MULT18_18 m0(.dataa({7'b0,data0_value}),.datab({3'b0,x0[14:0]}),.result(r0));
    MULT18_18 m1(.dataa({7'b0,data1_value}),.datab({3'b0,x1[14:0]}),.result(r1));
    MULT18_18 m2(.dataa({7'b0,data2_value}),.datab({3'b0,x2[14:0]}),.result(r2));
    MULT18_18 m3(.dataa({7'b0,data3_value}),.datab({3'b0,x3[14:0]}),.result(r3));
    MULT18_18 m4(.dataa({7'b0,data4_value}),.datab({3'b0,x4[14:0]}),.result(r4));
    MULT18_18 m5(.dataa({7'b0,data5_value}),.datab({3'b0,x5[14:0]}),.result(r5));
    MULT18_18 m6(.dataa({7'b0,data6_value}),.datab({3'b0,x6[14:0]}),.result(r6));
    MULT18_18 m7(.dataa({7'b0,data7_value}),.datab({3'b0,x7[14:0]}),.result(r7));
    //--------------------------------------------------------------------------------
    //取有效的长度
    reg [29:0]p0;
    reg [29:0]p1;
    reg [29:0]p2;
    reg [29:0]p3;
    reg [29:0]p4;
    reg [29:0]p5;
    reg [29:0]p6;
    reg [29:0]p7;

    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    begin
    p0<=30'b0;
    p1<=30'b0;
    p2<=30'b0;
    p3<=30'b0;
    p4<=30'b0;
    p5<=30'b0;
    p6<=30'b0;
    p7<=30'b0;
    end
    else //
    begin
    p0<=(data0_sign^x0[15])?(-r0[25:0]):(r0[25:0]);
    p1<=(data1_sign^x1[15])?(-r1[25:0]):(r1[25:0]);
    p2<=(data2_sign^x2[15])?(-r2[25:0]):(r2[25:0]);
    p3<=(data3_sign^x3[15])?(-r3[25:0]):(r3[25:0]);
    p4<=(data4_sign^x4[15])?(-r4[25:0]):(r4[25:0]);
    p5<=(data5_sign^x5[15])?(-r5[25:0]):(r5[25:0]);
    p6<=(data6_sign^x6[15])?(-r6[25:0]):(r6[25:0]);
    p7<=(data7_sign^x7[15])?(-r7[25:0]):(r7[25:0]);
    end

    end
    //-----------------------------------------------------------------------------
    //累加
    reg[29:0] suma1_reg,suma2_reg,suma3_reg,suma4_reg;
    reg[29:0] suma_out;

    always@(posedge clk or negedge rst_n)
    begin
    if(~rst_n)
    begin
    suma1_reg<=30'b0;suma2_reg<=30'b0;suma3_reg<=30'b0;suma4_reg<=30'b0;
    end

    else
    begin
    suma1_reg<=(p0+p1);
    suma2_reg<=(p2+p3);
    suma3_reg<=(p4+p5);
    suma4_reg<=(p6+p7);
    end
    end
    //------------------------------------------------------------------------------
    //计算结果
    always@(posedge clk or negedge rst_n)
    if(~rst_n)
    suma_out<=30'b0;
    else
    suma_out<=(suma1_reg+suma2_reg)+(suma3_reg+suma4_reg);


    assign dataout=suma_out[29:16]; //14位





    endmodule















     

  • 相关阅读:
    20201112 装饰器之函数即变量
    2月13日:毕业设计进度
    2月12日:毕业设计进度
    2月11日:毕业设计进度
    2月10日:毕业设计进度
    2月9日:毕业设计进度
    2月8日:毕业设计进度
    2月7日:毕业设计进度
    2月6日:毕业设计进度
    2月5日:毕业设计进度
  • 原文地址:https://www.cnblogs.com/tony1224/p/2413622.html
Copyright © 2020-2023  润新知