forked from Github_Repos/cvw
Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally into main
This commit is contained in:
commit
01685b982c
@ -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
|
@ -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.
@ -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
|
@ -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.
1
pipelined/src/cache/sram1p1rw.sv
vendored
1
pipelined/src/cache/sram1p1rw.sv
vendored
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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},
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
66
pipelined/src/privileged/privmode.sv
Normal file
66
pipelined/src/privileged/privmode.sv
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user