integer i,j,k; always@(A or B) begin //在模块内将一维转二维,方便计算 for(i=0;i<16;i=i+1) begin for(j=0;j<16;j=j+1) begin A1[i][j]=A[i*16*16+j*16+:16]; B1[i][j]=B[i*16*16+j*16+:16]; end end //初始化结果为0 for(i=0;i<16;i=i+1) begin for(j=0;j<16;j=j+1) begin Res1[i][j]=31'd0; end end //使用矩阵相乘的定义计算Res1矩阵的结果 //Res1[i][j]是A的第i行和B的第j列相乘再相加的结果 for(i=0;i<16;i=i+1)begin for(j=0;j<16;j=j+1)begin for(k=0;k<16;k=k+1)begin //A1[i][k]和B1[k][j]都是补码形式的有符号定点数 //A[补码]*B[补码]=(A*B)[补码] Res1[i][j]=Res1[i][j]+A1[i][k]*B1[k][j]; end end end //将二维转回一维,将Res1[0][0]存储在reg_result的最高位,Res[i][j]前面有i*16+j个数据,每个31位,因此转为1维的索引是 //16*16*31-1-(i*16+j)*31 //这里涉及到一个语法:A[7:3]和A[7-:4]是等价的 同理A[0+:3]和A[0:2]等价 for(i=0;i<16;i=i+1)begin for(j=0;j<16;j=j+1)begin //When 2d converted to 1d,it is stored from high bit to low bit. reg_result[16*16*31-1-((i*16+j)*31) -: 31]=Res1[i][j]; end end end assign Result=reg_result; endmodule
//2d to 1d for(i=0;i<16;i=i+1) begin for(j=0;j<16;j=j+1) begin I_16_1d[i*16*16+j*16+:16]=I_16_2d[i][j]; W0_1d[i*16*16+j*16+:16]=W0_2d[i][j]; W1_1d[i*16*16+j*16+:16]=W1_2d[i][j]; W2_1d[i*16*16+j*16+:16]=W2_2d[i][j]; W3_1d[i*16*16+j*16+:16]=W3_2d[i][j]; W4_1d[i*16*16+j*16+:16]=W4_2d[i][j]; W5_1d[i*16*16+j*16+:16]=W5_2d[i][j]; W6_1d[i*16*16+j*16+:16]=W6_2d[i][j]; W7_1d[i*16*16+j*16+:16]=W7_2d[i][j]; I0_16_2d[i][j]=16'b0; I1_16_2d[i][j]=16'b0; I2_16_2d[i][j]=16'b0; I3_16_2d[i][j]=16'b0; I4_16_2d[i][j]=16'b0; I5_16_2d[i][j]=16'b0; I6_16_2d[i][j]=16'b0; I7_16_2d[i][j]=16'b0; end end #20 for(i=0;i<16;i=i+1)begin for(j=0;j<16;j=j+1)begin I0_31_2d[i][j]=I0_31_1d[16*16*31-1-((i*16+j)*31) -: 31]; //截断处理: //1.1先赋值符号位 I0_16_2d[i][j][15]=I0_31_2d[i][j][30]; //1.2考虑低位截断(含有四舍五入) if(I0_31_2d[i][j][8]==1'b1)begin I0_31_2d[i][j][29:9]=I0_31_2d[i][j][29:9]+1; end //1.3考虑高位饱和(上溢、下溢、截断) if(I0_31_2d[i][j][30]==1'b0&&I0_31_2d[i][j][29:18]>=64) begin I0_16_2d[i][j][14:9]=6'b111_111; end elseif(I0_31_2d[i][j][30]==1'b1&&I0_31_2d[i][j][29:24]!=63)begin I0_16_2d[i][j][14:9]=6'b000_000; end else begin I0_16_2d[i][j][14:0]=I0_31_2d[i][j][23:9]; end end end for(i=0;i<16;i=i+1) begin for(j=0;j<16;j=j+1) begin I0_16_1d[i*16*16+j*16+:16]=I0_16_2d[i][j]; end end #20 //I1截断处理 for(i=0;i<16;i=i+1)begin for(j=0;j<16;j=j+1)begin I1_31_2d[i][j]=I1_31_1d[16*16*31-1-((i*16+j)*31) -: 31]; //先赋值符号位 I1_16_2d[i][j][15]=I1_31_2d[i][j][30]; //考虑截断(含有四舍五入) //这里其实只考虑了为1时向前进位,但实际上符号位为1时是不用进位的,原理见前面的低位截断分析 if(I1_31_2d[i][j][8]==1'b1)begin I1_31_2d[i][j][29:9]=I1_31_2d[i][j][29:9]+1; end //再考虑饱和(上溢、下溢和截断) if(I1_31_2d[i][j][30]==1'b0&&I1_31_2d[i][j][29:18]>=64) begin I1_16_2d[i][j][14:9]=6'b111_111; end elseif(I1_31_2d[i][j][30]==1'b1&&I1_31_2d[i][j][29:24]!=63)begin I1_16_2d[i][j][14:9]=6'b000_000; end else begin I1_16_2d[i][j][14:0]=I1_31_2d[i][j][23:9]; end end end
for(i=0;i<16;i=i+1) begin for(j=0;j<16;j=j+1) begin I1_16_1d[i*16*16+j*16+:16]=I1_16_2d[i][j]; end end
#20 //I2截断处理 for(i=0;i<16;i=i+1)begin for(j=0;j<16;j=j+1)begin I2_31_2d[i][j]=I2_31_1d[16*16*31-1-((i*16+j)*31) -: 31]; //先赋值符号位 I2_16_2d[i][j][15]=I2_31_2d[i][j][30]; //考虑截断(含有四舍五入) if(I2_31_2d[i][j][8]==1'b1)begin I2_31_2d[i][j][29:9]=I2_31_2d[i][j][29:9]+1; end //再考虑饱和(上溢、下溢和截断) if(I2_31_2d[i][j][30]==1'b0&&I2_31_2d[i][j][29:18]>=64) begin I2_16_2d[i][j][14:9]=6'b111_111; end elseif(I2_31_2d[i][j][30]==1'b1&&I2_31_2d[i][j][29:24]!=63)begin I2_16_2d[i][j][14:9]=6'b000_000; end else begin I2_16_2d[i][j][14:0]=I2_31_2d[i][j][23:9]; end end end
for(i=0;i<16;i=i+1) begin for(j=0;j<16;j=j+1) begin I2_16_1d[i*16*16+j*16+:16]=I2_16_2d[i][j]; end end #20 //I3截断处理 for(i=0;i<16;i=i+1)begin for(j=0;j<16;j=j+1)begin I3_31_2d[i][j]=I3_31_1d[16*16*31-1-((i*16+j)*31) -: 31]; //先赋值符号位 I3_16_2d[i][j][15]=I3_31_2d[i][j][30]; //考虑截断(含有四舍五入) if(I3_31_2d[i][j][8]==1'b1)begin I3_31_2d[i][j][29:9]=I3_31_2d[i][j][29:9]+1; end //再考虑饱和(上溢、下溢和截断) if(I3_31_2d[i][j][30]==1'b0&&I3_31_2d[i][j][29:18]>=64) begin I3_16_2d[i][j][14:9]=6'b111_111; end elseif(I3_31_2d[i][j][30]==1'b1&&I3_31_2d[i][j][29:24]!=63)begin I3_16_2d[i][j][14:9]=6'b000_000; end else begin I3_16_2d[i][j][14:0]=I3_31_2d[i][j][23:9]; end end end
for(i=0;i<16;i=i+1) begin for(j=0;j<16;j=j+1) begin I3_16_1d[i*16*16+j*16+:16]=I3_16_2d[i][j]; end end #20 //I4截断处理 for(i=0;i<16;i=i+1)begin for(j=0;j<16;j=j+1)begin I4_31_2d[i][j]=I4_31_1d[16*16*31-1-((i*16+j)*31) -: 31]; //先赋值符号位 I4_16_2d[i][j][15]=I4_31_2d[i][j][30]; //考虑截断(含有四舍五入) if(I4_31_2d[i][j][8]==1'b1)begin I4_31_2d[i][j][29:9]=I4_31_2d[i][j][29:9]+1; end //再考虑饱和(上溢、下溢和截断) if(I4_31_2d[i][j][30]==1'b0&&I4_31_2d[i][j][29:18]>=64) begin I4_16_2d[i][j][14:9]=6'b111_111; end elseif(I4_31_2d[i][j][30]==1'b1&&I4_31_2d[i][j][29:24]!=63)begin I4_16_2d[i][j][14:9]=6'b000_000; end else begin I4_16_2d[i][j][14:0]=I4_31_2d[i][j][23:9]; end end end
for(i=0;i<16;i=i+1) begin for(j=0;j<16;j=j+1) begin I4_16_1d[i*16*16+j*16+:16]=I4_16_2d[i][j]; end end
#20 //I5截断处理 for(i=0;i<16;i=i+1)begin for(j=0;j<16;j=j+1)begin I5_31_2d[i][j]=I5_31_1d[16*16*31-1-((i*16+j)*31) -: 31]; //先赋值符号位 I5_16_2d[i][j][15]=I5_31_2d[i][j][30]; //考虑截断(含有四舍五入) if(I5_31_2d[i][j][8]==1'b1)begin I5_31_2d[i][j][29:9]=I5_31_2d[i][j][29:9]+1; end //再考虑饱和(上溢、下溢和截断) if(I5_31_2d[i][j][30]==1'b0&&I5_31_2d[i][j][29:18]>=64) begin I5_16_2d[i][j][14:9]=6'b111_111; end elseif(I5_31_2d[i][j][30]==1'b1&&I5_31_2d[i][j][29:24]!=63)begin I5_16_2d[i][j][14:9]=6'b000_000; end else begin I5_16_2d[i][j][14:0]=I5_31_2d[i][j][23:9]; end end end
for(i=0;i<16;i=i+1) begin for(j=0;j<16;j=j+1) begin I5_16_1d[i*16*16+j*16+:16]=I5_16_2d[i][j]; end end #20 //I6截断处理 for(i=0;i<16;i=i+1)begin for(j=0;j<16;j=j+1)begin I6_31_2d[i][j]=I6_31_1d[16*16*31-1-((i*16+j)*31) -: 31]; //先赋值符号位 I6_16_2d[i][j][15]=I6_31_2d[i][j][30]; //考虑截断(含有四舍五入) if(I6_31_2d[i][j][8]==1'b1)begin I6_31_2d[i][j][29:9]=I6_31_2d[i][j][29:9]+1; end //再考虑饱和(上溢、下溢和截断) if(I6_31_2d[i][j][30]==1'b0&&I6_31_2d[i][j][29:18]>=64) begin I6_16_2d[i][j][14:9]=6'b111_111; end elseif(I6_31_2d[i][j][30]==1'b1&&I6_31_2d[i][j][29:24]!=63)begin I6_16_2d[i][j][14:9]=6'b000_000; end else begin I6_16_2d[i][j][14:0]=I6_31_2d[i][j][23:9]; end end end
for(i=0;i<16;i=i+1) begin for(j=0;j<16;j=j+1) begin I6_16_1d[i*16*16+j*16+:16]=I6_16_2d[i][j]; end end #20 //I7截断处理 for(i=0;i<16;i=i+1)begin for(j=0;j<16;j=j+1)begin I7_31_2d[i][j]=I7_31_1d[16*16*31-1-((i*16+j)*31) -: 31]; //先赋值符号位 I7_16_2d[i][j][15]=I7_31_2d[i][j][30]; //考虑截断(含有四舍五入) if(I7_31_2d[i][j][8]==1'b1)begin I7_31_2d[i][j][29:9]=I7_31_2d[i][j][29:9]+1; end //再考虑饱和(上溢、下溢和截断) if(I7_31_2d[i][j][30]==1'b0&&I7_31_2d[i][j][29:18]>=64) begin I7_16_2d[i][j][14:9]=6'b111_111; end elseif(I7_31_2d[i][j][30]==1'b1&&I7_31_2d[i][j][29:24]!=63)begin I7_16_2d[i][j][14:9]=6'b000_000; end else begin I7_16_2d[i][j][14:0]=I7_31_2d[i][j][23:9]; end end end
#20 for(i=0;i<16;i=i+1) begin for(j=0;j<16;j=j+1) begin I7_16_1d[i*16*16+j*16+:16]=I7_16_2d[i][j]; end end