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