diff --git a/wally-pipelined/src/dmem/dmem.sv b/wally-pipelined/src/dmem/dmem.sv index 9bc4a6a09..d1c11d93a 100644 --- a/wally-pipelined/src/dmem/dmem.sv +++ b/wally-pipelined/src/dmem/dmem.sv @@ -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 diff --git a/wally-pipelined/src/ebu/ahblite.sv b/wally-pipelined/src/ebu/ahblite.sv index ed353595c..bec919ece 100644 --- a/wally-pipelined/src/ebu/ahblite.sv +++ b/wally-pipelined/src/ebu/ahblite.sv @@ -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 diff --git a/wally-pipelined/src/ebu/pagetablewalker.sv b/wally-pipelined/src/ebu/pagetablewalker.sv new file mode 100644 index 000000000..2ba2b78c6 --- /dev/null +++ b/wally-pipelined/src/ebu/pagetablewalker.sv @@ -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 \ No newline at end of file diff --git a/wally-pipelined/src/ebu/pagetablewalker.sv_dev b/wally-pipelined/src/ebu/pagetablewalker.sv_dev deleted file mode 100644 index eaed09482..000000000 --- a/wally-pipelined/src/ebu/pagetablewalker.sv_dev +++ /dev/null @@ -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 \ No newline at end of file diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index 68325affb..bc1c68e44 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -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 diff --git a/wally-pipelined/src/mmu/tlb.sv b/wally-pipelined/src/mmu/tlb.sv index 4d4e46a37..77b5efba2 100644 --- a/wally-pipelined/src/mmu/tlb.sv +++ b/wally-pipelined/src/mmu/tlb.sv @@ -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) ( diff --git a/wally-pipelined/src/privileged/privileged.sv b/wally-pipelined/src/privileged/privileged.sv index a01fa557c..0830d3475 100644 --- a/wally-pipelined/src/privileged/privileged.sv +++ b/wally-pipelined/src/privileged/privileged.sv @@ -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; diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index bd69739c8..29e9d3428 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -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