initial commit

This commit is contained in:
2026-04-12 22:20:18 +08:00
commit 190c2edbb2
155 changed files with 36314 additions and 0 deletions

197
rtl/ip/open-la500/mul.v Normal file
View File

@@ -0,0 +1,197 @@
module YDecoder(
input yc, yb, ya, //c -> i+1; b -> i; a -> i-1
output negx, x, neg2x, _2x
);
assign negx = (yc & yb & ~ya) | (yc & ~yb & ya);
assign x = (~yc & ~yb & ya) | (~yc & yb & ~ya);
assign neg2x = (yc & ~yb & ~ya);
assign _2x = (~yc & yb & ya);
endmodule
module BoothBase(
input negx, x, neg2x, _2x,
input InX,
input PosLastX, NegLastX,
output PosNextX, NegNextX,
output OutX
);
assign OutX = (negx & ~InX) | (x & InX) | (neg2x & NegLastX) | (_2x & PosLastX);
assign PosNextX = InX;
assign NegNextX = ~InX;
endmodule
module BoothInterBase(
input [2:0] y,
input [63:0] InX,
output [63:0] OutX,
output Carry
);
wire negx, x, neg2x, _2x;
wire [1:0] CarrySig [64:0];
YDecoder uu(.yc(y[2]), .yb(y[1]), .ya(y[0]), .negx(negx), .x(x), .neg2x(neg2x), ._2x(_2x));
BoothBase fir(.negx(negx), .x(x), .neg2x(neg2x), ._2x(_2x), .InX(InX[0]), .PosLastX(1'b0), .NegLastX(1'b1), .PosNextX(CarrySig[1][0]), .NegNextX(CarrySig[1][1]), .OutX(OutX[0]));
generate
genvar i;
for (i=1; i<64; i=i+1) begin: gfor
BoothBase ui(
.negx(negx),
.x(x),
.neg2x(neg2x),
._2x(_2x),
.InX(InX[i]),
.PosLastX(CarrySig[i][0]),
.NegLastX(CarrySig[i][1]),
.PosNextX(CarrySig[i+1][0]),
.NegNextX(CarrySig[i+1][1]),
.OutX(OutX[i])
);
end
endgenerate
assign Carry = negx || neg2x;
endmodule
module addr(
input A, B, C,
output Carry, S
);
assign S = ~A & ~B & C | ~A & B & ~C | A & ~B & ~C | A & B & C;
assign Carry = A & B | A & C | B & C;
endmodule
module WallaceTreeBase(
input [16:0] InData,
input [13:0] CIn,
output [13:0] COut,
output C, S
);
//first stage
wire [4:0] FirSig;
addr first1(.A(InData[4]), .B(InData[3]), .C(InData[2]), .Carry(COut[0]), .S(FirSig[0]));
addr first2(.A(InData[7]), .B(InData[6]), .C(InData[5]), .Carry(COut[1]), .S(FirSig[1]));
addr first3(.A(InData[10]), .B(InData[9]), .C(InData[8]), .Carry(COut[2]), .S(FirSig[2]));
addr first4(.A(InData[13]), .B(InData[12]), .C(InData[11]), .Carry(COut[3]), .S(FirSig[3]));
addr first5(.A(InData[16]), .B(InData[15]), .C(InData[14]), .Carry(COut[4]), .S(FirSig[4]));
//second stage
wire [3:0] SecSig;
addr second1(.A(CIn[2]), .B(CIn[1]), .C(CIn[0]), .Carry(COut[5]), .S(SecSig[0]));
addr second2(.A(InData[0]), .B(CIn[4]), .C(CIn[3]), .Carry(COut[6]), .S(SecSig[1]));
addr second3(.A(FirSig[1]), .B(FirSig[0]), .C(InData[1]), .Carry(COut[7]), .S(SecSig[2]));
addr second4(.A(FirSig[4]), .B(FirSig[3]), .C(FirSig[2]), .Carry(COut[8]), .S(SecSig[3]));
//third stage
wire [1:0] ThiSig;
addr third1(.A(SecSig[0]), .B(CIn[6]), .C(CIn[5]), .Carry(COut[9]), .S(ThiSig[0]));
addr third2(.A(SecSig[3]), .B(SecSig[2]), .C(SecSig[1]), .Carry(COut[10]), .S(ThiSig[1]));
//fourth stage
wire [1:0] ForSig;
addr fourth1(.A(CIn[9]), .B(CIn[8]), .C(CIn[7]), .Carry(COut[11]), .S(ForSig[0]));
addr fourth2(.A(ThiSig[1]), .B(ThiSig[0]), .C(CIn[10]), .Carry(COut[12]), .S(ForSig[1]));
//fifth stage
wire FifSig;
addr fifth1(.A(ForSig[1]), .B(ForSig[0]), .C(CIn[11]), .Carry(COut[13]), .S(FifSig));
//sixth stage
addr sixth1(.A(FifSig), .B(CIn[13]), .C(CIn[12]), .Carry(C), .S(S));
endmodule
//-------------------------------------------------------------------------------------------------------------------
module mul(
input mul_clk, reset,
input mul_signed,
input [31:0] x, y, //x扩展至64位 y扩展至33位 区别有无符号
output [63:0] result
);
wire [63:0] CalX;
wire [32:0] CalY;
assign CalX = mul_signed ? {{32{x[31]}}, x} : {32'b0, x};
assign CalY = mul_signed ? {y[31], y} : {1'b0, y};
//booth
wire [16:0] Carry; //booth计算得到的进位
wire [63:0] BoothRes [16:0]; //booth的计算结果
BoothInterBase fir(.y({CalY[1], CalY[0], 1'b0}), .InX(CalX), .OutX(BoothRes[0]), .Carry(Carry[0]));
generate
genvar i;
for (i=2; i<32; i=i+2) begin: boothfor
BoothInterBase ai(
.y(CalY[i+1:i-1]),
.InX(CalX<<i),
.OutX(BoothRes[i>>1]),
.Carry(Carry[i>>1])
);
end
endgenerate
BoothInterBase las(.y({CalY[32], CalY[32], CalY[31]}), .InX(CalX<<32), .OutX(BoothRes[16]), .Carry(Carry[16]));
reg [16:0] SecStageCarry;
reg [63:0] SecStageBoothRes [16:0];
integer p;
always @(posedge mul_clk) begin
if (~reset) begin
SecStageCarry <= Carry;
for(p=0; p<17; p=p+1) begin
SecStageBoothRes[p] <= BoothRes[p];
end
end
end
//wallace
wire [13:0] WallaceInter [64:0];
wire [63:0] COut, SOut;
WallaceTreeBase firs(
.InData({SecStageBoothRes[0][0], SecStageBoothRes[1][0], SecStageBoothRes[2][0], SecStageBoothRes[3][0], SecStageBoothRes[4][0], SecStageBoothRes[5][0], SecStageBoothRes[6][0],
SecStageBoothRes[7][0], SecStageBoothRes[8][0], SecStageBoothRes[9][0], SecStageBoothRes[10][0], SecStageBoothRes[11][0], SecStageBoothRes[12][0], SecStageBoothRes[13][0], SecStageBoothRes[14][0],
SecStageBoothRes[15][0], SecStageBoothRes[16][0]}),
.CIn(SecStageCarry[13:0]),
.COut(WallaceInter[1]),
.C(COut[0]),
.S(SOut[0])
);
generate
genvar n;
for (n=1; n<64; n=n+1) begin: wallacefor
WallaceTreeBase bi(
.InData({SecStageBoothRes[0][n], SecStageBoothRes[1][n], SecStageBoothRes[2][n], SecStageBoothRes[3][n], SecStageBoothRes[4][n], SecStageBoothRes[5][n], SecStageBoothRes[6][n],
SecStageBoothRes[7][n], SecStageBoothRes[8][n], SecStageBoothRes[9][n], SecStageBoothRes[10][n], SecStageBoothRes[11][n], SecStageBoothRes[12][n], SecStageBoothRes[13][n], SecStageBoothRes[14][n],
SecStageBoothRes[15][n], SecStageBoothRes[16][n]}),
.CIn(WallaceInter[n]),
.COut(WallaceInter[n+1]),
.C(COut[n]),
.S(SOut[n])
);
end
endgenerate
//64bit add
assign result = SOut + {COut[62:0], SecStageCarry[14]} + SecStageCarry[15];
endmodule