forked from Github_Repos/cvw
Merge remote-tracking branch 'upstream/main' into bit-manip
This commit is contained in:
commit
5fe8b08253
@ -1 +1 @@
|
|||||||
Subproject commit ee028eb325525148a34420a4ca7959b24220a91e
|
Subproject commit a3b7f0c2cf89652b8a0cba3146890c512ff8ba44
|
@ -156,7 +156,7 @@ def GeometricAverage(benchmarks, field):
|
|||||||
return Product ** (1.0/index)
|
return Product ** (1.0/index)
|
||||||
|
|
||||||
def ComputeGeometricAverage(benchmarks):
|
def ComputeGeometricAverage(benchmarks):
|
||||||
fields = ['BDMR', 'BTMR', 'RASMPR', 'ClassMPR', 'ICacheMR', 'DCacheMR']
|
fields = ['BDMR', 'BTMR', 'RASMPR', 'ClassMPR', 'ICacheMR', 'DCacheMR', 'CPI']
|
||||||
AllAve = {}
|
AllAve = {}
|
||||||
for field in fields:
|
for field in fields:
|
||||||
Product = 1
|
Product = 1
|
||||||
@ -248,11 +248,11 @@ if(sys.argv[1] == '-b'):
|
|||||||
dct[PredType] = (currSize, currPercent)
|
dct[PredType] = (currSize, currPercent)
|
||||||
print(dct)
|
print(dct)
|
||||||
fig, axes = plt.subplots()
|
fig, axes = plt.subplots()
|
||||||
marker={'twobit' : '^', 'gshare' : 'o', 'global' : 's', 'gshareBasic' : '*', 'globalBasic' : 'x'}
|
marker={'twobit' : '^', 'gshare' : 'o', 'global' : 's', 'gshareBasic' : '*', 'globalBasic' : 'x', 'btb': 'x'}
|
||||||
colors={'twobit' : 'black', 'gshare' : 'blue', 'global' : 'dodgerblue', 'gshareBasic' : 'turquoise', 'globalBasic' : 'lightsteelblue'}
|
colors={'twobit' : 'black', 'gshare' : 'blue', 'global' : 'dodgerblue', 'gshareBasic' : 'turquoise', 'globalBasic' : 'lightsteelblue', 'btb' : 'blue'}
|
||||||
for cat in dct:
|
for cat in dct:
|
||||||
(x, y) = dct[cat]
|
(x, y) = dct[cat]
|
||||||
x=[int(2**int(v)/4) for v in x]
|
x=[int(2**int(v)) for v in x]
|
||||||
print(x, y)
|
print(x, y)
|
||||||
axes.plot(x,y, color=colors[cat])
|
axes.plot(x,y, color=colors[cat])
|
||||||
axes.scatter(x,y, label=cat, marker=marker[cat], color=colors[cat])
|
axes.scatter(x,y, label=cat, marker=marker[cat], color=colors[cat])
|
||||||
@ -262,9 +262,9 @@ if(sys.argv[1] == '-b'):
|
|||||||
axes.legend(loc='upper left')
|
axes.legend(loc='upper left')
|
||||||
axes.set_xscale("log")
|
axes.set_xscale("log")
|
||||||
axes.set_ylabel('Prediction Accuracy')
|
axes.set_ylabel('Prediction Accuracy')
|
||||||
axes.set_xlabel('Size (bytes)')
|
axes.set_xlabel('Entries')
|
||||||
axes.set_xticks([16, 64, 256, 1024, 4096, 16384])
|
axes.set_xticks([64, 256, 1024, 4096, 16384, 65536])
|
||||||
axes.set_xticklabels([16, 64, 256, 1024, 4096, 16384])
|
axes.set_xticklabels([64, 256, 1024, 4096, 16384, 65536])
|
||||||
axes.grid(color='b', alpha=0.5, linestyle='dashed', linewidth=0.5)
|
axes.grid(color='b', alpha=0.5, linestyle='dashed', linewidth=0.5)
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
@ -272,7 +272,9 @@ if(sys.argv[1] == '-b'):
|
|||||||
else:
|
else:
|
||||||
# steps 1 and 2
|
# steps 1 and 2
|
||||||
benchmarks = ProcessFile(sys.argv[1])
|
benchmarks = ProcessFile(sys.argv[1])
|
||||||
ComputeAverage(benchmarks)
|
print(benchmarks[0])
|
||||||
|
ComputeAll(benchmarks)
|
||||||
|
ComputeGeometricAverage(benchmarks)
|
||||||
# 3 process into useful data
|
# 3 process into useful data
|
||||||
# cache hit rates
|
# cache hit rates
|
||||||
# cache fill time
|
# cache fill time
|
||||||
@ -280,7 +282,6 @@ else:
|
|||||||
# hazard counts
|
# hazard counts
|
||||||
# CPI
|
# CPI
|
||||||
# instruction distribution
|
# instruction distribution
|
||||||
ComputeAll(benchmarks)
|
|
||||||
for benchmark in benchmarks:
|
for benchmark in benchmarks:
|
||||||
printStats(benchmark)
|
printStats(benchmark)
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@
|
|||||||
|
|
||||||
`define BPRED_SUPPORTED 1
|
`define BPRED_SUPPORTED 1
|
||||||
`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
|
`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
|
||||||
`define BPRED_SIZE 10
|
`define BPRED_SIZE 16
|
||||||
`define BTB_SIZE 10
|
`define BTB_SIZE 10
|
||||||
|
|
||||||
`define SVADU_SUPPORTED 0
|
`define SVADU_SUPPORTED 0
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
|
#--showoverrides
|
||||||
|
#--help --helpall
|
||||||
|
--traceregs
|
||||||
|
|
||||||
--override cpu/show_c_prefix=T
|
--override cpu/show_c_prefix=T
|
||||||
--override cpu/unaligned=F
|
--override cpu/unaligned=F
|
||||||
--override cpu/ignore_non_leaf_DAU=1
|
--override cpu/ignore_non_leaf_DAU=1
|
||||||
|
--override cpu/wfi_is_nop=T
|
||||||
|
|
||||||
# Enable the Imperas instruction coverage
|
# Enable the Imperas instruction coverage
|
||||||
#-extlib refRoot/cpu/cv=imperas.com/intercept/riscvInstructionCoverage/1.0
|
#-extlib refRoot/cpu/cv=imperas.com/intercept/riscvInstructionCoverage/1.0
|
||||||
@ -33,3 +38,6 @@
|
|||||||
|
|
||||||
# ignore settings of bits DAU for non leaf page table walks
|
# ignore settings of bits DAU for non leaf page table walks
|
||||||
--override cpu/ignore_non_leaf_DAU=1
|
--override cpu/ignore_non_leaf_DAU=1
|
||||||
|
|
||||||
|
# mimpid = 0x100
|
||||||
|
--override cpu/mimpid=0x100
|
||||||
|
@ -29,4 +29,4 @@
|
|||||||
IMPERAS_TOOLS=$(pwd)/imperas.ic \
|
IMPERAS_TOOLS=$(pwd)/imperas.ic \
|
||||||
OTHERFLAGS="+TRACE2LOG_ENABLE=1 VERBOSE=1" \
|
OTHERFLAGS="+TRACE2LOG_ENABLE=1 VERBOSE=1" \
|
||||||
TESTDIR=${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m/privilege/src/Lee.S/ \
|
TESTDIR=${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m/privilege/src/Lee.S/ \
|
||||||
vsim -do "do wally-pipelined-imperas.do rv64gc"
|
vsim -do "do wally-imperas.do rv64gc"
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
module hazard (
|
module hazard (
|
||||||
// Detect hazards
|
// Detect hazards
|
||||||
input logic BPPredWrongE, CSRWriteFenceM, RetM, TrapM,
|
input logic BPWrongE, CSRWriteFenceM, RetM, TrapM,
|
||||||
input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD,
|
input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD,
|
||||||
input logic LSUStallM, IFUStallF,
|
input logic LSUStallM, IFUStallF,
|
||||||
input logic FCvtIntStallD, FPUStallD,
|
input logic FCvtIntStallD, FPUStallD,
|
||||||
@ -65,8 +65,8 @@ module hazard (
|
|||||||
// Similarly, CSR writes and fences flush all subsequent instructions and refetch them in light of the new operating modes and cache/TLB contents
|
// Similarly, CSR writes and fences flush all subsequent instructions and refetch them in light of the new operating modes and cache/TLB contents
|
||||||
// Branch misprediction is found in the Execute stage and must flush the next two instructions.
|
// Branch misprediction is found in the Execute stage and must flush the next two instructions.
|
||||||
// However, an active division operation resides in the Execute stage, and when the BP incorrectly mispredicts the divide as a taken branch, the divde must still complete
|
// However, an active division operation resides in the Execute stage, and when the BP incorrectly mispredicts the divide as a taken branch, the divde must still complete
|
||||||
assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPPredWrongE;
|
assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE;
|
||||||
assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPPredWrongE & ~(DivBusyE | FDivBusyE));
|
assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE));
|
||||||
assign FlushMCause = TrapM | RetM | CSRWriteFenceM;
|
assign FlushMCause = TrapM | RetM | CSRWriteFenceM;
|
||||||
assign FlushWCause = TrapM;
|
assign FlushWCause = TrapM;
|
||||||
|
|
||||||
|
@ -38,7 +38,9 @@ module controller(
|
|||||||
output logic [2:0] ImmSrcD, // Type of immediate extension
|
output logic [2:0] ImmSrcD, // Type of immediate extension
|
||||||
input logic IllegalIEUFPUInstrD, // Illegal IEU and FPU instruction
|
input logic IllegalIEUFPUInstrD, // Illegal IEU and FPU instruction
|
||||||
output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers
|
output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers
|
||||||
// Execute stage control signals
|
output logic JumpD, // Jump instruction
|
||||||
|
output logic BranchD, // Branch instruction
|
||||||
|
// Execute stage control signals
|
||||||
input logic StallE, FlushE, // Stall, flush Execute stage
|
input logic StallE, FlushE, // Stall, flush Execute stage
|
||||||
input logic [1:0] FlagsE, // Comparison flags ({eq, lt})
|
input logic [1:0] FlagsE, // Comparison flags ({eq, lt})
|
||||||
input logic FWriteIntE, // Write integer register, coming from FPU controller
|
input logic FWriteIntE, // Write integer register, coming from FPU controller
|
||||||
@ -52,7 +54,8 @@ module controller(
|
|||||||
output logic IntDivE, // Integer divide
|
output logic IntDivE, // Integer divide
|
||||||
output logic MDUE, // MDU (multiply/divide) operatio
|
output logic MDUE, // MDU (multiply/divide) operatio
|
||||||
output logic W64E, // RV64 W-type operation
|
output logic W64E, // RV64 W-type operation
|
||||||
output logic JumpE, // jump instruction
|
output logic JumpE, // jump instruction
|
||||||
|
output logic BranchE, // Branch instruction
|
||||||
output logic SCE, // Store Conditional instruction
|
output logic SCE, // Store Conditional instruction
|
||||||
output logic BranchSignedE, // Branch comparison operands are signed (if it's a branch)
|
output logic BranchSignedE, // Branch comparison operands are signed (if it's a branch)
|
||||||
output logic [3:0] BSelectE, // One-Hot encoding of if it's ZBA_ZBB_ZBC_ZBS instruction
|
output logic [3:0] BSelectE, // One-Hot encoding of if it's ZBA_ZBB_ZBC_ZBS instruction
|
||||||
@ -66,9 +69,7 @@ module controller(
|
|||||||
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 InstrValidD, InstrValidE, InstrValidM, // Instruction is valid
|
output logic InstrValidD, InstrValidE, InstrValidM, // Instruction is valid
|
||||||
output logic BranchD, BranchE,
|
output logic FenceM, // Fence instruction
|
||||||
output logic JumpD,
|
|
||||||
|
|
||||||
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
|
||||||
@ -116,7 +117,7 @@ module controller(
|
|||||||
logic IEURegWriteE; // Register write
|
logic IEURegWriteE; // Register write
|
||||||
logic IllegalERegAdrD; // RV32E attempts to write upper 16 registers
|
logic IllegalERegAdrD; // RV32E attempts to write upper 16 registers
|
||||||
logic [1:0] AtomicE; // Atomic instruction
|
logic [1:0] AtomicE; // Atomic instruction
|
||||||
logic FenceD, FenceE, FenceM; // Fence instruction
|
logic FenceD, FenceE; // Fence instruction
|
||||||
logic SFenceVmaD; // sfence.vma instruction
|
logic SFenceVmaD; // sfence.vma instruction
|
||||||
logic IntDivM; // Integer divide instruction
|
logic IntDivM; // Integer divide instruction
|
||||||
logic [3:0] BSelectD; // One-Hot encoding if it's ZBA_ZBB_ZBC_ZBS instruction in decode stage
|
logic [3:0] BSelectD; // One-Hot encoding if it's ZBA_ZBB_ZBC_ZBS instruction in decode stage
|
||||||
|
@ -71,7 +71,8 @@ module ieu (
|
|||||||
output logic FCvtIntStallD, LoadStallD, // Stall causes from IEU to hazard unit
|
output logic FCvtIntStallD, LoadStallD, // Stall causes from IEU to hazard unit
|
||||||
output logic MDUStallD, CSRRdStallD, StoreStallD,
|
output logic MDUStallD, CSRRdStallD, StoreStallD,
|
||||||
output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction
|
output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction
|
||||||
output logic CSRWriteFenceM // CSR write or fence instruction needs to flush subsequent instructions
|
output logic CSRWriteFenceM, // CSR write or fence instruction needs to flush subsequent instructions
|
||||||
|
output logic FenceM
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [2:0] ImmSrcD; // Select type of immediate extension
|
logic [2:0] ImmSrcD; // Select type of immediate extension
|
||||||
@ -102,7 +103,7 @@ controller c(
|
|||||||
.Funct3E, .IntDivE, .MDUE, .W64E, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .BSelectE, .ZBBSelectE, .StallM, .FlushM, .MemRWM,
|
.Funct3E, .IntDivE, .MDUE, .W64E, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .BSelectE, .ZBBSelectE, .StallM, .FlushM, .MemRWM,
|
||||||
.CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
|
.CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
|
||||||
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
|
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
|
||||||
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .StoreStallD);
|
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .FenceM, .StoreStallD);
|
||||||
|
|
||||||
datapath dp(
|
datapath dp(
|
||||||
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,
|
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,
|
||||||
|
@ -33,11 +33,11 @@ module RASPredictor #(parameter int StackSize = 16 )(
|
|||||||
input logic clk,
|
input logic clk,
|
||||||
input logic reset,
|
input logic reset,
|
||||||
input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM,
|
input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM,
|
||||||
input logic WrongBPRetD, // Prediction class is wrong
|
input logic BPReturnWrongD, // Prediction class is wrong
|
||||||
input logic RetD,
|
input logic ReturnD,
|
||||||
input logic RetE, JalE, // Instr class
|
input logic ReturnE, CallE, // Instr class
|
||||||
input logic BPRetF,
|
input logic BPReturnF,
|
||||||
input logic [`XLEN-1:0] PCLinkE, // PC of instruction after a jal
|
input logic [`XLEN-1:0] PCLinkE, // PC of instruction after a call
|
||||||
output logic [`XLEN-1:0] RASPCF // Top of the stack
|
output logic [`XLEN-1:0] RASPCF // Top of the stack
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -54,21 +54,21 @@ module RASPredictor #(parameter int StackSize = 16 )(
|
|||||||
logic IncrRepairD, DecRepairD;
|
logic IncrRepairD, DecRepairD;
|
||||||
|
|
||||||
logic DecrementPtr;
|
logic DecrementPtr;
|
||||||
logic FlushedRetDE;
|
logic FlushedReturnDE;
|
||||||
logic WrongPredRetD;
|
logic WrongPredReturnD;
|
||||||
|
|
||||||
|
|
||||||
assign PopF = BPRetF & ~StallD & ~FlushD;
|
assign PopF = BPReturnF & ~StallD & ~FlushD;
|
||||||
assign PushE = JalE & ~StallM & ~FlushM;
|
assign PushE = CallE & ~StallM & ~FlushM;
|
||||||
|
|
||||||
assign WrongPredRetD = (WrongBPRetD) & ~StallE & ~FlushE;
|
assign WrongPredReturnD = (BPReturnWrongD) & ~StallE & ~FlushE;
|
||||||
assign FlushedRetDE = (~StallE & FlushE & RetD) | (~StallM & FlushM & RetE); // flushed ret
|
assign FlushedReturnDE = (~StallE & FlushE & ReturnD) | (~StallM & FlushM & ReturnE); // flushed return
|
||||||
|
|
||||||
assign RepairD = WrongPredRetD | FlushedRetDE ;
|
assign RepairD = WrongPredReturnD | FlushedReturnDE ;
|
||||||
|
|
||||||
assign IncrRepairD = FlushedRetDE | (WrongPredRetD & ~RetD); // Guessed it was a ret, but its not
|
assign IncrRepairD = FlushedReturnDE | (WrongPredReturnD & ~ReturnD); // Guessed it was a return, but its not
|
||||||
|
|
||||||
assign DecRepairD = WrongPredRetD & RetD; // Guessed non ret but is a ret.
|
assign DecRepairD = WrongPredReturnD & ReturnD; // Guessed non return but is a return.
|
||||||
|
|
||||||
assign CounterEn = PopF | PushE | RepairD;
|
assign CounterEn = PopF | PushE | RepairD;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ module bpred (
|
|||||||
input logic [31:0] InstrD, // Decompressed decode stage instruction. Used to decode instruction class
|
input logic [31:0] InstrD, // Decompressed decode stage instruction. Used to decode instruction class
|
||||||
input logic [`XLEN-1:0] PCNextF, // Next Fetch Address
|
input logic [`XLEN-1:0] PCNextF, // Next Fetch Address
|
||||||
input logic [`XLEN-1:0] PCPlus2or4F, // PCF+2/4
|
input logic [`XLEN-1:0] PCPlus2or4F, // PCF+2/4
|
||||||
output logic [`XLEN-1:0] PCNext1F, // Branch Predictor predicted or corrected fetch address on miss prediction
|
output logic [`XLEN-1:0] PC1NextF, // Branch Predictor predicted or corrected fetch address on miss prediction
|
||||||
output logic [`XLEN-1:0] NextValidPCE, // Address of next valid instruction after the instruction in the Memory stage
|
output logic [`XLEN-1:0] NextValidPCE, // Address of next valid instruction after the instruction in the Memory stage
|
||||||
|
|
||||||
// Update Predictor
|
// Update Predictor
|
||||||
@ -58,74 +58,75 @@ module bpred (
|
|||||||
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] IEUAdrM, // The branch/jump target address
|
input logic [`XLEN-1:0] IEUAdrM, // 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)
|
||||||
output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
|
output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as call, return, jr (not return), j, br
|
||||||
output logic JumpOrTakenBranchM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
|
|
||||||
|
|
||||||
// Report branch prediction status
|
// Report branch prediction status
|
||||||
output logic BPPredWrongE, // Prediction is wrong
|
output logic BPWrongE, // Prediction is wrong
|
||||||
output logic BPPredWrongM, // Prediction is wrong
|
output logic BPWrongM, // Prediction is wrong
|
||||||
output logic DirPredictionWrongM, // Prediction direction is wrong
|
output logic BPDirPredWrongM, // Prediction direction is wrong
|
||||||
output logic BTBPredPCWrongM, // Prediction target wrong
|
output logic BTAWrongM, // Prediction target wrong
|
||||||
output logic RASPredPCWrongM, // RAS prediction is wrong
|
output logic RASPredPCWrongM, // RAS prediction is wrong
|
||||||
output logic PredictionInstrClassWrongM // Class prediction is wrong
|
output logic IClassWrongM // Class prediction is wrong
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [1:0] DirPredictionF;
|
logic [1:0] BPDirPredF;
|
||||||
|
|
||||||
logic [`XLEN-1:0] BTAF, RASPCF;
|
logic [`XLEN-1:0] BTAF, RASPCF;
|
||||||
logic PredictionPCWrongE;
|
logic BPPCWrongE;
|
||||||
logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE;
|
logic IClassWrongE;
|
||||||
logic DirPredictionWrongE;
|
logic BPDirPredWrongE;
|
||||||
|
|
||||||
logic BPPCSrcF;
|
logic BPPCSrcF;
|
||||||
logic [`XLEN-1:0] BPPredPCF;
|
logic [`XLEN-1:0] BPPCF;
|
||||||
logic [`XLEN-1:0] PCNext0F;
|
logic [`XLEN-1:0] PC0NextF;
|
||||||
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 [`XLEN-1:0] BTAD;
|
logic [`XLEN-1:0] BTAD;
|
||||||
|
|
||||||
logic BTBJalF, BTBRetF, BTBJumpF, BTBBranchF;
|
logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF;
|
||||||
logic BPBranchF, BPJumpF, BPRetF, BPJalF;
|
logic BPBranchF, BPJumpF, BPReturnF, BPCallF;
|
||||||
logic BPBranchD, BPJumpD, BPRetD, BPJalD;
|
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
|
||||||
logic RetD, JalD;
|
logic ReturnD, CallD;
|
||||||
logic RetE, JalE;
|
logic ReturnE, CallE;
|
||||||
logic BranchM, JumpM, RetM, JalM;
|
logic BranchM, JumpM, ReturnM, CallM;
|
||||||
logic BranchW, JumpW, RetW, JalW;
|
logic BranchW, JumpW, ReturnW, CallW;
|
||||||
logic WrongBPRetD;
|
logic BPReturnWrongD;
|
||||||
logic [`XLEN-1:0] PCW, IEUAdrW;
|
logic [`XLEN-1:0] BTAE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Part 1 branch direction prediction
|
// Part 1 branch direction prediction
|
||||||
// look into the 2 port Sram model. something is wrong.
|
// look into the 2 port Sram model. something is wrong.
|
||||||
if (`BPRED_TYPE == "BP_TWOBIT") begin:Predictor
|
if (`BPRED_TYPE == "BP_TWOBIT") begin:Predictor
|
||||||
twoBitPredictor #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW,
|
twoBitPredictor #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW,
|
||||||
.FlushD, .FlushE, .FlushM, .FlushW,
|
.FlushD, .FlushE, .FlushM, .FlushW,
|
||||||
.PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE,
|
.PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE,
|
||||||
.BranchE, .BranchM, .PCSrcE);
|
.BranchE, .BranchM, .PCSrcE);
|
||||||
|
|
||||||
end else if (`BPRED_TYPE == "BP_GSHARE") begin:Predictor
|
end else if (`BPRED_TYPE == "BP_GSHARE") begin:Predictor
|
||||||
gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||||
.PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, .DirPredictionF, .DirPredictionWrongE,
|
.PCNextF, .PCF, .PCD, .PCE, .PCM, .BPDirPredF, .BPDirPredWrongE,
|
||||||
.BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW,
|
.BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW,
|
||||||
.PCSrcE);
|
.PCSrcE);
|
||||||
|
|
||||||
end else if (`BPRED_TYPE == "BP_GLOBAL") begin:Predictor
|
end else if (`BPRED_TYPE == "BP_GLOBAL") begin:Predictor
|
||||||
gshare #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
gshare #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||||
.PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, .DirPredictionF, .DirPredictionWrongE,
|
.PCNextF, .PCF, .PCD, .PCE, .PCM, .BPDirPredF, .BPDirPredWrongE,
|
||||||
.BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW,
|
.BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW,
|
||||||
.PCSrcE);
|
.PCSrcE);
|
||||||
|
|
||||||
end else if (`BPRED_TYPE == "BP_GSHARE_BASIC") begin:Predictor
|
end else if (`BPRED_TYPE == "BP_GSHARE_BASIC") begin:Predictor
|
||||||
gsharebasic #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
gsharebasic #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||||
.PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE,
|
.PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE,
|
||||||
.BranchE, .BranchM, .PCSrcE);
|
.BranchE, .BranchM, .PCSrcE);
|
||||||
|
|
||||||
end else if (`BPRED_TYPE == "BP_GLOBAL_BASIC") begin:Predictor
|
end else if (`BPRED_TYPE == "BP_GLOBAL_BASIC") begin:Predictor
|
||||||
gsharebasic #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
gsharebasic #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||||
.PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE,
|
.PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE,
|
||||||
.BranchE, .BranchM, .PCSrcE);
|
.BranchE, .BranchM, .PCSrcE);
|
||||||
|
|
||||||
end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor
|
end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor
|
||||||
@ -134,7 +135,7 @@ module bpred (
|
|||||||
localHistoryPredictor DirPredictor(.clk,
|
localHistoryPredictor DirPredictor(.clk,
|
||||||
.reset, .StallF, .StallE,
|
.reset, .StallF, .StallE,
|
||||||
.LookUpPC(PCNextF),
|
.LookUpPC(PCNextF),
|
||||||
.Prediction(DirPredictionF),
|
.Prediction(BPDirPredF),
|
||||||
// update
|
// update
|
||||||
.UpdatePC(PCE),
|
.UpdatePC(PCE),
|
||||||
.UpdateEN(InstrClassE[0] & ~StallE),
|
.UpdateEN(InstrClassE[0] & ~StallE),
|
||||||
@ -148,144 +149,79 @@ module bpred (
|
|||||||
|
|
||||||
btb #(`BTB_SIZE)
|
btb #(`BTB_SIZE)
|
||||||
TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||||
.PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW,
|
.PCNextF, .PCF, .PCD, .PCE, .PCM,
|
||||||
.BTAF, .BTAD,
|
.BTAF, .BTAD, .BTAE,
|
||||||
.BTBPredInstrClassF({BTBJalF, BTBRetF, BTBJumpF, BTBBranchF}),
|
.BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}),
|
||||||
.PredictionInstrClassWrongM,
|
.IClassWrongM, .IClassWrongE,
|
||||||
.IEUAdrE, .IEUAdrM, .IEUAdrW,
|
.IEUAdrE, .IEUAdrM,
|
||||||
.InstrClassD({JalD, RetD, JumpD, BranchD}), .InstrClassE({JalE, RetE, JumpE, BranchE}), .InstrClassM({JalM, RetM, JumpM, BranchM}),
|
.InstrClassD({CallD, ReturnD, JumpD, BranchD}),
|
||||||
.InstrClassW({JalW, RetW, JumpW, BranchW}));
|
.InstrClassE({CallE, ReturnE, JumpE, BranchE}),
|
||||||
|
.InstrClassM({CallM, ReturnM, JumpM, BranchM}),
|
||||||
|
.InstrClassW({CallW, ReturnW, JumpW, BranchW}));
|
||||||
|
|
||||||
if (!`INSTR_CLASS_PRED) begin : DirectClassDecode
|
icpred #(`INSTR_CLASS_PRED) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||||
// This section is mainly for testing, verification, and PPA comparison.
|
.PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW,
|
||||||
// An alternative to using the BTB to store the instruction class is to partially decode
|
.CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF,
|
||||||
// the instructions in the Fetch stage into, Jal, Ret, Jump, and Branch instructions.
|
.BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .IClassWrongM, .IClassWrongE, .BPReturnWrongD);
|
||||||
// This logic is not described in the text book as of 23 February 2023.
|
|
||||||
logic cjal, cj, cjr, cjalr, CJumpF, CBranchF;
|
|
||||||
logic NCJumpF, NCBranchF;
|
|
||||||
|
|
||||||
if(`C_SUPPORTED) begin
|
|
||||||
logic [4:0] CompressedOpcF;
|
|
||||||
assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]};
|
|
||||||
assign cjal = CompressedOpcF == 5'h09 & `XLEN == 32;
|
|
||||||
assign cj = CompressedOpcF == 5'h0d;
|
|
||||||
assign cjr = CompressedOpcF == 5'h14 & ~PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0;
|
|
||||||
assign cjalr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0;
|
|
||||||
assign CJumpF = cjal | cj | cjr | cjalr;
|
|
||||||
assign CBranchF = CompressedOpcF[4:1] == 4'h7;
|
|
||||||
end else begin
|
|
||||||
assign {cjal, cj, cjr, cjalr, CJumpF, CBranchF} = '0;
|
|
||||||
end
|
|
||||||
|
|
||||||
assign NCJumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F;
|
|
||||||
assign NCBranchF = PostSpillInstrRawF[6:0] == 7'h63;
|
|
||||||
|
|
||||||
assign BPBranchF = NCBranchF | (`C_SUPPORTED & CBranchF);
|
|
||||||
assign BPJumpF = NCJumpF | (`C_SUPPORTED & (CJumpF));
|
|
||||||
assign BPRetF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // return must return to ra or r5
|
|
||||||
(`C_SUPPORTED & (cjalr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01));
|
|
||||||
|
|
||||||
assign BPJalF = (NCJumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // jal(r) must link to ra or x5
|
|
||||||
(`C_SUPPORTED & (cjal | (cjalr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01)));
|
|
||||||
|
|
||||||
end else begin
|
|
||||||
// This section connects the BTB's instruction class prediction.
|
|
||||||
assign {BPJalF, BPRetF, BPJumpF, BPBranchF} = {BTBJalF, BTBRetF, BTBJumpF, BTBBranchF};
|
|
||||||
end
|
|
||||||
assign BPPCSrcF = (BPBranchF & DirPredictionF[1]) | BPJumpF;
|
|
||||||
|
|
||||||
// Part 3 RAS
|
// Part 3 RAS
|
||||||
RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
||||||
.BPRetF, .RetD, .RetE, .JalE,
|
.BPReturnF, .ReturnD, .ReturnE, .CallE,
|
||||||
.WrongBPRetD, .RASPCF, .PCLinkE);
|
.BPReturnWrongD, .RASPCF, .PCLinkE);
|
||||||
|
|
||||||
assign BPPredPCF = BPRetF ? RASPCF : BTAF;
|
|
||||||
|
|
||||||
assign RetD = JumpD & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or x5
|
|
||||||
assign JalD = JumpD & (InstrD[11:7] & 5'h1B) == 5'h01; // jal(r) must link to ra or x5
|
|
||||||
|
|
||||||
flopenrc #(2) InstrClassRegE(clk, reset, FlushE, ~StallE, {JalD, RetD}, {JalE, RetE});
|
|
||||||
flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, {JalE, RetE, JumpE, BranchE}, {JalM, RetM, JumpM, BranchM});
|
|
||||||
flopenrc #(4) InstrClassRegW(clk, reset, FlushM, ~StallW, {JalM, RetM, JumpM, BranchM}, {JalW, RetW, JumpW, BranchW});
|
|
||||||
flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM);
|
|
||||||
|
|
||||||
// branch predictor
|
|
||||||
flopenrc #(1) BPClassWrongRegM(clk, reset, FlushM, ~StallM, AnyWrongPredInstrClassE, PredictionInstrClassWrongM);
|
|
||||||
flopenrc #(1) WrongInstrClassRegE(clk, reset, FlushE, ~StallE, AnyWrongPredInstrClassD, AnyWrongPredInstrClassE);
|
|
||||||
|
|
||||||
// pipeline the predicted class
|
|
||||||
flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, {BPJalF, BPRetF, BPJumpF, BPBranchF}, {BPJalD, BPRetD, BPJumpD, BPBranchD});
|
|
||||||
|
|
||||||
// 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.
|
||||||
// if the class prediction is wrong a regular instruction may have been predicted as a taken branch
|
// if the class prediction is wrong a regular instruction may have been predicted as a taken branch
|
||||||
// this will result in PCD not being equal to the fall through address PCLinkE (PCE+4).
|
// this will result in PCD not being equal to the fall through address PCLinkE (PCE+4).
|
||||||
// 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;
|
|
||||||
|
|
||||||
// branch class prediction wrong.
|
|
||||||
assign AnyWrongPredInstrClassD = |({BPJalD, BPRetD, BPJumpD, BPBranchD} ^ {JalD, RetD, JumpD, BranchD});
|
|
||||||
assign WrongBPRetD = BPRetD ^ RetD;
|
|
||||||
|
|
||||||
// branch is wrong only if the PC does not match and both the Decode and Fetch stages have valid instructions.
|
// 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;
|
assign BPWrongE = (PCCorrectE != PCD) & InstrValidE & InstrValidD;
|
||||||
|
flopenrc #(1) BPWrongMReg(clk, reset, FlushM, ~StallM, BPWrongE, BPWrongM);
|
||||||
logic BPPredWrongEAlt;
|
|
||||||
logic NotMatch;
|
|
||||||
assign BPPredWrongEAlt = PredictionPCWrongE & InstrValidE & InstrValidD; // this does not work for cubic benchmark
|
|
||||||
assign NotMatch = BPPredWrongE != BPPredWrongEAlt;
|
|
||||||
|
|
||||||
// Output the predicted PC or corrected PC on miss-predict.
|
// Output the predicted PC or corrected PC on miss-predict.
|
||||||
|
assign BPPCSrcF = (BPBranchF & BPDirPredF[1]) | BPJumpF;
|
||||||
|
mux2 #(`XLEN) pcmuxbp(BTAF, RASPCF, BPReturnF, BPPCF);
|
||||||
// Selects the BP or PC+2/4.
|
// Selects the BP or PC+2/4.
|
||||||
mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPredPCF, BPPCSrcF, PCNext0F);
|
mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPCF, BPPCSrcF, PC0NextF);
|
||||||
// If the prediction is wrong select the correct address.
|
// If the prediction is wrong select the correct address.
|
||||||
mux2 #(`XLEN) pcmux1(PCNext0F, PCCorrectE, BPPredWrongE, PCNext1F);
|
mux2 #(`XLEN) pcmux1(PC0NextF, PCCorrectE, BPWrongE, PC1NextF);
|
||||||
// Correct branch/jump target.
|
// Correct branch/jump target.
|
||||||
mux2 #(`XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE);
|
mux2 #(`XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE);
|
||||||
|
|
||||||
// If the fence/csrw was predicted as a taken branch then we select PCF, rather PCE.
|
// If the fence/csrw was predicted as a taken branch then we select PCF, rather PCE.
|
||||||
// Effectively this is PCM+4 or the non-existant PCLinkM
|
// Effectively this is PCM+4 or the non-existant PCLinkM
|
||||||
if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPPredWrongM, NextValidPCE);
|
if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPWrongM, NextValidPCE);
|
||||||
else assign NextValidPCE = PCE;
|
else assign NextValidPCE = PCE;
|
||||||
|
|
||||||
if(`ZICOUNTERS_SUPPORTED) begin
|
if(`ZICOUNTERS_SUPPORTED) begin
|
||||||
logic JumpOrTakenBranchE;
|
logic [`XLEN-1:0] RASPCD, RASPCE;
|
||||||
logic [`XLEN-1:0] BTAE, RASPCD, RASPCE;
|
logic BTBPredPCWrongE, RASPredPCWrongE;
|
||||||
logic BTBPredPCWrongE, RASPredPCWrongE;
|
// performance counters
|
||||||
// performance counters
|
// 1. class (class wrong / minstret) (IClassWrongM / 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])
|
|
||||||
|
|
||||||
// Unforuantely we can't use PCD to infer the correctness of the BTB or RAS because the class prediction
|
// Unforuantely we can't use PCD to infer the correctness of the BTB or RAS because the class prediction
|
||||||
// could be wrong or the fall through address selected for branch predict not taken.
|
// 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
|
// By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of
|
||||||
// both without the above inaccuracies.
|
// both without the above inaccuracies.
|
||||||
assign BTBPredPCWrongE = (BTAE != IEUAdrE) & (BranchE | JumpE & ~RetE) & PCSrcE;
|
// **** use BTAWrongM from BTB.
|
||||||
assign RASPredPCWrongE = (RASPCE != IEUAdrE) & RetE & PCSrcE;
|
assign BTBPredPCWrongE = (BTAE != IEUAdrE) & (BranchE | JumpE & ~ReturnE) & PCSrcE;
|
||||||
|
assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE;
|
||||||
|
|
||||||
assign JumpOrTakenBranchE = (BranchE & PCSrcE) | JumpE;
|
flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD);
|
||||||
|
flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
|
||||||
flopenrc #(1) JumpOrTakenBranchMReg(clk, reset, FlushM, ~StallM, JumpOrTakenBranchE, JumpOrTakenBranchM);
|
flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
|
||||||
|
{BPDirPredWrongE, BTBPredPCWrongE, RASPredPCWrongE},
|
||||||
flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BTAD, BTAE);
|
{BPDirPredWrongM, BTAWrongM, RASPredPCWrongM});
|
||||||
|
|
||||||
flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD);
|
|
||||||
flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
|
|
||||||
flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
|
|
||||||
{DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE},
|
|
||||||
{DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM});
|
|
||||||
|
|
||||||
end else begin
|
end else begin
|
||||||
assign {BTBPredPCWrongM, RASPredPCWrongM, JumpOrTakenBranchM} = '0;
|
assign {BTAWrongM, RASPredPCWrongM} = '0;
|
||||||
end
|
end
|
||||||
|
|
||||||
// **** Fix me
|
// **** Fix me
|
||||||
assign InstrClassM = {JalM, RetM, JumpM, BranchM};
|
assign InstrClassM = {CallM, ReturnM, JumpM, BranchM};
|
||||||
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
|
|
||||||
flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW);
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -34,28 +34,33 @@ module btb #(parameter Depth = 10 ) (
|
|||||||
input logic clk,
|
input logic clk,
|
||||||
input logic reset,
|
input logic reset,
|
||||||
input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW,
|
input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW,
|
||||||
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW,// PC at various stages
|
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,// PC at various stages
|
||||||
output logic [`XLEN-1:0] BTAF, // BTB's guess at PC
|
output logic [`XLEN-1:0] BTAF, // BTB's guess at PC
|
||||||
output logic [`XLEN-1:0] BTAD,
|
output logic [`XLEN-1:0] BTAD,
|
||||||
output logic [3:0] BTBPredInstrClassF, // BTB's guess at instruction class
|
output logic [`XLEN-1:0] BTAE,
|
||||||
|
output logic [3:0] BTBIClassF, // BTB's guess at instruction class
|
||||||
// update
|
// update
|
||||||
input logic PredictionInstrClassWrongM, // BTB's instruction class guess was wrong
|
input logic IClassWrongM, // BTB's instruction class guess was wrong
|
||||||
|
input logic IClassWrongE,
|
||||||
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 [`XLEN-1:0] IEUAdrM, // Branch/jump target address to insert into btb
|
input logic [`XLEN-1:0] IEUAdrM, // Branch/jump target address to insert into btb
|
||||||
input logic [`XLEN-1:0] IEUAdrW,
|
|
||||||
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
|
||||||
input logic [3:0] InstrClassM, // Instruction class to insert into btb
|
input logic [3:0] InstrClassM, // Instruction class to insert into btb
|
||||||
input logic [3:0] InstrClassW
|
input logic [3:0] InstrClassW
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex;
|
logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex;
|
||||||
logic [`XLEN-1:0] ResetPC;
|
logic [`XLEN-1:0] ResetPC;
|
||||||
logic MatchD, MatchE, MatchM, MatchW, MatchX;
|
logic MatchD, MatchE, MatchM, MatchW, MatchX;
|
||||||
logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF;
|
logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF;
|
||||||
logic [`XLEN+3:0] TableBTBPredictionF;
|
logic [`XLEN+3:0] TableBTBPredF;
|
||||||
logic UpdateEn;
|
logic [`XLEN-1:0] IEUAdrW;
|
||||||
|
logic [`XLEN-1:0] PCW;
|
||||||
|
logic BTBWrongE, BTAWrongE;
|
||||||
|
logic BTBWrongM, BTAWrongM;
|
||||||
|
|
||||||
|
|
||||||
// hashing function for indexing the PC
|
// hashing function for indexing the PC
|
||||||
// We have Depth bits to index, but XLEN bits as the input.
|
// We have Depth bits to index, but XLEN bits as the input.
|
||||||
// bit 0 is always 0, bit 1 is 0 if using 4 byte instructions, but is not always 0 if
|
// bit 0 is always 0, bit 1 is 0 if using 4 byte instructions, but is not always 0 if
|
||||||
@ -84,15 +89,27 @@ module btb #(parameter Depth = 10 ) (
|
|||||||
MatchM ? {InstrClassM, IEUAdrM} :
|
MatchM ? {InstrClassM, IEUAdrM} :
|
||||||
{InstrClassW, IEUAdrW} ;
|
{InstrClassW, IEUAdrW} ;
|
||||||
|
|
||||||
assign {BTBPredInstrClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredictionF};
|
assign {BTBIClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredF};
|
||||||
|
|
||||||
assign UpdateEn = |InstrClassM | PredictionInstrClassWrongM;
|
|
||||||
|
|
||||||
// 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(
|
||||||
.clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredictionF),
|
.clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredF),
|
||||||
.ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(UpdateEn), .bwe2('1));
|
.ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(BTBWrongM), .bwe2('1));
|
||||||
|
|
||||||
flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD);
|
flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD);
|
||||||
|
|
||||||
|
// BTAE is not strickly necessary. However it is used by two parts of wally.
|
||||||
|
// 1. It gates updates to the BTB when the prediction does not change. This save power.
|
||||||
|
// 2. BTAWrongE is used by the performance counters to track when the BTB's BTA or instruction class is wrong.
|
||||||
|
flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BTAD, BTAE);
|
||||||
|
assign BTAWrongE = (BTAE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]);
|
||||||
|
|
||||||
|
flopenrc #(1) BTAWrongMReg(clk, reset, FlushM, ~StallM, BTAWrongE, BTAWrongM);
|
||||||
|
assign BTBWrongM = BTAWrongM | IClassWrongM;
|
||||||
|
|
||||||
|
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
|
||||||
|
flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW);
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -35,18 +35,18 @@ module gshare #(parameter k = 10,
|
|||||||
input logic reset,
|
input logic reset,
|
||||||
input logic StallF, StallD, StallE, StallM, StallW,
|
input logic StallF, StallD, StallE, StallM, StallW,
|
||||||
input logic FlushD, FlushE, FlushM, FlushW,
|
input logic FlushD, FlushE, FlushM, FlushW,
|
||||||
output logic [1:0] DirPredictionF,
|
output logic [1:0] BPDirPredF,
|
||||||
output logic DirPredictionWrongE,
|
output logic BPDirPredWrongE,
|
||||||
// update
|
// update
|
||||||
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW,
|
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,
|
||||||
input logic BPBranchF, BranchD, BranchE, BranchM, BranchW, PCSrcE
|
input logic BPBranchF, BranchD, BranchE, BranchM, BranchW, PCSrcE
|
||||||
);
|
);
|
||||||
|
|
||||||
logic MatchF, MatchD, MatchE, MatchM, MatchW;
|
logic MatchF, MatchD, MatchE, MatchM, MatchW;
|
||||||
logic MatchX;
|
logic MatchX;
|
||||||
|
|
||||||
logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE, ForwardNewDirPredictionF;
|
logic [1:0] TableBPDirPredF, BPDirPredD, BPDirPredE, FwdNewDirPredF;
|
||||||
logic [1:0] NewDirPredictionE, NewDirPredictionM, NewDirPredictionW;
|
logic [1:0] NewBPDirPredE, NewBPDirPredM, NewBPDirPredW;
|
||||||
|
|
||||||
logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW;
|
logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW;
|
||||||
|
|
||||||
@ -76,33 +76,33 @@ module gshare #(parameter k = 10,
|
|||||||
assign MatchW = BranchW & ~FlushW & (IndexF == IndexW);
|
assign MatchW = BranchW & ~FlushW & (IndexF == IndexW);
|
||||||
assign MatchX = MatchD | MatchE | MatchM | MatchW;
|
assign MatchX = MatchD | MatchE | MatchM | MatchW;
|
||||||
|
|
||||||
assign ForwardNewDirPredictionF = MatchD ? {2{DirPredictionD[1]}} :
|
assign FwdNewDirPredF = MatchD ? {2{BPDirPredD[1]}} :
|
||||||
MatchE ? {NewDirPredictionE} :
|
MatchE ? {NewBPDirPredE} :
|
||||||
MatchM ? {NewDirPredictionM} :
|
MatchM ? {NewBPDirPredM} :
|
||||||
NewDirPredictionW ;
|
NewBPDirPredW ;
|
||||||
|
|
||||||
assign DirPredictionF = MatchX ? ForwardNewDirPredictionF : TableDirPredictionF;
|
assign BPDirPredF = MatchX ? FwdNewDirPredF : TableBPDirPredF;
|
||||||
|
|
||||||
ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),
|
ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),
|
||||||
.ce1(~StallF), .ce2(~StallM & ~FlushM),
|
.ce1(~StallF), .ce2(~StallW & ~FlushW),
|
||||||
.ra1(IndexNextF),
|
.ra1(IndexNextF),
|
||||||
.rd1(TableDirPredictionF),
|
.rd1(TableBPDirPredF),
|
||||||
.wa2(IndexM),
|
.wa2(IndexM),
|
||||||
.wd2(NewDirPredictionM),
|
.wd2(NewBPDirPredM),
|
||||||
.we2(BranchM),
|
.we2(BranchM),
|
||||||
.bwe2(1'b1));
|
.bwe2(1'b1));
|
||||||
|
|
||||||
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD);
|
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, BPDirPredF, BPDirPredD);
|
||||||
flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE);
|
flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, BPDirPredD, BPDirPredE);
|
||||||
|
|
||||||
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE));
|
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(BPDirPredE), .NewState(NewBPDirPredE));
|
||||||
flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM);
|
flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewBPDirPredE, NewBPDirPredM);
|
||||||
flopenrc #(2) NewPredictionRegW(clk, reset, FlushW, ~StallW, NewDirPredictionM, NewDirPredictionW);
|
flopenrc #(2) NewPredictionRegW(clk, reset, FlushW, ~StallW, NewBPDirPredM, NewBPDirPredW);
|
||||||
|
|
||||||
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE;
|
assign BPDirPredWrongE = PCSrcE != BPDirPredE[1] & BranchE;
|
||||||
|
|
||||||
assign GHRNextF = BPBranchF ? {DirPredictionF[1], GHRF[k-1:1]} : GHRF;
|
assign GHRNextF = BPBranchF ? {BPDirPredF[1], GHRF[k-1:1]} : GHRF;
|
||||||
assign GHRF = BranchD ? {DirPredictionD[1], GHRD[k-1:1]} : GHRD;
|
assign GHRF = BranchD ? {BPDirPredD[1], GHRD[k-1:1]} : GHRD;
|
||||||
assign GHRD = BranchE ? {PCSrcE, GHRE[k-1:1]} : GHRE;
|
assign GHRD = BranchE ? {PCSrcE, GHRE[k-1:1]} : GHRE;
|
||||||
assign GHRE = BranchM ? {PCSrcM, GHRM[k-1:1]} : GHRM;
|
assign GHRE = BranchM ? {PCSrcM, GHRM[k-1:1]} : GHRM;
|
||||||
|
|
||||||
|
@ -35,16 +35,16 @@ module gsharebasic #(parameter k = 10,
|
|||||||
input logic reset,
|
input logic reset,
|
||||||
input logic StallF, StallD, StallE, StallM, StallW,
|
input logic StallF, StallD, StallE, StallM, StallW,
|
||||||
input logic FlushD, FlushE, FlushM, FlushW,
|
input logic FlushD, FlushE, FlushM, FlushW,
|
||||||
output logic [1:0] DirPredictionF,
|
output logic [1:0] BPDirPredF,
|
||||||
output logic DirPredictionWrongE,
|
output logic BPDirPredWrongE,
|
||||||
// update
|
// update
|
||||||
input logic [`XLEN-1:0] PCNextF, PCM,
|
input logic [`XLEN-1:0] PCNextF, PCM,
|
||||||
input logic BranchE, BranchM, PCSrcE
|
input logic BranchE, BranchM, PCSrcE
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [k-1:0] IndexNextF, IndexM;
|
logic [k-1:0] IndexNextF, IndexM;
|
||||||
logic [1:0] DirPredictionD, DirPredictionE;
|
logic [1:0] BPDirPredD, BPDirPredE;
|
||||||
logic [1:0] NewDirPredictionE, NewDirPredictionM;
|
logic [1:0] NewBPDirPredE, NewBPDirPredM;
|
||||||
|
|
||||||
logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHR;
|
logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHR;
|
||||||
logic [k-1:0] GHRNext;
|
logic [k-1:0] GHRNext;
|
||||||
@ -61,19 +61,19 @@ module gsharebasic #(parameter k = 10,
|
|||||||
ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),
|
ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),
|
||||||
.ce1(~StallF), .ce2(~StallW & ~FlushW),
|
.ce1(~StallF), .ce2(~StallW & ~FlushW),
|
||||||
.ra1(IndexNextF),
|
.ra1(IndexNextF),
|
||||||
.rd1(DirPredictionF),
|
.rd1(BPDirPredF),
|
||||||
.wa2(IndexM),
|
.wa2(IndexM),
|
||||||
.wd2(NewDirPredictionM),
|
.wd2(NewBPDirPredM),
|
||||||
.we2(BranchM),
|
.we2(BranchM),
|
||||||
.bwe2(1'b1));
|
.bwe2(1'b1));
|
||||||
|
|
||||||
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD);
|
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, BPDirPredF, BPDirPredD);
|
||||||
flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE);
|
flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, BPDirPredD, BPDirPredE);
|
||||||
|
|
||||||
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE));
|
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(BPDirPredE), .NewState(NewBPDirPredE));
|
||||||
flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM);
|
flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewBPDirPredE, NewBPDirPredM);
|
||||||
|
|
||||||
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE;
|
assign BPDirPredWrongE = PCSrcE != BPDirPredE[1] & BranchE;
|
||||||
|
|
||||||
assign GHRNext = BranchM ? {PCSrcM, GHR[k-1:1]} : GHR;
|
assign GHRNext = BranchM ? {PCSrcM, GHR[k-1:1]} : GHR;
|
||||||
flopenr #(k) GHRReg(clk, reset, ~StallM & ~FlushM & BranchM, GHRNext, GHR);
|
flopenr #(k) GHRReg(clk, reset, ~StallM & ~FlushM & BranchM, GHRNext, GHR);
|
||||||
|
106
src/ifu/bpred/icpred.sv
Normal file
106
src/ifu/bpred/icpred.sv
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// icpred.sv
|
||||||
|
//
|
||||||
|
// Written: Ross Thomposn ross1728@gmail.com
|
||||||
|
// Created: February 26, 2023
|
||||||
|
// Modified: February 26, 2023
|
||||||
|
//
|
||||||
|
// Purpose: Partial decode of instructions into control flow instructions (cfi)P
|
||||||
|
// Call, Return, Jump, and Branch
|
||||||
|
//
|
||||||
|
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||||
|
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||||
|
// may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://solderpad.org/licenses/SHL-2.1/
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||||
|
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
// either express or implied. See the License for the specific language governing permissions
|
||||||
|
// and limitations under the License.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
|
||||||
|
module icpred #(parameter INSTR_CLASS_PRED = 1)(
|
||||||
|
input logic clk, reset,
|
||||||
|
input logic StallF, StallD, StallE, StallM, StallW,
|
||||||
|
input logic FlushD, FlushE, FlushM, FlushW,
|
||||||
|
input logic [31:0] PostSpillInstrRawF, InstrD, // Instruction
|
||||||
|
input logic BranchD, BranchE,
|
||||||
|
input logic JumpD, JumpE,
|
||||||
|
output logic BranchM, BranchW,
|
||||||
|
output logic JumpM, JumpW,
|
||||||
|
output logic CallD, CallE, CallM, CallW,
|
||||||
|
output logic ReturnD, ReturnE, ReturnM, ReturnW,
|
||||||
|
input logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF,
|
||||||
|
output logic BPCallF, BPReturnF, BPJumpF, BPBranchF,
|
||||||
|
output logic IClassWrongM, BPReturnWrongD, IClassWrongE
|
||||||
|
);
|
||||||
|
|
||||||
|
logic IClassWrongD;
|
||||||
|
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
|
||||||
|
|
||||||
|
if (!INSTR_CLASS_PRED) begin : DirectClassDecode
|
||||||
|
// This section is mainly for testing, verification, and PPA comparison.
|
||||||
|
// An alternative to using the BTB to store the instruction class is to partially decode
|
||||||
|
// the instructions in the Fetch stage into, Call, Return, Jump, and Branch instructions.
|
||||||
|
// This logic is not described in the text book as of 23 February 2023.
|
||||||
|
logic ccall, cj, cjr, ccallr, CJumpF, CBranchF;
|
||||||
|
logic NCJumpF, NCBranchF;
|
||||||
|
|
||||||
|
if(`C_SUPPORTED) begin
|
||||||
|
logic [4:0] CompressedOpcF;
|
||||||
|
assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]};
|
||||||
|
assign ccall = CompressedOpcF == 5'h09 & `XLEN == 32;
|
||||||
|
assign cj = CompressedOpcF == 5'h0d;
|
||||||
|
assign cjr = CompressedOpcF == 5'h14 & ~PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0;
|
||||||
|
assign ccallr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0;
|
||||||
|
assign CJumpF = ccall | cj | cjr | ccallr;
|
||||||
|
assign CBranchF = CompressedOpcF[4:1] == 4'h7;
|
||||||
|
end else begin
|
||||||
|
assign {ccall, cj, cjr, ccallr, CJumpF, CBranchF} = '0;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign NCJumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F;
|
||||||
|
assign NCBranchF = PostSpillInstrRawF[6:0] == 7'h63;
|
||||||
|
|
||||||
|
assign BPBranchF = NCBranchF | (`C_SUPPORTED & CBranchF);
|
||||||
|
assign BPJumpF = NCJumpF | (`C_SUPPORTED & (CJumpF));
|
||||||
|
assign BPReturnF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // returnurn must returnurn to ra or r5
|
||||||
|
(`C_SUPPORTED & (ccallr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01));
|
||||||
|
|
||||||
|
assign BPCallF = (NCJumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // call(r) must link to ra or x5
|
||||||
|
(`C_SUPPORTED & (ccall | (ccallr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01)));
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
// This section connects the BTB's instruction class prediction.
|
||||||
|
assign {BPCallF, BPReturnF, BPJumpF, BPBranchF} = {BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF};
|
||||||
|
end
|
||||||
|
|
||||||
|
assign ReturnD = JumpD & (InstrD[19:15] & 5'h1B) == 5'h01; // returnurn must returnurn to ra or x5
|
||||||
|
assign CallD = JumpD & (InstrD[11:7] & 5'h1B) == 5'h01; // call(r) must link to ra or x5
|
||||||
|
|
||||||
|
flopenrc #(2) InstrClassRegE(clk, reset, FlushE, ~StallE, {CallD, ReturnD}, {CallE, ReturnE});
|
||||||
|
flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, {CallE, ReturnE, JumpE, BranchE}, {CallM, ReturnM, JumpM, BranchM});
|
||||||
|
flopenrc #(4) InstrClassRegW(clk, reset, FlushM, ~StallW, {CallM, ReturnM, JumpM, BranchM}, {CallW, ReturnW, JumpW, BranchW});
|
||||||
|
|
||||||
|
// branch predictor
|
||||||
|
flopenrc #(1) BPClassWrongRegM(clk, reset, FlushM, ~StallM, IClassWrongE, IClassWrongM);
|
||||||
|
flopenrc #(1) WrongInstrClassRegE(clk, reset, FlushE, ~StallE, IClassWrongD, IClassWrongE);
|
||||||
|
|
||||||
|
// pipeline the predicted class
|
||||||
|
flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, {BPCallF, BPReturnF, BPJumpF, BPBranchF}, {BPCallD, BPReturnD, BPJumpD, BPBranchD});
|
||||||
|
|
||||||
|
// branch class prediction wrong.
|
||||||
|
assign IClassWrongD = |({BPCallD, BPReturnD, BPJumpD, BPBranchD} ^ {CallD, ReturnD, JumpD, BranchD});
|
||||||
|
assign BPReturnWrongD = BPReturnD ^ ReturnD;
|
||||||
|
|
||||||
|
endmodule
|
@ -34,8 +34,8 @@ module twoBitPredictor #(parameter k = 10) (
|
|||||||
input logic StallF, StallD, StallE, StallM, StallW,
|
input logic StallF, StallD, StallE, StallM, StallW,
|
||||||
input logic FlushD, FlushE, FlushM, FlushW,
|
input logic FlushD, FlushE, FlushM, FlushW,
|
||||||
input logic [`XLEN-1:0] PCNextF, PCM,
|
input logic [`XLEN-1:0] PCNextF, PCM,
|
||||||
output logic [1:0] DirPredictionF,
|
output logic [1:0] BPDirPredF,
|
||||||
output logic DirPredictionWrongE,
|
output logic BPDirPredWrongE,
|
||||||
input logic BranchE, BranchM,
|
input logic BranchE, BranchM,
|
||||||
input logic PCSrcE
|
input logic PCSrcE
|
||||||
);
|
);
|
||||||
@ -43,8 +43,8 @@ module twoBitPredictor #(parameter k = 10) (
|
|||||||
logic [k-1:0] IndexNextF, IndexM;
|
logic [k-1:0] IndexNextF, IndexM;
|
||||||
logic [1:0] PredictionMemory;
|
logic [1:0] PredictionMemory;
|
||||||
logic DoForwarding, DoForwardingF;
|
logic DoForwarding, DoForwardingF;
|
||||||
logic [1:0] DirPredictionD, DirPredictionE;
|
logic [1:0] BPDirPredD, BPDirPredE;
|
||||||
logic [1:0] NewDirPredictionE, NewDirPredictionM;
|
logic [1:0] NewBPDirPredE, NewBPDirPredM;
|
||||||
|
|
||||||
// hashing function for indexing the PC
|
// hashing function for indexing the PC
|
||||||
// We have k bits to index, but XLEN bits as the input.
|
// We have k bits to index, but XLEN bits as the input.
|
||||||
@ -57,19 +57,19 @@ module twoBitPredictor #(parameter k = 10) (
|
|||||||
ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),
|
ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),
|
||||||
.ce1(~StallF), .ce2(~StallW & ~FlushW),
|
.ce1(~StallF), .ce2(~StallW & ~FlushW),
|
||||||
.ra1(IndexNextF),
|
.ra1(IndexNextF),
|
||||||
.rd1(DirPredictionF),
|
.rd1(BPDirPredF),
|
||||||
.wa2(IndexM),
|
.wa2(IndexM),
|
||||||
.wd2(NewDirPredictionM),
|
.wd2(NewBPDirPredM),
|
||||||
.we2(BranchM),
|
.we2(BranchM),
|
||||||
.bwe2(1'b1));
|
.bwe2(1'b1));
|
||||||
|
|
||||||
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD);
|
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, BPDirPredF, BPDirPredD);
|
||||||
flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE);
|
flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, BPDirPredD, BPDirPredE);
|
||||||
|
|
||||||
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE;
|
assign BPDirPredWrongE = PCSrcE != BPDirPredE[1] & BranchE;
|
||||||
|
|
||||||
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE));
|
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(BPDirPredE), .NewState(NewBPDirPredE));
|
||||||
flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM);
|
flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewBPDirPredE, NewBPDirPredM);
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -54,22 +54,22 @@ module ifu (
|
|||||||
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] IEUAdrM, // The branch/jump target address
|
input logic [`XLEN-1:0] IEUAdrM, // The branch/jump target address
|
||||||
output logic [`XLEN-1:0] PCE, // Execution stage instruction address
|
output logic [`XLEN-1:0] PCE, // Execution stage instruction address
|
||||||
output logic BPPredWrongE, // Prediction is wrong
|
output logic BPWrongE, // Prediction is wrong
|
||||||
output logic BPPredWrongM, // Prediction is wrong
|
output logic BPWrongM, // Prediction is wrong
|
||||||
// Mem
|
// Mem
|
||||||
output logic CommittedF, // I$ or bus memory operation started, delay interrupts
|
output logic CommittedF, // I$ or bus memory operation started, delay interrupts
|
||||||
input logic [`XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes.
|
input logic [`XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes.
|
||||||
output logic [`XLEN-1:0] PCNext2F, // Selected PC between branch prediction and next valid PC if CSRWriteFence
|
output logic [`XLEN-1:0] PC2NextF, // Selected PC between branch prediction and next valid PC if CSRWriteFence
|
||||||
output logic [31:0] InstrD, // The decoded instruction in Decode stage
|
output logic [31:0] InstrD, // The decoded instruction in Decode stage
|
||||||
output logic [31:0] InstrM, // The decoded instruction in Memory stage
|
output logic [31:0] InstrM, // The decoded instruction in Memory stage
|
||||||
output logic [`XLEN-1:0] PCM, // Memory stage instruction address
|
output logic [`XLEN-1:0] PCM, // Memory stage instruction address
|
||||||
// branch predictor
|
// branch predictor
|
||||||
output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
|
output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
|
||||||
output logic JumpOrTakenBranchM,
|
output logic BPDirPredWrongM, // Prediction direction is wrong
|
||||||
output logic DirPredictionWrongM, // Prediction direction is wrong
|
output logic BTAWrongM, // Prediction target wrong
|
||||||
output logic BTBPredPCWrongM, // Prediction target wrong
|
|
||||||
output logic RASPredPCWrongM, // RAS prediction is wrong
|
output logic RASPredPCWrongM, // RAS prediction is wrong
|
||||||
output logic PredictionInstrClassWrongM, // Class prediction is wrong
|
output logic IClassWrongM, // Class prediction is wrong
|
||||||
|
output logic ICacheStallF, // I$ busy with multicycle operation
|
||||||
// Faults
|
// Faults
|
||||||
input logic IllegalBaseInstrD, // Illegal non-compressed instruction
|
input logic IllegalBaseInstrD, // Illegal non-compressed instruction
|
||||||
input logic IllegalFPUInstrD, // Illegal FP instruction
|
input logic IllegalFPUInstrD, // Illegal FP instruction
|
||||||
@ -88,7 +88,7 @@ module ifu (
|
|||||||
input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
|
input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
|
||||||
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
|
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
|
||||||
output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
|
output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
|
||||||
output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
|
output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
|
||||||
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration from privileged unit
|
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration from privileged unit
|
||||||
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP address from privileged unit
|
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP address from privileged unit
|
||||||
output logic InstrAccessFaultF, // Instruction access fault
|
output logic InstrAccessFaultF, // Instruction access fault
|
||||||
@ -128,11 +128,10 @@ module ifu (
|
|||||||
logic CacheableF; // PMA indicates instruction address is cacheable
|
logic CacheableF; // PMA indicates instruction address is cacheable
|
||||||
logic SelNextSpillF; // In a spill, stall pipeline and gate local stallF
|
logic SelNextSpillF; // In a spill, stall pipeline and gate local stallF
|
||||||
logic BusStall; // Bus interface busy with multicycle operation
|
logic BusStall; // Bus interface busy with multicycle operation
|
||||||
logic ICacheStallF; // I$ busy with multicycle operation
|
|
||||||
logic IFUCacheBusStallD; // EIther I$ or bus busy with multicycle operation
|
logic IFUCacheBusStallD; // EIther I$ or bus busy with multicycle operation
|
||||||
logic GatedStallD; // StallD gated by selected next spill
|
logic GatedStallD; // StallD gated by selected next spill
|
||||||
// branch predictor signal
|
// branch predictor signal
|
||||||
logic [`XLEN-1:0] PCNext1F; // Branch predictor next PCF
|
logic [`XLEN-1:0] PC1NextF; // Branch predictor next PCF
|
||||||
logic BusCommittedF; // Bus memory operation in flight, delay interrupts
|
logic BusCommittedF; // Bus memory operation in flight, delay interrupts
|
||||||
logic CacheCommittedF; // I$ memory operation started, delay interrupts
|
logic CacheCommittedF; // I$ memory operation started, delay interrupts
|
||||||
logic SelIROM; // PMA indicates instruction address is in the IROM
|
logic SelIROM; // PMA indicates instruction address is in the IROM
|
||||||
@ -297,8 +296,8 @@ module ifu (
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
if(`ZICSR_SUPPORTED | `ZIFENCEI_SUPPORTED)
|
if(`ZICSR_SUPPORTED | `ZIFENCEI_SUPPORTED)
|
||||||
mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PCNext2F));
|
mux2 #(`XLEN) pcmux2(.d0(PC1NextF), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PC2NextF));
|
||||||
else assign PCNext2F = PCNext1F;
|
else assign PC2NextF = PC1NextF;
|
||||||
|
|
||||||
assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
|
assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
|
||||||
flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF);
|
flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF);
|
||||||
@ -330,14 +329,14 @@ module ifu (
|
|||||||
.StallF, .StallD, .StallE, .StallM, .StallW,
|
.StallF, .StallD, .StallE, .StallM, .StallW,
|
||||||
.FlushD, .FlushE, .FlushM, .FlushW, .InstrValidD, .InstrValidE,
|
.FlushD, .FlushE, .FlushM, .FlushW, .InstrValidD, .InstrValidE,
|
||||||
.BranchD, .BranchE, .JumpD, .JumpE,
|
.BranchD, .BranchE, .JumpD, .JumpE,
|
||||||
.InstrD, .PCNextF, .PCPlus2or4F, .PCNext1F, .PCE, .PCM, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCF, .NextValidPCE,
|
.InstrD, .PCNextF, .PCPlus2or4F, .PC1NextF, .PCE, .PCM, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCF, .NextValidPCE,
|
||||||
.PCD, .PCLinkE, .InstrClassM, .BPPredWrongE, .PostSpillInstrRawF, .JumpOrTakenBranchM, .BPPredWrongM,
|
.PCD, .PCLinkE, .InstrClassM, .BPWrongE, .PostSpillInstrRawF, .BPWrongM,
|
||||||
.DirPredictionWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM);
|
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM);
|
||||||
|
|
||||||
end else begin : bpred
|
end else begin : bpred
|
||||||
mux2 #(`XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PCNext1F));
|
mux2 #(`XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PC1NextF));
|
||||||
assign BPPredWrongE = PCSrcE;
|
assign BPWrongE = PCSrcE;
|
||||||
assign {InstrClassM, DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM} = '0;
|
assign {InstrClassM, BPDirPredWrongM, BTAWrongM, RASPredPCWrongM, IClassWrongM} = '0;
|
||||||
assign NextValidPCE = PCE;
|
assign NextValidPCE = PCE;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ module lsu (
|
|||||||
input logic [1:0] PrivilegeModeW, // Current privilege mode
|
input logic [1:0] PrivilegeModeW, // Current privilege mode
|
||||||
input logic BigEndianM, // Swap byte order to big endian
|
input logic BigEndianM, // Swap byte order to big endian
|
||||||
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
|
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
|
||||||
|
output logic DCacheStallM, // D$ busy with multicycle operation
|
||||||
// fpu
|
// fpu
|
||||||
input logic [`FLEN-1:0] FWriteDataM, // Write data from FPU
|
input logic [`FLEN-1:0] FWriteDataM, // Write data from FPU
|
||||||
input logic FpLoadStoreM, // Selects FPU as store for write data
|
input logic FpLoadStoreM, // Selects FPU as store for write data
|
||||||
@ -103,7 +104,6 @@ module lsu (
|
|||||||
|
|
||||||
logic GatedStallW; // Hazard unit StallW gated when SelHPTW = 1
|
logic GatedStallW; // Hazard unit StallW gated when SelHPTW = 1
|
||||||
|
|
||||||
logic DCacheStallM; // D$ busy with multicycle operation
|
|
||||||
logic BusStall; // Bus interface busy with multicycle operation
|
logic BusStall; // Bus interface busy with multicycle operation
|
||||||
logic HPTWStall; // HPTW busy with multicycle operation
|
logic HPTWStall; // HPTW busy with multicycle operation
|
||||||
|
|
||||||
|
@ -37,13 +37,14 @@ module csr #(parameter
|
|||||||
input logic FlushM, FlushW,
|
input logic FlushM, FlushW,
|
||||||
input logic StallE, StallM, StallW,
|
input logic StallE, StallM, StallW,
|
||||||
input logic [31:0] InstrM, // current instruction
|
input logic [31:0] InstrM, // current instruction
|
||||||
input logic [`XLEN-1:0] PCM, PCNext2F, // program counter, next PC going to trap/return logic
|
input logic [`XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return logic
|
||||||
input logic [`XLEN-1:0] SrcAM, IEUAdrM, // SrcA and memory address from IEU
|
input logic [`XLEN-1:0] SrcAM, IEUAdrM, // SrcA and memory address from IEU
|
||||||
input logic CSRReadM, CSRWriteM, // read or write CSR
|
input logic CSRReadM, CSRWriteM, // read or write CSR
|
||||||
input logic TrapM, // trap is occurring
|
input logic TrapM, // trap is occurring
|
||||||
input logic mretM, sretM, wfiM, // return or WFI instruction
|
input logic mretM, sretM, wfiM, // return or WFI instruction
|
||||||
input logic IntPendingM, // at least one interrupt is pending and could occur if enabled
|
input logic IntPendingM, // at least one interrupt is pending and could occur if enabled
|
||||||
input logic InterruptM, // interrupt is occurring
|
input logic InterruptM, // interrupt is occurring
|
||||||
|
input logic ExceptionM, // interrupt is occurring
|
||||||
input logic MTimerInt, // timer interrupt
|
input logic MTimerInt, // timer interrupt
|
||||||
input logic MExtInt, SExtInt, // external interrupt (from PLIC)
|
input logic MExtInt, SExtInt, // external interrupt (from PLIC)
|
||||||
input logic MSwInt, // software interrupt
|
input logic MSwInt, // software interrupt
|
||||||
@ -57,17 +58,23 @@ module csr #(parameter
|
|||||||
input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode
|
input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode
|
||||||
// inputs for performance counters
|
// inputs for performance counters
|
||||||
input logic LoadStallD,
|
input logic LoadStallD,
|
||||||
input logic DirPredictionWrongM,
|
input logic StoreStallD,
|
||||||
input logic BTBPredPCWrongM,
|
input logic ICacheStallF,
|
||||||
|
input logic DCacheStallM,
|
||||||
|
input logic BPDirPredWrongM,
|
||||||
|
input logic BTAWrongM,
|
||||||
input logic RASPredPCWrongM,
|
input logic RASPredPCWrongM,
|
||||||
input logic PredictionInstrClassWrongM,
|
input logic IClassWrongM,
|
||||||
input logic BPPredWrongM, // branch predictor is wrong
|
input logic BPWrongM, // branch predictor is wrong
|
||||||
input logic [3:0] InstrClassM,
|
input logic [3:0] InstrClassM,
|
||||||
input logic JumpOrTakenBranchM, // actual instruction class
|
|
||||||
input logic DCacheMiss,
|
input logic DCacheMiss,
|
||||||
input logic DCacheAccess,
|
input logic DCacheAccess,
|
||||||
input logic ICacheMiss,
|
input logic ICacheMiss,
|
||||||
input logic ICacheAccess,
|
input logic ICacheAccess,
|
||||||
|
input logic sfencevmaM,
|
||||||
|
input logic FenceM,
|
||||||
|
input logic DivBusyE, // integer divide busy
|
||||||
|
input logic FDivBusyE, // floating point divide busy
|
||||||
// outputs from CSRs
|
// outputs from CSRs
|
||||||
output logic [1:0] STATUS_MPP,
|
output logic [1:0] STATUS_MPP,
|
||||||
output logic STATUS_SPP, STATUS_TSR, STATUS_TVM,
|
output logic STATUS_SPP, STATUS_TSR, STATUS_TVM,
|
||||||
@ -155,7 +162,7 @@ module csr #(parameter
|
|||||||
// A return sets the PC to MEPC or SEPC
|
// A return sets the PC to MEPC or SEPC
|
||||||
assign RetM = mretM | sretM;
|
assign RetM = mretM | sretM;
|
||||||
mux2 #(`XLEN) epcmux(SEPC_REGW, MEPC_REGW, mretM, EPC);
|
mux2 #(`XLEN) epcmux(SEPC_REGW, MEPC_REGW, mretM, EPC);
|
||||||
mux3 #(`XLEN) pcmux3(PCNext2F, EPC, TrapVectorM, {TrapM, RetM}, UnalignedPCNextF);
|
mux3 #(`XLEN) pcmux3(PC2NextF, EPC, TrapVectorM, {TrapM, RetM}, UnalignedPCNextF);
|
||||||
|
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// CSRWriteValM
|
// CSRWriteValM
|
||||||
@ -258,9 +265,10 @@ module csr #(parameter
|
|||||||
|
|
||||||
if (`ZICOUNTERS_SUPPORTED) begin:counters
|
if (`ZICOUNTERS_SUPPORTED) begin:counters
|
||||||
csrc counters(.clk, .reset, .StallE, .StallM, .FlushM,
|
csrc counters(.clk, .reset, .StallE, .StallM, .FlushM,
|
||||||
.InstrValidNotFlushedM, .LoadStallD, .CSRMWriteM,
|
.InstrValidNotFlushedM, .LoadStallD, .StoreStallD, .CSRWriteM, .CSRMWriteM,
|
||||||
.DirPredictionWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM, .JumpOrTakenBranchM, .BPPredWrongM,
|
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM,
|
||||||
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess,
|
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .sfencevmaM,
|
||||||
|
.InterruptM, .ExceptionM, .FenceM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE,
|
||||||
.CSRAdrM, .PrivilegeModeW, .CSRWriteValM,
|
.CSRAdrM, .PrivilegeModeW, .CSRWriteValM,
|
||||||
.MCOUNTINHIBIT_REGW, .MCOUNTEREN_REGW, .SCOUNTEREN_REGW,
|
.MCOUNTINHIBIT_REGW, .MCOUNTEREN_REGW, .SCOUNTEREN_REGW,
|
||||||
.MTIME_CLINT, .CSRCReadValM, .IllegalCSRCAccessM);
|
.MTIME_CLINT, .CSRCReadValM, .IllegalCSRCAccessM);
|
||||||
|
@ -43,20 +43,28 @@ module csrc #(parameter
|
|||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
input logic StallE, StallM,
|
input logic StallE, StallM,
|
||||||
input logic FlushM,
|
input logic FlushM,
|
||||||
input logic InstrValidNotFlushedM, LoadStallD, CSRMWriteM,
|
input logic InstrValidNotFlushedM, LoadStallD, StoreStallD,
|
||||||
input logic DirPredictionWrongM,
|
input logic CSRMWriteM, CSRWriteM,
|
||||||
input logic BTBPredPCWrongM,
|
input logic BPDirPredWrongM,
|
||||||
|
input logic BTAWrongM,
|
||||||
input logic RASPredPCWrongM,
|
input logic RASPredPCWrongM,
|
||||||
input logic PredictionInstrClassWrongM,
|
input logic IClassWrongM,
|
||||||
input logic BPPredWrongM, // branch predictor is wrong
|
input logic BPWrongM, // branch predictor is wrong
|
||||||
input logic [3:0] InstrClassM,
|
input logic [3:0] InstrClassM,
|
||||||
input logic JumpOrTakenBranchM, // actual instruction class
|
|
||||||
input logic DCacheMiss,
|
input logic DCacheMiss,
|
||||||
input logic DCacheAccess,
|
input logic DCacheAccess,
|
||||||
input logic ICacheMiss,
|
input logic ICacheMiss,
|
||||||
input logic ICacheAccess,
|
input logic ICacheAccess,
|
||||||
|
input logic ICacheStallF,
|
||||||
|
input logic DCacheStallM,
|
||||||
|
input logic sfencevmaM,
|
||||||
|
input logic InterruptM,
|
||||||
|
input logic ExceptionM,
|
||||||
|
input logic FenceM,
|
||||||
|
input logic DivBusyE, // integer divide busy
|
||||||
|
input logic FDivBusyE, // floating point divide busy
|
||||||
input logic [11:0] CSRAdrM,
|
input logic [11:0] CSRAdrM,
|
||||||
input logic [1:0] PrivilegeModeW,
|
input logic [1:0] PrivilegeModeW,
|
||||||
input logic [`XLEN-1:0] CSRWriteValM,
|
input logic [`XLEN-1:0] CSRWriteValM,
|
||||||
input logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW,
|
input logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW,
|
||||||
input logic [63:0] MTIME_CLINT,
|
input logic [63:0] MTIME_CLINT,
|
||||||
@ -68,6 +76,7 @@ module csrc #(parameter
|
|||||||
logic [`XLEN-1:0] HPMCOUNTER_REGW[`COUNTERS-1:0];
|
logic [`XLEN-1:0] HPMCOUNTER_REGW[`COUNTERS-1:0];
|
||||||
logic [`XLEN-1:0] HPMCOUNTERH_REGW[`COUNTERS-1:0];
|
logic [`XLEN-1:0] HPMCOUNTERH_REGW[`COUNTERS-1:0];
|
||||||
logic LoadStallE, LoadStallM;
|
logic LoadStallE, LoadStallM;
|
||||||
|
logic StoreStallE, StoreStallM;
|
||||||
logic [`COUNTERS-1:0] WriteHPMCOUNTERM;
|
logic [`COUNTERS-1:0] WriteHPMCOUNTERM;
|
||||||
logic [`COUNTERS-1:0] CounterEvent;
|
logic [`COUNTERS-1:0] CounterEvent;
|
||||||
logic [63:0] HPMCOUNTERPlusM[`COUNTERS-1:0];
|
logic [63:0] HPMCOUNTERPlusM[`COUNTERS-1:0];
|
||||||
@ -75,8 +84,8 @@ module csrc #(parameter
|
|||||||
genvar i;
|
genvar i;
|
||||||
|
|
||||||
// Interface signals
|
// Interface signals
|
||||||
flopenrc #(1) LoadStallEReg(.clk, .reset, .clear(1'b0), .en(~StallE), .d(LoadStallD), .q(LoadStallE)); // don't flush the load stall during a load stall.
|
flopenrc #(2) LoadStallEReg(.clk, .reset, .clear(1'b0), .en(~StallE), .d({StoreStallD, LoadStallD}), .q({StoreStallE, LoadStallE})); // don't flush the load stall during a load stall.
|
||||||
flopenrc #(1) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d(LoadStallE), .q(LoadStallM));
|
flopenrc #(2) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d({StoreStallE, LoadStallE}), .q({StoreStallM, LoadStallM}));
|
||||||
|
|
||||||
// Determine when to increment each counter
|
// Determine when to increment each counter
|
||||||
assign CounterEvent[0] = 1'b1; // MCYCLE always increments
|
assign CounterEvent[0] = 1'b1; // MCYCLE always increments
|
||||||
@ -85,20 +94,29 @@ module csrc #(parameter
|
|||||||
if(`QEMU) begin: cevent // No other performance counters in QEMU
|
if(`QEMU) begin: cevent // No other performance counters in QEMU
|
||||||
assign CounterEvent[`COUNTERS-1:3] = 0;
|
assign CounterEvent[`COUNTERS-1:3] = 0;
|
||||||
end else begin: cevent // User-defined counters
|
end else begin: cevent // User-defined counters
|
||||||
assign CounterEvent[3] = LoadStallM & InstrValidNotFlushedM; // Load Stalls. don't want to suppress on flush as this only happens if flushed.
|
assign CounterEvent[3] = InstrClassM[0] & InstrValidNotFlushedM; // branch instruction
|
||||||
assign CounterEvent[4] = DirPredictionWrongM & InstrValidNotFlushedM; // Branch predictor wrong direction
|
assign CounterEvent[4] = InstrClassM[1] & ~InstrClassM[2] & InstrValidNotFlushedM; // jump and not return instructions
|
||||||
assign CounterEvent[5] = InstrClassM[0] & InstrValidNotFlushedM; // branch instruction
|
assign CounterEvent[5] = InstrClassM[2] & InstrValidNotFlushedM; // return instructions
|
||||||
assign CounterEvent[6] = BTBPredPCWrongM & InstrValidNotFlushedM; // branch predictor wrong target
|
assign CounterEvent[6] = BPWrongM & InstrValidNotFlushedM; // branch predictor wrong
|
||||||
assign CounterEvent[7] = JumpOrTakenBranchM & InstrValidNotFlushedM; // jump or taken branch instructions
|
assign CounterEvent[7] = BPDirPredWrongM & InstrValidNotFlushedM; // Branch predictor wrong direction
|
||||||
assign CounterEvent[8] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address
|
assign CounterEvent[8] = BTAWrongM & InstrValidNotFlushedM; // branch predictor wrong target
|
||||||
assign CounterEvent[9] = InstrClassM[2] & InstrValidNotFlushedM; // return instructions
|
assign CounterEvent[9] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address
|
||||||
assign CounterEvent[10] = PredictionInstrClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong
|
assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong
|
||||||
assign CounterEvent[11] = DCacheAccess & InstrValidNotFlushedM; // data cache access
|
assign CounterEvent[11] = LoadStallM & InstrValidNotFlushedM; // Load Stalls. don't want to suppress on flush as this only happens if flushed.
|
||||||
assign CounterEvent[12] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss
|
assign CounterEvent[12] = StoreStallM & InstrValidNotFlushedM; // Store Stall
|
||||||
assign CounterEvent[13] = ICacheAccess & InstrValidNotFlushedM; // instruction cache access
|
assign CounterEvent[13] = DCacheAccess & InstrValidNotFlushedM; // data cache access
|
||||||
assign CounterEvent[14] = ICacheMiss; // instruction cache miss. Miss asserted 1 cycle at start of cache miss
|
assign CounterEvent[14] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss
|
||||||
assign CounterEvent[15] = BPPredWrongM & InstrValidNotFlushedM; // branch predictor wrong
|
assign CounterEvent[15] = DCacheStallM; // d cache miss cycles
|
||||||
assign CounterEvent[`COUNTERS-1:16] = 0; // eventually give these sources, including FP instructions, I$/D$ misses, branches and mispredictions
|
assign CounterEvent[16] = ICacheAccess & InstrValidNotFlushedM; // instruction cache access
|
||||||
|
assign CounterEvent[17] = ICacheMiss; // instruction cache miss. Miss asserted 1 cycle at start of cache miss
|
||||||
|
assign CounterEvent[18] = ICacheStallF; // i cache miss cycles
|
||||||
|
assign CounterEvent[19] = CSRWriteM & InstrValidNotFlushedM; // CSR writes
|
||||||
|
assign CounterEvent[20] = FenceM & InstrValidNotFlushedM; // fence.i
|
||||||
|
assign CounterEvent[21] = sfencevmaM & InstrValidNotFlushedM; // sfence.vma
|
||||||
|
assign CounterEvent[22] = InterruptM; // interrupt, InstrValidNotFlushedM will be low
|
||||||
|
assign CounterEvent[23] = ExceptionM; // exceptions, InstrValidNotFlushedM will be low
|
||||||
|
assign CounterEvent[24] = DivBusyE | FDivBusyE; // division cycles *** RT: might need to be delay until the next cycle
|
||||||
|
assign CounterEvent[`COUNTERS-1:25] = 0; // eventually give these sources, including FP instructions, I$/D$ misses, branches and mispredictions
|
||||||
end
|
end
|
||||||
|
|
||||||
// Counter update and write logic
|
// Counter update and write logic
|
||||||
|
@ -38,7 +38,7 @@ module privileged (
|
|||||||
input logic [`XLEN-1:0] SrcAM, // GPR register to write
|
input logic [`XLEN-1:0] SrcAM, // GPR register to write
|
||||||
input logic [31:0] InstrM, // Instruction
|
input logic [31:0] InstrM, // Instruction
|
||||||
input logic [`XLEN-1:0] IEUAdrM, // address from IEU
|
input logic [`XLEN-1:0] IEUAdrM, // address from IEU
|
||||||
input logic [`XLEN-1:0] PCM, PCNext2F, // program counter, next PC going to trap/return PC logic
|
input logic [`XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return PC logic
|
||||||
// control signals
|
// control signals
|
||||||
input logic InstrValidM, // Current instruction is valid (not flushed)
|
input logic InstrValidM, // Current instruction is valid (not flushed)
|
||||||
input logic CommittedM, CommittedF, // current instruction is using bus; don't interrupt
|
input logic CommittedM, CommittedF, // current instruction is using bus; don't interrupt
|
||||||
@ -46,17 +46,21 @@ module privileged (
|
|||||||
// processor events for performance counter logging
|
// processor events for performance counter logging
|
||||||
input logic FRegWriteM, // instruction will write floating-point registers
|
input logic FRegWriteM, // instruction will write floating-point registers
|
||||||
input logic LoadStallD, // load instruction is stalling
|
input logic LoadStallD, // load instruction is stalling
|
||||||
input logic DirPredictionWrongM, // branch predictor guessed wrong directoin
|
input logic StoreStallD, // store instruction is stalling
|
||||||
input logic BTBPredPCWrongM, // branch predictor guessed wrong target
|
input logic ICacheStallF, // I cache stalled
|
||||||
input logic RASPredPCWrongM, // return adddress stack guessed wrong target
|
input logic DCacheStallM, // D cache stalled
|
||||||
input logic PredictionInstrClassWrongM, // branch predictor guessed wrong instruction class
|
input logic BPDirPredWrongM, // branch predictor guessed wrong direction
|
||||||
input logic BPPredWrongM, // branch predictor is wrong
|
input logic BTAWrongM, // branch predictor guessed wrong target
|
||||||
|
input logic RASPredPCWrongM, // return adddress stack guessed wrong target
|
||||||
|
input logic IClassWrongM, // branch predictor guessed wrong instruction class
|
||||||
|
input logic BPWrongM, // branch predictor is wrong
|
||||||
input logic [3:0] InstrClassM, // actual instruction class
|
input logic [3:0] InstrClassM, // actual instruction class
|
||||||
input logic JumpOrTakenBranchM, // actual instruction class
|
|
||||||
input logic DCacheMiss, // data cache miss
|
input logic DCacheMiss, // data cache miss
|
||||||
input logic DCacheAccess, // data cache accessed (hit or miss)
|
input logic DCacheAccess, // data cache accessed (hit or miss)
|
||||||
input logic ICacheMiss, // instruction cache miss
|
input logic ICacheMiss, // instruction cache miss
|
||||||
input logic ICacheAccess, // instruction cache access
|
input logic ICacheAccess, // instruction cache access
|
||||||
|
input logic DivBusyE, // integer divide busy
|
||||||
|
input logic FDivBusyE, // floating point divide busy
|
||||||
// fault sources
|
// fault sources
|
||||||
input logic InstrAccessFaultF, // instruction access fault
|
input logic InstrAccessFaultF, // instruction access fault
|
||||||
input logic LoadAccessFaultM, StoreAmoAccessFaultM, // load or store access fault
|
input logic LoadAccessFaultM, StoreAmoAccessFaultM, // load or store access fault
|
||||||
@ -84,6 +88,7 @@ module privileged (
|
|||||||
// control outputs
|
// control outputs
|
||||||
output logic RetM, TrapM, // return instruction, or trap
|
output logic RetM, TrapM, // return instruction, or trap
|
||||||
output logic sfencevmaM, // sfence.vma instruction
|
output logic sfencevmaM, // sfence.vma instruction
|
||||||
|
input logic FenceM, // fence instruction
|
||||||
output logic BigEndianM, // Use big endian in current privilege mode
|
output logic BigEndianM, // Use big endian in current privilege mode
|
||||||
// Fault outputs
|
// Fault outputs
|
||||||
output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire
|
output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire
|
||||||
@ -106,9 +111,9 @@ module privileged (
|
|||||||
logic DelegateM; // trap should be delegated
|
logic DelegateM; // trap should be delegated
|
||||||
logic wfiM; // wait for interrupt instruction
|
logic wfiM; // wait for interrupt instruction
|
||||||
logic IntPendingM; // interrupt is pending, even if not enabled. ends wfi
|
logic IntPendingM; // interrupt is pending, even if not enabled. ends wfi
|
||||||
logic InterruptM; // interrupt occuring
|
logic InterruptM; // interrupt occuring
|
||||||
|
logic ExceptionM; // Memory stage instruction caused a fault
|
||||||
|
|
||||||
// track the current privilege level
|
// track the current privilege level
|
||||||
privmode privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM,
|
privmode privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM,
|
||||||
.STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW);
|
.STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW);
|
||||||
@ -121,12 +126,13 @@ module privileged (
|
|||||||
|
|
||||||
// Control and Status Registers
|
// Control and Status Registers
|
||||||
csr csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW,
|
csr csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW,
|
||||||
.InstrM, .PCM, .SrcAM, .IEUAdrM, .PCNext2F,
|
.InstrM, .PCM, .SrcAM, .IEUAdrM, .PC2NextF,
|
||||||
.CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .wfiM, .IntPendingM, .InterruptM,
|
.CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .wfiM, .IntPendingM, .InterruptM,
|
||||||
.MTimerInt, .MExtInt, .SExtInt, .MSwInt,
|
.MTimerInt, .MExtInt, .SExtInt, .MSwInt,
|
||||||
.MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD,
|
.MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD,
|
||||||
.DirPredictionWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPPredWrongM,
|
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM,
|
||||||
.PredictionInstrClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .JumpOrTakenBranchM,
|
.sfencevmaM, .ExceptionM, .FenceM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE,
|
||||||
|
.IClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess,
|
||||||
.NextPrivilegeModeM, .PrivilegeModeW, .CauseM, .SelHPTW,
|
.NextPrivilegeModeM, .PrivilegeModeW, .CauseM, .SelHPTW,
|
||||||
.STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TVM,
|
.STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TVM,
|
||||||
.STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .STATUS_FS,
|
.STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .STATUS_FS,
|
||||||
@ -149,7 +155,7 @@ module privileged (
|
|||||||
.mretM, .sretM, .PrivilegeModeW,
|
.mretM, .sretM, .PrivilegeModeW,
|
||||||
.MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MEDELEG_REGW, .STATUS_MIE, .STATUS_SIE,
|
.MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MEDELEG_REGW, .STATUS_MIE, .STATUS_SIE,
|
||||||
.InstrValidM, .CommittedM, .CommittedF,
|
.InstrValidM, .CommittedM, .CommittedF,
|
||||||
.TrapM, .RetM, .wfiM, .InterruptM, .IntPendingM, .DelegateM, .WFIStallM, .CauseM);
|
.TrapM, .RetM, .wfiM, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .WFIStallM, .CauseM);
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ module trap (
|
|||||||
output logic TrapM, // Trap is occurring
|
output logic TrapM, // Trap is occurring
|
||||||
output logic RetM, // Return instruction being executed
|
output logic RetM, // Return instruction being executed
|
||||||
output logic InterruptM, // Interrupt is occurring
|
output logic InterruptM, // Interrupt is occurring
|
||||||
|
output logic ExceptionM, // exception is occurring
|
||||||
output logic IntPendingM, // Interrupt is pending, might occur if enabled
|
output logic IntPendingM, // Interrupt is pending, might occur if enabled
|
||||||
output logic DelegateM, // Delegate trap to supervisor handler
|
output logic DelegateM, // Delegate trap to supervisor handler
|
||||||
output logic WFIStallM, // Stall due to WFI instruction
|
output logic WFIStallM, // Stall due to WFI instruction
|
||||||
@ -52,7 +53,6 @@ module trap (
|
|||||||
);
|
);
|
||||||
|
|
||||||
logic MIntGlobalEnM, SIntGlobalEnM; // Global interupt enables
|
logic MIntGlobalEnM, SIntGlobalEnM; // Global interupt enables
|
||||||
logic ExceptionM; // exception is occurring
|
|
||||||
logic Committed; // LSU or IFU has committed to a bus operation that can't be interrupted
|
logic Committed; // LSU or IFU has committed to a bus operation that can't be interrupted
|
||||||
logic BothInstrAccessFaultM; // instruction or HPTW ITLB fill caused an Instruction Access Fault
|
logic BothInstrAccessFaultM; // instruction or HPTW ITLB fill caused an Instruction Access Fault
|
||||||
logic [11:0] PendingIntsM, ValidIntsM, EnabledIntsM; // interrupts are pending, valid, or enabled
|
logic [11:0] PendingIntsM, ValidIntsM, EnabledIntsM; // interrupts are pending, valid, or enabled
|
||||||
|
@ -66,7 +66,7 @@ module wallypipelinedcore (
|
|||||||
logic [`XLEN-1:0] PCFSpill, PCE, PCLinkE;
|
logic [`XLEN-1:0] PCFSpill, PCE, PCLinkE;
|
||||||
logic [`XLEN-1:0] PCM;
|
logic [`XLEN-1:0] PCM;
|
||||||
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
|
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
|
||||||
logic [`XLEN-1:0] UnalignedPCNextF, PCNext2F;
|
logic [`XLEN-1:0] UnalignedPCNextF, PC2NextF;
|
||||||
logic [1:0] MemRWM;
|
logic [1:0] MemRWM;
|
||||||
logic InstrValidD, InstrValidE, InstrValidM;
|
logic InstrValidD, InstrValidE, InstrValidM;
|
||||||
logic InstrMisalignedFaultM;
|
logic InstrMisalignedFaultM;
|
||||||
@ -140,11 +140,11 @@ module wallypipelinedcore (
|
|||||||
logic LSUHWRITE;
|
logic LSUHWRITE;
|
||||||
logic LSUHREADY;
|
logic LSUHREADY;
|
||||||
|
|
||||||
logic BPPredWrongE, BPPredWrongM;
|
logic BPWrongE, BPWrongM;
|
||||||
logic DirPredictionWrongM;
|
logic BPDirPredWrongM;
|
||||||
logic BTBPredPCWrongM;
|
logic BTAWrongM;
|
||||||
logic RASPredPCWrongM;
|
logic RASPredPCWrongM;
|
||||||
logic PredictionInstrClassWrongM;
|
logic IClassWrongM;
|
||||||
logic [3:0] InstrClassM;
|
logic [3:0] InstrClassM;
|
||||||
logic InstrAccessFaultF, HPTWInstrAccessFaultM;
|
logic InstrAccessFaultF, HPTWInstrAccessFaultM;
|
||||||
logic [2:0] LSUHSIZE;
|
logic [2:0] LSUHSIZE;
|
||||||
@ -160,24 +160,25 @@ module wallypipelinedcore (
|
|||||||
logic BigEndianM;
|
logic BigEndianM;
|
||||||
logic FCvtIntE;
|
logic FCvtIntE;
|
||||||
logic CommittedF;
|
logic CommittedF;
|
||||||
logic JumpOrTakenBranchM;
|
|
||||||
logic BranchD, BranchE, JumpD, JumpE;
|
logic BranchD, BranchE, JumpD, JumpE;
|
||||||
|
logic FenceM;
|
||||||
|
logic DCacheStallM, ICacheStallF;
|
||||||
|
|
||||||
// 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,
|
.InstrValidM, .InstrValidE, .InstrValidD,
|
||||||
.BranchD, .BranchE, .JumpD, .JumpE,
|
.BranchD, .BranchE, .JumpD, .JumpE, .ICacheStallF,
|
||||||
// Fetch
|
// Fetch
|
||||||
.HRDATA, .PCFSpill, .IFUHADDR, .PCNext2F,
|
.HRDATA, .PCFSpill, .IFUHADDR, .PC2NextF,
|
||||||
.IFUStallF, .IFUHBURST, .IFUHTRANS, .IFUHSIZE, .IFUHREADY, .IFUHWRITE,
|
.IFUStallF, .IFUHBURST, .IFUHTRANS, .IFUHSIZE, .IFUHREADY, .IFUHWRITE,
|
||||||
.ICacheAccess, .ICacheMiss,
|
.ICacheAccess, .ICacheMiss,
|
||||||
// Execute
|
// Execute
|
||||||
.PCLinkE, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCE, .BPPredWrongE, .BPPredWrongM,
|
.PCLinkE, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCE, .BPWrongE, .BPWrongM,
|
||||||
// Mem
|
// Mem
|
||||||
.CommittedF, .UnalignedPCNextF, .InvalidateICacheM, .CSRWriteFenceM,
|
.CommittedF, .UnalignedPCNextF, .InvalidateICacheM, .CSRWriteFenceM,
|
||||||
.InstrD, .InstrM, .PCM, .InstrClassM, .DirPredictionWrongM, .JumpOrTakenBranchM,
|
.InstrD, .InstrM, .PCM, .InstrClassM, .BPDirPredWrongM,
|
||||||
.BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM,
|
.BTAWrongM, .RASPredPCWrongM, .IClassWrongM,
|
||||||
// Faults out
|
// Faults out
|
||||||
.IllegalBaseInstrD, .IllegalFPUInstrD, .InstrPageFaultF, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM,
|
.IllegalBaseInstrD, .IllegalFPUInstrD, .InstrPageFaultF, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM,
|
||||||
// mmu management
|
// mmu management
|
||||||
@ -208,7 +209,7 @@ module wallypipelinedcore (
|
|||||||
// 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,
|
||||||
.CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .StoreStallD);
|
.CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .FenceM, .StoreStallD);
|
||||||
|
|
||||||
lsu lsu(
|
lsu lsu(
|
||||||
.clk, .reset, .StallM, .FlushM, .StallW, .FlushW,
|
.clk, .reset, .StallM, .FlushM, .StallW, .FlushW,
|
||||||
@ -231,6 +232,7 @@ module wallypipelinedcore (
|
|||||||
.STATUS_MPRV, // from csr
|
.STATUS_MPRV, // from csr
|
||||||
.STATUS_MPP, // from csr
|
.STATUS_MPP, // from csr
|
||||||
.sfencevmaM, // connects to privilege
|
.sfencevmaM, // connects to privilege
|
||||||
|
.DCacheStallM, // connects to privilege
|
||||||
.LoadPageFaultM, // connects to privilege
|
.LoadPageFaultM, // connects to privilege
|
||||||
.StoreAmoPageFaultM, // connects to privilege
|
.StoreAmoPageFaultM, // connects to privilege
|
||||||
.LoadMisalignedFaultM, // connects to privilege
|
.LoadMisalignedFaultM, // connects to privilege
|
||||||
@ -268,7 +270,7 @@ module wallypipelinedcore (
|
|||||||
|
|
||||||
// global stall and flush control
|
// global stall and flush control
|
||||||
hazard hzu(
|
hazard hzu(
|
||||||
.BPPredWrongE, .CSRWriteFenceM, .RetM, .TrapM,
|
.BPWrongE, .CSRWriteFenceM, .RetM, .TrapM,
|
||||||
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
|
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
|
||||||
.LSUStallM, .IFUStallF,
|
.LSUStallM, .IFUStallF,
|
||||||
.FCvtIntStallD, .FPUStallD,
|
.FCvtIntStallD, .FPUStallD,
|
||||||
@ -284,14 +286,14 @@ module wallypipelinedcore (
|
|||||||
privileged priv(
|
privileged priv(
|
||||||
.clk, .reset,
|
.clk, .reset,
|
||||||
.FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW,
|
.FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW,
|
||||||
.CSRReadM, .CSRWriteM, .SrcAM, .PCM, .PCNext2F,
|
.CSRReadM, .CSRWriteM, .SrcAM, .PCM, .PC2NextF,
|
||||||
.InstrM, .CSRReadValW, .UnalignedPCNextF,
|
.InstrM, .CSRReadValW, .UnalignedPCNextF,
|
||||||
.RetM, .TrapM, .sfencevmaM,
|
.RetM, .TrapM, .sfencevmaM, .FenceM, .DCacheStallM, .ICacheStallF,
|
||||||
.InstrValidM, .CommittedM, .CommittedF,
|
.InstrValidM, .CommittedM, .CommittedF,
|
||||||
.FRegWriteM, .LoadStallD,
|
.FRegWriteM, .LoadStallD, .StoreStallD,
|
||||||
.DirPredictionWrongM, .BTBPredPCWrongM, .BPPredWrongM,
|
.BPDirPredWrongM, .BTAWrongM, .BPWrongM,
|
||||||
.RASPredPCWrongM, .PredictionInstrClassWrongM,
|
.RASPredPCWrongM, .IClassWrongM, .DivBusyE, .FDivBusyE,
|
||||||
.InstrClassM, .JumpOrTakenBranchM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM,
|
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM,
|
||||||
.InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM,
|
.InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM,
|
||||||
.InstrMisalignedFaultM, .IllegalIEUFPUInstrD,
|
.InstrMisalignedFaultM, .IllegalIEUFPUInstrD,
|
||||||
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
|
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
|
||||||
@ -304,7 +306,7 @@ module wallypipelinedcore (
|
|||||||
.FRM_REGW,.BreakpointFaultM, .EcallFaultM, .WFIStallM, .BigEndianM);
|
.FRM_REGW,.BreakpointFaultM, .EcallFaultM, .WFIStallM, .BigEndianM);
|
||||||
end else begin
|
end else begin
|
||||||
assign CSRReadValW = 0;
|
assign CSRReadValW = 0;
|
||||||
assign UnalignedPCNextF = PCNext2F;
|
assign UnalignedPCNextF = PC2NextF;
|
||||||
assign RetM = 0;
|
assign RetM = 0;
|
||||||
assign TrapM = 0;
|
assign TrapM = 0;
|
||||||
assign WFIStallM = 0;
|
assign WFIStallM = 0;
|
||||||
|
@ -137,17 +137,24 @@ module testbench;
|
|||||||
.CMP_CSR (1)
|
.CMP_CSR (1)
|
||||||
) idv_trace2api(rvvi);
|
) idv_trace2api(rvvi);
|
||||||
|
|
||||||
|
int PRIV_RWX = RVVI_MEMORY_PRIVILEGE_READ | RVVI_MEMORY_PRIVILEGE_WRITE | RVVI_MEMORY_PRIVILEGE_EXEC;
|
||||||
|
int PRIV_RW = RVVI_MEMORY_PRIVILEGE_READ | RVVI_MEMORY_PRIVILEGE_WRITE;
|
||||||
|
int PRIV_X = RVVI_MEMORY_PRIVILEGE_EXEC;
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
|
|
||||||
MAX_ERRS = 3;
|
MAX_ERRS = 3;
|
||||||
|
|
||||||
// Initialize REF (do this before initializing the DUT)
|
// Initialize REF (do this before initializing the DUT)
|
||||||
if (!rvviVersionCheck(RVVI_API_VERSION)) begin
|
if (!rvviVersionCheck(RVVI_API_VERSION)) begin
|
||||||
msgfatal($sformatf("%m @ t=%0t: Expecting RVVI API version %0d.", $time, RVVI_API_VERSION));
|
msgfatal($sformatf("%m @ t=%0t: Expecting RVVI API version %0d.", $time, RVVI_API_VERSION));
|
||||||
end
|
end
|
||||||
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"));
|
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"));
|
||||||
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv"));
|
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv"));
|
||||||
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GC"));
|
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GC"));
|
||||||
void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 39));
|
void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 39));
|
||||||
|
void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6));
|
||||||
|
|
||||||
if (!rvviRefInit(elffilename)) begin
|
if (!rvviRefInit(elffilename)) begin
|
||||||
msgfatal($sformatf("%m @ t=%0t: rvviRefInit failed", $time));
|
msgfatal($sformatf("%m @ t=%0t: rvviRefInit failed", $time));
|
||||||
end
|
end
|
||||||
@ -158,6 +165,41 @@ module testbench;
|
|||||||
void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET
|
void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET
|
||||||
void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET
|
void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET
|
||||||
void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME
|
void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME
|
||||||
|
|
||||||
|
// cannot predict this register due to latency between
|
||||||
|
// pending and taken
|
||||||
|
void'(rvviRefCsrSetVolatile(0, 32'h344)); // MIP
|
||||||
|
void'(rvviRefCsrSetVolatile(0, 32'h144)); // SIP
|
||||||
|
|
||||||
|
// Memory lo, hi, priv (RVVI_MEMORY_PRIVILEGE_{READ,WRITE,EXEC})
|
||||||
|
void'(rvviRefMemorySetPrivilege(56'h0, 56'h7fffffffff, 0));
|
||||||
|
if (`BOOTROM_SUPPORTED)
|
||||||
|
void'(rvviRefMemorySetPrivilege(`BOOTROM_BASE, (`BOOTROM_BASE + `BOOTROM_RANGE), PRIV_X));
|
||||||
|
if (`UNCORE_RAM_SUPPORTED)
|
||||||
|
void'(rvviRefMemorySetPrivilege(`UNCORE_RAM_BASE, (`UNCORE_RAM_BASE + `UNCORE_RAM_RANGE), PRIV_RWX));
|
||||||
|
if (`EXT_MEM_SUPPORTED)
|
||||||
|
void'(rvviRefMemorySetPrivilege(`EXT_MEM_BASE, (`EXT_MEM_BASE + `EXT_MEM_RANGE), PRIV_RWX));
|
||||||
|
|
||||||
|
if (`CLINT_SUPPORTED) begin
|
||||||
|
void'(rvviRefMemorySetPrivilege(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE), PRIV_RW));
|
||||||
|
void'(rvviRefMemorySetVolatile(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE)));
|
||||||
|
end
|
||||||
|
if (`GPIO_SUPPORTED) begin
|
||||||
|
void'(rvviRefMemorySetPrivilege(`GPIO_BASE, (`GPIO_BASE + `GPIO_RANGE), PRIV_RW));
|
||||||
|
void'(rvviRefMemorySetVolatile(`GPIO_BASE, (`GPIO_BASE + `GPIO_RANGE)));
|
||||||
|
end
|
||||||
|
if (`UART_SUPPORTED) begin
|
||||||
|
void'(rvviRefMemorySetPrivilege(`UART_BASE, (`UART_BASE + `UART_RANGE), PRIV_RW));
|
||||||
|
void'(rvviRefMemorySetVolatile(`UART_BASE, (`UART_BASE + `UART_RANGE)));
|
||||||
|
end
|
||||||
|
if (`PLIC_SUPPORTED) begin
|
||||||
|
void'(rvviRefMemorySetPrivilege(`PLIC_BASE, (`PLIC_BASE + `PLIC_RANGE), PRIV_RW));
|
||||||
|
void'(rvviRefMemorySetVolatile(`PLIC_BASE, (`PLIC_BASE + `PLIC_RANGE)));
|
||||||
|
end
|
||||||
|
if (`SDC_SUPPORTED) begin
|
||||||
|
void'(rvviRefMemorySetPrivilege(`SDC_BASE, (`SDC_BASE + `SDC_RANGE), PRIV_RW));
|
||||||
|
void'(rvviRefMemorySetVolatile(`SDC_BASE, (`SDC_BASE + `SDC_RANGE)));
|
||||||
|
end
|
||||||
|
|
||||||
if(`XLEN==32) begin
|
if(`XLEN==32) begin
|
||||||
void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH
|
void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH
|
||||||
@ -166,16 +208,24 @@ module testbench;
|
|||||||
void'(rvviRefCsrSetVolatile(0, 32'hB82)); // MINSTRETH
|
void'(rvviRefCsrSetVolatile(0, 32'hB82)); // MINSTRETH
|
||||||
end
|
end
|
||||||
|
|
||||||
// Enable the trace2log module
|
void'(rvviRefCsrSetVolatile(0, 32'h104)); // SIE - Temporary!!!!
|
||||||
if ($value$plusargs("TRACE2LOG_ENABLE=%d", TRACE2LOG_ENABLE)) begin
|
|
||||||
msgnote($sformatf("%m @ t=%0t: TRACE2LOG_ENABLE is %0d", $time, TRACE2LOG_ENABLE));
|
|
||||||
end
|
|
||||||
|
|
||||||
if ($value$plusargs("TRACE2COV_ENABLE=%d", TRACE2COV_ENABLE)) begin
|
// These should be done in the attached client
|
||||||
msgnote($sformatf("%m @ t=%0t: TRACE2COV_ENABLE is %0d", $time, TRACE2COV_ENABLE));
|
// // Enable the trace2log module
|
||||||
end
|
// if ($value$plusargs("TRACE2LOG_ENABLE=%d", TRACE2LOG_ENABLE)) begin
|
||||||
|
// msgnote($sformatf("%m @ t=%0t: TRACE2LOG_ENABLE is %0d", $time, TRACE2LOG_ENABLE));
|
||||||
|
// end
|
||||||
|
//
|
||||||
|
// if ($value$plusargs("TRACE2COV_ENABLE=%d", TRACE2COV_ENABLE)) begin
|
||||||
|
// msgnote($sformatf("%m @ t=%0t: TRACE2COV_ENABLE is %0d", $time, TRACE2COV_ENABLE));
|
||||||
|
// end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
always @(dut.core.MTimerInt) void'(rvvi.net_push("MTimerInterrupt", dut.core.MTimerInt));
|
||||||
|
always @(dut.core.MExtInt) void'(rvvi.net_push("MExternalInterrupt", dut.core.MExtInt));
|
||||||
|
always @(dut.core.SExtInt) void'(rvvi.net_push("SExternalInterrupt", dut.core.SExtInt));
|
||||||
|
always @(dut.core.MSwInt) void'(rvvi.net_push("MSWInterrupt", dut.core.MSwInt));
|
||||||
|
|
||||||
final begin
|
final begin
|
||||||
void'(rvviRefShutdown());
|
void'(rvviRefShutdown());
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user