forked from Github_Repos/cvw
Merge branch 'openhwgroup:main' into zbc_optimize
This commit is contained in:
commit
d7deed1690
38
src/cache/cache.sv
vendored
38
src/cache/cache.sv
vendored
@ -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
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
8
src/cache/cacheLRU.sv
vendored
8
src/cache/cacheLRU.sv
vendored
@ -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))
|
||||||
|
@ -135,10 +135,16 @@ module decompress (
|
|||||||
IllegalCompInstrD = 1;
|
IllegalCompInstrD = 1;
|
||||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||||
end
|
end
|
||||||
|
// coverage off
|
||||||
|
// are excluding this branch from coverage because in rv64gc XLEN is always 64 and thus greater than 32 bits
|
||||||
|
// This branch will only be taken if instr16[12:10] == 3'b111 and 'XLEN !> 32, because all other
|
||||||
|
// possible values for instr16[12:10] are covered by branches above. XLEN !> 32
|
||||||
|
// will never occur in rv64gc so this branch can not be covered
|
||||||
else begin // illegal instruction
|
else begin // illegal instruction
|
||||||
IllegalCompInstrD = 1;
|
IllegalCompInstrD = 1;
|
||||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||||
end
|
end
|
||||||
|
// coverage on
|
||||||
5'b01101: InstrD = {immCJ, 5'b00000, 7'b1101111}; // c.j
|
5'b01101: InstrD = {immCJ, 5'b00000, 7'b1101111}; // c.j
|
||||||
5'b01110: InstrD = {immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz
|
5'b01110: InstrD = {immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz
|
||||||
5'b01111: InstrD = {immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez
|
5'b01111: InstrD = {immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez
|
||||||
|
@ -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),
|
||||||
|
@ -57,6 +57,23 @@ main:
|
|||||||
fcvt.l.q a0, ft3
|
fcvt.l.q a0, ft3
|
||||||
fcvt.lu.q a0, ft3
|
fcvt.lu.q a0, ft3
|
||||||
|
|
||||||
|
|
||||||
|
// Tests verfying that half and quad floating point convertion instructions are not supported by rv64gc
|
||||||
|
# fcvt.h.d ft3, ft0 // Somehow this instruction is taking the route on line 124
|
||||||
|
// idea: enable the Q extension for this to work properly? A: Q and halfs not supported in rv64gc
|
||||||
|
# fcvt.h.w ft3, a0
|
||||||
|
# fcvt.w.h a0, ft0
|
||||||
|
# fcvt.q.w ft3, a0
|
||||||
|
# fcvt.w.q a0, ft0
|
||||||
|
# fcvt.q.d ft3, ft0
|
||||||
|
|
||||||
|
.word 0x38007553 // Testing the all False case for 119 - funct7 under, op = 101 0011
|
||||||
|
.word 0x40000053 // Line 145 All False Test case - illegal instruction?
|
||||||
|
.word 0xd0400053 // Line 156 All False Test case - illegal instruction?
|
||||||
|
.word 0xc0400053 // Line 162 All False Test case - illegal instruction?
|
||||||
|
.word 0xd2400053 // Line 168 All False Test case - illegal instruction?
|
||||||
|
.word 0xc2400053 // Line 174 All False Test case - illegal instruction?
|
||||||
|
|
||||||
# Test illegal instructions are detected
|
# Test illegal instructions are detected
|
||||||
.word 0x00000007 // illegal floating-point load (bad Funct3)
|
.word 0x00000007 // illegal floating-point load (bad Funct3)
|
||||||
.word 0x00000027 // illegal floating-point store (bad Funct3)
|
.word 0x00000027 // illegal floating-point store (bad Funct3)
|
||||||
|
@ -32,9 +32,23 @@ main:
|
|||||||
csrs mstatus, t0
|
csrs mstatus, t0
|
||||||
|
|
||||||
# calling compressed floating point load double instruction
|
# calling compressed floating point load double instruction
|
||||||
//.halfword 0x2000 // CL type compressed floating-point ld-->funct3,imm,rs1',imm,rd',op
|
//.hword 0x2000 // CL type compressed floating-point ld-->funct3,imm,rs1',imm,rd',op
|
||||||
// binary version 0000 0000 0000 0000 0010 0000 0000 0000
|
// binary version 0000 0000 0000 0000 0010 0000 0000 0000
|
||||||
mv s0, sp
|
mv s0, sp
|
||||||
c.fld fs0, 0(s0)
|
c.fld fs0, 0(s0)
|
||||||
|
|
||||||
|
c.fsd fs0, 0(s0)
|
||||||
|
|
||||||
|
// c.fldsp fs0, 0
|
||||||
|
.hword 0x2002
|
||||||
|
|
||||||
|
// c.fsdsp fs0, 0
|
||||||
|
.hword 0xA002
|
||||||
|
|
||||||
|
//# Illegal compressed instruction with op = 01, instr[15:10] = 100111, and 0's everywhere else
|
||||||
|
//.hword 0x9C01
|
||||||
|
|
||||||
|
# Line Illegal compressed instruction
|
||||||
|
.hword 0x9C41
|
||||||
|
|
||||||
j done
|
j done
|
||||||
|
@ -43,4 +43,48 @@ main:
|
|||||||
csrw sepc, t0
|
csrw sepc, t0
|
||||||
csrw stimecmp, t0
|
csrw stimecmp, t0
|
||||||
|
|
||||||
|
# Switch to machine mode
|
||||||
|
li a0, 3
|
||||||
|
ecall
|
||||||
|
# Testing the HPMCOUNTERM performance counter: writing
|
||||||
|
# Base address is 2816 (MHPMCOUNTERBASE)
|
||||||
|
# There are 32 HPMCOUNTER registers
|
||||||
|
csrw 2816, t0
|
||||||
|
csrw 2817, t0
|
||||||
|
csrw 2818, t0
|
||||||
|
csrw 2819, t0
|
||||||
|
csrw 2820, t0
|
||||||
|
csrw 2821, t0
|
||||||
|
csrw 2822, t0
|
||||||
|
csrw 2823, t0
|
||||||
|
csrw 2824, t0
|
||||||
|
csrw 2825, t0
|
||||||
|
csrw 2826, t0
|
||||||
|
csrw 2827, t0
|
||||||
|
csrw 2828, t0
|
||||||
|
csrw 2829, t0
|
||||||
|
csrw 2830, t0
|
||||||
|
csrw 2831, t0
|
||||||
|
csrw 2832, t0
|
||||||
|
csrw 2833, t0
|
||||||
|
csrw 2834, t0
|
||||||
|
csrw 2835, t0
|
||||||
|
csrw 2836, t0
|
||||||
|
csrw 2837, t0
|
||||||
|
csrw 2838, t0
|
||||||
|
csrw 2839, t0
|
||||||
|
csrw 2840, t0
|
||||||
|
csrw 2841, t0
|
||||||
|
csrw 2842, t0
|
||||||
|
csrw 2843, t0
|
||||||
|
csrw 2844, t0
|
||||||
|
csrw 2845, t0
|
||||||
|
csrw 2846, t0
|
||||||
|
csrw 2847, t0
|
||||||
|
|
||||||
|
# Testing the HPMCOUNTERM performance counter: reading
|
||||||
|
csrr t0, 2817
|
||||||
j done
|
j done
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
4
tests/fp/combined_IF_vectors/IF_vectors/README
Normal file
4
tests/fp/combined_IF_vectors/IF_vectors/README
Normal 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
|
8
tests/fp/combined_IF_vectors/create_IF_vectors.sh
Executable file
8
tests/fp/combined_IF_vectors/create_IF_vectors.sh
Executable 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
|
251
tests/fp/combined_IF_vectors/extract_arch_vectors.py
Executable file
251
tests/fp/combined_IF_vectors/extract_arch_vectors.py
Executable 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)
|
79
tests/fp/combined_IF_vectors/extract_testfloat_vectors.py
Executable file
79
tests/fp/combined_IF_vectors/extract_testfloat_vectors.py
Executable 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()
|
@ -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
|
Loading…
Reference in New Issue
Block a user