This commit is contained in:
mmasserfrye 2022-05-12 18:08:20 +00:00
commit 01685b982c
35 changed files with 200 additions and 265 deletions

@ -1 +1 @@
Subproject commit 261a65e0a2d3e8d62d81b1d8fe7e309a096bc6a9
Subproject commit 2d2aaa7b85c60219c591555b647dfa1785ffe1b3

@ -1 +1 @@
Subproject commit 307c77b26e070ae85ffea665ad9b642b40e33c86
Subproject commit effd553a6a91ed9b0ba251796a8a44505a45174f

@ -1 +1 @@
Subproject commit a7e27bc046405f0dbcde091be99f5a5d564e2172
Subproject commit cb4295f9ce5da2881d7746015a6105adb8f09071

@ -1 +1 @@
Subproject commit cf04274f50621fd9ef9147793cca6dd1657985c7
Subproject commit 3e2bf06b071a77ae62c09bf07c5229d1f9397d94

View File

@ -1,10 +0,0 @@
ch5.debug: ch5
riscv64-unknown-elf-objdump -D ch5 > ch5.debug
ch5: ch5.S Makefile
riscv64-unknown-elf-gcc -nodefaultlibs -nostartfiles -o ch5 ch5.S
# -ffreestanding
# -nostdlib
clean:
rm -f ch5 ch5.debug

Binary file not shown.

View File

@ -1,16 +0,0 @@
# ch5.s
# David_Harris@hmc.edu 14 December 2021
.section .text.init
.globl _start
_start:
lw x1, 4(x0)
sw x1, 8(x0)
add x2, x1, x1
beq x1, x2, done
loop:
jal x0, loop
done:
.end

View File

@ -1,38 +0,0 @@
ch5: file format elf64-littleriscv
Disassembly of section .text:
0000000000010078 <_start>:
10078: 00402083 lw ra,4(zero) # 4 <_start-0x10074>
1007c: 00102423 sw ra,8(zero) # 8 <_start-0x10070>
10080: 00108133 add sp,ra,ra
10084: 00208463 beq ra,sp,1008c <done>
0000000000010088 <loop>:
10088: 0000006f j 10088 <loop>
Disassembly of section .riscv.attributes:
0000000000000000 <.riscv.attributes>:
0: 3241 addiw tp,tp,-16
2: 0000 unimp
4: 7200 ld s0,32(a2)
6: 7369 lui t1,0xffffa
8: 01007663 bgeu zero,a6,14 <_start-0x10064>
c: 0028 addi a0,sp,8
e: 0000 unimp
10: 7205 lui tp,0xfffe1
12: 3676 fld fa2,376(sp)
14: 6934 ld a3,80(a0)
16: 7032 0x7032
18: 5f30 lw a2,120(a4)
1a: 326d addiw tp,tp,-5
1c: 3070 fld fa2,224(s0)
1e: 615f 7032 5f30 0x5f307032615f
24: 3266 fld ft4,120(sp)
26: 3070 fld fa2,224(s0)
28: 645f 7032 5f30 0x5f307032645f
2e: 30703263 0x30703263
...

Binary file not shown.

View File

@ -43,7 +43,6 @@ module sram1p1rw #(parameter DEPTH=128, WIDTH=256) (
logic [WIDTH-1:0] StoredData[DEPTH-1:0];
logic [$clog2(DEPTH)-1:0] AdrD;
logic WriteEnableD;
always_ff @(posedge clk) AdrD <= Adr;

View File

@ -41,7 +41,7 @@ module fma(
input logic [`NE-1:0] XExpE, YExpE, ZExpE, // input exponents - execute stage
input logic [`NF:0] XManE, YManE, ZManE, // input mantissa - execute stage
input logic XSgnM, YSgnM, // input signs - memory stage
input logic [`NE-1:0] XExpM, YExpM, ZExpM, // input exponents - memory stage
input logic [`NE-1:0] ZExpM, // input exponents - memory stage
input logic [`NF:0] XManM, YManM, ZManM, // input mantissa - memory stage
input logic XDenormE, YDenormE, ZDenormE, // is denorm
input logic XZeroE, YZeroE, ZZeroE, // is zero - execute stage
@ -85,7 +85,7 @@ module fma(
{AddendStickyE, KillProdE, InvZE, NormCntE, NegSumE, ZSgnEffE, PSgnE, FOpCtrlE[2]&~FOpCtrlE[1]&~FOpCtrlE[0]},
{AddendStickyM, KillProdM, InvZM, NormCntM, NegSumM, ZSgnEffM, PSgnM, Mult});
fma2 fma2(.XSgnM, .YSgnM, .XExpM, .YExpM, .ZExpM, .XManM, .YManM, .ZManM,
fma2 fma2(.XSgnM, .YSgnM, .ZExpM, .XManM, .YManM, .ZManM,
.FrmM, .FmtM, .ProdExpM, .AddendStickyM, .KillProdM, .SumM, .NegSumM, .InvZM, .NormCntM, .ZSgnEffM, .PSgnM,
.XZeroM, .YZeroM, .ZZeroM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .XSNaNM, .YSNaNM, .ZSNaNM, .Mult,
.FMAResM, .FMAFlgM);
@ -283,6 +283,7 @@ module align(
// - Denormal numbers have a diffrent exponent value depending on the precision
assign ZExpVal = ZDenormE ? Denorm : ZExpE;
// assign AlignCnt = ProdExpE - {2'b0, ZExpVal} + (`NF+3);
// *** can we use ProdExpE instead of XExp/YExp to save an adder? DH 5/12/22
assign AlignCnt = XZeroE|YZeroE ? -1 : {2'b0, XExpVal} + {2'b0, YExpVal} - {2'b0, (`NE)'(`BIAS)} + `NF+3 - {2'b0, ZExpVal};
// Defualt Addition without shifting
@ -433,7 +434,7 @@ endmodule
module fma2(
input logic XSgnM, YSgnM, // input signs
input logic [`NE-1:0] XExpM, YExpM, ZExpM, // input exponents
input logic [`NE-1:0] ZExpM, // input exponents
input logic [`NF:0] XManM, YManM, ZManM, // input mantissas
input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
input logic [`FPSIZES/3:0] FmtM, // precision 1 = double 0 = single
@ -481,7 +482,7 @@ module fma2(
// Normalization
///////////////////////////////////////////////////////////////////////////////
normalize normalize(.SumM, .ZExpM, .ProdExpM, .NormCntM, .FmtM, .KillProdM, .AddendStickyM, .NormSum, .NegSumM,
normalize normalize(.SumM, .ZExpM, .ProdExpM, .NormCntM, .FmtM, .KillProdM, .AddendStickyM, .NormSum,
.SumZero, .NormSumSticky, .UfSticky, .SumExp, .ResultDenorm);
@ -529,7 +530,7 @@ module fma2(
// Select the result
///////////////////////////////////////////////////////////////////////////////
resultselect resultselect(.XSgnM, .YSgnM, .XExpM, .YExpM, .ZExpM, .XManM, .YManM, .ZManM,
resultselect resultselect(.XSgnM, .YSgnM, .ZExpM, .XManM, .YManM, .ZManM,
.FrmM, .FmtM, .AddendStickyM, .KillProdM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .RoundAdd,
.ZSgnEffM, .PSgnM, .ResultSgn, .CalcPlus1, .Invalid, .Overflow, .Underflow,
.ResultDenorm, .ResultExp, .ResultFrac, .FMAResM);
@ -577,7 +578,6 @@ module normalize(
input logic [`FPSIZES/3:0] FmtM, // precision 1 = double 0 = single
input logic KillProdM, // is the product set to zero
input logic AddendStickyM, // the sticky bit caclulated from the aligned addend
input logic NegSumM, // was the sum negitive
output logic [`NF+2:0] NormSum, // normalized sum
output logic SumZero, // is the sum zero
output logic NormSumSticky, UfSticky, // sticky bits
@ -1095,7 +1095,7 @@ endmodule
module resultselect(
input logic XSgnM, YSgnM, // input signs
input logic [`NE-1:0] XExpM, YExpM, ZExpM, // input exponents
input logic [`NE-1:0] ZExpM, // input exponents
input logic [`NF:0] XManM, YManM, ZManM, // input mantissas
input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
input logic [`FPSIZES/3:0] FmtM, // precision 1 = double 0 = single

View File

@ -87,7 +87,7 @@ module fpu (
logic XSgnE, YSgnE, ZSgnE; // input's sign - execute stage
logic XSgnM, YSgnM; // input's sign - memory stage
logic [10:0] XExpE, YExpE, ZExpE; // input's exponent - execute stage
logic [10:0] XExpM, YExpM, ZExpM; // input's exponent - memory stage
logic [10:0] ZExpM; // input's exponent - memory stage
logic [52:0] XManE, YManE, ZManE; // input's fraction - execute stage
logic [52:0] XManM, YManM, ZManM; // input's fraction - memory stage
logic XNaNE, YNaNE, ZNaNE; // is the input a NaN - execute stage
@ -189,7 +189,7 @@ module fpu (
fma fma (.clk, .reset, .FlushM, .StallM,
.XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE,
.XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE,
.XSgnM, .YSgnM, .XExpM, .YExpM, .ZExpM, .XManM, .YManM, .ZManM,
.XSgnM, .YSgnM, .ZExpM, .XManM, .YManM, .ZManM,
.XNaNM, .YNaNM, .ZNaNM, .XZeroM, .YZeroM, .ZZeroM,
.XInfM, .YInfM, .ZInfM, .XSNaNM, .YSNaNM, .ZSNaNM,
.FOpCtrlE,
@ -212,25 +212,12 @@ module fpu (
.XNaNQ, .YNaNQ, .XInfQ, .YInfQ, .XZeroQ, .YZeroQ, .load_preload,
.FDivBusyE, .done(FDivSqrtDoneE), .AS_Result(FDivResM), .Flags(FDivFlgM));
// convert from signle to double and vice versa
// other FP execution units
cvtfp cvtfp (.XExpE, .XManE, .XSgnE, .XZeroE, .XDenormE, .XInfE, .XNaNE, .XSNaNE, .FrmE, .FmtE, .CvtFpResE, .CvtFpFlgE);
// compare unit
// - computation is done in one stage
// - writes to FP file durring min/max instructions
// - other comparisons write a 1 or 0 to the integer register
fcmp fcmp (.FmtE, .FOpCtrlE, .XSgnE, .YSgnE, .XExpE, .YExpE, .XManE, .YManE,
.XZeroE, .YZeroE, .XNaNE, .YNaNE, .XSNaNE, .YSNaNE, .FSrcXE, .FSrcYE, .CmpNVE, .CmpResE);
// sign injection unit
fsgn fsgn (.SgnOpCodeE(FOpCtrlE[1:0]), .XSgnE, .YSgnE, .FSrcXE, .FmtE, .XExpMaxE,
.SgnResE);
// classify
fclassify fclassify (.XSgnE, .XDenormE, .XZeroE, .XNaNE, .XInfE, .XNormE,
.XSNaNE, .ClassResE);
// Convert
fsgn fsgn (.SgnOpCodeE(FOpCtrlE[1:0]), .XSgnE, .YSgnE, .FSrcXE, .FmtE, .SgnResE);
fclassify fclassify (.XSgnE, .XDenormE, .XZeroE, .XNaNE, .XInfE, .XNormE, .XSNaNE, .ClassResE);
fcvt fcvt (.XSgnE, .XExpE, .XManE, .XZeroE, .XNaNE, .XInfE, .XDenormE, .ForwardedSrcAE, .FOpCtrlE, .FmtE, .FrmE,
.CvtResE, .CvtFlgE);
@ -253,8 +240,8 @@ module fpu (
// E/M pipe registers
// flopenrc #(64) EMFpReg1(clk, reset, FlushM, ~StallM, FSrcXE, FSrcXM);
flopenrc #(65) EMFpReg2 (clk, reset, FlushM, ~StallM, {XSgnE,XExpE,XManE}, {XSgnM,XExpM,XManM});
flopenrc #(65) EMFpReg3 (clk, reset, FlushM, ~StallM, {YSgnE,YExpE,YManE}, {YSgnM,YExpM,YManM});
flopenrc #(54) EMFpReg2 (clk, reset, FlushM, ~StallM, {XSgnE,XManE}, {XSgnM,XManM});
flopenrc #(54) EMFpReg3 (clk, reset, FlushM, ~StallM, {YSgnE,YManE}, {YSgnM,YManM});
flopenrc #(64) EMFpReg4 (clk, reset, FlushM, ~StallM, {ZExpE,ZManE}, {ZExpM,ZManM});
flopenrc #(12) EMFpReg5 (clk, reset, FlushM, ~StallM,
{XZeroE, YZeroE, ZZeroE, XInfE, YInfE, ZInfE, XNaNE, YNaNE, ZNaNE, XSNaNE, YSNaNE, ZSNaNE},

View File

@ -3,7 +3,6 @@
module fsgn (
input logic XSgnE, YSgnE, // X and Y sign bits
input logic [63:0] FSrcXE, // X
input logic XExpMaxE, // max possible exponent (all ones)
input logic FmtE, // precision 1 = double 0 = single
input logic [1:0] SgnOpCodeE, // operation control
output logic [63:0] SgnResE // result

View File

@ -60,6 +60,8 @@ module hazard(
// A stage must stall if the next stage is stalled
// If any stages are stalled, the first stage that isn't stalled must flush.
// *** can stalls be pushed into earlier stages (e.g. no stall after Decode?)
assign StallFCause = CSRWritePendingDEM & ~(TrapM | RetM | BPPredWrongE);
// stall in decode if instruction is a load/mul/csr dependent on previous
assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FPUStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE);

View File

@ -52,7 +52,6 @@ module controller(
output logic MDUE, W64E,
output logic JumpE,
output logic SCE,
output logic [1:0] AtomicE,
// Memory stage control signals
input logic StallM, FlushM,
output logic [1:0] MemRWM,
@ -107,6 +106,7 @@ module controller(
logic BranchFlagE;
logic IEURegWriteE;
logic IllegalERegAdrD;
logic [1:0] AtomicE;
// Extract fields
assign OpD = InstrD[6:0];

View File

@ -77,11 +77,7 @@ module datapath (
// Execute stage signals
logic [`XLEN-1:0] R1E, R2E;
logic [`XLEN-1:0] ExtImmE;
// logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, SrcAE2, SrcBE2; // *** MAde forwardedsrcae an output to get rid of a mux in the critical path.
logic [`XLEN-1:0] SrcAE, SrcBE;
logic [`XLEN-1:0] SrcAE2, SrcBE2;
logic [`XLEN-1:0] ALUResultE, AltResultE, IEUResultE;
// Memory stage signals
logic [`XLEN-1:0] IEUResultM;

View File

@ -50,7 +50,6 @@ module ieu (
// Memory stage interface
input logic SquashSCW, // from LSU
output logic [1:0] MemRWM, // read/write control goes to LSU
output logic [1:0] AtomicE, // atomic control goes to LSU
output logic [1:0] AtomicM, // atomic control goes to LSU
output logic [`XLEN-1:0] WriteDataE, // Address and write data to LSU
@ -98,7 +97,7 @@ module ieu (
.IllegalIEUInstrFaultD, .IllegalBaseInstrFaultD, .StallE, .FlushE, .FlagsE, .FWriteIntE,
.PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .MemReadE, .CSRReadE,
.Funct3E, .MDUE, .W64E, .JumpE, .StallM, .FlushM, .MemRWM,
.CSRReadM, .CSRWriteM, .PrivilegedM, .SCE, .AtomicE, .AtomicM, .Funct3M,
.CSRReadM, .CSRWriteM, .PrivilegedM, .SCE, .AtomicM, .Funct3M,
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM,
.StallW, .FlushW, .RegWriteW, .ResultSrcW, .CSRWritePendingDEM, .StoreStallD);

View File

@ -33,8 +33,8 @@
module ifu (
input logic clk, reset,
input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushF, FlushD, FlushE, FlushM, FlushW,
input logic StallF, StallD, StallE, StallM,
input logic FlushF, FlushD, FlushE, FlushM,
// Bus interface
(* mark_debug = "true" *) input logic [`XLEN-1:0] IFUBusHRDATA,
(* mark_debug = "true" *) input logic IFUBusAck,
@ -65,7 +65,6 @@ module ifu (
output logic InstrPageFaultF,
output logic IllegalIEUInstrFaultD,
output logic InstrMisalignedFaultM,
input logic ExceptionM,
// mmu management
input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] PTE,
@ -183,11 +182,9 @@ module ifu (
localparam integer WORDSPERLINE = (CACHE_ENABLED) ? `ICACHE_LINELENINBITS/`XLEN : 1;
localparam integer LINELEN = (CACHE_ENABLED) ? `ICACHE_LINELENINBITS : `XLEN;
localparam integer LOGWPL = (`DMEM == `MEM_CACHE) ? $clog2(WORDSPERLINE) : 1;
logic [LINELEN-1:0] ReadDataLine;
logic [LINELEN-1:0] ICacheBusWriteData;
logic [`PA_BITS-1:0] ICacheBusAdr;
logic ICacheBusAck;
logic [31:0] temp;
logic SelUncachedAdr;
busdp #(WORDSPERLINE, LINELEN, LOGWPL, CACHE_ENABLED)

View File

@ -32,7 +32,7 @@
module atomic (
input logic clk,
input logic reset, FlushW, StallW,
input logic reset, StallW,
input logic [`XLEN-1:0] ReadDataM,
input logic [`XLEN-1:0] LSUWriteDataM,
input logic [`PA_BITS-1:0] LSUPAdrM,
@ -52,7 +52,7 @@ module atomic (
.result(AMOResult));
mux2 #(`XLEN) wdmux(LSUWriteDataM, AMOResult, LSUAtomicM[1], AMOWriteDataM);
assign MemReadM = PreLSURWM[1] & ~IgnoreRequest;
lrsc lrsc(.clk, .reset, .FlushW, .StallW, .MemReadM, .PreLSURWM, .LSUAtomicM, .LSUPAdrM,
lrsc lrsc(.clk, .reset, .StallW, .MemReadM, .PreLSURWM, .LSUAtomicM, .LSUPAdrM,
.SquashSCW, .LSURWM);
endmodule

View File

@ -34,7 +34,7 @@
module lrsc
(
input logic clk, reset,
input logic FlushW, StallW,
input logic StallW,
input logic MemReadM,
input logic [1:0] PreLSURWM,
output logic [1:0] LSURWM,

View File

@ -93,7 +93,7 @@ module lsu (
logic [6:0] LSUFunct7M;
logic [1:0] LSUAtomicM;
(* mark_debug = "true" *) logic [`XLEN+1:0] PreLSUPAdrM;
logic [11:0] PreLSUAdrE, LSUAdrE;
logic [11:0] LSUAdrE;
logic CPUBusy;
logic DCacheStallM;
logic CacheableM;
@ -131,7 +131,7 @@ module lsu (
end else begin
assign {InterlockStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF, IgnoreRequestTLB} = '0;
assign IgnoreRequestTrapM = TrapM; assign CPUBusy = StallW; assign PreLSURWM = MemRWM;
assign LSUAdrE = PreLSUAdrE; assign PreLSUAdrE = IEUAdrE[11:0];
assign LSUAdrE = IEUAdrE[11:0];
assign PreLSUPAdrM = IEUAdrExtM;
assign LSUFunct3M = Funct3M; assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM;
assign LSUWriteDataM = WriteDataM;
@ -202,13 +202,11 @@ module lsu (
localparam integer WORDSPERLINE = (CACHE_ENABLED) ? `DCACHE_LINELENINBITS/`XLEN : 1;
localparam integer LINELEN = (CACHE_ENABLED) ? `DCACHE_LINELENINBITS : `XLEN;
localparam integer LOGWPL = (CACHE_ENABLED) ? $clog2(WORDSPERLINE) : 1;
logic [LINELEN-1:0] ReadDataLineM;
logic [LINELEN-1:0] DCacheBusWriteData;
logic [`PA_BITS-1:0] DCacheBusAdr;
logic DCacheWriteLine;
logic DCacheFetchLine;
logic DCacheBusAck;
logic SelBus;
logic [LOGWPL-1:0] WordCount;
busdp #(WORDSPERLINE, LINELEN, LOGWPL, CACHE_ENABLED) busdp(
@ -251,7 +249,7 @@ module lsu (
// Atomic operations
/////////////////////////////////////////////////////////////////////////////////////////////
if (`A_SUPPORTED) begin:atomic
atomic atomic(.clk, .reset, .FlushW, .StallW, .ReadDataM, .LSUWriteDataM, .LSUPAdrM,
atomic atomic(.clk, .reset, .StallW, .ReadDataM, .LSUWriteDataM, .LSUPAdrM,
.LSUFunct7M, .LSUFunct3M, .LSUAtomicM, .PreLSURWM, .IgnoreRequest,
.AMOWriteDataM, .SquashSCW, .LSURWM);
end else begin:lrsc

View File

@ -61,7 +61,6 @@ module hptw
logic DTLBWalk; // register TLBs translation miss requests
logic [`PPN_BITS-1:0] BasePageTablePPN;
logic [`PPN_BITS-1:0] CurrentPPN;
logic MemWrite;
logic Executable, Writable, Readable, Valid, PTE_U;
logic Misaligned, MegapageMisaligned;
logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE;

View File

@ -58,8 +58,6 @@ module tlbcontrol #(parameter ITLB = 0) (
);
// Sections of the page table entry
logic [11:0] PageOffset;
logic [`SVMODE_BITS-1:0] SVMode;
logic [1:0] EffectivePrivilegeMode;
logic PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R, PTE_V; // Useful PTE Control Bits

View File

@ -41,7 +41,6 @@ module muldiv (
output logic [`XLEN-1:0] MDUResultW,
// Divide Done
output logic DivBusyE,
output logic DivE,
// hazards
input logic StallM, StallW, FlushM, FlushW, TrapM
);
@ -52,6 +51,7 @@ module muldiv (
logic [`XLEN*2-1:0] ProdM;
logic DivSignedE;
logic DivE;
logic W64M;
// Multiplier

View File

@ -41,7 +41,7 @@ module csr #(parameter
input logic StallE, StallM, StallW,
input logic [31:0] InstrM,
input logic [`XLEN-1:0] PCM, SrcAM,
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, wfiM, InterruptM,
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, mretM, sretM, wfiM, InterruptM,
input logic MTimerInt, MExtInt, SExtInt, MSwInt,
input logic [63:0] MTIME_CLINT,
input logic InstrValidM, FRegWriteM, LoadStallD,
@ -62,7 +62,7 @@ module csr #(parameter
output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW,
output logic [`XLEN-1:0] MEDELEG_REGW,
output logic [`XLEN-1:0] SATP_REGW,
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, MIDELEG_REGW,
output logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
output logic STATUS_MIE, STATUS_SIE,
output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TW,
output logic [1:0] STATUS_FS,
@ -71,7 +71,6 @@ module csr #(parameter
input logic [4:0] SetFflagsM,
output logic [2:0] FRM_REGW,
// output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
output logic [`XLEN-1:0] CSRReadValW,
output logic IllegalCSRAccessM, BigEndianM
);
@ -96,7 +95,7 @@ module csr #(parameter
logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM, InsufficientCSRPrivilegeM;
logic IllegalCSRMWriteReadonlyM;
logic [`XLEN-1:0] CSRReadVal2M;
logic [11:0] IP_REGW_writeable;
logic [11:0] MIP_REGW_writeable;
logic InstrValidNotFlushedM;
assign InstrValidNotFlushedM = ~StallW & ~FlushW;
@ -107,7 +106,7 @@ module csr #(parameter
CSRSrcM = InstrM[14] ? {{(`XLEN-5){1'b0}}, InstrM[19:15]} : SrcAM;
// CSR set and clear for MIP/SIP should only touch internal state, not interrupt inputs
if (CSRAdrM == MIP | CSRAdrM == SIP) CSRReadVal2M = {{(`XLEN-12){1'b0}}, IP_REGW_writeable};
if (CSRAdrM == MIP | CSRAdrM == SIP) CSRReadVal2M = {{(`XLEN-12){1'b0}}, MIP_REGW_writeable};
else CSRReadVal2M = CSRReadValM;
// Compute AND/OR modification
@ -135,7 +134,7 @@ module csr #(parameter
csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW,
.CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM,
.MExtInt, .SExtInt, .MTimerInt, .MSwInt,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW, .IP_REGW_writeable);
.MIP_REGW, .MIE_REGW, .MIP_REGW_writeable);
csrsr csrsr(.clk, .reset, .StallW,
.WriteMSTATUSM, .WriteMSTATUSHM, .WriteSSTATUSM,
.TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW,
@ -145,7 +144,7 @@ module csr #(parameter
.STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TVM,
.STATUS_FS, .BigEndianM);
csrc counters(.clk, .reset,
.StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW,
.StallE, .StallM, .StallW, .FlushM, .FlushW,
.InstrValidM, .LoadStallD, .CSRMWriteM,
.BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM,
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess,
@ -166,7 +165,7 @@ module csr #(parameter
.STATUS_TVM, .CSRWriteValM, .PrivilegeModeW,
.CSRSReadValM, .STVEC_REGW, .SEPC_REGW,
.SCOUNTEREN_REGW,
.SATP_REGW, .SIP_REGW, .SIE_REGW,
.SATP_REGW, .MIP_REGW, .MIE_REGW,
.WriteSSTATUSM, .IllegalCSRSAccessM);
csru csru(.clk, .reset, .InstrValidNotFlushedM, .StallW,
.CSRUWriteM, .CSRAdrM, .CSRWriteValM, .STATUS_FS, .CSRUReadValM,

View File

@ -43,7 +43,7 @@ module csrc #(parameter
) (
input logic clk, reset,
input logic StallE, StallM, StallW,
input logic FlushE, FlushM, FlushW,
input logic FlushM, FlushW,
input logic InstrValidM, LoadStallD, CSRMWriteM,
input logic BPPredDirWrongM,
input logic BTBPredPCWrongM,

View File

@ -43,12 +43,10 @@ module csri #(parameter
input logic [`XLEN-1:0] CSRWriteValM,
input logic [11:0] CSRAdrM,
(* mark_debug = "true" *) input logic MExtInt, SExtInt, MTimerInt, MSwInt,
input logic [11:0] MIDELEG_REGW,
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW,
(* mark_debug = "true" *) output logic [11:0] IP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
output logic [11:0] MIP_REGW, MIE_REGW,
(* mark_debug = "true" *) output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
);
logic [11:0] IP_REGW, IE_REGW;
logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK, MIE_WRITE_MASK;
logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM;
@ -63,8 +61,8 @@ module csri #(parameter
// SEIP, STIP, SSIP is writable in MIP if S mode exists
// SSIP is writable in SIP if S mode exists
if (`S_SUPPORTED) begin:mask
assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writable in MIP (20210108-draft 3.1.9)
assign SIP_WRITE_MASK = 12'h002; // SSIP is writable in SIP (privileged 20210108-draft 4.1.3)
assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9)
assign SIP_WRITE_MASK = 12'h002; // SSIP is writeable in SIP (privileged 20210108-draft 4.1.3)
assign MIE_WRITE_MASK = 12'hAAA;
end else begin:mask
assign MIP_WRITE_MASK = 12'h000;
@ -72,25 +70,13 @@ module csri #(parameter
assign MIE_WRITE_MASK = 12'h888;
end
always @(posedge clk)
if (reset) IP_REGW_writeable <= 12'b0;
else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[11:0] & MIP_WRITE_MASK);
else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[11:0] & SIP_WRITE_MASK);
if (reset) MIP_REGW_writeable <= 12'b0;
else if (WriteMIPM) MIP_REGW_writeable <= (CSRWriteValM[11:0] & MIP_WRITE_MASK);
else if (WriteSIPM) MIP_REGW_writeable <= (CSRWriteValM[11:0] & SIP_WRITE_MASK) | (MIP_REGW_writeable & ~SIP_WRITE_MASK);
always @(posedge clk)
if (reset) IE_REGW <= 12'b0;
else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields
else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields
assign IP_REGW = {MExtInt,1'b0,SExtInt|IP_REGW_writeable[9],1'b0,MTimerInt,1'b0,IP_REGW_writeable[5],1'b0,MSwInt,1'b0,IP_REGW_writeable[1],1'b0};
assign MIP_REGW = IP_REGW;
assign MIE_REGW = IE_REGW;
if (`S_SUPPORTED) begin
assign SIP_REGW = IP_REGW & 12'h222;
assign SIE_REGW = IE_REGW & 12'h222;
end else begin
assign SIP_REGW = 12'b0;
assign SIE_REGW = 12'b0;
end
if (reset) MIE_REGW <= 12'b0;
else if (WriteMIEM) MIE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields
else if (WriteSIEM) MIE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (MIE_REGW & 12'h888); // only S fields
assign MIP_REGW = {MExtInt,1'b0,SExtInt|MIP_REGW_writeable[9],1'b0,MTimerInt,1'b0,MIP_REGW_writeable[5],1'b0,MSwInt,1'b0,MIP_REGW_writeable[1],1'b0};
endmodule

View File

@ -187,7 +187,7 @@ module csrm #(parameter
MARCHID: CSRMReadValM = 0;
MIMPID: CSRMReadValM = `XLEN'h100; // pipelined implementation
MHARTID: CSRMReadValM = MHARTID_REGW; // hardwired to 0
MCONFIGPTR: CSRReadValM = 0; // hardwired to 0
MCONFIGPTR: CSRMReadValM = 0; // hardwired to 0
MSTATUS: CSRMReadValM = MSTATUS_REGW;
MSTATUSH: CSRMReadValM = MSTATUSH_REGW;
MTVEC: CSRMReadValM = MTVEC_REGW;

View File

@ -61,14 +61,11 @@ module csrs #(parameter
(* mark_debug = "true" *) output logic [`XLEN-1:0] SEPC_REGW,
output logic [31:0] SCOUNTEREN_REGW,
output logic [`XLEN-1:0] SATP_REGW,
(* mark_debug = "true" *) input logic [11:0] SIP_REGW, SIE_REGW,
(* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW,
output logic WriteSSTATUSM,
output logic IllegalCSRSAccessM
);
//logic [`XLEN-1:0] zero = 0;
//logic [31:0] allones = {32{1'b1}};
//logic [`XLEN-1:0] SEDELEG_MASK = ~(zero | 3'b111 << 9); // sedeleg[11:9] hardwired to zero per Privileged Spec 3.1.8
// Supervisor mode CSRs sometimes supported
if (`S_SUPPORTED) begin:csrs
@ -105,8 +102,8 @@ module csrs #(parameter
case (CSRAdrM)
SSTATUS: CSRSReadValM = SSTATUS_REGW;
STVEC: CSRSReadValM = STVEC_REGW;
SIP: CSRSReadValM = {{(`XLEN-12){1'b0}}, SIP_REGW};
SIE: CSRSReadValM = {{(`XLEN-12){1'b0}}, SIE_REGW};
SIP: CSRSReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW & 12'h222}; // only read supervisor fields
SIE: CSRSReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW & 12'h222}; // only read supervisor fields
SSCRATCH: CSRSReadValM = SSCRATCH_REGW;
SEPC: CSRSReadValM = SEPC_REGW;
SCAUSE: CSRSReadValM = SCAUSE_REGW;

View File

@ -32,29 +32,67 @@
`include "wally-config.vh"
module privdec (
input logic clk, reset,
input logic StallM,
input logic [31:20] InstrM,
input logic PrivilegedM, IllegalIEUInstrFaultM, IllegalCSRAccessM, IllegalFPUInstrM,
input logic TrappedSRETM, WFITimeoutM,
input logic [1:0] PrivilegeModeW,
input logic STATUS_TSR, STATUS_TVM,
input logic STATUS_TSR, STATUS_TVM, STATUS_TW,
input logic [1:0] STATUS_FS,
output logic IllegalInstrFaultM,
output logic sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM);
output logic IllegalInstrFaultM, ITLBFlushF, DTLBFlushM,
output logic EcallFaultM, BreakpointFaultM,
output logic sretM, mretM, wfiM, sfencevmaM);
logic IllegalPrivilegedInstrM, IllegalOrDisabledFPUInstrM;
logic WFITimeoutM;
logic StallMQ;
logic ebreakM, ecallM;
// xRET defined in Privileged Spect 3.2.2
///////////////////////////////////////////
// Decode privileged instructions
///////////////////////////////////////////
assign sretM = PrivilegedM & (InstrM[31:20] == 12'b000100000010) & `S_SUPPORTED &
PrivilegeModeW[0] & ~STATUS_TSR;
(PrivilegeModeW == `M_MODE || PrivilegeModeW == `S_MODE & ~STATUS_TSR);
assign mretM = PrivilegedM & (InstrM[31:20] == 12'b001100000010) & (PrivilegeModeW == `M_MODE);
assign ecallM = PrivilegedM & (InstrM[31:20] == 12'b000000000000);
assign ebreakM = PrivilegedM & (InstrM[31:20] == 12'b000000000001);
assign wfiM = PrivilegedM & (InstrM[31:20] == 12'b000100000101);
assign sfencevmaM = PrivilegedM & (InstrM[31:25] == 7'b0001001) &
(PrivilegeModeW == `M_MODE | (PrivilegeModeW == `S_MODE & ~STATUS_TVM));
///////////////////////////////////////////
// WFI timeout Privileged Spec 3.1.6.5
///////////////////////////////////////////
if (`U_SUPPORTED) begin:wfi
logic [`WFI_TIMEOUT_BIT:0] WFICount, WFICountPlus1;
assign WFICountPlus1 = WFICount + 1;
floprc #(`WFI_TIMEOUT_BIT+1) wficountreg(clk, reset, ~wfiM, WFICountPlus1, WFICount); // count while in WFI
assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != `M_MODE) | (`S_SUPPORTED & PrivilegeModeW == `U_MODE)) & WFICount[`WFI_TIMEOUT_BIT];
end else assign WFITimeoutM = 0;
///////////////////////////////////////////
// Extract exceptions by name and handle them
///////////////////////////////////////////
assign BreakpointFaultM = ebreakM; // could have other causes from a debugger
assign EcallFaultM = ecallM;
///////////////////////////////////////////
// sfence.vma causes TLB flushes
///////////////////////////////////////////
// sets ITLBFlush to pulse for one cycle of the sfence.vma instruction
// In this instr we want to flush the tlb and then do a pagetable walk to update the itlb and continue the program.
// But we're still in the stalled sfence instruction, so if itlbflushf == sfencevmaM, tlbflush would never drop and
// the tlbwrite would never take place after the pagetable walk. by adding in ~StallMQ, we are able to drop itlbflush
// after a cycle AND pulse it for another cycle on any further back-to-back sfences.
flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(StallMQ));
assign ITLBFlushF = sfencevmaM & ~StallMQ;
assign DTLBFlushM = sfencevmaM;
///////////////////////////////////////////
// Fault on illegal instructions
///////////////////////////////////////////
assign IllegalPrivilegedInstrM = PrivilegedM & ~(sretM|mretM|ecallM|ebreakM|wfiM|sfencevmaM);
assign IllegalOrDisabledFPUInstrM = IllegalFPUInstrM | (STATUS_FS == 2'b00);
assign IllegalInstrFaultM = (IllegalIEUInstrFaultM & IllegalOrDisabledFPUInstrM) | IllegalPrivilegedInstrM | IllegalCSRAccessM |
TrappedSRETM | WFITimeoutM;
WFITimeoutM;
endmodule

View File

@ -39,7 +39,7 @@ module privileged (
output logic [`XLEN-1:0] PrivilegedNextPCM,
output logic RetM, TrapM,
output logic ITLBFlushF, DTLBFlushM,
input logic InstrValidM, CommittedM, DivE,
input logic InstrValidM, CommittedM,
input logic FRegWriteM, LoadStallD,
input logic BPPredDirWrongM,
input logic BTBPredPCWrongM,
@ -69,7 +69,6 @@ module privileged (
input logic StoreAmoAccessFaultM,
input logic SelHPTW,
output logic ExceptionM,
output logic IllegalFPUInstrE,
output logic [1:0] PrivilegeModeW,
output logic [`XLEN-1:0] SATP_REGW,
@ -82,76 +81,43 @@ module privileged (
output logic BreakpointFaultM, EcallFaultM, wfiM, IntPendingM, BigEndianM
);
logic [1:0] NextPrivilegeModeM;
logic [`XLEN-1:0] CauseM, NextFaultMtvalM;
logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW;
logic [`XLEN-1:0] MEDELEG_REGW;
logic [11:0] MIDELEG_REGW;
logic sretM, mretM, ecallM, ebreakM, sfencevmaM;
logic sretM, mretM, sfencevmaM;
logic IllegalCSRAccessM;
logic IllegalIEUInstrFaultE, IllegalIEUInstrFaultM;
logic IllegalFPUInstrM;
logic InstrPageFaultD, InstrPageFaultE, InstrPageFaultM;
logic InstrAccessFaultD, InstrAccessFaultE, InstrAccessFaultM;
logic IllegalInstrFaultM, TrappedSRETM;
logic IllegalInstrFaultM;
logic MTrapM, STrapM, UTrapM;
logic MTrapM, STrapM;
(* mark_debug = "true" *) logic InterruptM;
logic STATUS_SPP, STATUS_TSR, STATUS_TW, STATUS_TVM;
logic STATUS_MIE, STATUS_SIE;
logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW;
logic md;
logic StallMQ;
logic WFITimeoutM;
logic [11:0] MIP_REGW, MIE_REGW;
logic [1:0] NextPrivilegeModeM;
///////////////////////////////////////////
// track the current privilege level
///////////////////////////////////////////
// get bits of DELEG registers based on CAUSE
assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]];
// PrivilegeMode FSM
always_comb begin
if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8)
if (`S_SUPPORTED & md & (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE))
NextPrivilegeModeM = `S_MODE;
else NextPrivilegeModeM = `M_MODE;
end else if (mretM) NextPrivilegeModeM = STATUS_MPP;
else if (sretM) begin
if (STATUS_TSR & PrivilegeModeW == `S_MODE) begin
NextPrivilegeModeM = PrivilegeModeW;
end else NextPrivilegeModeM = {1'b0, STATUS_SPP};
end else NextPrivilegeModeM = PrivilegeModeW;
end
assign TrappedSRETM = sretM & STATUS_TSR & PrivilegeModeW == `S_MODE;
flopenl #(2) privmodereg(clk, reset, ~StallW, NextPrivilegeModeM, `M_MODE, PrivilegeModeW);
///////////////////////////////////////////
// WFI timeout Privileged Spec 3.1.6.5
///////////////////////////////////////////
if (`U_SUPPORTED) begin:wfi
logic [`WFI_TIMEOUT_BIT:0] WFICount, WFICountPlus1;
assign WFICountPlus1 = WFICount + 1;
floprc #(`WFI_TIMEOUT_BIT+1) wficountreg(clk, reset, ~wfiM, WFICountPlus1, WFICount); // count while in WFI
assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != `M_MODE) | (`S_SUPPORTED & PrivilegeModeW == `U_MODE)) & WFICount[`WFI_TIMEOUT_BIT];
end else assign WFITimeoutM = 0;
privmode privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .CauseM,
.MEDELEG_REGW, .MIDELEG_REGW, .STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW);
///////////////////////////////////////////
// decode privileged instructions
///////////////////////////////////////////
privdec pmd(.InstrM(InstrM[31:20]),
.PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM, .TrappedSRETM, .WFITimeoutM,
.PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_FS, .IllegalInstrFaultM,
.sretM, .mretM, .ecallM, .ebreakM, .wfiM, .sfencevmaM);
privdec pmd(.clk, .reset, .StallM, .InstrM(InstrM[31:20]),
.PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM,
.PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .STATUS_FS, .IllegalInstrFaultM,
.ITLBFlushF, .DTLBFlushM, .EcallFaultM, .BreakpointFaultM,
.sretM, .mretM, .wfiM, .sfencevmaM);
///////////////////////////////////////////
// Control and Status Registers
@ -160,7 +126,7 @@ module privileged (
.FlushE, .FlushM, .FlushW,
.StallE, .StallM, .StallW,
.InstrM, .PCM, .SrcAM,
.CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM, .wfiM, .InterruptM,
.CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .mretM, .sretM, .wfiM, .InterruptM,
.MTimerInt, .MExtInt, .SExtInt, .MSwInt,
.MTIME_CLINT,
.InstrValidM, .FRegWriteM, .LoadStallD,
@ -173,7 +139,7 @@ module privileged (
.MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW,
.MEDELEG_REGW,
.SATP_REGW,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW,
.MIP_REGW, .MIE_REGW, .MIDELEG_REGW,
.STATUS_MIE, .STATUS_SIE,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .STATUS_FS,
.PMPCFG_ARRAY_REGW,
@ -183,21 +149,6 @@ module privileged (
.CSRReadValW,
.IllegalCSRAccessM, .BigEndianM);
///////////////////////////////////////////
// Extract exceptions by name and handle them
///////////////////////////////////////////
assign BreakpointFaultM = ebreakM; // could have other causes too
assign EcallFaultM = ecallM;
flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(StallMQ));
assign ITLBFlushF = sfencevmaM & ~StallMQ;
assign DTLBFlushM = sfencevmaM;
// sets ITLBFlush to pulse for one cycle of the sfence.vma instruction
// In this instr we want to flush the tlb and then do a pagetable walk to update the itlb and continue the program.
// But we're still in the stalled sfence instruction, so if itlbflushf == sfencevmaM, tlbflush would never drop and
// the tlbwrite would never take place after the pagetable walk. by adding in ~StallMQ, we are able to drop itlbflush
// after a cycle AND pulse it for another cycle on any further back-to-back sfences.
// A page fault might occur because of insufficient privilege during a TLB
@ -214,7 +165,7 @@ module privileged (
{IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE, IllegalFPUInstrE},
{IllegalIEUInstrFaultM, InstrPageFaultM, InstrAccessFaultM, IllegalFPUInstrM});
// *** it should be possible to combine some of these faults earlier to reduce module boundary crossings and save flops dh 5 july 2021
trap trap(.clk, .reset,
trap trap(.reset,
.InstrMisalignedFaultM, .InstrAccessFaultM, .IllegalInstrFaultM,
.BreakpointFaultM, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
.LoadAccessFaultM, .StoreAmoAccessFaultM, .EcallFaultM, .InstrPageFaultM,
@ -222,16 +173,15 @@ module privileged (
.mretM, .sretM,
.PrivilegeModeW, .NextPrivilegeModeM,
.MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW,
.MIP_REGW, .MIE_REGW, .MIDELEG_REGW,
.STATUS_MIE, .STATUS_SIE,
.PCM,
.IEUAdrM,
.InstrM,
.InstrValidM, .CommittedM, .DivE,
.TrapM, .MTrapM, .STrapM, .UTrapM, .RetM,
.InstrValidM, .CommittedM,
.TrapM, .MTrapM, .STrapM, .RetM,
.InterruptM, .IntPendingM,
.ExceptionM,
.PrivilegedNextPCM, .CauseM, .NextFaultMtvalM);
.PrivilegedNextPCM, .CauseM, .NextFaultMtvalM);
endmodule

View File

@ -0,0 +1,66 @@
///////////////////////////////////////////
// privmode.sv
//
// Written: David_Harris@hmc.edu 12 May 2022
// Modified:
//
// Purpose: Track privilege mode
// See RISC-V Privileged Mode Specification 20190608 3.1.10-11
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// MIT LICENSE
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module privmode (
input logic clk, reset,
input logic StallW, TrapM, mretM, sretM,
input logic [`XLEN-1:0] CauseM, MEDELEG_REGW,
input logic [11:0] MIDELEG_REGW,
input logic [1:0] STATUS_MPP,
input logic STATUS_SPP,
output logic [1:0] NextPrivilegeModeM, PrivilegeModeW
);
if (`U_SUPPORTED) begin:privmode
logic md;
// get bits of DELEG registers based on CAUSE
assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]];
// PrivilegeMode FSM
always_comb begin
if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8)
if (`S_SUPPORTED & md & (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE))
NextPrivilegeModeM = `S_MODE;
else NextPrivilegeModeM = `M_MODE;
end else if (mretM) NextPrivilegeModeM = STATUS_MPP;
else if (sretM) NextPrivilegeModeM = {1'b0, STATUS_SPP};
else NextPrivilegeModeM = PrivilegeModeW;
end
flopenl #(2) privmodereg(clk, reset, ~StallW, NextPrivilegeModeM, `M_MODE, PrivilegeModeW);
end else begin // only machine mode supported
assign NextPrivilegeModeM = `M_MODE;
assign PrivilegeModeW = `M_MODE;
end
endmodule

View File

@ -32,8 +32,7 @@
`include "wally-config.vh"
module trap (
input logic clk,
input logic reset,
input logic reset,
(* mark_debug = "true" *) input logic InstrMisalignedFaultM, InstrAccessFaultM, IllegalInstrFaultM,
(* mark_debug = "true" *) input logic BreakpointFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM,
(* mark_debug = "true" *) input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM,
@ -41,25 +40,24 @@ module trap (
(* mark_debug = "true" *) input logic mretM, sretM,
input logic [1:0] PrivilegeModeW, NextPrivilegeModeM,
(* mark_debug = "true" *) input logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW,
(* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, MIDELEG_REGW,
(* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
input logic STATUS_MIE, STATUS_SIE,
input logic [`XLEN-1:0] PCM,
input logic [`XLEN-1:0] IEUAdrM,
input logic [31:0] InstrM,
input logic InstrValidM, CommittedM, DivE,
output logic TrapM, MTrapM, STrapM, UTrapM, RetM,
input logic InstrValidM, CommittedM,
output logic TrapM, MTrapM, STrapM, RetM,
output logic InterruptM, IntPendingM,
output logic ExceptionM,
output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM
// output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
// input logic WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM
);
logic MIntGlobalEnM, SIntGlobalEnM;
logic ExceptionM;
(* mark_debug = "true" *) logic [11:0] PendingIntsM, ValidIntsM;
//logic InterruptM;
logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector;
logic Exception1M;
// Determine pending enabled interrupts
// interrupt if any sources are pending

View File

@ -63,13 +63,11 @@ module wallypipelinedcore (
// new signals that must connect through DP
logic MDUE, W64E;
logic CSRReadM, CSRWriteM, PrivilegedM;
logic [1:0] AtomicE;
logic [1:0] AtomicM;
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE;
(* mark_debug = "true" *) logic [`XLEN-1:0] SrcAM;
logic [2:0] Funct3E;
// logic [31:0] InstrF;
logic [31:0] InstrD, InstrW;
logic [31:0] InstrD;
(* mark_debug = "true" *) logic [31:0] InstrM;
logic [`XLEN-1:0] PCF, PCD, PCE, PCLinkE;
(* mark_debug = "true" *) logic [`XLEN-1:0] PCM;
@ -86,7 +84,6 @@ module wallypipelinedcore (
logic PCSrcE;
logic CSRWritePendingDEM;
logic DivBusyE;
logic DivE;
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
logic SquashSCW;
// floating point unit signals
@ -157,7 +154,6 @@ module wallypipelinedcore (
logic InstrAccessFaultF;
logic [2:0] LSUBusSize;
logic ExceptionM;
logic DCacheMiss;
logic DCacheAccess;
logic ICacheMiss;
@ -168,10 +164,8 @@ module wallypipelinedcore (
ifu ifu(
.clk, .reset,
.StallF, .StallD, .StallE, .StallM, .StallW,
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW,
.ExceptionM,
.StallF, .StallD, .StallE, .StallM,
.FlushF, .FlushD, .FlushE, .FlushM,
// Fetch
.IFUBusHRDATA, .IFUBusAck, .PCF, .IFUBusAdr,
.IFUBusRead, .IFUStallF,
@ -221,7 +215,6 @@ module wallypipelinedcore (
// Memory stage interface
.SquashSCW, // from LSU
.MemRWM, // read/write control goes to LSU
.AtomicE, // atomic control goes to LSU
.AtomicM, // atomic control goes to LSU
.WriteDataE, // Write data to LSU
.Funct3M, // size and signedness to LSU
@ -323,7 +316,7 @@ module wallypipelinedcore (
.InstrM, .CSRReadValW, .PrivilegedNextPCM,
.RetM, .TrapM,
.ITLBFlushF, .DTLBFlushM,
.InstrValidM, .CommittedM, .DivE,
.InstrValidM, .CommittedM,
.FRegWriteM, .LoadStallD,
.BPPredDirWrongM, .BTBPredPCWrongM,
.RASPredPCWrongM, .BPPredClassNonCFIWrongM,
@ -339,7 +332,7 @@ module wallypipelinedcore (
// *** do these need to be split up into one for dmem and one for ifu?
// instead, could we only care about the instr and F pins that come from ifu and only care about the load/store and m pins that come from dmem?
.InstrAccessFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM, .SelHPTW,
.ExceptionM, .IllegalFPUInstrE,
.IllegalFPUInstrE,
.PrivilegeModeW, .SATP_REGW,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
@ -360,7 +353,7 @@ module wallypipelinedcore (
.clk, .reset,
.ForwardedSrcAE, .ForwardedSrcBE,
.Funct3E, .Funct3M, .MDUE, .W64E,
.MDUResultW, .DivBusyE, .DivE,
.MDUResultW, .DivBusyE,
.StallM, .StallW, .FlushM, .FlushW, .TrapM
);
end else begin // no M instructions supported

View File

@ -138,7 +138,7 @@ module testbench;
`define RF dut.core.ieu.dp.regf.rf
`define PC dut.core.ifu.pcreg.q
`define PRIV_BASE dut.core.priv.priv
`define PRIV `PRIV_BASE.privmodereg.q
`define PRIV `PRIV_BASE.privmode.privmode.privmodereg.q
`define CSR_BASE `PRIV_BASE.csr
`define MEIP `PRIV_BASE.MExtInt
`define SEIP `PRIV_BASE.SExtInt
@ -146,8 +146,8 @@ module testbench;
`define HPMCOUNTER `CSR_BASE.counters.counters.HPMCOUNTER_REGW
`define MEDELEG `CSR_BASE.csrm.deleg.MEDELEGreg.q
`define MIDELEG `CSR_BASE.csrm.deleg.MIDELEGreg.q
`define MIE `CSR_BASE.csri.IE_REGW
`define MIP `CSR_BASE.csri.IP_REGW_writeable
`define MIE `CSR_BASE.csri.MIE_REGW
`define MIP `CSR_BASE.csri.MIP_REGW_writeable
`define MCAUSE `CSR_BASE.csrm.MCAUSEreg.q
`define SCAUSE `CSR_BASE.csrs.csrs.SCAUSEreg.q
`define MEPC `CSR_BASE.csrm.MEPCreg.q
@ -692,8 +692,6 @@ module testbench;
"sstatus": `checkCSR(`CSR_BASE.csrs.SSTATUS_REGW)
"mtvec": `checkCSR(`CSR_BASE.csrm.MTVEC_REGW)
"mie": `checkCSR(`CSR_BASE.csrm.MIE_REGW)
"sip": `checkCSR(`CSR_BASE.csrs.SIP_REGW)
"sie": `checkCSR(`CSR_BASE.csrs.SIE_REGW)
"mideleg": `checkCSR(`CSR_BASE.csrm.MIDELEG_REGW)
"medeleg": `checkCSR(`CSR_BASE.csrm.MEDELEG_REGW)
"mepc": `checkCSR(`CSR_BASE.csrm.MEPC_REGW)