Merge remote-tracking branch 'upstream/main' into main

This commit is contained in:
Kip Macsai-Goren 2023-02-10 10:01:14 -08:00
commit f91d74896a
29 changed files with 160 additions and 157 deletions

View File

@ -110,12 +110,12 @@ Ubuntu users may need to install and update various tools. Beware when cutting
### Install RISC-V GCC Cross-Compiler ### Install RISC-V GCC Cross-Compiler
To install GCC from source can take hours to compile. This configuration enables multilib to target many flavors of RISC-V. This book is tested with GCC 12.2 (tagged 2022.09.21), but will likely work with newer versions as well. To install GCC from source can take hours to compile. This configuration enables multilib to target many flavors of RISC-V. This book is tested with GCC 12.2 (tagged 2023.01.31), but will likely work with newer versions as well.
$ git clone https://github.com/riscv/riscv-gnu-toolchain $ git clone https://github.com/riscv/riscv-gnu-toolchain
$ cd riscv-gnu-toolchain $ cd riscv-gnu-toolchain
$ git checkout 2022.09.21 $ git checkout 2023.01.31
$ ./configure --prefix=$RISCV --enable-multilib --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;" $ ./configure --prefix=$RISCV --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;"
$ make --jobs $ make --jobs
Note: make --jobs will reduce compile time by compiling in parallel. However, adding this option could dramatically increase the memory utilization of your local machine. Note: make --jobs will reduce compile time by compiling in parallel. However, adding this option could dramatically increase the memory utilization of your local machine.
@ -143,7 +143,7 @@ Spike also takes a while to install and compile, but this can be done concurrent
$ git clone https://github.com/riscv-software-src/riscv-isa-sim $ git clone https://github.com/riscv-software-src/riscv-isa-sim
$ mkdir riscv-isa-sim/build $ mkdir riscv-isa-sim/build
$ cd riscv-isa-sim/build $ cd riscv-isa-sim/build
$ ../configure --prefix=$RISCV --enable-commitlog $ ../configure --prefix=$RISCV
$ make --jobs $ make --jobs
$ make install $ make install
$ cd ../arch_test_target/spike/device $ cd ../arch_test_target/spike/device

View File

@ -28,6 +28,7 @@
import os import os
import sys import sys
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import re
def ComputeCPI(benchmark): def ComputeCPI(benchmark):
'Computes and inserts CPI into benchmark stats.' 'Computes and inserts CPI into benchmark stats.'
@ -145,6 +146,11 @@ def FormatToPlot(currBenchmark):
if(sys.argv[1] == '-b'): if(sys.argv[1] == '-b'):
configList = [] configList = []
summery = 0
if(sys.argv[2] == '-s'):
summery = 1
sys.argv = sys.argv[1::]
print('summery = %d' % summery)
for config in sys.argv[2::]: for config in sys.argv[2::]:
benchmarks = ProcessFile(config) benchmarks = ProcessFile(config)
ComputeAverage(benchmarks) ComputeAverage(benchmarks)
@ -171,6 +177,8 @@ if(sys.argv[1] == '-b'):
size = len(benchmarkDict) size = len(benchmarkDict)
index = 1 index = 1
print('summery = %d' % summery)
if(summery == 0):
print('Number of plots', size) print('Number of plots', size)
for benchmarkName in benchmarkDict: for benchmarkName in benchmarkDict:
currBenchmark = benchmarkDict[benchmarkName] currBenchmark = benchmarkDict[benchmarkName]
@ -182,7 +190,37 @@ if(sys.argv[1] == '-b'):
plt.ylabel('BR Dir Miss Rate (%)') plt.ylabel('BR Dir Miss Rate (%)')
#plt.xlabel('Predictor') #plt.xlabel('Predictor')
index += 1 index += 1
#plt.tight_layout() else:
combined = benchmarkDict['All_']
(name, value) = FormatToPlot(combined)
lst = []
dct = {}
category = []
length = []
accuracy = []
for index in range(0, len(name)):
match = re.match(r"([a-z]+)([0-9]+)", name[index], re.I)
percent = 100 -value[index]
if match:
(PredType, size) = match.groups()
category.append(PredType)
length.append(size)
accuracy.append(percent)
if(PredType not in dct):
dct[PredType] = ([size], [percent])
else:
(currSize, currPercent) = dct[PredType]
currSize.append(size)
currPercent.append(percent)
dct[PredType] = (currSize, currPercent)
print(dct)
for cat in dct:
(x, y) = dct[cat]
plt.scatter(x, y, label=cat)
plt.plot(x, y)
plt.ylabel('Prediction Accuracy')
plt.xlabel('Size (b or k)')
plt.legend(loc='upper left')
plt.show() plt.show()

View File

@ -54,13 +54,15 @@ fi
cd $RISCV cd $RISCV
git clone https://github.com/riscv/riscv-gnu-toolchain git clone https://github.com/riscv/riscv-gnu-toolchain
cd riscv-gnu-toolchain cd riscv-gnu-toolchain
./configure --prefix=${RISCV} --enable-multilib --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;" git checkout 2023.01.31
./configure --prefix=${RISCV} --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;"
make -j ${NUM_THREADS} make -j ${NUM_THREADS}
make install make install
# elf2hex # elf2hex
cd $RISCV cd $RISCV
export PATH=$RISCV/riscv-gnu-toolchain/bin:$PATH #export PATH=$RISCV/riscv-gnu-toolchain/bin:$PATH
gexport PATH=$RISCV/bin:$PATH
git clone https://github.com/sifive/elf2hex.git git clone https://github.com/sifive/elf2hex.git
cd elf2hex cd elf2hex
autoreconf -i autoreconf -i
@ -87,7 +89,7 @@ cd $RISCV
git clone https://github.com/riscv-software-src/riscv-isa-sim git clone https://github.com/riscv-software-src/riscv-isa-sim
mkdir -p riscv-isa-sim/build mkdir -p riscv-isa-sim/build
cd riscv-isa-sim/build cd riscv-isa-sim/build
../configure --prefix=$RISCV --enable-commitlog ../configure --prefix=$RISCV
make -j ${NUM_THREADS} make -j ${NUM_THREADS}
make install make install
cd ../arch_test_target/spike/device cd ../arch_test_target/spike/device

View File

@ -63,7 +63,8 @@ module controller(
output logic [2:0] Funct3M, // Instruction's funct3 field output logic [2:0] Funct3M, // Instruction's funct3 field
output logic RegWriteM, // Instruction writes a register (needed for Hazard unit) output logic RegWriteM, // Instruction writes a register (needed for Hazard unit)
output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$ output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$
output logic InstrValidM, // Instruction is valid output logic InstrValidD, InstrValidE, InstrValidM, // Instruction is valid
output logic FWriteIntM, // FPU controller writes integer register file output logic FWriteIntM, // FPU controller writes integer register file
// Writeback stage control signals // Writeback stage control signals
input logic StallW, FlushW, // Stall, flush Writeback stage input logic StallW, FlushW, // Stall, flush Writeback stage
@ -97,7 +98,6 @@ module controller(
logic FenceXD; // Fence instruction logic FenceXD; // Fence instruction
logic InvalidateICacheD, FlushDCacheD;// Invalidate I$, flush D$ logic InvalidateICacheD, FlushDCacheD;// Invalidate I$, flush D$
logic CSRWriteD, CSRWriteE; // CSR write logic CSRWriteD, CSRWriteE; // CSR write
logic InstrValidD, InstrValidE; // Instruction is valid
logic PrivilegedD, PrivilegedE; // Privileged instruction logic PrivilegedD, PrivilegedE; // Privileged instruction
logic InvalidateICacheE, FlushDCacheE;// Invalidate I$, flush D$ logic InvalidateICacheE, FlushDCacheE;// Invalidate I$, flush D$
logic [`CTRLW-1:0] ControlsD; // Main Instruction Decoder control signals logic [`CTRLW-1:0] ControlsD; // Main Instruction Decoder control signals

View File

@ -54,7 +54,7 @@ module ieu (
output logic [4:0] RdM, // Destination register output logic [4:0] RdM, // Destination register
input logic [`XLEN-1:0] FIntResM, // Integer result from FPU (fmv, fclass, fcmp) input logic [`XLEN-1:0] FIntResM, // Integer result from FPU (fmv, fclass, fcmp)
output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$ output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$
output logic InstrValidM, // Instruction is valid output logic InstrValidD, InstrValidE, InstrValidM,// Instruction is valid
// Writeback stage signals // Writeback stage signals
input logic [`XLEN-1:0] FIntDivResultW, // Integer divide result from FPU fdivsqrt) input logic [`XLEN-1:0] FIntDivResultW, // Integer divide result from FPU fdivsqrt)
input logic [`XLEN-1:0] CSRReadValW, // CSR read value, input logic [`XLEN-1:0] CSRReadValW, // CSR read value,
@ -98,7 +98,7 @@ module ieu (
.PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .MemReadE, .CSRReadE, .PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .MemReadE, .CSRReadE,
.Funct3E, .Funct7E, .IntDivE, .MDUE, .W64E, .JumpE, .SCE, .BranchSignedE, .StallM, .FlushM, .MemRWM, .Funct3E, .Funct7E, .IntDivE, .MDUE, .W64E, .JumpE, .SCE, .BranchSignedE, .StallM, .FlushM, .MemRWM,
.CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM, .RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .StoreStallD); .StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .StoreStallD);
datapath dp( datapath dp(

View File

@ -42,7 +42,7 @@ module RASPredictor #(parameter int StackSize = 16 )(
logic CounterEn; logic CounterEn;
localparam Depth = $clog2(StackSize); localparam Depth = $clog2(StackSize);
logic [Depth-1:0] NextPtr, Ptr, PtrP1, PtrM1; logic [Depth-1:0] NextPtr, Ptr, P1, M1, IncDecPtr;
logic [StackSize-1:0] [`XLEN-1:0] memory; logic [StackSize-1:0] [`XLEN-1:0] memory;
integer index; integer index;
@ -71,10 +71,11 @@ module RASPredictor #(parameter int StackSize = 16 )(
assign CounterEn = PopF | PushE | RepairD; assign CounterEn = PopF | PushE | RepairD;
assign DecrementPtr = (PopF | DecRepairD) & ~IncrRepairD; assign DecrementPtr = (PopF | DecRepairD) & ~IncrRepairD;
mux2 #(Depth) PtrMux(PtrP1, PtrM1, DecrementPtr, NextPtr);
assign PtrM1 = Ptr - 1'b1; assign P1 = 1;
assign PtrP1 = Ptr + 1'b1; assign M1 = '1; // -1
mux2 #(Depth) PtrMux(P1, M1, DecrementPtr, IncDecPtr);
assign NextPtr = Ptr + IncDecPtr;
flopenr #(Depth) PTR(clk, reset, CounterEn, NextPtr, Ptr); flopenr #(Depth) PTR(clk, reset, CounterEn, NextPtr, Ptr);
@ -84,7 +85,7 @@ module RASPredictor #(parameter int StackSize = 16 )(
for(index=0; index<StackSize; index++) for(index=0; index<StackSize; index++)
memory[index] <= {`XLEN{1'b0}}; memory[index] <= {`XLEN{1'b0}};
end else if(PushE) begin end else if(PushE) begin
memory[PtrP1] <= #1 PCLinkE; memory[NextPtr] <= #1 PCLinkE;
end end
end end

View File

@ -51,6 +51,7 @@ module bpred (
input logic [31:0] PostSpillInstrRawF, // Instruction input logic [31:0] PostSpillInstrRawF, // Instruction
// Branch and jump outcome // Branch and jump outcome
input logic InstrValidD, InstrValidE,
input logic PCSrcE, // Executation stage branch is taken input logic PCSrcE, // Executation stage branch is taken
input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address
input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address) input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
@ -69,12 +70,12 @@ module bpred (
logic PredValidF; logic PredValidF;
logic [1:0] DirPredictionF; logic [1:0] DirPredictionF;
logic [3:0] BTBPredInstrClassF, PredInstrClassF, PredInstrClassD, PredInstrClassE; logic [3:0] BTBPredInstrClassF, PredInstrClassF, PredInstrClassD;
logic [`XLEN-1:0] PredPCF, RASPCF; logic [`XLEN-1:0] PredPCF, RASPCF;
logic PredictionPCWrongE; logic PredictionPCWrongE;
logic PredictionInstrClassWrongE; logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE;
logic [3:0] InstrClassF, InstrClassD, InstrClassE, InstrClassW; logic [3:0] InstrClassF, InstrClassD, InstrClassE, InstrClassW;
logic DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE, BPPredClassNonCFIWrongE; logic DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE;
logic SelBPPredF; logic SelBPPredF;
logic [`XLEN-1:0] BPPredPCF; logic [`XLEN-1:0] BPPredPCF;
@ -82,7 +83,6 @@ module bpred (
logic [`XLEN-1:0] PCCorrectE; logic [`XLEN-1:0] PCCorrectE;
logic [3:0] WrongPredInstrClassD; logic [3:0] WrongPredInstrClassD;
logic BTBTargetWrongE; logic BTBTargetWrongE;
logic RASTargetWrongE; logic RASTargetWrongE;
logic JumpOrTakenBranchE; logic JumpOrTakenBranchE;
@ -104,8 +104,7 @@ module bpred (
end else if (`BPRED_TYPE == "BPSPECULATIVEGLOBAL") begin:Predictor end else if (`BPRED_TYPE == "BPSPECULATIVEGLOBAL") begin:Predictor
speculativeglobalhistory #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, speculativeglobalhistory #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.DirPredictionF, .DirPredictionWrongE, .DirPredictionF, .DirPredictionWrongE,
.BranchInstrF(PredInstrClassF[0]), .BranchInstrD(InstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PredInstrClassF, .InstrClassD, .InstrClassE, .WrongPredInstrClassD, .PCSrcE);
.BranchInstrW(InstrClassW[0]), .WrongPredInstrClassD, .PCSrcE);
end else if (`BPRED_TYPE == "BPGSHARE") begin:Predictor end else if (`BPRED_TYPE == "BPGSHARE") begin:Predictor
gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
@ -132,20 +131,15 @@ module bpred (
-----/\----- EXCLUDED -----/\----- */ -----/\----- EXCLUDED -----/\----- */
end end
// this predictor will have two pieces of data,
// 1) A direction (1 = Taken, 0 = Not Taken)
// 2) Any information which is necessary for the predictor to build its next state.
// For a 2 bit table this is the prediction count.
// Part 2 Branch target address prediction // Part 2 Branch target address prediction
// *** For now the BTB will house the direct and indirect targets // BTB contains target address for all CFI
btb TargetPredictor(.clk, .reset, .StallF, .StallD, .StallM, .FlushD, .FlushM, btb TargetPredictor(.clk, .reset, .StallF, .StallD, .StallM, .FlushD, .FlushM,
.PCNextF, .PCF, .PCD, .PCE, .PCNextF, .PCF, .PCD, .PCE,
.PredPCF, .PredPCF,
.BTBPredInstrClassF, .BTBPredInstrClassF,
.PredValidF, .PredValidF,
.PredictionInstrClassWrongE, .AnyWrongPredInstrClassE,
.IEUAdrE, .IEUAdrE,
.InstrClassD, .InstrClassD,
.InstrClassE); .InstrClassE);
@ -205,16 +199,15 @@ module bpred (
flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, InstrClassE, InstrClassM); flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, InstrClassE, InstrClassM);
flopenrc #(4) InstrClassRegW(clk, reset, FlushW, ~StallW, InstrClassM, InstrClassW); flopenrc #(4) InstrClassRegW(clk, reset, FlushW, ~StallW, InstrClassM, InstrClassW);
flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM); flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM);
flopenrc #(1) JumpOrTakenBranchMReg(clk, reset, FlushM, ~StallM, JumpOrTakenBranchE, JumpOrTakenBranchM);
// branch predictor // branch predictor
flopenrc #(4) BPPredWrongRegM(clk, reset, FlushM, ~StallM, flopenrc #(4) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
{DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE, PredictionInstrClassWrongE}, {DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE, AnyWrongPredInstrClassE},
{DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM}); {DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM});
// pipeline the class // pipeline the class
flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, PredInstrClassF, PredInstrClassD); flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, PredInstrClassF, PredInstrClassD);
flopenrc #(4) PredInstrClassRegE(clk, reset, FlushE, ~StallE, PredInstrClassD, PredInstrClassE); flopenrc #(1) WrongInstrClassRegE(clk, reset, FlushE, ~StallE, AnyWrongPredInstrClassD, AnyWrongPredInstrClassE);
// Check the prediction // Check the prediction
// if it is a CFI then check if the next instruction address (PCD) matches the branch's target or fallthrough address. // if it is a CFI then check if the next instruction address (PCD) matches the branch's target or fallthrough address.
@ -223,11 +216,13 @@ module bpred (
// The next instruction is always valid as no other flush would occur at the same time as the branch and not // The next instruction is always valid as no other flush would occur at the same time as the branch and not
// also flush the branch. This will change in a superscaler cpu. // also flush the branch. This will change in a superscaler cpu.
assign PredictionPCWrongE = PCCorrectE != PCD; assign PredictionPCWrongE = PCCorrectE != PCD;
assign BPPredWrongE = PredictionPCWrongE & (|InstrClassE | BPPredClassNonCFIWrongE);
// The branch direction is checked inside each branch predictor, but does not actually matter for // branch class prediction wrong.
// branch miss prediction recovery. If the class or direction is wrong, but the target is correct assign WrongPredInstrClassD = PredInstrClassD ^ InstrClassD;
// we an ignore the branch miss-prediction. assign AnyWrongPredInstrClassD = |WrongPredInstrClassD;
// branch is wrong only if the PC does not match and both the Decode and Fetch stages have valid instructions.
assign BPPredWrongE = PredictionPCWrongE & InstrValidE & InstrValidD;
// Output the predicted PC or corrected PC on miss-predict. // Output the predicted PC or corrected PC on miss-predict.
// Selects the BP or PC+2/4. // Selects the BP or PC+2/4.
@ -242,39 +237,23 @@ module bpred (
if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPPredWrongM, NextValidPCE); if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPPredWrongM, NextValidPCE);
else assign NextValidPCE = PCE; else assign NextValidPCE = PCE;
// Finally we need to check if the class is wrong. When the class is wrong the BTB needs to be updated.
// Also we want to track this in a performance counter.
assign PredictionInstrClassWrongE = InstrClassE != PredInstrClassE;
// The remaining checks are used for performance counters.
// If we have a jump, jump register or jal or jalr and the PC is wrong we need to increment the performance counter.
//assign BTBPredPCWrongE = (InstrClassE[3] | InstrClassE[1] | InstrClassE[0]) & PredictionPCWrongE;
//assign BTBPredPCWrongE = TargetWrongE & (InstrClassE[3] | InstrClassE[1] | InstrClassE[0]) & PCSrcE;
assign BTBPredPCWrongE = BTBTargetWrongE;
// similar with RAS. Over counts ras if the class prediction was wrong.
//assign RASPredPCWrongE = TargetWrongE & InstrClassE[2] & PCSrcE;
assign RASPredPCWrongE = RASTargetWrongE;
// Finally if the real instruction class is non CFI but the predictor said it was we need to count.
assign BPPredClassNonCFIWrongE = PredictionInstrClassWrongE & ~|InstrClassE;
// branch class prediction wrong.
assign WrongPredInstrClassD = PredInstrClassD ^ InstrClassD;
// performance counters // performance counters
// 1. class (class wrong / minstret) (PredictionInstrClassWrongM / csr) // Correct now // 1. class (class wrong / minstret) (PredictionInstrClassWrongM / csr) // Correct now
// 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal) // 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal)
// 3. target ras (ras target wrong / class[2]) // 3. target ras (ras target wrong / class[2])
// 4. direction (br dir wrong / class[0]) // 4. direction (br dir wrong / class[0])
assign BTBTargetWrongE = (PredPCE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] | InstrClassE[3]) & PCSrcE; // Unforuantely we can't relay on PCD to infer the correctness of the BTB or RAS because the class prediction
assign RASTargetWrongE = (RASPCE != IEUAdrE) & InstrClassE[2] & PCSrcE; // could be wrong or the fall through address selected for branch predict not taken.
// By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of
// both without the above inaccuracies.
assign BTBPredPCWrongE = (PredPCE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] | InstrClassE[3]) & PCSrcE;
assign RASPredPCWrongE = (RASPCE != IEUAdrE) & InstrClassE[2] & PCSrcE;
assign JumpOrTakenBranchE = (InstrClassE[0] & PCSrcE) | InstrClassE[1] | InstrClassE[3]; assign JumpOrTakenBranchE = (InstrClassE[0] & PCSrcE) | InstrClassE[1] | InstrClassE[3];
flopenrc #(1) JumpOrTakenBranchMReg(clk, reset, FlushM, ~StallM, JumpOrTakenBranchE, JumpOrTakenBranchM);
flopenrc #(`XLEN) BTBTargetDReg(clk, reset, FlushD, ~StallD, PredPCF, PredPCD); flopenrc #(`XLEN) BTBTargetDReg(clk, reset, FlushD, ~StallD, PredPCF, PredPCD);
flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, PredPCD, PredPCE); flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, PredPCD, PredPCE);

View File

@ -39,7 +39,7 @@ module btb #(parameter int Depth = 10 ) (
output logic [3:0] BTBPredInstrClassF, // BTB's guess at instruction class output logic [3:0] BTBPredInstrClassF, // BTB's guess at instruction class
output logic PredValidF, // BTB's guess is valid output logic PredValidF, // BTB's guess is valid
// update // update
input logic PredictionInstrClassWrongE, // BTB's instruction class guess was wrong input logic AnyWrongPredInstrClassE, // BTB's instruction class guess was wrong
input logic [`XLEN-1:0] IEUAdrE, // Branch/jump target address to insert into btb input logic [`XLEN-1:0] IEUAdrE, // Branch/jump target address to insert into btb
input logic [3:0] InstrClassD, // Instruction class to insert into btb input logic [3:0] InstrClassD, // Instruction class to insert into btb
input logic [3:0] InstrClassE // Instruction class to insert into btb input logic [3:0] InstrClassE // Instruction class to insert into btb
@ -98,7 +98,7 @@ module btb #(parameter int Depth = 10 ) (
//assign PredValidF = MatchXF ? 1'b1 : TablePredValidF; //assign PredValidF = MatchXF ? 1'b1 : TablePredValidF;
assign UpdateEn = |InstrClassE | PredictionInstrClassWrongE; assign UpdateEn = |InstrClassE | AnyWrongPredInstrClassE;
// An optimization may be using a PC relative address. // An optimization may be using a PC relative address.
ram2p1r1wbe #(2**Depth, `XLEN+4) memory( ram2p1r1wbe #(2**Depth, `XLEN+4) memory(

View File

@ -36,7 +36,7 @@ module speculativeglobalhistory #(parameter int k = 10 ) (
output logic [1:0] DirPredictionF, output logic [1:0] DirPredictionF,
output logic DirPredictionWrongE, output logic DirPredictionWrongE,
// update // update
input logic BranchInstrF, BranchInstrD, BranchInstrE, BranchInstrM, BranchInstrW, input logic [3:0] PredInstrClassF, InstrClassD, InstrClassE,
input logic [3:0] WrongPredInstrClassD, input logic [3:0] WrongPredInstrClassD,
input logic PCSrcE input logic PCSrcE
); );
@ -45,20 +45,16 @@ module speculativeglobalhistory #(parameter int k = 10 ) (
logic MatchNextX, MatchXF; logic MatchNextX, MatchXF;
logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE; logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE;
logic [1:0] NewDirPredictionF, NewDirPredictionD, NewDirPredictionE; logic [1:0] NewDirPredictionE;
logic [k-1:0] GHRF;
logic GHRExtraF;
logic [k-1:0] GHRD, GHRE, GHRM, GHRW;
logic [k-1:0] GHRNextF;
logic [k-1:0] GHRNextD;
logic [k-1:0] GHRNextE, GHRNextM, GHRNextW;
logic [k-1:0] IndexNextF, IndexF;
logic [k-1:0] IndexD, IndexE;
logic [k-1:0] GHRF, GHRD, GHRE;
logic GHRLastF;
logic [k-1:0] GHRNextF, GHRNextD, GHRNextE;
logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE;
logic [1:0] ForwardNewDirPrediction, ForwardDirPredictionF; logic [1:0] ForwardNewDirPrediction, ForwardDirPredictionF;
logic FlushDOrDirWrong;
assign IndexNextF = GHRNextF; assign IndexNextF = GHRNextF;
assign IndexF = GHRF; assign IndexF = GHRF;
assign IndexD = GHRD[k-1:0]; assign IndexD = GHRD[k-1:0];
@ -70,20 +66,20 @@ module speculativeglobalhistory #(parameter int k = 10 ) (
.rd1(TableDirPredictionF), .rd1(TableDirPredictionF),
.wa2(IndexE), .wa2(IndexE),
.wd2(NewDirPredictionE), .wd2(NewDirPredictionE),
.we2(BranchInstrE & ~StallM & ~FlushM), .we2(InstrClassE[0]),
.bwe2(1'b1)); .bwe2(1'b1));
// if there are non-flushed branches in the pipeline we need to forward the prediction from that stage to the NextF demi stage // if there are non-flushed branches in the pipeline we need to forward the prediction from that stage to the NextF demi stage
// and then register for use in the Fetch stage. // and then register for use in the Fetch stage.
assign MatchF = BranchInstrF & ~FlushD & (IndexNextF == IndexF); assign MatchF = PredInstrClassF[0] & ~FlushD & (IndexNextF == IndexF);
assign MatchD = BranchInstrD & ~FlushE & (IndexNextF == IndexD); assign MatchD = InstrClassD[0] & ~FlushE & (IndexNextF == IndexD);
assign MatchE = BranchInstrE & ~FlushM & (IndexNextF == IndexE); assign MatchE = InstrClassE[0] & ~FlushM & (IndexNextF == IndexE);
assign MatchNextX = MatchF | MatchD | MatchE; assign MatchNextX = MatchF | MatchD | MatchE;
flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF);
assign ForwardNewDirPrediction = MatchF ? NewDirPredictionF : assign ForwardNewDirPrediction = MatchF ? {2{DirPredictionF[1]}} :
MatchD ? NewDirPredictionD : MatchD ? {2{DirPredictionD[1]}} :
NewDirPredictionE ; NewDirPredictionE ;
flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF); flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF);
@ -94,49 +90,37 @@ module speculativeglobalhistory #(parameter int k = 10 ) (
flopenr #(2) PredictionRegD(clk, reset, ~StallD, DirPredictionF, DirPredictionD); flopenr #(2) PredictionRegD(clk, reset, ~StallD, DirPredictionF, DirPredictionD);
flopenr #(2) PredictionRegE(clk, reset, ~StallE, DirPredictionD, DirPredictionE); flopenr #(2) PredictionRegE(clk, reset, ~StallE, DirPredictionD, DirPredictionE);
// New prediction pipeline
assign NewDirPredictionF = {DirPredictionF[1], DirPredictionF[1]};
flopenr #(2) NewPredDReg(clk, reset, ~StallD, NewDirPredictionF, NewDirPredictionD);
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE));
// GHR pipeline // GHR pipeline
// this version fails the regression test do to pessimistic x propagation.
// assign GHRNextF = FlushD | DirPredictionWrongE ? GHRNextD[k-1:0] :
// BranchInstrF ? {DirPredictionF[1], GHRF[k-1:1]} :
// GHRF;
always_comb begin // If Fetch has a branch, speculatively insert prediction into the GHR
if(FlushD | DirPredictionWrongE) begin // If the front end is flushed or the direction prediction is wrong, reset to
GHRNextF = GHRNextD[k-1:0]; // most recent valid GHR. For a BP wrong this is GHRD with the correct prediction shifted in.
end else if(BranchInstrF) GHRNextF = {DirPredictionF[1], GHRF[k-1:1]}; // For FlushE this is GHRE. GHRNextE is both.
else GHRNextF = GHRF; assign FlushDOrDirWrong = FlushD | DirPredictionWrongE;
end mux3 #(k) GHRFMux(GHRF, {DirPredictionF[1], GHRF[k-1:1]}, GHRNextE[k-1:0],
{FlushDOrDirWrong, PredInstrClassF[0]}, GHRNextF);
flopenr #(k) GHRFReg(clk, reset, (~StallF) | FlushD, GHRNextF, GHRF); // Need 1 extra bit to store the shifted out GHRF if repair needs to back shift.
flopenr #(1) GHRFExtraReg(clk, reset, (~StallF) | FlushD, GHRF[0], GHRExtraF); flopenr #(k) GHRFReg(clk, reset, ~StallF | FlushDOrDirWrong, GHRNextF, GHRF);
flopenr #(1) GHRFLastReg(clk, reset, ~StallF | FlushDOrDirWrong, GHRF[0], GHRLastF);
// use with out instruction class prediction // With instruction class prediction, the class could be wrong and is checked in Decode.
//assign GHRNextD = FlushD ? GHRNextE[k-1:0] : GHRF[k-1:0]; // If it is wrong and branch does exist then shift right and insert the prediction.
// with instruction class prediction // If the branch does not exist then shift left and use GHRLastF to restore the LSB.
assign GHRNextD = (FlushD | DirPredictionWrongE) ? GHRNextE[k-1:0] : logic [k-1:0] GHRClassWrong;
WrongPredInstrClassD[0] & BranchInstrD ? {DirPredictionD[1], GHRF[k-1:1]} : // shift right mux2 #(k) GHRClassWrongMux({DirPredictionD[1], GHRF[k-1:1]}, {GHRF[k-2:0], GHRLastF}, InstrClassD[0], GHRClassWrong);
WrongPredInstrClassD[0] & ~BranchInstrD ? {GHRF[k-2:0], GHRExtraF}: // shift left // As with GHRF FlushD and wrong direction prediction flushes the pipeline and restores to GHRNextE.
GHRF[k-1:0]; mux3 #(k) GHRDMux(GHRF, GHRClassWrong, GHRNextE, {FlushDOrDirWrong, WrongPredInstrClassD[0]}, GHRNextD);
flopenr #(k) GHRDReg(clk, reset, (~StallD) | FlushD, GHRNextD, GHRD); flopenr #(k) GHRDReg(clk, reset, ~StallD | FlushDOrDirWrong, GHRNextD, GHRD);
assign GHRNextE = BranchInstrE & ~FlushM ? {PCSrcE, GHRD[k-2:0]} : // if the branch is not flushed mux3 #(k) GHREMux(GHRD, GHRE, {PCSrcE, GHRD[k-2:0]}, {InstrClassE[0] & ~FlushM, FlushE}, GHRNextE);
FlushE ? GHRNextM : // branch is flushed
GHRD;
flopenr #(k) GHREReg(clk, reset, (~StallE) | FlushE, GHRNextE, GHRE);
assign GHRNextM = FlushM ? GHRNextW : GHRE; flopenr #(k) GHREReg(clk, reset, ((InstrClassE[0] & ~FlushM) & ~StallE) | FlushE, GHRNextE, GHRE);
flopenr #(k) GHRMReg(clk, reset, (~StallM) | FlushM, GHRNextM, GHRM);
assign GHRNextW = FlushW ? GHRW : GHRM; assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & InstrClassE[0];
flopenr #(k) GHRWReg(clk, reset, (BranchInstrW & ~StallW) | FlushW, GHRNextW, GHRW);
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE;
endmodule endmodule

View File

@ -35,6 +35,7 @@ module ifu (
// Command from CPU // Command from CPU
input logic InvalidateICacheM, // Clears all instruction cache valid bits input logic InvalidateICacheM, // Clears all instruction cache valid bits
input logic CSRWriteFenceM, // CSR write or fence instruction, PCNextF = the next valid PC (typically PCE) input logic CSRWriteFenceM, // CSR write or fence instruction, PCNextF = the next valid PC (typically PCE)
input logic InstrValidD, InstrValidE, InstrValidM,
// Bus interface // Bus interface
output logic [`PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU output logic [`PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU
input logic [`XLEN-1:0] HRDATA, // Bus read data from IFU to EBU input logic [`XLEN-1:0] HRDATA, // Bus read data from IFU to EBU
@ -322,7 +323,7 @@ module ifu (
if (`BPRED_SUPPORTED) begin : bpred if (`BPRED_SUPPORTED) begin : bpred
bpred bpred(.clk, .reset, bpred bpred(.clk, .reset,
.StallF, .StallD, .StallE, .StallM, .StallW, .StallF, .StallD, .StallE, .StallM, .StallW,
.FlushD, .FlushE, .FlushM, .FlushW, .FlushD, .FlushE, .FlushM, .FlushW, .InstrValidD, .InstrValidE,
.InstrD, .PCNextF, .PCPlus2or4F, .PCNext1F, .PCE, .PCM, .PCSrcE, .IEUAdrE, .PCF, .NextValidPCE, .InstrD, .PCNextF, .PCPlus2or4F, .PCNext1F, .PCE, .PCM, .PCSrcE, .IEUAdrE, .PCF, .NextValidPCE,
.PCD, .PCLinkE, .InstrClassM, .BPPredWrongE, .PostSpillInstrRawF, .JumpOrTakenBranchM, .BPPredWrongM, .PCD, .PCLinkE, .InstrClassM, .BPPredWrongE, .PostSpillInstrRawF, .JumpOrTakenBranchM, .BPPredWrongM,
.DirPredictionWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM); .DirPredictionWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM);

View File

@ -145,7 +145,7 @@ module csrsr (
STATUS_MXR_INT <= #1 0; STATUS_MXR_INT <= #1 0;
STATUS_SUM_INT <= #1 0; STATUS_SUM_INT <= #1 0;
STATUS_MPRV_INT <= #1 0; // Per Priv 3.3 STATUS_MPRV_INT <= #1 0; // Per Priv 3.3
STATUS_FS_INT <= #1 `F_SUPPORTED ? 2'b01 : 2'b00; STATUS_FS_INT <= #1 `F_SUPPORTED ? 2'b00 : 2'b00; // leave floating-point off until activated, even if F_SUPPORTED
STATUS_MPP <= #1 0; STATUS_MPP <= #1 0;
STATUS_SPP <= #1 0; STATUS_SPP <= #1 0;
STATUS_MPIE <= #1 0; STATUS_MPIE <= #1 0;
@ -156,8 +156,6 @@ module csrsr (
STATUS_SBE <= #1 0; STATUS_SBE <= #1 0;
STATUS_UBE <= #1 0; STATUS_UBE <= #1 0;
end else if (~StallW) begin end else if (~StallW) begin
if (FRegWriteM | WriteFRMM | WriteFFLAGSM) STATUS_FS_INT <= #1 2'b11; // mark Float State dirty *** this should happen in M stage, be part of if/else;
if (TrapM) begin if (TrapM) begin
// Update interrupt enables per Privileged Spec p. 21 // Update interrupt enables per Privileged Spec p. 21
// y = PrivilegeModeW // y = PrivilegeModeW
@ -211,6 +209,6 @@ module csrsr (
STATUS_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5]; STATUS_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5];
STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1]; STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1];
STATUS_UBE <= #1 CSRWriteValM[6] & `U_SUPPORTED & `BIGENDIAN_SUPPORTED; STATUS_UBE <= #1 CSRWriteValM[6] & `U_SUPPORTED & `BIGENDIAN_SUPPORTED;
end end else if (FRegWriteM | WriteFRMM | WriteFFLAGSM) STATUS_FS_INT <= #1 2'b11;
end end
endmodule endmodule

View File

@ -68,7 +68,7 @@ module wallypipelinedcore (
logic [`XLEN-1:0] CSRReadValW, MDUResultW; logic [`XLEN-1:0] CSRReadValW, MDUResultW;
logic [`XLEN-1:0] UnalignedPCNextF, PCNext2F; logic [`XLEN-1:0] UnalignedPCNextF, PCNext2F;
logic [1:0] MemRWM; logic [1:0] MemRWM;
logic InstrValidM; logic InstrValidD, InstrValidE, InstrValidM;
logic InstrMisalignedFaultM; logic InstrMisalignedFaultM;
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD; logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM; logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM;
@ -166,6 +166,7 @@ module wallypipelinedcore (
// instruction fetch unit: PC, branch prediction, instruction cache // instruction fetch unit: PC, branch prediction, instruction cache
ifu ifu(.clk, .reset, ifu ifu(.clk, .reset,
.StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.InstrValidM, .InstrValidE, .InstrValidD,
// Fetch // Fetch
.HRDATA, .PCFSpill, .IFUHADDR, .PCNext2F, .HRDATA, .PCFSpill, .IFUHADDR, .PCNext2F,
.IFUStallF, .IFUHBURST, .IFUHTRANS, .IFUHSIZE, .IFUHREADY, .IFUHWRITE, .IFUStallF, .IFUHBURST, .IFUHTRANS, .IFUHSIZE, .IFUHREADY, .IFUHWRITE,
@ -201,7 +202,7 @@ module wallypipelinedcore (
.RdE, .RdM, .FIntResM, .InvalidateICacheM, .FlushDCacheM, .RdE, .RdM, .FIntResM, .InvalidateICacheM, .FlushDCacheM,
// Writeback stage // Writeback stage
.CSRReadValW, .MDUResultW, .FIntDivResultW, .RdW, .ReadDataW(ReadDataW[`XLEN-1:0]), .CSRReadValW, .MDUResultW, .FIntDivResultW, .RdW, .ReadDataW(ReadDataW[`XLEN-1:0]),
.InstrValidM, .FCvtIntResW, .FCvtIntW, .InstrValidM, .InstrValidE, .InstrValidD, .FCvtIntResW, .FCvtIntW,
// hazards // hazards
.StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD, .PCSrcE, .FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD, .PCSrcE,

View File

@ -2,8 +2,15 @@
TARGET = debug TARGET = debug
$(TARGET).signature.output: $(TARGET).elf.memfile $(TARGET).elf
spike --isa=rv64gc +signature=$(TARGET).signature.output +signature-granularity=4 $(TARGET).elf
# diff --ignore-case $(TARGET).signature.output $(TARGET).reference_output || exit
# echo "Signature matches! Success!"
mkdir -p ../work
cp -f * ../work
$(TARGET).elf.memfile:$(TARGET).elf $(TARGET).elf.objdump.addr $(TARGET).elf.memfile:$(TARGET).elf $(TARGET).elf.objdump.addr
riscv64-unknown-elf-elf2hex --bit-width $(if $(findstring rv64,$*),64,32) --input $< --output $@ riscv64-unknown-elf-elf2hex --bit-width 64 --input $< --output $@
$(TARGET).elf.objdump.addr: $(TARGET).elf.objdump $(TARGET).elf.objdump.addr: $(TARGET).elf.objdump
extractFunctionRadix.sh $< extractFunctionRadix.sh $<
@ -15,13 +22,9 @@ $(TARGET).elf: $(TARGET).S Makefile
riscv64-unknown-elf-gcc -g -o $(TARGET).elf -march=rv64gc -mabi=lp64 -mcmodel=medany \ riscv64-unknown-elf-gcc -g -o $(TARGET).elf -march=rv64gc -mabi=lp64 -mcmodel=medany \
-nostartfiles -T$(WALLY)/examples/link/link.ld $(TARGET).S -nostartfiles -T$(WALLY)/examples/link/link.ld $(TARGET).S
sim:
spike --isa=rv64gc +signature=$(TARGET).signature.output +signature-granularity=8 $(TARGET).elf
diff --ignore-case $(TARGET).signature.output $(TARGET).reference_output || exit
echo "Signature matches! Success!"
clean: clean:
rm -f $(TARGET).elf $(TARGET).elf.* rm -f $(TARGET).elf $(TARGET).elf.* *.signature.output

View File

@ -5,6 +5,8 @@
.global rvtest_entry_point .global rvtest_entry_point
rvtest_entry_point: rvtest_entry_point:
lui t0, 0x1e # turn on Floating point and XS
csrs mstatus, t0
# openhwgroup/cvw Issue #55 # openhwgroup/cvw Issue #55
la a6, begin_signature la a6, begin_signature

View File

@ -1,21 +1,12 @@
// //
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/////////////////////////////////////////// ///////////////////////////////////////////
#include "model_test.h" #include "model_test.h"
#include "arch_test.h" #include "arch_test.h"
RVTEST_ISA("RV64I")
.section .text.init .section .text.init
.globl rvtest_entry_point .globl rvtest_entry_point
@ -23,4 +14,7 @@ rvtest_entry_point:
RVMODEL_BOOT RVMODEL_BOOT
RVTEST_CODE_BEGIN RVTEST_CODE_BEGIN
RVTEST_CASE(0,"//check ISA:=regex(.*64.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;",temp)
RVTEST_SIGBASE( x6, wally_signature) RVTEST_SIGBASE( x6, wally_signature)