Connect tlb, pagetablewalker, and memory

This commit is contained in:
Thomas Fleming 2021-03-18 14:35:46 -04:00
parent f04e554e35
commit 062c4d40da
8 changed files with 181 additions and 125 deletions

View File

@ -50,19 +50,20 @@ module dmem (
output logic LoadMisalignedFaultM, LoadAccessFaultM,
output logic StoreMisalignedFaultM, StoreAccessFaultM,
// TLB management
//input logic [`XLEN-1:0] PageTableEntryM,
input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] PageTableEntryM,
input logic [`XLEN-1:0] SATP_REGW,
//input logic DTLBWriteM, DTLBFlushM,
input logic DTLBWriteM, // DTLBFlushM,
output logic DTLBMissM, DTLBHitM
);
logic SquashSCM;
// *** temporary hack until walker is hooked up -- Thomas F
logic [`XLEN-1:0] PageTableEntryM = '0;
// logic [`XLEN-1:0] PageTableEntryM = '0;
logic DTLBFlushM = '0;
logic DTLBWriteM = '0;
tlb #(3) dtlb(clk, reset, SATP_REGW, MemAdrM, PageTableEntryM, DTLBWriteM,
// logic DTLBWriteM = '0;
tlb #(3) dtlb(clk, reset, SATP_REGW, PrivilegeModeW, MemAdrM, PageTableEntryM, DTLBWriteM,
DTLBFlushM, MemPAdrM, DTLBMissM, DTLBHitM);
// Determine if an Unaligned access is taking place

View File

@ -46,8 +46,11 @@ module ahblite (
input logic MemReadM, MemWriteM,
input logic [`XLEN-1:0] WriteDataM,
input logic [1:0] MemSizeM,
// Signals from MMU ***
// MMUPAdr;
// Signals from MMU
input logic [`XLEN-1:0] MMUPAdr,
input logic MMUTranslate,
output logic [`XLEN-1:0] MMUReadPTE,
output logic MMUReady,
// Return from bus
output logic [`XLEN-1:0] ReadDataW,
// AHB-Lite external signals

View File

@ -0,0 +1,143 @@
///////////////////////////////////////////
// pagetablewalker.sv
//
// Written: tfleming@hmc.edu 2 March 2021
// Modified:
//
// Purpose: Page Table Walker
// Part of the Memory Management Unit (MMU)
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// 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"
`include "wally-constants.vh"
module pagetablewalker (
input logic clk, reset,
input logic [`XLEN-1:0] SATP_REGW,
input logic ITLBMissF, DTLBMissM,
input logic [`XLEN-1:0] PCF, MemAdrM,
output logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM,
output logic ITLBWriteF, DTLBWriteM,
// *** handshake to tlbs probably not needed, since stalls take effect
// output logic TranslationComplete
// Signals from and to ahblite
input logic [`XLEN-1:0] MMUReadPTE,
input logic MMUReady,
output logic [`XLEN-1:0] MMUPAdr,
output logic MMUTranslate
);
logic SvMode;
logic [`PPN_BITS-1:0] BasePageTablePPN;
logic [`XLEN-1:0] DirectInstrPTE, DirectMemPTE;
logic [9:0] DirectPTEFlags = {2'b0, 8'b00001111};
// rv32 temp case
logic [`VPN_BITS-1:0] PCPageNumber;
logic [`VPN_BITS-1:0] MemAdrPageNumber;
assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0];
assign PCPageNumber = PCF[`VPN_BITS+11:12];
assign MemAdrPageNumber = MemAdrM[`VPN_BITS+11:12];
generate
if (`XLEN == 32) begin
assign DirectInstrPTE = {PCPageNumber, DirectPTEFlags};
assign DirectMemPTE = {MemAdrPageNumber, DirectPTEFlags};
end else begin
assign DirectInstrPTE = {10'b0, PCPageNumber, DirectPTEFlags};
assign DirectMemPTE = {10'b0, MemAdrPageNumber, DirectPTEFlags};
end
endgenerate
flopenr #(`XLEN) instrpte(clk, reset, ITLBMissF, DirectInstrPTE, PageTableEntryF);
flopenr #(`XLEN) datapte(clk, reset, DTLBMissM, DirectMemPTE, PageTableEntryM);
flopr #(1) iwritesignal(clk, reset, ITLBMissF, ITLBWriteF);
flopr #(1) dwritesignal(clk, reset, DTLBMissM, DTLBWriteM);
/*
generate
if (`XLEN == 32) begin
assign SvMode = SATP_REGW[31];
logic VPN1 [9:0] = TranslationVAdr[31:22];
logic VPN0 [9:0] = TranslationVAdr[21:12]; // *** could optimize by not passing offset?
logic TranslationPAdr [33:0];
typedef enum {IDLE, DATA_LEVEL1, DATA_LEVEL0, DATA_LEAF, DATA FAULT} statetype;
statetype WalkerState, NextWalkerState;
always_ff @(posedge HCLK, negedge HRESETn)
if (~HRESETn) WalkerState <= #1 IDLE;
else WalkerState <= #1 NextWalkerState;
always_comb begin
NextWalkerState = 'X;
case (WalkerState)
IDLE: if (TLBMissM) NextWalkerState = LEVEL1;
else NextWalkerState = IDLE;
LEVEL1: if (HREADY && ValidEntry) NextWalkerState = LEVEL0;
else if (HREADY) NextWalkerState = FAULT;
else NextWalkerState = LEVEL1;
LEVEL2: if (HREADY && ValidEntry) NextWalkerState = LEAF;
else if (HREADY) NextWalkerState = FAULT;
else NextWalkerState = LEVEL2;
LEAF: NextWalkerState = IDLE;
endcase
end
always_ff @(posedge HCLK, negedge HRESETn)
if (~HRESETn) begin
TranslationPAdr <= '0;
PageTableEntryF <= '0;
TranslationComplete <= '0;
end else begin
// default values
case (NextWalkerState)
LEVEL1: TranslationPAdr <= {BasePageTablePPN, VPN1, 2'b00};
LEVEL2: TranslationPAdr <= {CurrentPPN, VPN0, 2'b00};
LEAF: begin
PageTableEntryF <= CurrentPageTableEntry;
TranslationComplete <= '1;
end
endcase
end
assign #1 Translate = (NextWalkerState == LEVEL1);
end else begin
// sv39 not yet implemented
assign SvMode = SATP_REGW[63];
end
endgenerate
// rv32 case
*/
endmodule

View File

@ -1,106 +0,0 @@
///////////////////////////////////////////
// pagetablewalker.sv
//
// Written: tfleming@hmc.edu 2 March 2021
// Modified:
//
// Purpose: Page Table Walker
// Part of the Memory Management Unit (MMU)
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// 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 pagetablewalker (
input logic clk, reset,
input logic [`XLEN-1:0] SATP_REGW,
input logic ITLBMissF, DTLBMissM,
input logic [`XLEN-1:0] TranslationVAdr,
input logic HCLK, HRESETn,
input logic HREADY,
output logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM,
output logic ITLBWriteF, DTLBWriteM,
output logic TranslationComplete
);
/*
generate
if (`XLEN == 32) begin
logic Sv_Mode = satp[31]
end else begin
logic Sv_Mode [3:0] = satp[63:60]
end
endgenerate
*/
logic Sv_Mode = SATP_REGW[31];
logic BasePageTablePPN [21:0] = SATP_REGW[21:0];
logic VPN1 [9:0] = TranslationVAdr[31:22];
logic VPN0 [9:0] = TranslationVAdr[21:12]; // *** could optimize by not passing offset?
logic TranslationPAdr [33:0];
typedef enum {IDLE, DATA_LEVEL1, DATA_LEVEL0, DATA_LEAF, DATA FAULT} statetype;
statetype WalkerState, NextWalkerState;
always_ff @(posedge HCLK, negedge HRESETn)
if (~HRESETn) WalkerState <= #1 IDLE;
else WalkerState <= #1 NextWalkerState;
always_comb begin
NextWalkerState = 'X;
case (WalkerState)
IDLE: if (TLBMissM) NextWalkerState = LEVEL1;
else NextWalkerState = IDLE;
LEVEL1: if (HREADY && ValidEntry) NextWalkerState = LEVEL0;
else if (HREADY) NextWalkerState = FAULT;
else NextWalkerState = LEVEL1;
LEVEL2: if (HREADY && ValidEntry) NextWalkerState = LEAF;
else if (HREADY) NextWalkerState = FAULT;
else NextWalkerState = LEVEL2;
LEAF: NextWalkerState = IDLE;
endcase
end
always_ff @(posedge HCLK, negedge HRESETn)
if (~HRESETn) begin
TranslationPAdr <= '0;
PageTableEntryF <= '0;
TranslationComplete <= '0;
end else begin
// default values
case (NextWalkerState)
LEVEL1: TranslationPAdr <= {BasePageTablePPN, VPN1, 2'b00};
LEVEL2: TranslationPAdr <= {CurrentPPN, VPN0, 2'b00};
LEAF: begin
PageTableEntryF <= CurrentPageTableEntry;
TranslationComplete <= '1;
end
endcase
end
assign #1 Translate = (NextWalkerState == LEVEL1);
endmodule

View File

@ -55,9 +55,10 @@ module ifu (
output logic InstrMisalignedFaultM,
output logic [`XLEN-1:0] InstrMisalignedAdrM,
// TLB management
//input logic [`XLEN-1:0] PageTableEntryF,
input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] PageTableEntryF,
input logic [`XLEN-1:0] SATP_REGW,
//input logic ITLBWriteF, ITLBFlushF,
input logic ITLBWriteF, // ITLBFlushF,
output logic ITLBMissF, ITLBHitF,
// bogus
input logic [15:0] rd2
@ -74,10 +75,10 @@ module ifu (
logic [31:0] nop = 32'h00000013; // instruction for NOP
// *** temporary hack until walker is hooked up -- Thomas F
logic [`XLEN-1:0] PageTableEntryF = '0;
// logic [`XLEN-1:0] PageTableEntryF = '0;
logic ITLBFlushF = '0;
logic ITLBWriteF = '0;
tlb #(3) itlb(clk, reset, SATP_REGW, PCF, PageTableEntryF, ITLBWriteF, ITLBFlushF,
// logic ITLBWriteF = '0;
tlb #(3) itlb(clk, reset, SATP_REGW, PrivilegeModeW, PCF, PageTableEntryF, ITLBWriteF, ITLBFlushF,
InstrPAdrF, ITLBMissF, ITLBHitF);
// branch predictor signals

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////
// tlb_toy.sv
// tlb.sv
//
// Written: jtorrey@hmc.edu 16 February 2021
// Modified:
@ -60,6 +60,9 @@ module tlb #(parameter ENTRY_BITS = 3) (
// Current value of satp CSR (from privileged unit)
input [`XLEN-1:0] SATP_REGW,
// Current privilege level of the processeor
input [1:0] PrivilegeModeW,
// Virtual address input
input [`XLEN-1:0] VirtualAddress,
@ -77,6 +80,7 @@ module tlb #(parameter ENTRY_BITS = 3) (
);
logic SvMode;
logic Translate;
generate
if (`XLEN == 32) begin
@ -85,6 +89,11 @@ module tlb #(parameter ENTRY_BITS = 3) (
assign SvMode = SATP_REGW[63]; // currently just a boolean whether translation enabled
end
endgenerate
// *** Currently fake virtual memory being on for testing purposes
// *** DO NOT ENABLE UNLESS TESTING
// assign SvMode = 1;
assign Translate = SvMode & (PrivilegeModeW != `M_MODE);
// *** If we want to support multiple virtual memory modes (ie sv39 AND sv48),
// we could have some muxes that control which parameters are current.
@ -134,13 +143,13 @@ module tlb #(parameter ENTRY_BITS = 3) (
generate
if (`XLEN == 32) begin
mux2 #(`XLEN) addressmux(VirtualAddress, PhysicalAddressFull[31:0], SvMode, PhysicalAddress);
mux2 #(`XLEN) addressmux(VirtualAddress, PhysicalAddressFull[31:0], Translate, PhysicalAddress);
end else begin
mux2 #(`XLEN) addressmux(VirtualAddress, {8'b0, PhysicalAddressFull}, SvMode, PhysicalAddress);
mux2 #(`XLEN) addressmux(VirtualAddress, {8'b0, PhysicalAddressFull}, Translate, PhysicalAddress);
end
endgenerate
assign TLBMiss = ~TLBHit & ~(TLBWrite | TLBFlush) & SvMode;
assign TLBMiss = ~TLBHit & ~(TLBWrite | TLBFlush) & Translate;
endmodule
module tlb_ram #(parameter ENTRY_BITS = 3) (

View File

@ -44,12 +44,13 @@ module privileged (
input logic TimerIntM, ExtIntM, SwIntM,
input logic [`XLEN-1:0] InstrMisalignedAdrM, MemAdrM,
input logic [4:0] SetFflagsM,
output logic [1:0] PrivilegeModeW,
output logic [`XLEN-1:0] SATP_REGW,
output logic [2:0] FRM_REGW,
input logic FlushD, FlushE, FlushM, StallD, StallW
);
logic [1:0] NextPrivilegeModeM, PrivilegeModeW;
logic [1:0] NextPrivilegeModeM;
logic [`XLEN-1:0] CauseM, NextFaultMtvalM;
logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW;

View File

@ -93,9 +93,13 @@ module wallypipelinedhart (
logic ITLBMissF, ITLBHitF;
logic DTLBMissM, DTLBHitM;
logic [`XLEN-1:0] SATP_REGW;
logic [1:0] PrivilegeModeW;
logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM;
logic [`XLEN-1:0] MMUPAdr, MMUReadPTE;
logic MMUTranslate, MMUReady;
// bus interface to dmem
logic MemReadM, MemWriteM;
logic [2:0] Funct3M;
@ -106,7 +110,7 @@ module wallypipelinedhart (
logic InstrReadF;
logic DataStall, InstrStall;
logic InstrAckD, MemAckW;
logic BPPredWrongE;
logic BPPredWrongE;
ifu ifu(.InstrInF(InstrRData), .*); // instruction fetch unit: PC, branch prediction, instruction cache
@ -121,7 +125,7 @@ module wallypipelinedhart (
.Funct7M(InstrM[31:25]),
.*);
// walker walker(.*); *** // can send addresses to ahblite, send out pagetablestall
pagetablewalker pagetablewalker(.*); // can send addresses to ahblite, send out pagetablestall
// *** can connect to hazard unit
// changing from this to the line above breaks the program. auipc at 104 fails; seems to be flushed.
// Would need to insertinstruction as InstrD, not InstrF