📄 mult.v
字号:
end
//---------------------------------------
// lower 31bit of A (input to Multiplier)
//---------------------------------------
always @(A or SIZE)
begin
if (SIZE == 1'b0)
AH <= {16'h0000,A[14:0]};
else
AH <= A[30:0];
end
//---------------------------------------
// upper/lower of B (input to Multiplier)
//---------------------------------------
always @(B or SHIFT or SIZE)
begin
if (SIZE == 1'b0)
BH <= {1'b0,B[14:0]};
else if (SHIFT == 1'b0)
BH <= B[15:0];
else
BH <= {1'b0,B[30:16]};
end
//-----------
// Multiplier
//----------
always @(AH or BH)
begin
ABH[46:0] <= AH[30:0] * BH[15:0]; // 31bit * 16bit -> 47bit
end
//---
// PM
//---
always @(SHIFT or SIZE or A or B)
begin
if (SHIFT)
begin
P2 <= {1'b0, (A[31])? B[30:0]:31'h00000000};
P3 <= {1'b0, (B[31])? A[30:0]:31'h00000000};
end
else if(~SIZE)
begin
P2 <= {17'h00000, (A[15])? B[14:0]:15'h0000};
P3 <= {17'h00000, (B[15])? A[14:0]:15'h0000};
end
else
begin
P2 <= 32'h00000000;
P3 <= 32'h00000000;
end
end
always @(P2 or P3)
begin
P23 <= P2 + P3;
end
always @(ABH or SHIFT or SIZE or A or B)
begin
if (SIZE == 1'b0)
ABH2 <= {17'h00000,(A[15] & B[15]),ABH[29:15]};
else if (SHIFT == 1'b0)
ABH2 <= {1'b0, ABH[46:15]};
else
ABH2 <= {1'b0,(A[31] & B[31]),ABH[45:15]};
end
always @(P23 or SIGN)
begin
if (SIGN == 1'b0)
P23S <= {1'b0, P23};
else
P23S <= {1'b1,~P23};
end
always @(P23S or ABH or ABH2 or SIGN)
begin
PM[47:15] <= ABH2[32:0] + P23S + SIGN;
PM[14: 0] <= ABH[14: 0];
end
//---------
// Select C
//---------
always @(PM or SHIFT or SIZE)
begin
if (SHIFT == 1'b0)
if (~SIZE & PM[47])
C <= {16'hffff, PM};
else
C <= {16'h0000, PM};
else
C <= {PM, 16'h0000};
end
//-------------------------------------
// 64bit ADDER with Satulating function
//-------------------------------------
//
// Essential of Saturate Operation [ MAC[64] + C[64] ]
//
// +S | Left plane shows value of MAC.
// \ | "+S" is + side saturate value (ex.00007FFF).
// \ <P> "-S" is - side saturate value (ex.FFFF8000).
// <P'> \ | Addition of plus C rotates MAC value counterclockwise.
// \ | Addition of minus C rotates MAC value clockwise.
// 7F.. \| 00..
// ------------------- Region<M'> : MAC=80000000~FFFF7FFF
// 80.. /| FF.. Region<M > : MAC=FFFF8000~FFFFFFFF
// / | Region<P > : MAC=00000000~00007FFF
// <M'> / | Region<P'> : MAC=00008000~7FFFFFFF
// / <M>
// / | Note that initial MAC value may be in any region.
// -S | And value C may also be 00000000~FFFFFFFF.
//
// ===========================================
// Initial_MAC Rotation(C) MAC+C Result_MAC
// ===========================================
// P + P OK
// P + P' 00007FFF
// P + M' 00007FFF
// P + M 00007FFF
// -------------------------------------------
// P' + P 00007FFF Impossible
// P' + P' 00007FFF
// P' + M' 00007FFF
// P' + M 00007FFF
// -------------------------------------------
// M' + P OK
// M' + P' 00007FFF Imposible
// M' + M' FFFF8000
// M' + M OK
// -------------------------------------------
// M + P OK
// M + P' 00007FFF
// M + M' 00007FFF Impossible
// M + M OK
// ===========================================
// P - P OK
// P - P' FFFF8000 Impossible
// P - M' FFFF8000
// P - M OK
// -------------------------------------------
// P' - P OK
// P' - P' 00007FFF
// P' - M' FFFF8000 Impossible
// P' - M OK
// -------------------------------------------
// M' - P FFFF8000
// M' - P' FFFF8000
// M' - M' FFFF8000
// M' - M FFFF8000 Impossible
// -------------------------------------------
// M - P FFFF8000
// M - P' FFFF8000
// M - M' FFFF8000
// M - M OK
// ===========================================
// Again, Compactly...
// ===========================================
// Initial_MAC Rotation(C) MAC+C Result_MAC
// ===========================================
// P /M +/- P /M OK
// P /M +/- P'/M' 00007FFF/FFFF8000
// P /M +/- M'/P' 00007FFF/FFFF8000
// P /M +/- M /P 00007FFF/FFFF8000
// -------------------------------------------
// P'/M' +/- P /M Impossible = Don't care
// P'/M' +/- P'/M' 00007FFF/FFFF8000
// P'/M' +/- M'/P' 00007FFF/FFFF8000
// P'/M' +/- M /P 00007FFF/FFFF8000
// -------------------------------------------
// M'/P' +/- P /M OK
// M'/P' +/- P'/M' Impossible = Don't care
// M'/P' +/- M'/P' FFFF8000/00007FFF <--caution !
// M'/P' +/- M /P OK
// -------------------------------------------
// M /P +/- P /M OK
// M /P +/- P'/M' 00007FFF/FFFF8000
// M /P +/- M'/P' Impossible = Don't care
// M /P +/- M /P OK
// ===========================================
// Again, Much Compactly...
// ===========================================
// Initial_MAC Rotation(C) MAC+C Result_MAC
// ===========================================
// P /M +/- P /M OK
// P /M +/- P'/M' 00007FFF/FFFF8000
// P /M +/- - /+ 00007FFF/FFFF8000
// -------------------------------------------
// P'/M' +/- P /M Impossible = Don't care
// P'/M' +/- P'/M' 00007FFF/FFFF8000
// P'/M' +/- - /+ 00007FFF/FFFF8000
// -------------------------------------------
// M'/P' +/- P /M OK
// - /+ +/- M'/P' FFFF8000/00007FFF <--caution !
// M'/P' +/- M /P OK
// -------------------------------------------
// M /P +/- P /M OK
// - /+ +/- P'/M' 00007FFF/FFFF8000
// M /P +/- M /P OK
// ===========================================
// Again, Much Compactly...
// ===========================================
// Initial_MAC Rotation(C) MAC+C Result_MAC
// ===========================================
// + /- +/- P /M OK
// + /- +/- P'/M' 00007FFF/FFFF8000
// + /- +/- - /+ 00007FFF/FFFF8000
// -------------------------------------------
// - /+ +/- P /M OK
// - /+ +/- M'/P' FFFF8000/00007FFF <--caution !
// - /+ +/- M /P OK
// - /+ +/- P'/M' 00007FFF/FFFF8000
// ===========================================
// Again, Much Compactly...
// ===========================================
// Initial_MAC Rotation(C) MAC+C Result_MAC
// ===========================================
// * /* +/- P /M OK
// * /* +/- P'/M' 00007FFF/FFFF8000
// + /- +/- - /+ 00007FFF/FFFF8000
// - /+ +/- M'/P' FFFF8000/00007FFF <--caution !
// - /+ +/- M /P OK
// ===========================================
always @(C or MACH or MACL or ZH)
begin
ADDRESULT <= C + {((ZH == 1'b0) ? MACH : 32'h00000000), MACL};
end
reg [1:0] RESULT_REGION48; //00:P, 01:P', 10:M, 11:M'
reg RESULT_REGION32; //0:P, 1:M, No P'/M' region in case of 32bit saturation.
always @(ADDRESULT)
begin
RESULT_REGION48[1] <= ADDRESULT[63];
RESULT_REGION32 <= ADDRESULT[31];
if (ADDRESULT[63] == 1'b0)
//RESULT_REGION48[0] <= (ADDRESULT[63:47] >= 17'h00001);
RESULT_REGION48[0] <= (ADDRESULT[63:47] != 17'h00000);
else
//RESULT_REGION48[0] <= (ADDRESULT[63:47] <= 17'hFFFFE);
RESULT_REGION48[0] <= (ADDRESULT[63:47] != 17'hFFFFF);
end
always @(ADDRESULT or C or MACH or MACL or ADD or RESULT_REGION48 or RESULT_REGION32)
begin
case(ADD)
2'b00 : begin // ADD
ADDRESULT2 <= ADDRESULT;
SAT <= 1'b0;
end
2'b10 : begin // ADDS48
if (~C[63]) // + rotation
case ({MACH[31], RESULT_REGION48})
3'b000 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //+,P
3'b001 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,P'
3'b010 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,M
3'b011 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,M'
3'b100 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //-,P
3'b101 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //-,P'
3'b110 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //-,M
3'b111 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,M'
default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
endcase
else // - rotation
case ({MACH[31], RESULT_REGION48})
3'b000 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //+,P
3'b001 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,P'
3'b010 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //+,M
3'b011 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //+,M'
3'b100 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,P
3'b101 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,P'
3'b110 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //-,M
3'b111 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,M'
default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
endcase
end
2'b11 : begin // ADDS32
if (~C[31]) // + rotation
case ({MACL[31], RESULT_REGION32})
2'b00 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //+,P
2'b01 : {ADDRESULT2,SAT} <= {64'h000000007FFFFFFF,1'b1}; //+,M
2'b10 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //-,P
2'b11 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //-,M
default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
endcase
else // - rotation
case ({MACL[31], RESULT_REGION32})
2'b00 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //+,P
2'b01 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //+,M
2'b10 : {ADDRESULT2,SAT} <= {64'hFFFFFFFF80000000,1'b1}; //-,P
2'b11 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0}; //-,M
default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
endcase
end
default : begin
ADDRESULT2 <= 64'hxxxxxxxxxxxxxxxx;
SAT <= 1'b0;
end
endcase
end
//-----
// MACH
//-----
// Clear condition of MACH: following command do not clear MACH
// MAC.L 1 0001111 8F
// MAC.W 1 1001111 CF
// MUL.L 1 0000111 87
// MULS.W 1 0101111 AF
// MULU.W 1 0101110 AE
// Should do saturating operation
always @(posedge CLK)
begin
if (SLOT & WRMACH)
MACH <= MACIN1;
else if (SLOT & MULCOM2[7]
& (MULCOM2[5:0] != 6'b001111)
& (MULCOM2[6:0] != 7'b0000111)
& (MULCOM2[6:0] != 7'b0101111)
& (MULCOM2[6:0] != 7'b0101110)
)
begin
MACH <= 32'h00000000;
end
else if ((STATE == `MACWS) && (SAT == 1'b1))
begin
MACH <= MACH | 32'h00000001;
end
else if (LATMACH == 1'b1)
begin
MACH <= ADDRESULT2[63:32];
end
end
//-----
// MACL
//-----
// Clear condition of MACL: following command do not clear MACL
// MAC.L 1 0001111 8F
// MAC.W 1 1001111 CF
always @(posedge CLK)
begin
if (SLOT & WRMACL)
MACL <= MACIN2;
else if (SLOT & MULCOM2[7] & (MULCOM2[5:0] != 6'b001111))
begin
MACL <= 32'h00000000;
end
else if (LATMACL == 1'b1)
begin
MACL <= ADDRESULT2[31:0];
end
end
//======================================================
endmodule
//======================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -