forked from Github_Repos/cvw
Merge remote-tracking branch 'upstream/main' into main
This commit is contained in:
commit
f91d74896a
@ -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
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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(
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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(
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user