Merge branch 'main' into cache

Conflicts:
	wally-pipelined/src/uncore/dtim.sv
This commit is contained in:
Jarred Allen 2021-03-25 12:10:26 -04:00
commit 2f5d854f87
9 changed files with 335 additions and 87 deletions

3
.gitignore vendored
View File

@ -3,6 +3,9 @@
.nfs* .nfs*
__pycache__/
.vscode/
#vsim work files to ignore #vsim work files to ignore
transcript transcript
vsim.wlf vsim.wlf

View File

@ -0,0 +1 @@
`define LIB SKY130

View File

@ -2,9 +2,6 @@
// Teo Ene & David_Harris@hmc.edu 25 Feb 2021 // Teo Ene & David_Harris@hmc.edu 25 Feb 2021
// Measure PPA of various building blocks // Measure PPA of various building blocks
// replace this with the tools setting a library path to a config/skl130 directory containing config.vh
`define LIB SKL130
module top( module top(
input logic a1, input logic a1,
input logic [7:0] a8, b8, input logic [7:0] a8, b8,
@ -49,7 +46,7 @@ endmodule
module INVX2(input logic a, output logic y); module INVX2(input logic a, output logic y);
generate generate
if (LIB == SKL130) if (LIB == SKY130)
sky130_osu_sc_12T_ms__inv_2 inv(a, y); sky130_osu_sc_12T_ms__inv_2 inv(a, y);
else if (LIB == SKL90) else if (LIB == SKL90)
scc9gena_inv_2 inv(a, y) scc9gena_inv_2 inv(a, y)

View File

@ -48,7 +48,7 @@ module ahblite (
input logic [1:0] MemSizeM, input logic [1:0] MemSizeM,
// Signals from MMU // Signals from MMU
input logic [`XLEN-1:0] MMUPAdr, input logic [`XLEN-1:0] MMUPAdr,
input logic MMUTranslate, input logic MMUTranslate, MMUTranslationComplete,
output logic [`XLEN-1:0] MMUReadPTE, output logic [`XLEN-1:0] MMUReadPTE,
output logic MMUReady, output logic MMUReady,
// Return from bus // Return from bus
@ -75,7 +75,8 @@ module ahblite (
); );
logic GrantData; logic GrantData;
logic [2:0] ISize; logic [31:0] AccessAddress;
logic [2:0] AccessSize, PTESize, ISize;
logic [`AHBW-1:0] HRDATAMasked, ReadDataM, ReadDataNewW, ReadDataOldW, WriteData; logic [`AHBW-1:0] HRDATAMasked, ReadDataM, ReadDataNewW, ReadDataOldW, WriteData;
logic IReady, DReady; logic IReady, DReady;
logic CaptureDataM; logic CaptureDataM;
@ -89,47 +90,69 @@ module ahblite (
// Data accesses have priority over instructions. However, if a data access comes // Data accesses have priority over instructions. However, if a data access comes
// while an instruction read is occuring, the instruction read finishes before // while an instruction read is occuring, the instruction read finishes before
// the data access can take place. // the data access can take place.
typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD, INSTRREADC, ATOMICREAD, ATOMICWRITE} statetype; typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD, INSTRREADC, ATOMICREAD, ATOMICWRITE, MMUTRANSLATE, MMUIDLE} statetype;
statetype BusState, NextBusState; statetype BusState, NextBusState;
flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextBusState, IDLE, BusState); flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextBusState, IDLE, BusState);
always_comb always_comb
case (BusState) case (BusState)
IDLE: if (AtomicM[1]) NextBusState = ATOMICREAD; IDLE: if (MMUTranslate) NextBusState = MMUTRANSLATE;
else if (MemReadM) NextBusState = MEMREAD; // Memory has pirority over instructions else if (AtomicM[1]) NextBusState = ATOMICREAD;
else if (MemWriteM) NextBusState = MEMWRITE; else if (MemReadM) NextBusState = MEMREAD; // Memory has priority over instructions
else if (InstrReadF) NextBusState = INSTRREAD; else if (MemWriteM) NextBusState = MEMWRITE;
else NextBusState = IDLE; else if (InstrReadF) NextBusState = INSTRREAD;
ATOMICREAD: if (~HREADY) NextBusState = ATOMICREAD; else NextBusState = IDLE;
else NextBusState = ATOMICWRITE; MMUTRANSLATE: if (~HREADY) NextBusState = MMUTRANSLATE;
ATOMICWRITE: if (~HREADY) NextBusState = ATOMICWRITE; else NextBusState = MMUIDLE;
else if (InstrReadF) NextBusState = INSTRREAD; // *** Could the MMUIDLE state just be the normal idle state?
else NextBusState = IDLE; // Do we trust MMUTranslate to be high exactly when we need translation?
MEMREAD: if (~HREADY) NextBusState = MEMREAD; MMUIDLE: if (~MMUTranslationComplete)
else if (InstrReadF) NextBusState = INSTRREADC; NextBusState = MMUTRANSLATE;
else NextBusState = IDLE; else if (AtomicM[1]) NextBusState = ATOMICREAD;
MEMWRITE: if (~HREADY) NextBusState = MEMWRITE; else if (MemReadM) NextBusState = MEMREAD; // Memory has priority over instructions
else if (InstrReadF) NextBusState = INSTRREAD; else if (MemWriteM) NextBusState = MEMWRITE;
else NextBusState = IDLE; else if (InstrReadF) NextBusState = INSTRREAD;
else NextBusState = IDLE;
ATOMICREAD: if (~HREADY) NextBusState = ATOMICREAD;
else NextBusState = ATOMICWRITE;
ATOMICWRITE: if (~HREADY) NextBusState = ATOMICWRITE;
else if (InstrReadF) NextBusState = INSTRREAD;
else NextBusState = IDLE;
MEMREAD: if (~HREADY) NextBusState = MEMREAD;
else if (InstrReadF) NextBusState = INSTRREADC;
else NextBusState = IDLE;
MEMWRITE: if (~HREADY) NextBusState = MEMWRITE;
else if (InstrReadF) NextBusState = INSTRREAD;
else NextBusState = IDLE;
INSTRREAD: INSTRREAD:
if (~HREADY) NextBusState = INSTRREAD; if (~HREADY) NextBusState = INSTRREAD;
else NextBusState = IDLE; // if (InstrReadF still high) else NextBusState = IDLE; // if (InstrReadF still high)
INSTRREADC: if (~HREADY) NextBusState = INSTRREADC; // "C" for "competing", meaning please don't mess up the memread in the W stage. INSTRREADC: if (~HREADY) NextBusState = INSTRREADC; // "C" for "competing", meaning please don't mess up the memread in the W stage.
else NextBusState = IDLE; else NextBusState = IDLE;
endcase endcase
// stall signals // stall signals
assign #2 DataStall = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || assign #2 DataStall = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE); (NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE) ||
assign #1 InstrStall = (NextBusState == INSTRREAD) || (NextBusState == INSTRREADC); (NextBusState == MMUTRANSLATE) || (NextBusState == MMUIDLE);
// *** Could get finer grained stalling if we distinguish between MMU
// instruction address translation and data address translation
assign #1 InstrStall = (NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) ||
(NextBusState == MMUTRANSLATE) || (NextBusState == MMUIDLE);
// bus outputs // bus outputs
assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE); (NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE);
assign #1 HADDR = (GrantData) ? MemPAdrM[31:0] : InstrPAdrF[31:0]; assign #1 AccessAddress = (GrantData) ? MemPAdrM[31:0] : InstrPAdrF[31:0];
assign #1 HADDR = (MMUTranslate) ? MMUPAdr[31:0] : AccessAddress;
generate
if (`XLEN == 32) assign PTESize = 3'b010; // in rv32, PTEs are 4 bytes
else assign PTESize = 3'b011; // in rv64, PTEs are 8 bytes
endgenerate
assign ISize = 3'b010; // 32 bit instructions for now; later improve for filling cache with full width; ignored on reads anyway assign ISize = 3'b010; // 32 bit instructions for now; later improve for filling cache with full width; ignored on reads anyway
assign #1 HSIZE = GrantData ? {1'b0, MemSizeM} : ISize; assign #1 AccessSize = (GrantData) ? {1'b0, MemSizeM} : ISize;
assign #1 HSIZE = (MMUTranslate) ? PTESize : AccessSize;
assign HBURST = 3'b000; // Single burst only supported; consider generalizing for cache fillsfH assign HBURST = 3'b000; // Single burst only supported; consider generalizing for cache fillsfH
assign HPROT = 4'b0011; // not used; see Section 3.7 assign HPROT = 4'b0011; // not used; see Section 3.7
assign HTRANS = (NextBusState != IDLE) ? 2'b10 : 2'b00; // NONSEQ if reading or writing, IDLE otherwise assign HTRANS = (NextBusState != IDLE) ? 2'b10 : 2'b00; // NONSEQ if reading or writing, IDLE otherwise
@ -145,7 +168,10 @@ module ahblite (
// Route signals to Instruction and Data Caches // Route signals to Instruction and Data Caches
// *** assumes AHBW = XLEN // *** assumes AHBW = XLEN
assign #1 MMUReady = (NextBusState == MMUIDLE);
assign InstrRData = HRDATA; assign InstrRData = HRDATA;
assign MMUReadPTE = HRDATA;
assign ReadDataM = HRDATAMasked; // changed from W to M dh 2/7/2021 assign ReadDataM = HRDATAMasked; // changed from W to M dh 2/7/2021
assign CaptureDataM = ((BusState == MEMREAD) && (NextBusState != MEMREAD)) || assign CaptureDataM = ((BusState == MEMREAD) && (NextBusState != MEMREAD)) ||
((BusState == ATOMICREAD) && (NextBusState == ATOMICWRITE)); ((BusState == ATOMICREAD) && (NextBusState == ATOMICWRITE));

View File

@ -32,25 +32,29 @@ module pagetablewalker (
input logic [`XLEN-1:0] SATP_REGW, input logic [`XLEN-1:0] SATP_REGW,
input logic MemWriteM,
input logic ITLBMissF, DTLBMissM, input logic ITLBMissF, DTLBMissM,
input logic [`XLEN-1:0] PCF, MemAdrM, input logic [`XLEN-1:0] PCF, MemAdrM,
output logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM, output logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM,
output logic ITLBWriteF, DTLBWriteM, output logic ITLBWriteF, DTLBWriteM,
// *** handshake to tlbs probably not needed, since stalls take effect // *** handshake to tlbs probably not needed, since stalls take effect
// output logic TranslationComplete output logic MMUTranslationComplete,
// Signals from and to ahblite // Signals from and to ahblite
input logic [`XLEN-1:0] MMUReadPTE, input logic [`XLEN-1:0] MMUReadPTE,
input logic MMUReady, input logic MMUReady,
output logic [`XLEN-1:0] MMUPAdr, output logic [`XLEN-1:0] MMUPAdr,
output logic MMUTranslate output logic MMUTranslate,
// Faults
output logic InstrPageFaultM, LoadPageFaultM, StorePageFaultM
); );
logic SvMode; logic SvMode;
logic [`PPN_BITS-1:0] BasePageTablePPN; logic [`PPN_BITS-1:0] BasePageTablePPN;
logic [`XLEN-1:0] DirectInstrPTE, DirectMemPTE; logic [`XLEN-1:0] DirectInstrPTE, DirectMemPTE, TranslationVAdr;
logic [9:0] DirectPTEFlags = {2'b0, 8'b00001111}; logic [9:0] DirectPTEFlags = {2'b0, 8'b00001111};
@ -73,71 +77,233 @@ module pagetablewalker (
end end
endgenerate endgenerate
flopenr #(`XLEN) instrpte(clk, reset, ITLBMissF, DirectInstrPTE, PageTableEntryF); //flopenr #(`XLEN) instrpte(clk, reset, ITLBMissF, DirectInstrPTE, PageTableEntryF);
flopenr #(`XLEN) datapte(clk, reset, DTLBMissM, DirectMemPTE, PageTableEntryM); //flopenr #(`XLEN) datapte(clk, reset, DTLBMissM, DirectMemPTE, PageTableEntryM);
flopr #(1) iwritesignal(clk, reset, ITLBMissF, ITLBWriteF); //flopr #(1) iwritesignal(clk, reset, ITLBMissF, ITLBWriteF);
flopr #(1) dwritesignal(clk, reset, DTLBMissM, DTLBWriteM); //flopr #(1) dwritesignal(clk, reset, DTLBMissM, DTLBWriteM);
// Prefer data address translations over instruction address translations
assign TranslationVAdr = (DTLBMissM) ? MemAdrM : PCF;
assign MMUTranslate = DTLBMissM || ITLBMissF;
/*
generate generate
if (`XLEN == 32) begin if (`XLEN == 32) begin
assign SvMode = SATP_REGW[31]; assign SvMode = SATP_REGW[31];
logic VPN1 [9:0] = TranslationVAdr[31:22]; logic [9:0] VPN1 = TranslationVAdr[31:22];
logic VPN0 [9:0] = TranslationVAdr[21:12]; // *** could optimize by not passing offset? logic [9:0] VPN0 = TranslationVAdr[21:12]; // *** could optimize by not passing offset?
logic TranslationPAdr [33:0]; logic [33:0] TranslationPAdr;
logic [21:0] CurrentPPN;
typedef enum {IDLE, DATA_LEVEL1, DATA_LEVEL0, DATA_LEAF, DATA FAULT} statetype; logic Dirty, Accessed, Global, User,
Executable, Writable, Readable, Valid;
logic ValidPTE, AccessAlert, MegapageMisaligned, BadMegapage, LeafPTE;
typedef enum {IDLE, LEVEL1, LEVEL0, LEAF, FAULT} statetype;
statetype WalkerState, NextWalkerState; statetype WalkerState, NextWalkerState;
always_ff @(posedge HCLK, negedge HRESETn) // *** Do we need a synchronizer here for walker to talk to ahblite?
if (~HRESETn) WalkerState <= #1 IDLE; flopenl #(.TYPE(statetype)) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
else WalkerState <= #1 NextWalkerState;
always_comb begin always_comb begin
NextWalkerState = 'X;
case (WalkerState) case (WalkerState)
IDLE: if (TLBMissM) NextWalkerState = LEVEL1; IDLE: if (MMUTranslate) NextWalkerState = LEVEL1;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
LEVEL1: if (HREADY && ValidEntry) NextWalkerState = LEVEL0; LEVEL1: if (~MMUReady) NextWalkerState = LEVEL1;
else if (HREADY) NextWalkerState = FAULT; // else if (~ValidPTE || (LeafPTE && BadMegapage))
else NextWalkerState = LEVEL1; // NextWalkerState = FAULT;
LEVEL2: if (HREADY && ValidEntry) NextWalkerState = LEAF; // *** Leave megapage implementation for later
else if (HREADY) NextWalkerState = FAULT; // else if (ValidPTE && LeafPTE) NextWalkerState = LEAF;
else NextWalkerState = LEVEL2; else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0;
LEAF: NextWalkerState = IDLE; else NextWalkerState = FAULT;
LEVEL0: if (~MMUReady) NextWalkerState = LEVEL0;
else if (ValidPTE && LeafPTE && ~AccessAlert)
NextWalkerState = LEAF;
else NextWalkerState = FAULT;
LEAF: if (MMUTranslate) NextWalkerState = LEVEL1;
else NextWalkerState = IDLE;
FAULT: if (MMUTranslate) NextWalkerState = LEVEL1;
else NextWalkerState = IDLE;
endcase endcase
end end
always_ff @(posedge HCLK, negedge HRESETn) // unswizzle PTE bits
if (~HRESETn) begin assign {Dirty, Accessed, Global, User,
Executable, Writable, Readable, Valid} = MMUReadPTE[7:0];
// A megapage is a Level 1 leaf page. This page must have zero PPN[0].
assign MegapageMisaligned = |(CurrentPPN[9:0]);
assign LeafPTE = Executable | Writable | Readable;
assign ValidPTE = Valid && ~(Writable && ~Readable);
assign AccessAlert = ~Accessed || (MemWriteM && ~Dirty);
assign BadMegapage = MegapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
// *** Should translate this flop block into our flop module notation
always_ff @(posedge clk, negedge reset)
if (reset) begin
TranslationPAdr <= '0; TranslationPAdr <= '0;
PageTableEntryF <= '0; PageTableEntryF <= '0;
TranslationComplete <= '0; MMUTranslationComplete <= '0;
DTLBWriteM <= '0;
ITLBWriteF <= '0;
InstrPageFaultM <= '0;
LoadPageFaultM <= '0;
StorePageFaultM <= '0;
end else begin end else begin
// default values // default values
TranslationPAdr <= '0;
PageTableEntryF <= '0;
MMUTranslationComplete <= '0;
DTLBWriteM <= '0;
ITLBWriteF <= '0;
InstrPageFaultM <= '0;
LoadPageFaultM <= '0;
StorePageFaultM <= '0;
case (NextWalkerState) case (NextWalkerState)
LEVEL1: TranslationPAdr <= {BasePageTablePPN, VPN1, 2'b00}; LEVEL1: begin
LEVEL2: TranslationPAdr <= {CurrentPPN, VPN0, 2'b00}; TranslationPAdr <= {BasePageTablePPN, VPN1, 2'b00};
end
LEVEL0: begin
TranslationPAdr <= {CurrentPPN, VPN0, 2'b00};
end
LEAF: begin LEAF: begin
PageTableEntryF <= CurrentPageTableEntry; PageTableEntryF <= MMUReadPTE;
TranslationComplete <= '1; PageTableEntryM <= MMUReadPTE;
end MMUTranslationComplete <= '1;
DTLBWriteM <= DTLBMissM;
ITLBWriteF <= ~DTLBMissM; // Prefer data over instructions
end
FAULT: begin
InstrPageFaultM <= ~DTLBMissM;
LoadPageFaultM <= DTLBMissM && ~MemWriteM;
StorePageFaultM <= DTLBMissM && MemWriteM;
end
endcase endcase
end end
assign #1 Translate = (NextWalkerState == LEVEL1); // Interpret inputs from ahblite
assign CurrentPPN = MMUReadPTE[31:10];
// Assign outputs to ahblite
// *** Currently truncate address to 32 bits. This must be changed if
// we support larger physical address spaces
assign MMUPAdr = TranslationPAdr[31:0];
end else begin end else begin
// sv39 not yet implemented
assign SvMode = SATP_REGW[63]; assign SvMode = SATP_REGW[63];
logic [8:0] VPN2 = TranslationVAdr[38:30];
logic [8:0] VPN1 = TranslationVAdr[29:21];
logic [8:0] VPN0 = TranslationVAdr[20:12]; // *** could optimize by not passing offset?
logic [55:0] TranslationPAdr;
logic [43:0] CurrentPPN;
logic Dirty, Accessed, Global, User,
Executable, Writable, Readable, Valid;
logic ValidPTE, AccessAlert, GigapageMisaligned, MegapageMisaligned,
BadGigapage, BadMegapage, LeafPTE;
typedef enum {IDLE, LEVEL2, LEVEL1, LEVEL0, LEAF, FAULT} statetype;
statetype WalkerState, NextWalkerState;
// *** Do we need a synchronizer here for walker to talk to ahblite?
flopenl #(.TYPE(statetype)) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
always_comb begin
case (WalkerState)
IDLE: if (MMUTranslate) NextWalkerState = LEVEL1;
else NextWalkerState = IDLE;
LEVEL2: if (~MMUReady) NextWalkerState = LEVEL2;
else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL1;
else NextWalkerState = FAULT;
LEVEL1: if (~MMUReady) NextWalkerState = LEVEL1;
// else if (~ValidPTE || (LeafPTE && BadMegapage))
// NextWalkerState = FAULT;
// *** Leave megapage implementation for later
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF;
else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0;
else NextWalkerState = FAULT;
LEVEL0: if (~MMUReady) NextWalkerState = LEVEL0;
else if (ValidPTE && LeafPTE && ~AccessAlert)
NextWalkerState = LEAF;
else NextWalkerState = FAULT;
LEAF: if (MMUTranslate) NextWalkerState = LEVEL2;
else NextWalkerState = IDLE;
FAULT: if (MMUTranslate) NextWalkerState = LEVEL2;
else NextWalkerState = IDLE;
endcase
end
// unswizzle PTE bits
assign {Dirty, Accessed, Global, User,
Executable, Writable, Readable, Valid} = MMUReadPTE[7:0];
// A megapage is a Level 1 leaf page. This page must have zero PPN[0].
assign GigapageMisaligned = |(CurrentPPN[17:0]);
assign MegapageMisaligned = |(CurrentPPN[8:0]);
assign LeafPTE = Executable | Writable | Readable;
assign ValidPTE = Valid && ~(Writable && ~Readable);
assign AccessAlert = ~Accessed || (MemWriteM && ~Dirty);
assign BadGigapage = GigapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
assign BadMegapage = MegapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
// *** Should translate this flop block into our flop module notation
always_ff @(posedge clk, negedge reset)
if (reset) begin
TranslationPAdr <= '0;
PageTableEntryF <= '0;
MMUTranslationComplete <= '0;
DTLBWriteM <= '0;
ITLBWriteF <= '0;
InstrPageFaultM <= '0;
LoadPageFaultM <= '0;
StorePageFaultM <= '0;
end else begin
// default values
TranslationPAdr <= '0;
PageTableEntryF <= '0;
MMUTranslationComplete <= '0;
DTLBWriteM <= '0;
ITLBWriteF <= '0;
InstrPageFaultM <= '0;
LoadPageFaultM <= '0;
StorePageFaultM <= '0;
case (NextWalkerState)
LEVEL2: begin
TranslationPAdr <= {BasePageTablePPN, VPN2, 3'b00};
end
LEVEL1: begin
TranslationPAdr <= {CurrentPPN, VPN1, 3'b00};
end
LEVEL0: begin
TranslationPAdr <= {CurrentPPN, VPN0, 3'b00};
end
LEAF: begin
PageTableEntryF <= MMUReadPTE;
PageTableEntryM <= MMUReadPTE;
MMUTranslationComplete <= '1;
DTLBWriteM <= DTLBMissM;
ITLBWriteF <= ~DTLBMissM; // Prefer data over instructions
end
FAULT: begin
InstrPageFaultM <= ~DTLBMissM;
LoadPageFaultM <= DTLBMissM && ~MemWriteM;
StorePageFaultM <= DTLBMissM && MemWriteM;
end
endcase
end
// Interpret inputs from ahblite
assign CurrentPPN = MMUReadPTE[53:10];
// Assign outputs to ahblite
// *** Currently truncate address to 32 bits. This must be changed if
// we support larger physical address spaces
assign MMUPAdr = TranslationPAdr[31:0];
end end
endgenerate endgenerate
// rv32 case
*/
endmodule endmodule

View File

@ -51,7 +51,20 @@ module csrm #(parameter
PMPCFG2 = 12'h3A2, PMPCFG2 = 12'h3A2,
PMPCFG3 = 12'h3A3, PMPCFG3 = 12'h3A3,
PMPADDR0 = 12'h3B0, PMPADDR0 = 12'h3B0,
//... more physical memory protection PMPADDR1 = 12'h3B1,
PMPADDR2 = 12'h3B2,
PMPADDR3 = 12'h3B3,
PMPADDR4 = 12'h3B4,
PMPADDR5 = 12'h3B5,
PMPADDR6 = 12'h3B6,
PMPADDR7 = 12'h3B7,
PMPADDR8 = 12'h3B8,
PMPADDR9 = 12'h3B9,
PMPADDR10 = 12'h3BA,
PMPADDR11 = 12'h3BB,
PMPADDR12 = 12'h3BC,
PMPADDR13 = 12'h3BD,
PMPADDR14 = 12'h3BE,
PMPADDR15 = 12'h3BF, PMPADDR15 = 12'h3BF,
TSELECT = 12'h7A0, TSELECT = 12'h7A0,
TDATA1 = 12'h7A1, TDATA1 = 12'h7A1,
@ -77,7 +90,8 @@ module csrm #(parameter
logic [`XLEN-1:0] MISA_REGW; logic [`XLEN-1:0] MISA_REGW;
logic [`XLEN-1:0] MSCRATCH_REGW,MCAUSE_REGW, MTVAL_REGW; logic [`XLEN-1:0] MSCRATCH_REGW,MCAUSE_REGW, MTVAL_REGW;
logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW; // 64-bit registers in RV64, or two 32-bit registers in RV32 logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW; // 64-bit registers in RV64, or two 32-bit registers in RV32
logic [`XLEN-1:0] PMPADDR0_REGW; // will need to add more logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [0:15]; // *** Might have to make 16 individual registers
//logic [`XLEN-1:0] PMPADDR0_REGW;
logic [`XLEN-1:0] zero = 0; logic [`XLEN-1:0] zero = 0;
logic [31:0] allones = {32{1'b1}}; logic [31:0] allones = {32{1'b1}};
logic [`XLEN-1:0] MEDELEG_MASK = ~(zero | 1'b1 << 11); // medeleg[11] hardwired to zero per Privileged Spec 3.1.8 logic [`XLEN-1:0] MEDELEG_MASK = ~(zero | 1'b1 << 11); // medeleg[11] hardwired to zero per Privileged Spec 3.1.8
@ -86,7 +100,7 @@ module csrm #(parameter
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM; logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM; logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
logic WritePMPCFG0M, WritePMPCFG2M; logic WritePMPCFG0M, WritePMPCFG2M;
logic WritePMPADDR0M; logic WritePMPADDRM [0:15];
logic [25:0] MISAbits = `MISA; logic [25:0] MISAbits = `MISA;
// MISA is hardwired. Spec says it could be written to disable features, but this is not supported by Wally // MISA is hardwired. Spec says it could be written to disable features, but this is not supported by Wally
@ -103,7 +117,22 @@ module csrm #(parameter
assign WriteMTVALM = MTrapM | (CSRMWriteM && (CSRAdrM == MTVAL)); assign WriteMTVALM = MTrapM | (CSRMWriteM && (CSRAdrM == MTVAL));
assign WritePMPCFG0M = (CSRMWriteM && (CSRAdrM == PMPCFG0)); assign WritePMPCFG0M = (CSRMWriteM && (CSRAdrM == PMPCFG0));
assign WritePMPCFG2M = (CSRMWriteM && (CSRAdrM == PMPCFG2)); assign WritePMPCFG2M = (CSRMWriteM && (CSRAdrM == PMPCFG2));
assign WritePMPADDR0M = (CSRMWriteM && (CSRAdrM == PMPADDR0)); assign WritePMPADDRM[0] = (CSRMWriteM && (CSRAdrM == PMPADDR0));
assign WritePMPADDRM[1] = (CSRMWriteM && (CSRAdrM == PMPADDR1));
assign WritePMPADDRM[2] = (CSRMWriteM && (CSRAdrM == PMPADDR2));
assign WritePMPADDRM[3] = (CSRMWriteM && (CSRAdrM == PMPADDR3));
assign WritePMPADDRM[4] = (CSRMWriteM && (CSRAdrM == PMPADDR4));
assign WritePMPADDRM[5] = (CSRMWriteM && (CSRAdrM == PMPADDR5));
assign WritePMPADDRM[6] = (CSRMWriteM && (CSRAdrM == PMPADDR6));
assign WritePMPADDRM[7] = (CSRMWriteM && (CSRAdrM == PMPADDR7));
assign WritePMPADDRM[8] = (CSRMWriteM && (CSRAdrM == PMPADDR8));
assign WritePMPADDRM[9] = (CSRMWriteM && (CSRAdrM == PMPADDR9));
assign WritePMPADDRM[10] = (CSRMWriteM && (CSRAdrM == PMPADDR10));
assign WritePMPADDRM[11] = (CSRMWriteM && (CSRAdrM == PMPADDR11));
assign WritePMPADDRM[12] = (CSRMWriteM && (CSRAdrM == PMPADDR12));
assign WritePMPADDRM[13] = (CSRMWriteM && (CSRAdrM == PMPADDR13));
assign WritePMPADDRM[14] = (CSRMWriteM && (CSRAdrM == PMPADDR14));
assign WritePMPADDRM[15] = (CSRMWriteM && (CSRAdrM == PMPADDR15));
assign WriteMCOUNTERENM = CSRMWriteM && (CSRAdrM == MCOUNTEREN); assign WriteMCOUNTERENM = CSRMWriteM && (CSRAdrM == MCOUNTEREN);
assign WriteMCOUNTINHIBITM = CSRMWriteM && (CSRAdrM == MCOUNTINHIBIT); assign WriteMCOUNTINHIBITM = CSRMWriteM && (CSRAdrM == MCOUNTINHIBIT);
@ -132,7 +161,15 @@ module csrm #(parameter
flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], allones, MCOUNTEREN_REGW); flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], allones, MCOUNTEREN_REGW);
endgenerate endgenerate
flopenl #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], allones, MCOUNTINHIBIT_REGW); flopenl #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], allones, MCOUNTINHIBIT_REGW);
flopenr #(`XLEN) PMPADDR0reg(clk, reset, WritePMPADDR0M, CSRWriteValM, PMPADDR0_REGW);
// There are 16 PMPADDR registers, each of which has its own flop
generate
genvar i;
for (i = 0; i < 16; i++) begin: pmp_flop
flopenr #(`XLEN) PMPADDRreg(clk, reset, WritePMPADDRM[i], CSRWriteValM, PMPADDR_ARRAY_REGW[i]);
end
endgenerate
// PMPCFG registers are a pair of 64-bit in RV64 and four 32-bit in RV32 // PMPCFG registers are a pair of 64-bit in RV64 and four 32-bit in RV32
generate generate
if (`XLEN==64) begin if (`XLEN==64) begin
@ -175,7 +212,22 @@ module csrm #(parameter
PMPCFG1: CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG01_REGW[63:31]}; PMPCFG1: CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG01_REGW[63:31]};
PMPCFG2: CSRMReadValM = PMPCFG23_REGW[`XLEN-1:0]; PMPCFG2: CSRMReadValM = PMPCFG23_REGW[`XLEN-1:0];
PMPCFG3: CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG23_REGW[63:31]}; PMPCFG3: CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG23_REGW[63:31]};
PMPADDR0: CSRMReadValM = PMPADDR0_REGW; PMPADDR0: CSRMReadValM = PMPADDR_ARRAY_REGW[0];
PMPADDR1: CSRMReadValM = PMPADDR_ARRAY_REGW[1];
PMPADDR2: CSRMReadValM = PMPADDR_ARRAY_REGW[2];
PMPADDR3: CSRMReadValM = PMPADDR_ARRAY_REGW[3];
PMPADDR4: CSRMReadValM = PMPADDR_ARRAY_REGW[4];
PMPADDR5: CSRMReadValM = PMPADDR_ARRAY_REGW[5];
PMPADDR6: CSRMReadValM = PMPADDR_ARRAY_REGW[6];
PMPADDR7: CSRMReadValM = PMPADDR_ARRAY_REGW[7];
PMPADDR8: CSRMReadValM = PMPADDR_ARRAY_REGW[8];
PMPADDR9: CSRMReadValM = PMPADDR_ARRAY_REGW[9];
PMPADDR10: CSRMReadValM = PMPADDR_ARRAY_REGW[10];
PMPADDR11: CSRMReadValM = PMPADDR_ARRAY_REGW[11];
PMPADDR12: CSRMReadValM = PMPADDR_ARRAY_REGW[12];
PMPADDR13: CSRMReadValM = PMPADDR_ARRAY_REGW[13];
PMPADDR14: CSRMReadValM = PMPADDR_ARRAY_REGW[14];
PMPADDR15: CSRMReadValM = PMPADDR_ARRAY_REGW[15];
default: begin default: begin
CSRMReadValM = 0; CSRMReadValM = 0;
IllegalCSRMAccessM = 1; IllegalCSRMAccessM = 1;

View File

@ -39,6 +39,7 @@ module privileged (
input logic InstrValidW, FloatRegWriteW, LoadStallD, BPPredWrongM, input logic InstrValidW, FloatRegWriteW, LoadStallD, BPPredWrongM,
input logic [3:0] InstrClassM, input logic [3:0] InstrClassM,
input logic PrivilegedM, input logic PrivilegedM,
input logic InstrPageFaultM, LoadPageFaultM, StorePageFaultM,
input logic InstrMisalignedFaultM, InstrAccessFaultF, IllegalIEUInstrFaultD, input logic InstrMisalignedFaultM, InstrAccessFaultF, IllegalIEUInstrFaultD,
input logic LoadMisalignedFaultM, LoadAccessFaultM, input logic LoadMisalignedFaultM, LoadAccessFaultM,
input logic StoreMisalignedFaultM, StoreAccessFaultM, input logic StoreMisalignedFaultM, StoreAccessFaultM,
@ -48,7 +49,7 @@ module privileged (
output logic [1:0] PrivilegeModeW, output logic [1:0] PrivilegeModeW,
output logic [`XLEN-1:0] SATP_REGW, output logic [`XLEN-1:0] SATP_REGW,
output logic [2:0] FRM_REGW, output logic [2:0] FRM_REGW,
input logic FlushD, FlushE, FlushM, StallD, StallW input logic FlushD, FlushE, FlushM, StallD, StallW, StallE, StallM
); );
logic [1:0] NextPrivilegeModeM; logic [1:0] NextPrivilegeModeM;
@ -65,7 +66,6 @@ module privileged (
logic IllegalInstrFaultM; logic IllegalInstrFaultM;
logic BreakpointFaultM, EcallFaultM; logic BreakpointFaultM, EcallFaultM;
logic InstrPageFaultM, LoadPageFaultM, StorePageFaultM;
logic MTrapM, STrapM, UTrapM; logic MTrapM, STrapM, UTrapM;
logic [1:0] STATUS_MPP; logic [1:0] STATUS_MPP;
@ -119,9 +119,11 @@ module privileged (
assign BreakpointFaultM = ebreakM; // could have other causes too assign BreakpointFaultM = ebreakM; // could have other causes too
assign EcallFaultM = ecallM; assign EcallFaultM = ecallM;
assign InstrPageFaultM = 0; // *** Page faults now driven by page table walker. Might need to make the
assign LoadPageFaultM = 0; // below signals ORs of a walker fault and a tlb fault if both of those come in
assign StorePageFaultM = 0; // assign InstrPageFaultM = 0;
// assign LoadPageFaultM = 0;
// assign StorePageFaultM = 0;
// pipeline fault signals // pipeline fault signals
flopenrc #(1) faultregD(clk, reset, FlushD, ~StallD, InstrAccessFaultF, InstrAccessFaultD); flopenrc #(1) faultregD(clk, reset, FlushD, ~StallD, InstrAccessFaultF, InstrAccessFaultD);

View File

@ -87,13 +87,13 @@ module dtim #(parameter BASE=0, RANGE = 65535) (
always_ff @(posedge HCLK) begin always_ff @(posedge HCLK) begin
HWADDR <= #1 A; HWADDR <= #1 A;
HREADTim0 <= #1 RAM[A[31:3]]; HREADTim0 <= #1 RAM[A[31:3]];
if (memwrite && risingHREADYTim) RAM[HWADDR[31:3]] <= HWDATA; if (memwrite && risingHREADYTim) RAM[HWADDR[31:3]] <= #1 HWDATA;
end end
end else begin end else begin
always_ff @(posedge HCLK) begin always_ff @(posedge HCLK) begin
HWADDR <= #1 A; HWADDR <= #1 A;
HREADTim0 <= #1 RAM[A[31:2]]; HREADTim0 <= #1 RAM[A[31:2]];
if (memwrite && risingHREADYTim) RAM[HWADDR[31:2]] <= HWDATA; if (memwrite && risingHREADYTim) RAM[HWADDR[31:2]] <= #1 HWDATA;
end end
end end
endgenerate endgenerate

View File

@ -76,6 +76,7 @@ module wallypipelinedhart (
logic InstrMisalignedFaultM; logic InstrMisalignedFaultM;
logic DataMisalignedM; logic DataMisalignedM;
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD; logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
logic InstrPageFaultM, LoadPageFaultM, StorePageFaultM;
logic LoadMisalignedFaultM, LoadAccessFaultM; logic LoadMisalignedFaultM, LoadAccessFaultM;
logic StoreMisalignedFaultM, StoreAccessFaultM; logic StoreMisalignedFaultM, StoreAccessFaultM;
logic [`XLEN-1:0] InstrMisalignedAdrM; logic [`XLEN-1:0] InstrMisalignedAdrM;
@ -100,7 +101,7 @@ module wallypipelinedhart (
// IMem stalls // IMem stalls
logic ICacheStallF; logic ICacheStallF;
logic [`XLEN-1:0] MMUPAdr, MMUReadPTE; logic [`XLEN-1:0] MMUPAdr, MMUReadPTE;
logic MMUTranslate, MMUReady; logic MMUTranslate, MMUTranslationComplete, MMUReady;
// bus interface to dmem // bus interface to dmem
logic MemReadM, MemWriteM; logic MemReadM, MemWriteM;