Merge branch 'openhwgroup:main' into main

This commit is contained in:
Alexa Wright 2023-04-03 14:30:54 -07:00 committed by GitHub
commit 803fee5903
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 569 additions and 220 deletions

38
src/cache/cache.sv vendored
View File

@ -96,8 +96,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache; logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache;
logic SelFetchBuffer; logic SelFetchBuffer;
logic CacheEn; logic CacheEn;
logic [CACHEWORDSPERLINE-1:0] MemPAdrDecoded; logic [LINELEN/8-1:0] LineByteMask;
logic [LINELEN/8-1:0] LineByteMask, DemuxedByteMask, FetchBufferByteSel;
logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr; logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr;
genvar index; genvar index;
@ -161,21 +160,30 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Write Path // Write Path
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
if(!READ_ONLY_CACHE) begin:WriteSelLogic
logic [CACHEWORDSPERLINE-1:0] MemPAdrDecoded;
logic [LINELEN/8-1:0] DemuxedByteMask, FetchBufferByteSel;
// Adjust byte mask from word to cache line // Adjust byte mask from word to cache line
onehotdecoder #(LOGCWPL) adrdec(.bin(PAdr[LOGCWPL+LOGLLENBYTES-1:LOGLLENBYTES]), .decoded(MemPAdrDecoded)); onehotdecoder #(LOGCWPL) adrdec(.bin(PAdr[LOGCWPL+LOGLLENBYTES-1:LOGLLENBYTES]), .decoded(MemPAdrDecoded));
for(index = 0; index < 2**LOGCWPL; index++) begin for(index = 0; index < 2**LOGCWPL; index++) begin
assign DemuxedByteMask[(index+1)*(WORDLEN/8)-1:index*(WORDLEN/8)] = MemPAdrDecoded[index] ? ByteMask : '0; assign DemuxedByteMask[(index+1)*(WORDLEN/8)-1:index*(WORDLEN/8)] = MemPAdrDecoded[index] ? ByteMask : '0;
end
assign FetchBufferByteSel = SetValid & ~SetDirty ? '1 : ~DemuxedByteMask; // If load miss set all muxes to 1.
// Merge write data into fetched cache line for store miss
for(index = 0; index < LINELEN/8; index++) begin
mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]),
.d1(FetchBuffer[8*index+7:8*index]), .s(FetchBufferByteSel[index]), .y(LineWriteData[8*index+7:8*index]));
end
assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0;
end end
assign FetchBufferByteSel = SetValid & ~SetDirty ? '1 : ~DemuxedByteMask; // If load miss set all muxes to 1. else
assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0; begin:WriteSelLogic
// No need for this mux if the cache does not handle writes.
// Merge write data into fetched cache line for store miss assign LineWriteData = FetchBuffer;
for(index = 0; index < LINELEN/8; index++) begin assign LineByteMask = '1;
mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]), end
.d1(FetchBuffer[8*index+7:8*index]), .s(FetchBufferByteSel[index]), .y(LineWriteData[8*index+7:8*index]));
end
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Flush logic // Flush logic
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -98,7 +98,9 @@ module cacheLRU
assign LRUUpdate[t1] = LRUUpdate[s] & WayEncoded[r]; assign LRUUpdate[t1] = LRUUpdate[s] & WayEncoded[r];
end end
mux2 #(1) LRUMuxes[NUMWAYS-2:0](CurrLRU, ~WayExpanded, LRUUpdate, NextLRU); // The root node of the LRU tree will always be selected in LRUUpdate. No mux needed.
assign NextLRU[NUMWAYS-2] = ~WayExpanded[NUMWAYS-2];
mux2 #(1) LRUMuxes[NUMWAYS-3:0](CurrLRU[NUMWAYS-3:0], ~WayExpanded[NUMWAYS-3:0], LRUUpdate[NUMWAYS-3:0], NextLRU[NUMWAYS-3:0]);
// Compute next victim way. // Compute next victim way.
for(s = NUMWAYS-2; s >= NUMWAYS/2; s--) begin for(s = NUMWAYS-2; s >= NUMWAYS/2; s--) begin
@ -128,8 +130,8 @@ module cacheLRU
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
if (reset) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0; if (reset) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0;
if(CacheEn) begin if(CacheEn) begin
if((InvalidateCache | FlushCache) & ~FlushStage) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0; // if((InvalidateCache | FlushCache) & ~FlushStage) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0;
else if (LRUWriteEn & ~FlushStage) begin if (LRUWriteEn & ~FlushStage) begin
LRUMemory[PAdr] <= NextLRU; LRUMemory[PAdr] <= NextLRU;
end end
if(LRUWriteEn & ~FlushStage & (PAdr == CacheSet)) if(LRUWriteEn & ~FlushStage & (PAdr == CacheSet))

View File

@ -37,14 +37,13 @@ module alu #(parameter WIDTH=32) (
input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
input logic [2:0] ZBBSelect, // ZBB mux select signal input logic [2:0] ZBBSelect, // ZBB mux select signal
input logic [2:0] Funct3, // For BMU decoding input logic [2:0] Funct3, // For BMU decoding
input logic CompLT, // Less-Than flag from comparator
input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage
output logic [WIDTH-1:0] Result, // ALU result output logic [WIDTH-1:0] ALUResult, // ALU result
output logic [WIDTH-1:0] Sum); // Sum of operands output logic [WIDTH-1:0] Sum); // Sum of operands
// CondInvB = ~B when subtracting, B otherwise. Shift = shift result. SLT/U = result of a slt/u instruction. // CondInvB = ~B when subtracting, B otherwise. Shift = shift result. SLT/U = result of a slt/u instruction.
// FullResult = ALU result before adjusting for a RV64 w-suffix instruction. // FullResult = ALU result before adjusting for a RV64 w-suffix instruction.
logic [WIDTH-1:0] CondMaskInvB, Shift, FullResult, ALUResult; // Intermediate Signals logic [WIDTH-1:0] CondMaskInvB, Shift, FullResult, PreALUResult; // Intermediate Signals
logic [WIDTH-1:0] CondMaskB; // Result of B mask select mux logic [WIDTH-1:0] CondMaskB; // Result of B mask select mux
logic [WIDTH-1:0] CondShiftA; // Result of A shifted select mux logic [WIDTH-1:0] CondShiftA; // Result of A shifted select mux
logic [WIDTH-1:0] CondExtA; // Result of Zero Extend A select mux logic [WIDTH-1:0] CondExtA; // Result of Zero Extend A select mux
@ -84,16 +83,16 @@ module alu #(parameter WIDTH=32) (
end end
// Support RV64I W-type addw/subw/addiw/shifts that discard upper 32 bits and sign-extend 32-bit result to 64 bits // Support RV64I W-type addw/subw/addiw/shifts that discard upper 32 bits and sign-extend 32-bit result to 64 bits
if (WIDTH == 64) assign ALUResult = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult; if (WIDTH == 64) assign PreALUResult = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult;
else assign ALUResult = FullResult; else assign PreALUResult = FullResult;
// Final Result B instruction select mux // Final Result B instruction select mux
if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : bitmanipalu if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : bitmanipalu
bitmanipalu #(WIDTH) balu(.A, .B, .W64, .BSelect, .ZBBSelect, bitmanipalu #(WIDTH) balu(.A, .B, .W64, .BSelect, .ZBBSelect,
.Funct3, .CompLT, .BALUControl, .ALUResult, .FullResult, .Funct3, .LT,.LTU, .BALUControl, .PreALUResult, .FullResult,
.CondMaskB, .CondShiftA, .Result); .CondMaskB, .CondShiftA, .ALUResult);
end else begin end else begin
assign Result = ALUResult; assign ALUResult = PreALUResult;
assign CondMaskB = B; assign CondMaskB = B;
assign CondShiftA = A; assign CondShiftA = A;
end end

View File

@ -35,12 +35,13 @@ module bitmanipalu #(parameter WIDTH=32) (
input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
input logic [2:0] ZBBSelect, // ZBB mux select signal input logic [2:0] ZBBSelect, // ZBB mux select signal
input logic [2:0] Funct3, // Funct3 field of opcode indicates operation to perform input logic [2:0] Funct3, // Funct3 field of opcode indicates operation to perform
input logic CompLT, // Less-Than flag from comparator input logic LT, // less than flag
input logic LTU, // less than unsigned flag
input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage
input logic [WIDTH-1:0] ALUResult, FullResult, // ALUResult, FullResult signals input logic [WIDTH-1:0] PreALUResult, FullResult,// PreALUResult, FullResult signals
output logic [WIDTH-1:0] CondMaskB, // B is conditionally masked for ZBS instructions output logic [WIDTH-1:0] CondMaskB, // B is conditionally masked for ZBS instructions
output logic [WIDTH-1:0] CondShiftA, // A is conditionally shifted for ShAdd instructions output logic [WIDTH-1:0] CondShiftA, // A is conditionally shifted for ShAdd instructions
output logic [WIDTH-1:0] Result); // Result output logic [WIDTH-1:0] ALUResult); // Result
logic [WIDTH-1:0] ZBBResult, ZBCResult; // ZBB, ZBC Result logic [WIDTH-1:0] ZBBResult, ZBCResult; // ZBB, ZBC Result
logic [WIDTH-1:0] MaskB; // BitMask of B logic [WIDTH-1:0] MaskB; // BitMask of B
@ -84,16 +85,16 @@ module bitmanipalu #(parameter WIDTH=32) (
// ZBB Unit // ZBB Unit
if (`ZBB_SUPPORTED) begin: zbb if (`ZBB_SUPPORTED) begin: zbb
zbb #(WIDTH) ZBB(.A, .RevA, .B, .W64, .lt(CompLT), .ZBBSelect, .ZBBResult); zbb #(WIDTH) ZBB(.A, .RevA, .B, .W64, .LT, .LTU, .BUnsigned(Funct3[0]), .ZBBSelect, .ZBBResult);
end else assign ZBBResult = 0; end else assign ZBBResult = 0;
// Result Select Mux // Result Select Mux
always_comb always_comb
case (BSelect) case (BSelect)
// 00: ALU, 01: ZBA/ZBS, 10: ZBB, 11: ZBC // 00: ALU, 01: ZBA/ZBS, 10: ZBB, 11: ZBC
2'b00: Result = ALUResult; 2'b00: ALUResult = PreALUResult;
2'b01: Result = FullResult; // NOTE: We don't use ALUResult because ZBA/ZBS instructions don't sign extend the MSB of the right-hand word. 2'b01: ALUResult = FullResult; // NOTE: We don't use ALUResult because ZBA/ZBS instructions don't sign extend the MSB of the right-hand word.
2'b10: Result = ZBBResult; 2'b10: ALUResult = ZBBResult;
2'b11: Result = ZBCResult; 2'b11: ALUResult = ZBCResult;
endcase endcase
endmodule endmodule

View File

@ -48,7 +48,6 @@ module bmuctrl(
output logic [1:0] BSelectE, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding output logic [1:0] BSelectE, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding
output logic [2:0] ZBBSelectE, // ZBB mux select signal output logic [2:0] ZBBSelectE, // ZBB mux select signal
output logic BRegWriteE, // Indicates if it is a R type B instruction in Execute output logic BRegWriteE, // Indicates if it is a R type B instruction in Execute
output logic BComparatorSignedE, // Indicates if comparator signed in Execute Stage
output logic [2:0] BALUControlE // ALU Control signals for B instructions in Execute Stage output logic [2:0] BALUControlE // ALU Control signals for B instructions in Execute Stage
); );
@ -56,7 +55,6 @@ module bmuctrl(
logic [2:0] Funct3D; // Funct3 field in Decode stage logic [2:0] Funct3D; // Funct3 field in Decode stage
logic [6:0] Funct7D; // Funct7 field in Decode stage logic [6:0] Funct7D; // Funct7 field in Decode stage
logic [4:0] Rs2D; // Rs2 source register in Decode stage logic [4:0] Rs2D; // Rs2 source register in Decode stage
logic BComparatorSignedD; // Indicates if comparator signed (max, min instruction) in Decode Stage
logic RotateD; // Indicates if rotate instruction in Decode Stage logic RotateD; // Indicates if rotate instruction in Decode Stage
logic MaskD; // Indicates if zbs instruction in Decode Stage logic MaskD; // Indicates if zbs instruction in Decode Stage
logic PreShiftD; // Indicates if sh1add, sh2add, sh3add instruction in Decode Stage logic PreShiftD; // Indicates if sh1add, sh2add, sh3add instruction in Decode Stage
@ -110,10 +108,10 @@ module bmuctrl(
BMUControlsD = `BMUCTRLW'b000_10_010_1_1_0_1_0_0_0_0_0; // rev8 BMUControlsD = `BMUCTRLW'b000_10_010_1_1_0_1_0_0_0_0_0; // rev8
17'b0010011_0010100_101: if (Rs2D[4:0] == 5'b00111) 17'b0010011_0010100_101: if (Rs2D[4:0] == 5'b00111)
BMUControlsD = `BMUCTRLW'b000_10_010_1_1_0_1_0_0_0_0_0; // orc.b BMUControlsD = `BMUCTRLW'b000_10_010_1_1_0_1_0_0_0_0_0; // orc.b
17'b0110011_0000101_110: BMUControlsD = `BMUCTRLW'b000_10_111_1_0_0_1_0_0_0_0_0; // max 17'b0110011_0000101_110: BMUControlsD = `BMUCTRLW'b000_10_111_1_0_0_1_1_0_0_0_0; // max
17'b0110011_0000101_111: BMUControlsD = `BMUCTRLW'b000_10_111_1_0_0_1_0_0_0_0_0; // maxu 17'b0110011_0000101_111: BMUControlsD = `BMUCTRLW'b000_10_111_1_0_0_1_1_0_0_0_0; // maxu
17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_0_0_0_0_0; // min 17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_1_0_0_0_0; // min
17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_0_0_0_0_0; // minu 17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_1_0_0_0_0; // minu
endcase endcase
if (`XLEN==32) if (`XLEN==32)
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
@ -172,12 +170,9 @@ module bmuctrl(
// Pack BALUControl Signals // Pack BALUControl Signals
assign BALUControlD = {RotateD, MaskD, PreShiftD}; assign BALUControlD = {RotateD, MaskD, PreShiftD};
// Comparator should perform signed comparison when min/max instruction. We have overlap in funct3 with some branch instructions so we use opcode to differentiate betwen min/max and branches
assign BComparatorSignedD = (Funct3D[2]^Funct3D[0]) & ~OpD[6];
// Choose ALUSelect brom BMU for BMU operations, Funct3 for IEU operations, or 0 for addition // Choose ALUSelect brom BMU for BMU operations, Funct3 for IEU operations, or 0 for addition
assign ALUSelectD = BALUOpD ? BALUSelectD : (ALUOpD ? Funct3D : 3'b000); assign ALUSelectD = BALUOpD ? BALUSelectD : (ALUOpD ? Funct3D : 3'b000);
// BMU Execute stage pipieline control register // BMU Execute stage pipieline control register
flopenrc#(10) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BComparatorSignedD, BALUControlD}, {BSelectE, ZBBSelectE, BRegWriteE, BComparatorSignedE, BALUControlE}); flopenrc#(9) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BALUControlD}, {BSelectE, ZBBSelectE, BRegWriteE, BALUControlE});
endmodule endmodule

View File

@ -30,20 +30,20 @@
`include "wally-config.vh" `include "wally-config.vh"
module clmul #(parameter WIDTH=32) ( module clmul #(parameter WIDTH=32) (
input logic [WIDTH-1:0] A, B, // Operands input logic [WIDTH-1:0] X, Y, // Operands
output logic [WIDTH-1:0] ClmulResult); // ZBS result output logic [WIDTH-1:0] ClmulResult); // ZBS result
logic [(WIDTH*WIDTH)-1:0] s; // intermediary signals for carry-less multiply logic [(WIDTH*WIDTH)-1:0] S; // intermediary signals for carry-less multiply
integer i,j; integer i,j;
always_comb begin always_comb begin
for (i=0;i<WIDTH;i++) begin: outer for (i=0;i<WIDTH;i++) begin: outer
s[WIDTH*i]=A[0]&B[i]; S[WIDTH*i] = X[0] & Y[i];
for (j=1;j<=i;j++) begin: inner for (j=1;j<=i;j++) begin: inner
s[WIDTH*i+j] = (A[j]&B[i-j])^s[WIDTH*i+j-1]; S[WIDTH*i+j] = (X[j] & Y[i-j]) ^ S[WIDTH*i+j-1];
end end
ClmulResult[i] = s[WIDTH*i+j-1]; ClmulResult[i] = S[WIDTH*i+j-1];
end end
end end
endmodule endmodule

View File

@ -33,21 +33,25 @@
module zbb #(parameter WIDTH=32) ( module zbb #(parameter WIDTH=32) (
input logic [WIDTH-1:0] A, RevA, B, // Operands input logic [WIDTH-1:0] A, RevA, B, // Operands
input logic W64, // Indicates word operation input logic W64, // Indicates word operation
input logic lt, // lt flag input logic LT, // lt flag
input logic LTU, // ltu flag
input logic BUnsigned, // max/min (signed) flag
input logic [2:0] ZBBSelect, // ZBB Result select signal input logic [2:0] ZBBSelect, // ZBB Result select signal
output logic [WIDTH-1:0] ZBBResult); // ZBB result output logic [WIDTH-1:0] ZBBResult); // ZBB result
logic lt; // lt given signed/unsigned
logic [WIDTH-1:0] CntResult; // count result logic [WIDTH-1:0] CntResult; // count result
logic [WIDTH-1:0] MinMaxResult; // min, max result logic [WIDTH-1:0] MinMaxResult; // min, max result
logic [WIDTH-1:0] ByteResult; // byte results logic [WIDTH-1:0] ByteResult; // byte results
logic [WIDTH-1:0] ExtResult; // sign/zero extend results logic [WIDTH-1:0] ExtResult; // sign/zero extend results
mux2 #(1) ltmux(LT, LTU, BUnsigned , lt);
cnt #(WIDTH) cnt(.A, .RevA, .B(B[1:0]), .W64, .CntResult); cnt #(WIDTH) cnt(.A, .RevA, .B(B[1:0]), .W64, .CntResult);
byteUnit #(WIDTH) bu(.A, .ByteSelect(B[0]), .ByteResult); byteUnit #(WIDTH) bu(.A, .ByteSelect(B[0]), .ByteResult);
ext #(WIDTH) ext(.A, .ExtSelect({~B[2], {B[2] & B[0]}}), .ExtResult); ext #(WIDTH) ext(.A, .ExtSelect({~B[2], {B[2] & B[0]}}), .ExtResult);
// ZBBSelect[2] differentiates between min(u) vs max(u) instruction // ZBBSelect[2] differentiates between min(u) vs max(u) instruction
mux2 #(WIDTH) minmaxmux(B, A, lt^ZBBSelect[2], MinMaxResult); mux2 #(WIDTH) minmaxmux(B, A, ZBBSelect[2]^lt, MinMaxResult);
// ZBB Result select mux // ZBB Result select mux
mux4 #(WIDTH) zbbresultmux(CntResult, ExtResult, ByteResult, MinMaxResult, ZBBSelect[1:0], ZBBResult); mux4 #(WIDTH) zbbresultmux(CntResult, ExtResult, ByteResult, MinMaxResult, ZBBSelect[1:0], ZBBResult);

View File

@ -36,19 +36,16 @@ module zbc #(parameter WIDTH=32) (
logic [WIDTH-1:0] ClmulResult, RevClmulResult; logic [WIDTH-1:0] ClmulResult, RevClmulResult;
logic [WIDTH-1:0] RevB; logic [WIDTH-1:0] RevB;
logic [WIDTH-1:0] x,y; logic [WIDTH-1:0] X, Y;
logic [1:0] select;
assign select = ~Funct3[1:0]; bitreverse #(WIDTH) brB(B, RevB);
bitreverse #(WIDTH) brB(.A(B), .RevA(RevB)); mux3 #(WIDTH) xmux({RevA[WIDTH-2:0], {1'b0}}, RevA, A, ~Funct3[1:0], X);
mux3 #(WIDTH) ymux({{1'b0}, RevB[WIDTH-2:0]}, RevB, B, ~Funct3[1:0], Y);
mux3 #(WIDTH) xmux({RevA[WIDTH-2:0], {1'b0}}, RevA, A, select, x); clmul #(WIDTH) clm(.X, .Y, .ClmulResult);
mux3 #(WIDTH) ymux({{1'b0},RevB[WIDTH-2:0]}, RevB, B, select, y);
clmul #(WIDTH) clm(.A(x), .B(y), .ClmulResult(ClmulResult)); bitreverse #(WIDTH) brClmulResult(ClmulResult, RevClmulResult);
bitreverse #(WIDTH) brClmulResult(.A(ClmulResult), .RevA(RevClmulResult));
mux2 #(WIDTH) zbcresultmux(ClmulResult, RevClmulResult, Funct3[1], ZBCResult); mux2 #(WIDTH) zbcresultmux(ClmulResult, RevClmulResult, Funct3[1], ZBCResult);
endmodule endmodule

View File

@ -125,7 +125,6 @@ module controller(
logic IntDivM; // Integer divide instruction logic IntDivM; // Integer divide instruction
logic [1:0] BSelectD; // One-Hot encoding if it's ZBA_ZBB_ZBC_ZBS instruction in decode stage logic [1:0] BSelectD; // One-Hot encoding if it's ZBA_ZBB_ZBC_ZBS instruction in decode stage
logic [2:0] ZBBSelectD; // ZBB Mux Select Signal logic [2:0] ZBBSelectD; // ZBB Mux Select Signal
logic BComparatorSignedE; // Indicates if max, min (signed comarison) instruction in Execute Stage
logic IFunctD, RFunctD, MFunctD; // Detect I, R, and M-type RV32IM/Rv64IM instructions logic IFunctD, RFunctD, MFunctD; // Detect I, R, and M-type RV32IM/Rv64IM instructions
logic LFunctD, SFunctD, BFunctD; // Detect load, store, branch instructions logic LFunctD, SFunctD, BFunctD; // Detect load, store, branch instructions
logic JFunctD; // detect jalr instruction logic JFunctD; // detect jalr instruction
@ -257,7 +256,7 @@ module controller(
bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUOpD, .BSelectD, .ZBBSelectD, bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUOpD, .BSelectD, .ZBBSelectD,
.BRegWriteD, .BALUSrcBD, .BW64D, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE, .BRegWriteD, .BALUSrcBD, .BW64D, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE,
.ALUSelectD, .BSelectE, .ZBBSelectE, .BRegWriteE, .BComparatorSignedE, .BALUControlE); .ALUSelectD, .BSelectE, .ZBBSelectE, .BRegWriteE, .BALUControlE);
if (`ZBA_SUPPORTED) begin if (`ZBA_SUPPORTED) begin
// ALU Decoding is more comprehensive when ZBA is supported. slt and slti conflicts with sh1add, sh1add.uw // ALU Decoding is more comprehensive when ZBA is supported. slt and slti conflicts with sh1add, sh1add.uw
assign sltD = (Funct3D == 3'b010 & (~(Funct7D[4]) | ~OpD[5])) ; assign sltD = (Funct3D == 3'b010 & (~(Funct7D[4]) | ~OpD[5])) ;
@ -283,7 +282,6 @@ module controller(
assign BSelectE = 2'b00; assign BSelectE = 2'b00;
assign BSelectD = 2'b00; assign BSelectD = 2'b00;
assign ZBBSelectE = 3'b000; assign ZBBSelectE = 3'b000;
assign BComparatorSignedE = 1'b0;
assign BALUControlE = 3'b0; assign BALUControlE = 3'b0;
end end
@ -311,8 +309,7 @@ module controller(
// Branch Logic // Branch Logic
// The comparator handles both signed and unsigned branches using BranchSignedE // The comparator handles both signed and unsigned branches using BranchSignedE
// Hence, only eq and lt flags are needed // Hence, only eq and lt flags are needed
// We also want comparator to handle signed comparison on a max/min bitmanip instruction assign BranchSignedE = (~(Funct3E[2:1] == 2'b11) & BranchE);
assign BranchSignedE = (~(Funct3E[2:1] == 2'b11) & BranchE) | BComparatorSignedE;
assign {eqE, ltE} = FlagsE; assign {eqE, ltE} = FlagsE;
mux2 #(1) branchflagmux(eqE, ltE, Funct3E[2], BranchFlagE); mux2 #(1) branchflagmux(eqE, ltE, Funct3E[2], BranchFlagE);
assign BranchTakenE = BranchFlagE ^ Funct3E[0]; assign BranchTakenE = BranchFlagE ^ Funct3E[0];

View File

@ -114,7 +114,7 @@ module datapath (
comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE); comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE);
mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE); mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE); mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE);
alu #(`XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, FlagsE[0], BALUControlE, ALUResultE, IEUAdrE); alu #(`XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, BALUControlE, ALUResultE, IEUAdrE);
mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE); mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE);
mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE); mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);

View File

@ -1,7 +1,8 @@
/////////////////////////////////////////// <///////////////////////////////////////////
// //
// Written: me@KatherineParry.com // Written: me@KatherineParry.com
// Modified: 7/5/2022 // Modified: 7/5/2022
// Modified: 4/2/2023
// //
// Purpose: Testbench for Testfloat // Purpose: Testbench for Testfloat
// //
@ -32,75 +33,74 @@
module testbenchfp; module testbenchfp;
parameter TEST="none"; parameter TEST="none";
string Tests[]; // list of tests to be run string Tests[]; // list of tests to be run
logic [2:0] OpCtrl[]; // list of op controls logic [2:0] OpCtrl[]; // list of op controls
logic [2:0] Unit[]; // list of units being tested logic [2:0] Unit[]; // list of units being tested
logic WriteInt[]; // Is being written to integer resgiter logic WriteInt[]; // Is being written to integer resgiter
logic [2:0] Frm[4:0] = {3'b100, 3'b010, 3'b011, 3'b001, 3'b000}; // rounding modes: rne-000, rz-001, ru-011, rd-010, rnm-100 logic [2:0] Frm[4:0] = {3'b100, 3'b010, 3'b011, 3'b001, 3'b000}; // rounding modes: rne-000, rz-001, ru-011, rd-010, rnm-100
logic [1:0] Fmt[]; // list of formats for the other units logic [1:0] Fmt[]; // list of formats for the other units
logic clk=0;
logic [31:0] TestNum=0; // index for the test
logic [31:0] OpCtrlNum=0; // index for OpCtrl
logic [31:0] errors=0; // how many errors
logic [31:0] VectorNum=0; // index for test vector
logic [31:0] FrmNum=0; // index for rounding mode
logic [`FLEN*4+7:0] TestVectors[8388609:0]; // list of test vectors
logic clk=0; logic [1:0] FmtVal; // value of the current Fmt
logic [31:0] TestNum=0; // index for the test logic [2:0] UnitVal, OpCtrlVal, FrmVal; // value of the currnet Unit/OpCtrl/FrmVal
logic [31:0] OpCtrlNum=0; // index for OpCtrl logic WriteIntVal; // value of the current WriteInt
logic [31:0] errors=0; // how many errors logic [`FLEN-1:0] X, Y, Z; // inputs read from TestFloat
logic [31:0] VectorNum=0; // index for test vector logic [`XLEN-1:0] SrcA; // integer input
logic [31:0] FrmNum=0; // index for rounding mode logic [`FLEN-1:0] Ans; // correct answer from TestFloat
logic [`FLEN*4+7:0] TestVectors[8388609:0]; // list of test vectors logic [`FLEN-1:0] Res; // result from other units
logic [4:0] AnsFlg; // correct flags read from testfloat
logic [1:0] FmtVal; // value of the current Fmt logic [4:0] ResFlg, Flg; // Result flags
logic [2:0] UnitVal, OpCtrlVal, FrmVal; // value of the currnet Unit/OpCtrl/FrmVal logic [`FMTBITS-1:0] ModFmt; // format - 10 = half, 00 = single, 01 = double, 11 = quad
logic WriteIntVal; // value of the current WriteInt logic [`FLEN-1:0] FpRes, FpCmpRes; // Results from each unit
logic [`FLEN-1:0] X, Y, Z; // inputs read from TestFloat logic [`XLEN-1:0] IntRes, CmpRes; // Results from each unit
logic [`XLEN-1:0] SrcA; // integer input logic [4:0] FmaFlg, CvtFlg, DivFlg, CmpFlg; // Outputed flags
logic [`FLEN-1:0] Ans; // correct answer from TestFloat logic AnsNaN, ResNaN, NaNGood;
logic [`FLEN-1:0] Res; // result from other units logic Xs, Ys, Zs; // sign of the inputs
logic [4:0] AnsFlg; // correct flags read from testfloat logic [`NE-1:0] Xe, Ye, Ze; // exponent of the inputs
logic [4:0] ResFlg, Flg; // Result flags logic [`NF:0] Xm, Ym, Zm; // mantissas of the inputs
logic [`FMTBITS-1:0] ModFmt; // format - 10 = half, 00 = single, 01 = double, 11 = quad logic XNaN, YNaN, ZNaN; // is the input NaN
logic [`FLEN-1:0] FpRes, FpCmpRes; // Results from each unit logic XSNaN, YSNaN, ZSNaN; // is the input a signaling NaN
logic [`XLEN-1:0] IntRes, CmpRes; // Results from each unit logic XSubnorm, ZSubnorm; // is the input denormalized
logic [4:0] FmaFlg, CvtFlg, DivFlg, CmpFlg; // Outputed flags logic XInf, YInf, ZInf; // is the input infinity
logic AnsNaN, ResNaN, NaNGood; logic XZero, YZero, ZZero; // is the input zero
logic Xs, Ys, Zs; // sign of the inputs logic XExpMax, YExpMax, ZExpMax; // is the input's exponent all ones
logic [`NE-1:0] Xe, Ye, Ze; // exponent of the inputs logic [`CVTLEN-1:0] CvtLzcInE; // input to the Leading Zero Counter (priority encoder)
logic [`NF:0] Xm, Ym, Zm; // mantissas of the inputs logic IntZero;
logic XNaN, YNaN, ZNaN; // is the input NaN logic CvtResSgnE;
logic XSNaN, YSNaN, ZSNaN; // is the input a signaling NaN logic [`NE:0] CvtCalcExpE; // the calculated expoent
logic XSubnorm, ZSubnorm; // is the input denormalized logic [`LOGCVTLEN-1:0] CvtShiftAmtE; // how much to shift by
logic XInf, YInf, ZInf; // is the input infinity logic [`DIVb:0] Quot;
logic XZero, YZero, ZZero; // is the input zero logic CvtResSubnormUfE;
logic XExpMax, YExpMax, ZExpMax; // is the input's exponent all ones logic DivStart, FDivBusyE, OldFDivBusyE;
logic [`CVTLEN-1:0] CvtLzcInE; // input to the Leading Zero Counter (priority encoder) logic reset = 1'b0;
logic IntZero; logic [$clog2(`NF+2)-1:0] XZeroCnt, YZeroCnt;
logic CvtResSgnE; logic [`DURLEN-1:0] Dur;
logic [`NE:0] CvtCalcExpE; // the calculated expoent
logic [`LOGCVTLEN-1:0] CvtShiftAmtE; // how much to shift by
logic [`DIVb:0] Quot;
logic CvtResSubnormUfE;
logic DivStart, FDivBusyE, OldFDivBusyE;
logic reset = 1'b0;
logic [$clog2(`NF+2)-1:0] XZeroCnt, YZeroCnt;
logic [`DURLEN-1:0] Dur;
// in-between FMA signals // in-between FMA signals
logic Mult; logic Mult;
logic Ss; logic Ss;
logic [`NE+1:0] Pe; logic [`NE+1:0] Pe;
logic [`NE+1:0] Se; logic [`NE+1:0] Se;
logic ASticky; logic ASticky;
logic KillProd; logic KillProd;
logic [$clog2(3*`NF+5)-1:0] SCnt; logic [$clog2(3*`NF+5)-1:0] SCnt;
logic [3*`NF+3:0] Sm; logic [3*`NF+3:0] Sm;
logic InvA; logic InvA;
logic NegSum; logic NegSum;
logic As; logic As;
logic Ps; logic Ps;
logic DivSticky; logic DivSticky;
logic DivDone; logic DivDone;
logic DivNegSticky; logic DivNegSticky;
logic [`NE+1:0] DivCalcExp; logic [`NE+1:0] DivCalcExp;
logic divsqrtop; logic divsqrtop;
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
@ -126,28 +126,28 @@ module testbenchfp;
$display("TEST is %s", TEST); $display("TEST is %s", TEST);
if (`Q_SUPPORTED) begin // if Quad percision is supported if (`Q_SUPPORTED) begin // if Quad percision is supported
if (TEST === "cvtint"| TEST === "all") begin // if testing integer conversion if (TEST === "cvtint"| TEST === "all") begin // if testing integer conversion
// add the 128-bit cvtint tests to the to-be-tested list // add the 128-bit cvtint tests to the to-be-tested list
Tests = {Tests, f128rv32cvtint}; Tests = {Tests, f128rv32cvtint};
// add the op-codes for these tests to the op-code list // add the op-codes for these tests to the op-code list
OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL};
WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1};
// add what unit is used and the fmt to their lists (one for each test) // add what unit is used and the fmt to their lists (one for each test)
for(int i = 0; i<20; i++) begin for(int i = 0; i<20; i++) begin
Unit = {Unit, `CVTINTUNIT}; Unit = {Unit, `CVTINTUNIT};
Fmt = {Fmt, 2'b11}; Fmt = {Fmt, 2'b11};
end end
if (`XLEN == 64) begin // if 64-bit integers are supported add their conversions if (`XLEN == 64) begin // if 64-bit integers are supported add their conversions
Tests = {Tests, f128rv64cvtint}; Tests = {Tests, f128rv64cvtint};
// add the op-codes for these tests to the op-code list // add the op-codes for these tests to the op-code list
OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL};
WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1};
// add what unit is used and the fmt to their lists (one for each test) // add what unit is used and the fmt to their lists (one for each test)
for(int i = 0; i<20; i++) begin for(int i = 0; i<20; i++) begin
Unit = {Unit, `CVTINTUNIT}; Unit = {Unit, `CVTINTUNIT};
Fmt = {Fmt, 2'b11}; Fmt = {Fmt, 2'b11};
end end
end end
end end
if (TEST === "cvtfp" | TEST === "all") begin // if the floating-point conversions are being tested if (TEST === "cvtfp" | TEST === "all") begin // if the floating-point conversions are being tested
if(`D_SUPPORTED) begin // if double precision is supported if(`D_SUPPORTED) begin // if double precision is supported
// add the 128 <-> 64 bit conversions to the to-be-tested list // add the 128 <-> 64 bit conversions to the to-be-tested list
@ -270,27 +270,27 @@ module testbenchfp;
end end
if (`D_SUPPORTED) begin // if double precision is supported if (`D_SUPPORTED) begin // if double precision is supported
if (TEST === "cvtint"| TEST === "all") begin // if integer conversion is being tested if (TEST === "cvtint"| TEST === "all") begin // if integer conversion is being tested
Tests = {Tests, f64rv32cvtint}; Tests = {Tests, f64rv32cvtint};
// add the op-codes for these tests to the op-code list // add the op-codes for these tests to the op-code list
OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL};
WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1};
// add what unit is used and the fmt to their lists (one for each test) // add what unit is used and the fmt to their lists (one for each test)
for(int i = 0; i<20; i++) begin for(int i = 0; i<20; i++) begin
Unit = {Unit, `CVTINTUNIT}; Unit = {Unit, `CVTINTUNIT};
Fmt = {Fmt, 2'b01}; Fmt = {Fmt, 2'b01};
end end
if (`XLEN == 64) begin // if 64-bit integers are being supported if (`XLEN == 64) begin // if 64-bit integers are being supported
Tests = {Tests, f64rv64cvtint}; Tests = {Tests, f64rv64cvtint};
// add the op-codes for these tests to the op-code list // add the op-codes for these tests to the op-code list
OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL};
WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1};
// add what unit is used and the fmt to their lists (one for each test) // add what unit is used and the fmt to their lists (one for each test)
for(int i = 0; i<20; i++) begin for(int i = 0; i<20; i++) begin
Unit = {Unit, `CVTINTUNIT}; Unit = {Unit, `CVTINTUNIT};
Fmt = {Fmt, 2'b01}; Fmt = {Fmt, 2'b01};
end end
end end
end end
if (TEST === "cvtfp" | TEST === "all") begin // if floating point conversions are being tested if (TEST === "cvtfp" | TEST === "all") begin // if floating point conversions are being tested
if(`F_SUPPORTED) begin // if single precision is supported if(`F_SUPPORTED) begin // if single precision is supported
// add the 64 <-> 32 bit conversions to the to-be-tested list // add the 64 <-> 32 bit conversions to the to-be-tested list
@ -397,27 +397,27 @@ module testbenchfp;
end end
if (`F_SUPPORTED) begin // if single precision being supported if (`F_SUPPORTED) begin // if single precision being supported
if (TEST === "cvtint"| TEST === "all") begin // if integer conversion is being tested if (TEST === "cvtint"| TEST === "all") begin // if integer conversion is being tested
Tests = {Tests, f32rv32cvtint}; Tests = {Tests, f32rv32cvtint};
// add the op-codes for these tests to the op-code list // add the op-codes for these tests to the op-code list
OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL};
WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1};
// add what unit is used and the fmt to their lists (one for each test) // add what unit is used and the fmt to their lists (one for each test)
for(int i = 0; i<20; i++) begin for(int i = 0; i<20; i++) begin
Unit = {Unit, `CVTINTUNIT}; Unit = {Unit, `CVTINTUNIT};
Fmt = {Fmt, 2'b00}; Fmt = {Fmt, 2'b00};
end end
if (`XLEN == 64) begin // if 64-bit integers are supported if (`XLEN == 64) begin // if 64-bit integers are supported
Tests = {Tests, f32rv64cvtint}; Tests = {Tests, f32rv64cvtint};
// add the op-codes for these tests to the op-code list // add the op-codes for these tests to the op-code list
OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL};
WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1};
// add what unit is used and the fmt to their lists (one for each test) // add what unit is used and the fmt to their lists (one for each test)
for(int i = 0; i<20; i++) begin for(int i = 0; i<20; i++) begin
Unit = {Unit, `CVTINTUNIT}; Unit = {Unit, `CVTINTUNIT};
Fmt = {Fmt, 2'b00}; Fmt = {Fmt, 2'b00};
end end
end end
end end
if (TEST === "cvtfp" | TEST === "all") begin // if floating point conversion is being tested if (TEST === "cvtfp" | TEST === "all") begin // if floating point conversion is being tested
if(`ZFH_SUPPORTED) begin if(`ZFH_SUPPORTED) begin
// add the 32 <-> 16 bit conversions to the to-be-tested list // add the 32 <-> 16 bit conversions to the to-be-tested list
@ -508,27 +508,27 @@ module testbenchfp;
end end
if (`ZFH_SUPPORTED) begin // if half precision supported if (`ZFH_SUPPORTED) begin // if half precision supported
if (TEST === "cvtint"| TEST === "all") begin // if in conversions are being tested if (TEST === "cvtint"| TEST === "all") begin // if in conversions are being tested
Tests = {Tests, f16rv32cvtint}; Tests = {Tests, f16rv32cvtint};
// add the op-codes for these tests to the op-code list // add the op-codes for these tests to the op-code list
OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL};
WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1};
// add what unit is used and the fmt to their lists (one for each test) // add what unit is used and the fmt to their lists (one for each test)
for(int i = 0; i<20; i++) begin for(int i = 0; i<20; i++) begin
Unit = {Unit, `CVTINTUNIT}; Unit = {Unit, `CVTINTUNIT};
Fmt = {Fmt, 2'b10}; Fmt = {Fmt, 2'b10};
end end
if (`XLEN == 64) begin // if 64-bit integers are supported if (`XLEN == 64) begin // if 64-bit integers are supported
Tests = {Tests, f16rv64cvtint}; Tests = {Tests, f16rv64cvtint};
// add the op-codes for these tests to the op-code list // add the op-codes for these tests to the op-code list
OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL};
WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1};
// add what unit is used and the fmt to their lists (one for each test) // add what unit is used and the fmt to their lists (one for each test)
for(int i = 0; i<20; i++) begin for(int i = 0; i<20; i++) begin
Unit = {Unit, `CVTINTUNIT}; Unit = {Unit, `CVTINTUNIT};
Fmt = {Fmt, 2'b10}; Fmt = {Fmt, 2'b10};
end end
end end
end end
if (TEST === "cmp" | TEST === "all") begin // if comparisions are being tested if (TEST === "cmp" | TEST === "all") begin // if comparisions are being tested
// add the correct tests/op-ctrls/unit/fmt to their lists // add the correct tests/op-ctrls/unit/fmt to their lists
Tests = {Tests, f16cmp}; Tests = {Tests, f16cmp};
@ -656,7 +656,8 @@ module testbenchfp;
end end
// extract the inputs (X, Y, Z, SrcA) and the output (Ans, AnsFlg) from the current test vector // extract the inputs (X, Y, Z, SrcA) and the output (Ans, AnsFlg) from the current test vector
readvectors readvectors (.clk, .Fmt(FmtVal), .ModFmt, .TestVector(TestVectors[VectorNum]), .VectorNum, .Ans(Ans), .AnsFlg(AnsFlg), .SrcA, readvectors readvectors (.clk, .Fmt(FmtVal), .ModFmt, .TestVector(TestVectors[VectorNum]),
.VectorNum, .Ans(Ans), .AnsFlg(AnsFlg), .SrcA,
.Xs, .Ys, .Zs, .Unit(UnitVal), .Xs, .Ys, .Zs, .Unit(UnitVal),
.Xe, .Ye, .Ze, .TestNum, .OpCtrl(OpCtrlVal), .Xe, .Ye, .Ze, .TestNum, .OpCtrl(OpCtrlVal),
.Xm, .Ym, .Zm, .DivStart, .Xm, .Ym, .Zm, .DivStart,
@ -680,7 +681,7 @@ module testbenchfp;
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
// instantiate devices under test // instantiate devices under test
if (TEST === "fma"| TEST === "mul" | TEST === "add" | TEST === "all") begin : fma if (TEST === "fma"| TEST === "mul" | TEST === "add" | TEST === "sub" | TEST === "all") begin : fma
fma fma(.Xs(Xs), .Ys(Ys), .Zs(Zs), fma fma(.Xs(Xs), .Ys(Ys), .Zs(Zs),
.Xe(Xe), .Ye(Ye), .Ze(Ze), .Xe(Xe), .Ye(Ye), .Ze(Ze),
.Xm(Xm), .Ym(Ym), .Zm(Zm), .Xm(Xm), .Ym(Ym), .Zm(Zm),

View File

@ -0,0 +1,4 @@
This folder holds the archtest and testfloat vectors necessary fo evaluating performance
of standalone intdiv vs combined IFdivsqrt
to generate vectors, uncomment line 8 in create_all_vectors.sh

View File

@ -0,0 +1,8 @@
#!/bin/sh
# create test vectors for stand alone int
./extract_testfloat_vectors.py
./extract_arch_vectors.py
# to create tvs for evaluation of combined IFdivsqrt
#./combined_IF_vectors/create_IF_vectors.sh

View File

@ -0,0 +1,251 @@
#! /usr/bin/python3
# author: Alessandro Maiuolo
# contact: amaiuolo@g.hmc.edu
# date created: 3-29-2023
# extract all arch test vectors
import os
wally = os.popen('echo $WALLY').read().strip()
def ext_bits(my_string):
target_len = 32 # we want 128 bits, div by 4 bc hex notation
zeroes_to_add = target_len - len(my_string)
return zeroes_to_add*"0" + my_string
def twos_comp(b, x):
if b == 32:
return hex(0x100000000 - int(x,16))[2:]
elif b == 64:
return hex(0x10000000000000000 - int(x,16))[2:]
else:
return "UNEXPECTED_BITSIZE"
def unpack_rf(packed):
bin_u = bin(int(packed, 16))[2:].zfill(8) # translate to binary
flags = hex(int(bin_u[3:],2))[2:].zfill(2)
rounding_mode = hex(int(bin_u[:3],2))[2:]
return flags, rounding_mode
# rounding mode dictionary
round_dict = {
"rne":"0",
"rnm":"4",
"ru":"3",
"rz":"1",
"rd":"2",
"dyn":"7"
}
# fcsr dictionary
fcsr_dict = {
"0":"rne",
"128":"rnm",
"96":"ru",
"32":"rz",
"64":"rd",
"224":"dyn"
}
print("creating arch test vectors")
class Config:
def __init__(self, bits, letter, op, filt, op_code):
self.bits = bits
self.letter = letter
self.op = op
self.filt = filt
self.op_code = op_code
def create_vectors(my_config):
suite_folder_num = my_config.bits
if my_config.bits == 64 and my_config.letter == "F": suite_folder_num = 32
source_dir1 = "{}/addins/riscv-arch-test/riscv-test-suite/rv{}i_m/{}/src/".format(wally, suite_folder_num, my_config.letter)
source_dir2 = "{}/tests/riscof/work/riscv-arch-test/rv{}i_m/{}/src/".format(wally, my_config.bits, my_config.letter)
dest_dir = "{}/tests/fp/combined_IF_vectors/IF_vectors/".format(wally)
all_vectors1 = os.listdir(source_dir1)
filt_vectors1 = [v for v in all_vectors1 if my_config.filt in v]
# print(filt_vectors1)
filt_vectors2 = [v + "/ref/Reference-sail_c_simulator.signature" for v in all_vectors1 if my_config.filt in v]
# iterate through all vectors
for i in range(len(filt_vectors1)):
vector1 = filt_vectors1[i]
vector2 = filt_vectors2[i]
operation = my_config.op_code
rounding_mode = "X"
flags = "XX"
# use name to create our new tv
dest_file = open("{}cvw_{}_{}.tv".format(dest_dir, my_config.bits, vector1[:-2]), 'a')
# open vectors
src_file1 = open(source_dir1 + vector1,'r')
src_file2 = open(source_dir2 + vector2,'r')
# for each test in the vector
reading = True
src_file2.readline() #skip first bc junk
# print(my_config.bits, my_config.letter)
if my_config.letter == "F" and my_config.bits == 64:
reading = True
# print("trigger 64F")
#skip first 2 lines bc junk
src_file2.readline()
while reading:
# get answer and flags from Ref...signature
# answers are before deadbeef (first line of 4)
# flags are after deadbeef (third line of 4)
answer = src_file2.readline().strip()
deadbeef = src_file2.readline().strip()
# print(answer)
if not (answer == "e7d4b281" and deadbeef == "6f5ca309"): # if there is still stuff to read
# get flags
packed = src_file2.readline().strip()[6:]
flags, rounding_mode = unpack_rf(packed)
# skip 00000000 buffer
src_file2.readline()
# parse through .S file
detected = False
done = False
op1val = "0"
op2val = "0"
while not (detected or done):
# print("det1")
line = src_file1.readline()
# print(line)
if "op1val" in line:
# print("det2")
# parse line
op1val = line.split("op1val")[1].split("x")[1].split(";")[0]
if my_config.op != "fsqrt": # sqrt doesn't have two input vals
op2val = line.split("op2val")[1].split("x")[1].strip()
if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there
else:
op2val = 32*"X"
# go to next test in vector
detected = True
elif "RVTEST_CODE_END" in line:
done = True
# put it all together
if not done:
translation = "{}_{}_{}_{}_{}_{}".format(operation, ext_bits(op1val), ext_bits(op2val), ext_bits(answer.strip()), flags, rounding_mode)
dest_file.write(translation + "\n")
else:
# print("read false")
reading = False
elif my_config.letter == "M" and my_config.bits == 64:
reading = True
#skip first 2 lines bc junk
src_file2.readline()
while reading:
# print("trigger 64M")
# get answer from Ref...signature
# answers span two lines and are reversed
answer2 = src_file2.readline().strip()
answer1 = src_file2.readline().strip()
answer = answer1 + answer2
# print(answer1,answer2)
if not (answer2 == "e7d4b281" and answer1 == "6f5ca309"): # if there is still stuff to read
# parse through .S file
detected = False
done = False
op1val = "0"
op2val = "0"
while not (detected or done):
# print("det1")
line = src_file1.readline()
# print(line)
if "op1val" in line:
# print("det2")
# parse line
op1val = line.split("op1val")[1].split("x")[1].split(";")[0]
if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling
op1val = twos_comp(my_config.bits, op1val)
if my_config.op != "fsqrt": # sqrt doesn't have two input vals, unnec here but keeping for later
op2val = line.split("op2val")[1].split("x")[1].strip()
if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there
if "-" in line.split("op2val")[1].split("x")[0]: # neg sign handling
op2val = twos_comp(my_config.bits, op2val)
# go to next test in vector
detected = True
elif "RVTEST_CODE_END" in line:
done = True
# ints don't have flags
flags = "XX"
# put it all together
if not done:
translation = "{}_{}_{}_{}_{}_{}".format(operation, ext_bits(op1val), ext_bits(op2val), ext_bits(answer.strip()), flags.strip(), rounding_mode)
dest_file.write(translation + "\n")
else:
# print("read false")
reading = False
else:
while reading:
# get answer and flags from Ref...signature
answer = src_file2.readline()
# print(answer)
packed = src_file2.readline()[6:]
# print(packed)
if len(packed.strip())>0: # if there is still stuff to read
# print("packed")
# parse through .S file
detected = False
done = False
op1val = "0"
op2val = "0"
while not (detected or done):
# print("det1")
line = src_file1.readline()
# print(line)
if "op1val" in line:
# print("det2")
# parse line
op1val = line.split("op1val")[1].split("x")[1].split(";")[0]
if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling
op1val = twos_comp(my_config.bits, op1val)
if my_config.op != "fsqrt": # sqrt doesn't have two input vals
op2val = line.split("op2val")[1].split("x")[1].strip()
if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there
if "-" in line.split("op2val")[1].split("x")[0]: # neg sign handling
op2val = twos_comp(my_config.bits, op2val)
# go to next test in vector
detected = True
elif "RVTEST_CODE_END" in line:
done = True
# rounding mode for float
if not done and (my_config.op == "fsqrt" or my_config.op == "fdiv"):
flags, rounding_mode = unpack_rf(packed)
# put it all together
if not done:
translation = "{}_{}_{}_{}_{}_{}".format(operation, ext_bits(op1val), ext_bits(op2val), ext_bits(answer.strip()), flags, rounding_mode)
dest_file.write(translation + "\n")
else:
# print("read false")
reading = False
print("out")
dest_file.close()
src_file1.close()
src_file2.close()
config_list = [
Config(32, "M", "div", "div_", 0),
Config(32, "F", "fdiv", "fdiv", 1),
Config(32, "F", "fsqrt", "fsqrt", 2),
Config(32, "M", "rem", "rem-", 3),
Config(32, "M", "divu", "divu-", 4),
Config(32, "M", "remu", "remu-", 5),
Config(64, "M", "div", "div-", 0),
Config(64, "F", "fdiv", "fdiv", 1),
Config(64, "F", "fsqrt", "fsqrt", 2),
Config(64, "M", "rem", "rem-", 3),
Config(64, "M", "divu", "divu-", 4),
Config(64, "M", "remu", "remu-", 5),
Config(64, "M", "divw", "divw-", 6),
Config(64, "M", "divuw", "divuw-", 7),
Config(64, "M", "remw", "remw-", 8),
Config(64, "M", "remuw", "remuw-", 9)
]
for c in config_list:
create_vectors(c)

View File

@ -0,0 +1,79 @@
#! /usr/bin/python3
# extract sqrt and float div testfloat vectors
# author: Alessandro Maiuolo
# contact: amaiuolo@g.hmc.edu
# date created: 3-29-2023
import os
wally = os.popen('echo $WALLY').read().strip()
# print(wally)
def ext_bits(my_string):
target_len = 32 # we want 128 bits, div by 4 bc hex notation
zeroes_to_add = target_len - len(my_string)
return zeroes_to_add*"0" + my_string
# rounding mode dictionary
round_dict = {
"rne":"0",
"rnm":"4",
"ru":"3",
"rz":"1",
"rd":"2",
"dyn":"7"
}
print("creating testfloat div test vectors")
source_dir = "{}/tests/fp/vectors/".format(wally)
dest_dir = "{}/tests/fp/combined_IF_vectors/IF_vectors/".format(wally)
all_vectors = os.listdir(source_dir)
div_vectors = [v for v in all_vectors if "div" in v]
# iterate through all float div vectors
for vector in div_vectors:
# use name to determine configs
config_list = vector.split(".")[0].split("_")
operation = "1" #float div
rounding_mode = round_dict[str(config_list[2])]
# use name to create our new tv
dest_file = open(dest_dir + "cvw_" + vector, 'a')
# open vector
src_file = open(source_dir + vector,'r')
# for each test in the vector
for i in src_file.readlines():
translation = "" # this stores the test that we are currently working on
[input_1, input_2, answer, flags] = i.split("_") # separate inputs, answer, and flags
# put it all together, strip nec for removing \n on the end of the flags
translation = "{}_{}_{}_{}_{}_{}".format(operation, ext_bits(input_1), ext_bits(input_2), ext_bits(answer), flags.strip(), rounding_mode)
dest_file.write(translation + "\n")
dest_file.close()
src_file.close()
print("creating testfloat sqrt test vectors")
sqrt_vectors = [v for v in all_vectors if "sqrt" in v]
# iterate through all float div vectors
for vector in sqrt_vectors:
# use name to determine configs
config_list = vector.split(".")[0].split("_")
operation = "2" #sqrt
rounding_mode = round_dict[str(config_list[2])]
# use name to create our new tv
dest_file = open(dest_dir + "cvw_" + vector, 'a')
# open vector
src_file = open(source_dir + vector,'r')
# for each test in the vector
for i in src_file.readlines():
translation = "" # this stores the test that we are currently working on
[input_1, answer, flags] = i.split("_") # separate inputs, answer, and flags
# put it all together, strip nec for removing \n on the end of the flags
translation = "{}_{}_{}_{}_{}_{}".format(operation, ext_bits(input_1), "X"*32, ext_bits(answer), flags.strip(), rounding_mode)
dest_file.write(translation + "\n")
dest_file.close()
src_file.close()

View File

@ -3,3 +3,6 @@
mkdir -p vectors mkdir -p vectors
./create_vectors.sh ./create_vectors.sh
./remove_spaces.sh ./remove_spaces.sh
# to create tvs for evaluation of combined IFdivsqrt
#./combined_IF_vectors/create_IF_vectors.sh