Don't use this branch walker still broken.

This commit is contained in:
Ross Thompson 2021-06-28 17:26:11 -05:00
parent d80ebab941
commit bc9c944ba0
6 changed files with 194 additions and 93 deletions

View File

@ -218,9 +218,11 @@ add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/har
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/MemReadM add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/MemReadM
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/MemWriteM add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/MemWriteM
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/InstrReadF add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/InstrReadF
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/MemSizeM
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HCLK add wave -noupdate -group AHB /testbench/dut/hart/ebu/HCLK
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HRESETn add wave -noupdate -group AHB /testbench/dut/hart/ebu/HRESETn
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HRDATA add wave -noupdate -group AHB /testbench/dut/hart/ebu/HRDATA
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HRDATANext
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HREADY add wave -noupdate -group AHB /testbench/dut/hart/ebu/HREADY
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HRESP add wave -noupdate -group AHB /testbench/dut/hart/ebu/HRESP
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HADDR add wave -noupdate -group AHB /testbench/dut/hart/ebu/HADDR
@ -234,9 +236,12 @@ add wave -noupdate -group AHB /testbench/dut/hart/ebu/HMASTLOCK
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HADDRD add wave -noupdate -group AHB /testbench/dut/hart/ebu/HADDRD
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HSIZED add wave -noupdate -group AHB /testbench/dut/hart/ebu/HSIZED
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HWRITED add wave -noupdate -group AHB /testbench/dut/hart/ebu/HWRITED
add wave -noupdate -group AHB /testbench/dut/hart/ebu/StallW
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/CurrState add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/CurrState
add wave -noupdate -expand -group lsu /testbench/dut/hart/arbiter/MemAdrM add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/DataStall
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/MemAdrM
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/MemPAdrM add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/MemPAdrM
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/ReadDataW
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/WriteDataM add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/WriteDataM
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/AtomicMaskedM add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/AtomicMaskedM
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/DSquashBusAccessM add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/DSquashBusAccessM
@ -282,8 +287,25 @@ add wave -noupdate -group CLINT /testbench/dut/uncore/genblk1/clint/MTIME
add wave -noupdate -group CLINT /testbench/dut/uncore/genblk1/clint/MTIMECMP add wave -noupdate -group CLINT /testbench/dut/uncore/genblk1/clint/MTIMECMP
add wave -noupdate -group CLINT /testbench/dut/uncore/genblk1/clint/TimerIntM add wave -noupdate -group CLINT /testbench/dut/uncore/genblk1/clint/TimerIntM
add wave -noupdate -group CLINT /testbench/dut/uncore/genblk1/clint/SwIntM add wave -noupdate -group CLINT /testbench/dut/uncore/genblk1/clint/SwIntM
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/PRegEn
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/WalkerState
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/MMUReady
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/HPTWStall
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/TranslationPAdr
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/MMUReadPTE
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/MMUPAdr
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/CurrentPTE
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/ValidPTE
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/LeafPTE
add wave -noupdate -expand -group {LSU ARB} /testbench/dut/hart/arbiter/HPTWTranslate
add wave -noupdate -expand -group {LSU ARB} /testbench/dut/hart/arbiter/HPTWPAdr
add wave -noupdate -expand -group {LSU ARB} /testbench/dut/hart/arbiter/HPTWReadPTE
add wave -noupdate -expand -group {LSU ARB} /testbench/dut/hart/arbiter/HPTWReady
add wave -noupdate -expand -group {LSU ARB} -expand -group toLSU /testbench/dut/hart/arbiter/MemAdrMtoLSU
add wave -noupdate -expand -group {LSU ARB} /testbench/dut/hart/arbiter/SelPTW
add wave -noupdate /testbench/dut/hart/lsu/DataStall
TreeUpdate [SetDefaultTree] TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 4} {32648010 ns} 0} {{Cursor 5} {11165332 ns} 0} {{Cursor 3} {7672141 ns} 0} WaveRestoreCursors {{Cursor 4} {32648010 ns} 0} {{Cursor 5} {11172098 ns} 0} {{Cursor 3} {7672141 ns} 0}
quietly wave cursor active 2 quietly wave cursor active 2
configure wave -namecolwidth 250 configure wave -namecolwidth 250
configure wave -valuecolwidth 189 configure wave -valuecolwidth 189
@ -299,4 +321,4 @@ configure wave -griddelta 40
configure wave -timeline 0 configure wave -timeline 0
configure wave -timelineunits ns configure wave -timelineunits ns
update update
WaveRestoreZoom {11156770 ns} {11173894 ns} WaveRestoreZoom {11171939 ns} {11172253 ns}

View File

@ -29,71 +29,73 @@
// *** Ross Thompson amo misalignment check? // *** Ross Thompson amo misalignment check?
module lsu ( module lsu (
input logic clk, reset, input logic clk, reset,
input logic StallM, FlushM, StallW, FlushW, input logic StallM, FlushM, StallW, FlushW,
output logic DataStall, output logic DataStall,
output logic HPTWReady, output logic HPTWReady,
// Memory Stage // Memory Stage
// connected to cpu (controls) // connected to cpu (controls)
input logic [1:0] MemRWM, input logic [1:0] MemRWM,
input logic [2:0] Funct3M, input logic [2:0] Funct3M,
input logic [1:0] AtomicM, input logic [1:0] AtomicM,
output logic CommittedM, output logic CommittedM,
output logic SquashSCW, output logic SquashSCW,
output logic DataMisalignedM, output logic DataMisalignedM,
// address and write data // address and write data
input logic [`XLEN-1:0] MemAdrM, input logic [`XLEN-1:0] MemAdrM,
input logic [`XLEN-1:0] WriteDataM, input logic [`XLEN-1:0] WriteDataM,
output logic [`XLEN-1:0] ReadDataW, // from ahb output logic [`XLEN-1:0] ReadDataW,
// cpu privilege // cpu privilege
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
input logic DTLBFlushM, input logic DTLBFlushM,
// faults // faults
input logic NonBusTrapM, input logic NonBusTrapM,
output logic DTLBLoadPageFaultM, DTLBStorePageFaultM, output logic DTLBLoadPageFaultM, DTLBStorePageFaultM,
output logic LoadMisalignedFaultM, LoadAccessFaultM, output logic LoadMisalignedFaultM, LoadAccessFaultM,
// cpu hazard unit (trap) // cpu hazard unit (trap)
output logic StoreMisalignedFaultM, StoreAccessFaultM, output logic StoreMisalignedFaultM, StoreAccessFaultM,
// connect to ahb // connect to ahb
input logic CommitM, // should this be generated in the abh interface? input logic CommitM, // should this be generated in the abh interface?
output logic [`PA_BITS-1:0] MemPAdrM, // to ahb output logic [`PA_BITS-1:0] MemPAdrM, // to ahb
output logic MemReadM, MemWriteM, output logic MemReadM, MemWriteM,
output logic [1:0] AtomicMaskedM, output logic [1:0] AtomicMaskedM,
input logic MemAckW, // from ahb input logic MemAckW, // from ahb
input logic [`XLEN-1:0] HRDATAW, // from ahb input logic [`XLEN-1:0] HRDATAW, // from ahb
output logic [2:0] Funct3MfromLSU,
output logic StallWfromLSU,
// mmu management // mmu management
// page table walker // page table walker
input logic [`XLEN-1:0] PageTableEntryM, input logic [`XLEN-1:0] PageTableEntryM,
input logic [1:0] PageTypeM, input logic [1:0] PageTypeM,
input logic [`XLEN-1:0] SATP_REGW, // from csr input logic [`XLEN-1:0] SATP_REGW, // from csr
input logic STATUS_MXR, STATUS_SUM, // from csr input logic STATUS_MXR, STATUS_SUM, // from csr
input logic DTLBWriteM, input logic DTLBWriteM,
output logic DTLBMissM, output logic DTLBMissM,
input logic DisableTranslation, // used to stop intermediate PTE physical addresses being saved to TLB. input logic DisableTranslation, // used to stop intermediate PTE physical addresses being saved to TLB.
output logic DTLBHitM, // not connected output logic DTLBHitM, // not connected
// PMA/PMP (inside mmu) signals // PMA/PMP (inside mmu) signals
input logic [31:0] HADDR, // *** replace all of these H inputs with physical adress once pma checkers have been edited to use paddr as well. input logic [31:0] HADDR, // *** replace all of these H inputs with physical adress once pma checkers have been edited to use paddr as well.
input logic [2:0] HSIZE, input logic [2:0] HSIZE,
input logic HWRITE, input logic HWRITE,
input logic AtomicAccessM, WriteAccessM, ReadAccessM, // execute access is hardwired to zero in this mmu because we're only working with data in the M stage. input logic AtomicAccessM, WriteAccessM, ReadAccessM, // execute access is hardwired to zero in this mmu because we're only working with data in the M stage.
input logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW, // *** all of these come from the privileged unit, so thwyre gonna have to come over into ifu and dmem input logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW, // *** all of these come from the privileged unit, so thwyre gonna have to come over into ifu and dmem
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], // *** this one especially has a large note attached to it in pmpchecker. input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], // *** this one especially has a large note attached to it in pmpchecker.
output logic PMALoadAccessFaultM, PMAStoreAccessFaultM, output logic PMALoadAccessFaultM, PMAStoreAccessFaultM,
output logic PMPLoadAccessFaultM, PMPStoreAccessFaultM, // *** can these be parameterized? we dont need the m stage ones for the immu and vice versa. output logic PMPLoadAccessFaultM, PMPStoreAccessFaultM, // *** can these be parameterized? we dont need the m stage ones for the immu and vice versa.
output logic DSquashBusAccessM output logic DSquashBusAccessM
// output logic [5:0] DHSELRegionsM // output logic [5:0] DHSELRegionsM
); );
@ -246,13 +248,15 @@ module lsu (
end end
end end
STATE_FETCH: begin STATE_FETCH: begin
DataStall = 1'b1;
if (MemAckW & ~StallW) begin if (MemAckW & ~StallW) begin
NextState = STATE_READY; NextState = STATE_READY;
DataStall = 1'b0;
end else if (MemAckW & StallW) begin end else if (MemAckW & StallW) begin
NextState = STATE_STALLED; NextState = STATE_STALLED;
DataStall = 1'b1;
end else begin end else begin
NextState = STATE_FETCH; NextState = STATE_FETCH;
DataStall = 1'b1;
end end
end end
STATE_STALLED: begin STATE_STALLED: begin
@ -268,7 +272,12 @@ module lsu (
NextState = STATE_READY; NextState = STATE_READY;
end end
endcase endcase
end end // always_comb
// *** for now just pass through size
assign Funct3MfromLSU = Funct3M;
assign StallWfromLSU = StallW;
endmodule endmodule

View File

@ -35,6 +35,7 @@ module lsuArb
// to page table walker. // to page table walker.
output logic [`XLEN-1:0] HPTWReadPTE, output logic [`XLEN-1:0] HPTWReadPTE,
output logic HPTWReady, output logic HPTWReady,
output logic HPTWStall,
// from CPU // from CPU
input logic [1:0] MemRWM, input logic [1:0] MemRWM,
@ -42,6 +43,7 @@ module lsuArb
input logic [1:0] AtomicM, input logic [1:0] AtomicM,
input logic [`XLEN-1:0] MemAdrM, input logic [`XLEN-1:0] MemAdrM,
input logic [`XLEN-1:0] WriteDataM, input logic [`XLEN-1:0] WriteDataM,
input logic StallW,
// to CPU // to CPU
output logic [`XLEN-1:0] ReadDataW, output logic [`XLEN-1:0] ReadDataW,
output logic CommittedM, output logic CommittedM,
@ -56,12 +58,13 @@ module lsuArb
output logic [1:0] AtomicMtoLSU, output logic [1:0] AtomicMtoLSU,
output logic [`XLEN-1:0] MemAdrMtoLSU, output logic [`XLEN-1:0] MemAdrMtoLSU,
output logic [`XLEN-1:0] WriteDataMtoLSU, output logic [`XLEN-1:0] WriteDataMtoLSU,
output logic StallWtoLSU,
// from LSU // from LSU
input logic CommittedMfromLSU, input logic CommittedMfromLSU,
input logic SquashSCWfromLSU, input logic SquashSCWfromLSU,
input logic DataMisalignedMfromLSU, input logic DataMisalignedMfromLSU,
input logic [`XLEN-1:0] ReadDataWFromLSU, input logic [`XLEN-1:0] ReadDataWFromLSU,
input logic HPTWReadyfromLSU, input logic HPTWReadyfromLSU,
input logic DataStall input logic DataStall
); );
@ -124,6 +127,7 @@ module lsuArb
assign AtomicMtoLSU = SelPTW ? 2'b00 : AtomicM; assign AtomicMtoLSU = SelPTW ? 2'b00 : AtomicM;
assign MemAdrMtoLSU = SelPTW ? HPTWPAdr : MemAdrM; assign MemAdrMtoLSU = SelPTW ? HPTWPAdr : MemAdrM;
assign WriteDataMtoLSU = SelPTW ? `XLEN'b0 : WriteDataM; assign WriteDataMtoLSU = SelPTW ? `XLEN'b0 : WriteDataM;
assign StallWtoLSU = SelPTW ? 1'b0 : StallW;
// demux the inputs from LSU to walker or cpu's data port. // demux the inputs from LSU to walker or cpu's data port.
@ -133,6 +137,10 @@ module lsuArb
assign SquashSCW = SelPTW ? 1'b0 : SquashSCWfromLSU; assign SquashSCW = SelPTW ? 1'b0 : SquashSCWfromLSU;
assign DataMisalignedM = SelPTW ? 1'b0 : DataMisalignedMfromLSU; assign DataMisalignedM = SelPTW ? 1'b0 : DataMisalignedMfromLSU;
assign HPTWReady = HPTWReadyfromLSU; assign HPTWReady = HPTWReadyfromLSU;
assign DCacheStall = DataStall; // *** this is probably going to change. // *** need to rename DcacheStall and Datastall.
// not clear at all. I think it should be LSUStall from the LSU,
// which is demuxed to HPTWStall and CPUDataStall? (not sure on this last one).
assign HPTWStall = SelPTW ? DataStall : 1'b1;
assign DCacheStall = SelPTW ? 1'b0 : DataStall; // *** this is probably going to change.
endmodule endmodule

View File

@ -55,6 +55,7 @@ module pagetablewalker (
// *** modify to send to LSU // *** KMG: These are inputs/results from the ahblite whose addresses should have already been checked, so I don't think they need to be sent through the LSU // *** modify to send to LSU // *** KMG: These are inputs/results from the ahblite whose addresses should have already been checked, so I don't think they need to be sent through the LSU
input logic [`XLEN-1:0] MMUReadPTE, input logic [`XLEN-1:0] MMUReadPTE,
input logic MMUReady, input logic MMUReady,
input logic HPTWStall,
// *** modify to send to LSU // *** modify to send to LSU
output logic [`XLEN-1:0] MMUPAdr, output logic [`XLEN-1:0] MMUPAdr,
@ -140,14 +141,22 @@ module pagetablewalker (
assign PageTypeF = PageType; assign PageTypeF = PageType;
assign PageTypeM = PageType; assign PageTypeM = PageType;
localparam LEVEL0 = 3'h0; localparam LEVEL0_WDV = 4'h0;
localparam LEVEL1 = 3'h1; localparam LEVEL0 = 4'h8;
localparam LEVEL1_WDV = 4'h1;
localparam LEVEL1 = 4'h9;
localparam LEVEL2_WDV = 4'h2;
localparam LEVEL2 = 4'hA;
localparam LEVEL3_WDV = 4'h3;
localparam LEVEL3 = 4'hB;
// space left for more levels // space left for more levels
localparam LEAF = 3'h5; localparam LEAF = 4'h5;
localparam IDLE = 3'h6; localparam IDLE = 4'h6;
localparam FAULT = 3'h7; localparam FAULT = 4'h7;
logic [2:0] WalkerState, NextWalkerState; logic [3:0] WalkerState, NextWalkerState;
logic PRegEn;
generate generate
if (`XLEN == 32) begin if (`XLEN == 32) begin
@ -155,27 +164,32 @@ localparam LEVEL0 = 3'h0;
flopenl #(3) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); flopenl #(3) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
assign PRegEn = (WalkerState == LEVEL1 || WalkerState == LEVEL0) && ~HPTWStall;
// State transition logic // State transition logic
always_comb begin always_comb begin
case (WalkerState) case (WalkerState)
IDLE: if (MMUTranslate) NextWalkerState = LEVEL1; IDLE: if (MMUTranslate) NextWalkerState = LEVEL1_WDV;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
LEVEL1: if (~MMUReady) NextWalkerState = LEVEL1; LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV;
else NextWalkerState = LEVEL1;
LEVEL1:
// *** <FUTURE WORK> According to the architecture, we should // *** <FUTURE WORK> According to the architecture, we should
// fault upon finding a superpage that is misaligned or has 0 // fault upon finding a superpage that is misaligned or has 0
// access bit. The following commented line of code is // access bit. The following commented line of code is
// supposed to perform that check. However, it is untested. // supposed to perform that check. However, it is untested.
else if (ValidPTE && LeafPTE && ~BadMegapage) NextWalkerState = LEAF; if (ValidPTE && LeafPTE && ~BadMegapage) NextWalkerState = LEAF;
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line. // else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0; else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0_WDV;
else NextWalkerState = FAULT; else NextWalkerState = FAULT;
LEVEL0: if (~MMUReady) NextWalkerState = LEVEL0; LEVEL0_WDV: if (HPTWStall) NextWalkerState = LEVEL0_WDV;
else if (ValidPTE && LeafPTE && ~AccessAlert) else NextWalkerState = LEVEL0;
LEVEL0: if (ValidPTE && LeafPTE && ~AccessAlert)
NextWalkerState = LEAF; NextWalkerState = LEAF;
else NextWalkerState = FAULT; else NextWalkerState = FAULT;
LEAF: if (MMUTranslate) NextWalkerState = LEVEL1; LEAF: if (MMUTranslate) NextWalkerState = LEVEL1_WDV;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
FAULT: if (MMUTranslate) NextWalkerState = LEVEL1; FAULT: if (MMUTranslate) NextWalkerState = LEVEL1_WDV;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
// Default case should never happen, but is included for linter. // Default case should never happen, but is included for linter.
default: NextWalkerState = IDLE; default: NextWalkerState = IDLE;
@ -201,7 +215,7 @@ localparam LEVEL0 = 3'h0;
WalkerLoadPageFaultM = '0; WalkerLoadPageFaultM = '0;
WalkerStorePageFaultM = '0; WalkerStorePageFaultM = '0;
MMUStall = '1; MMUStall = '1;
case (NextWalkerState) case (NextWalkerState)
IDLE: begin IDLE: begin
MMUStall = '0; MMUStall = '0;
@ -209,9 +223,15 @@ localparam LEVEL0 = 3'h0;
LEVEL1: begin LEVEL1: begin
TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00};
end end
LEVEL1_WDV: begin
TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00};
end
LEVEL0: begin LEVEL0: begin
TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
end end
LEVEL0_WDV: begin
TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
end
LEAF: begin LEAF: begin
// Keep physical address alive to prevent HADDR dropping to 0 // Keep physical address alive to prevent HADDR dropping to 0
TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
@ -233,9 +253,16 @@ localparam LEVEL0 = 3'h0;
endcase endcase
end end
// Capture page table entry from ahblite // Capture page table entry from data cache
flopenr #(32) ptereg(clk, reset, MMUReady, MMUReadPTE, SavedPTE); // *** may need to delay reading this value until the next clock cycle.
mux2 #(32) ptemux(SavedPTE, MMUReadPTE, MMUReady, CurrentPTE); // The clk to q latency of the SRAM in the data cache will be long.
// I cannot see directly using this value. This is no different than
// a load delay hazard. This will require rewriting the walker fsm.
// also need a new signal to save. Should be a mealy output of the fsm
// request followed by ~stall.
flopenr #(32) ptereg(clk, reset, PRegEn, MMUReadPTE, SavedPTE);
//mux2 #(32) ptemux(SavedPTE, MMUReadPTE, PRegEn, CurrentPTE);
assign CurrentPTE = SavedPTE;
assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10]; assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10];
// Assign outputs to ahblite // Assign outputs to ahblite
@ -244,61 +271,70 @@ localparam LEVEL0 = 3'h0;
assign MMUPAdr = TranslationPAdr[31:0]; assign MMUPAdr = TranslationPAdr[31:0];
end else begin end else begin
localparam LEVEL2 = 3'h2;
localparam LEVEL3 = 3'h3;
logic [8:0] VPN3, VPN2, VPN1, VPN0; logic [8:0] VPN3, VPN2, VPN1, VPN0;
logic TerapageMisaligned, GigapageMisaligned, BadTerapage, BadGigapage; logic TerapageMisaligned, GigapageMisaligned, BadTerapage, BadGigapage;
flopenl #(3) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); flopenl #(4) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
assign PRegEn = (WalkerState == LEVEL1 || WalkerState == LEVEL0 ||
WalkerState == LEVEL2 || WalkerState == LEVEL3) && ~HPTWStall;
always_comb begin always_comb begin
case (WalkerState) case (WalkerState)
IDLE: if (MMUTranslate && SvMode == `SV48) NextWalkerState = LEVEL3; IDLE: if (MMUTranslate && SvMode == `SV48) NextWalkerState = LEVEL3_WDV;
else if (MMUTranslate && SvMode == `SV39) NextWalkerState = LEVEL2; else if (MMUTranslate && SvMode == `SV39) NextWalkerState = LEVEL2_WDV;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
LEVEL3: if (~MMUReady) NextWalkerState = LEVEL3; LEVEL3_WDV: if (HPTWStall) NextWalkerState = LEVEL3_WDV;
else NextWalkerState = LEVEL3;
LEVEL3:
// *** <FUTURE WORK> According to the architecture, we should // *** <FUTURE WORK> According to the architecture, we should
// fault upon finding a superpage that is misaligned or has 0 // fault upon finding a superpage that is misaligned or has 0
// access bit. The following commented line of code is // access bit. The following commented line of code is
// supposed to perform that check. However, it is untested. // supposed to perform that check. However, it is untested.
else if (ValidPTE && LeafPTE && ~BadTerapage) NextWalkerState = LEAF; if (ValidPTE && LeafPTE && ~BadTerapage) NextWalkerState = LEAF;
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line. // else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL2; else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL2_WDV;
else NextWalkerState = FAULT; else NextWalkerState = FAULT;
LEVEL2: if (~MMUReady) NextWalkerState = LEVEL2; LEVEL2_WDV: if (HPTWStall) NextWalkerState = LEVEL2_WDV;
else NextWalkerState = LEVEL2;
LEVEL2:
// *** <FUTURE WORK> According to the architecture, we should // *** <FUTURE WORK> According to the architecture, we should
// fault upon finding a superpage that is misaligned or has 0 // fault upon finding a superpage that is misaligned or has 0
// access bit. The following commented line of code is // access bit. The following commented line of code is
// supposed to perform that check. However, it is untested. // supposed to perform that check. However, it is untested.
else if (ValidPTE && LeafPTE && ~BadGigapage) NextWalkerState = LEAF; if (ValidPTE && LeafPTE && ~BadGigapage) NextWalkerState = LEAF;
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line. // else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL1; else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL1_WDV;
else NextWalkerState = FAULT; else NextWalkerState = FAULT;
LEVEL1: if (~MMUReady) NextWalkerState = LEVEL1; LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV;
else NextWalkerState = LEVEL1;
LEVEL1:
// *** <FUTURE WORK> According to the architecture, we should // *** <FUTURE WORK> According to the architecture, we should
// fault upon finding a superpage that is misaligned or has 0 // fault upon finding a superpage that is misaligned or has 0
// access bit. The following commented line of code is // access bit. The following commented line of code is
// supposed to perform that check. However, it is untested. // supposed to perform that check. However, it is untested.
else if (ValidPTE && LeafPTE && ~BadMegapage) NextWalkerState = LEAF; if (ValidPTE && LeafPTE && ~BadMegapage) NextWalkerState = LEAF;
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line. // else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0; else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0_WDV;
else NextWalkerState = FAULT; else NextWalkerState = FAULT;
LEVEL0: if (~MMUReady) NextWalkerState = LEVEL0; LEVEL0_WDV: if (HPTWStall) NextWalkerState = LEVEL0_WDV;
else if (ValidPTE && LeafPTE && ~AccessAlert) NextWalkerState = LEAF; else NextWalkerState = LEVEL0;
LEVEL0:
if (ValidPTE && LeafPTE && ~AccessAlert) NextWalkerState = LEAF;
else NextWalkerState = FAULT; else NextWalkerState = FAULT;
LEAF: if (MMUTranslate && SvMode == `SV48) NextWalkerState = LEVEL3; LEAF: if (MMUTranslate && SvMode == `SV48) NextWalkerState = LEVEL3_WDV;
else if (MMUTranslate && SvMode == `SV39) NextWalkerState = LEVEL2; else if (MMUTranslate && SvMode == `SV39) NextWalkerState = LEVEL2_WDV;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
FAULT: if (MMUTranslate && SvMode == `SV48) NextWalkerState = LEVEL3; FAULT: if (MMUTranslate && SvMode == `SV48) NextWalkerState = LEVEL3_WDV;
else if (MMUTranslate && SvMode == `SV39) NextWalkerState = LEVEL2; else if (MMUTranslate && SvMode == `SV39) NextWalkerState = LEVEL2_WDV;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
// Default case should never happen, but is included for linter. // Default case should never happen, but is included for linter.
default: NextWalkerState = IDLE; default: NextWalkerState = IDLE;
@ -346,15 +382,29 @@ localparam LEVEL0 = 3'h0;
// *** this is a huge breaking point. if we're going through level3 every time, even when sv48 is off, // *** this is a huge breaking point. if we're going through level3 every time, even when sv48 is off,
// what should translationPAdr be when level3 is just off? // what should translationPAdr be when level3 is just off?
end end
LEVEL3_WDV: begin
TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000};
// *** this is a huge breaking point. if we're going through level3 every time, even when sv48 is off,
// what should translationPAdr be when level3 is just off?
end
LEVEL2: begin LEVEL2: begin
TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000};
end end
LEVEL2_WDV: begin
TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000};
end
LEVEL1: begin LEVEL1: begin
TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; TranslationPAdr = {CurrentPPN, VPN1, 3'b000};
end end
LEVEL1_WDV: begin
TranslationPAdr = {CurrentPPN, VPN1, 3'b000};
end
LEVEL0: begin LEVEL0: begin
TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
end end
LEVEL0_WDV: begin
TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
end
LEAF: begin LEAF: begin
// Keep physical address alive to prevent HADDR dropping to 0 // Keep physical address alive to prevent HADDR dropping to 0
TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
@ -380,8 +430,9 @@ localparam LEVEL0 = 3'h0;
end end
// Capture page table entry from ahblite // Capture page table entry from ahblite
flopenr #(`XLEN) ptereg(clk, reset, MMUReady, MMUReadPTE, SavedPTE); flopenr #(`XLEN) ptereg(clk, reset, PRegEn, MMUReadPTE, SavedPTE);
mux2 #(`XLEN) ptemux(SavedPTE, MMUReadPTE, MMUReady, CurrentPTE); //mux2 #(`XLEN) ptemux(SavedPTE, MMUReadPTE, PRegEn, CurrentPTE);
assign CurrentPTE = SavedPTE;
assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10]; assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10];
// Assign outputs to ahblite // Assign outputs to ahblite

View File

@ -136,7 +136,7 @@ module tlb #(parameter ENTRY_BITS = 3,
endgenerate endgenerate
// Whether translation should occur // Whether translation should occur
assign Translate = (SvMode != `NO_TRANSLATE) & (PrivilegeModeW != `M_MODE); assign Translate = (SvMode != `NO_TRANSLATE) & (PrivilegeModeW != `M_MODE) & ~ DisableTranslation;
// Determine how the TLB is currently being used // Determine how the TLB is currently being used
// Note that we use ReadAccess for both loads and instruction fetches // Note that we use ReadAccess for both loads and instruction fetches

View File

@ -132,6 +132,7 @@ module wallypipelinedhart
logic MMUStall; logic MMUStall;
logic MMUTranslate, MMUReady; logic MMUTranslate, MMUReady;
logic HPTWReadyfromLSU; logic HPTWReadyfromLSU;
logic HPTWStall;
// bus interface to dmem // bus interface to dmem
@ -171,6 +172,9 @@ module wallypipelinedhart
logic CommittedMfromLSU; logic CommittedMfromLSU;
logic SquashSCWfromLSU; logic SquashSCWfromLSU;
logic DataMisalignedMfromLSU; logic DataMisalignedMfromLSU;
logic StallWtoLSU;
logic StallWfromLSU;
logic [2:0] Funct3MfromLSU;
@ -199,11 +203,13 @@ module wallypipelinedhart
.HPTWPAdr(MMUPAdr), .HPTWPAdr(MMUPAdr),
.HPTWReadPTE(MMUReadPTE), .HPTWReadPTE(MMUReadPTE),
.HPTWReady(MMUReady), .HPTWReady(MMUReady),
.HPTWStall(HPTWStall),
// CPU connection // CPU connection
.MemRWM(MemRWM|FMemRWM), .MemRWM(MemRWM|FMemRWM),
.Funct3M(Funct3M), .Funct3M(Funct3M),
.AtomicM(AtomicM), .AtomicM(AtomicM),
.MemAdrM(MemAdrM), .MemAdrM(MemAdrM),
.StallW(StallW),
.WriteDataM(WriteDatatmpM), .WriteDataM(WriteDatatmpM),
.ReadDataW(ReadDataW), .ReadDataW(ReadDataW),
.CommittedM(CommittedM), .CommittedM(CommittedM),
@ -216,7 +222,8 @@ module wallypipelinedhart
.Funct3MtoLSU(Funct3MtoLSU), .Funct3MtoLSU(Funct3MtoLSU),
.AtomicMtoLSU(AtomicMtoLSU), .AtomicMtoLSU(AtomicMtoLSU),
.MemAdrMtoLSU(MemAdrMtoLSU), .MemAdrMtoLSU(MemAdrMtoLSU),
.WriteDataMtoLSU(WriteDataMtoLSU), .WriteDataMtoLSU(WriteDataMtoLSU),
.StallWtoLSU(StallWtoLSU),
.CommittedMfromLSU(CommittedMfromLSU), .CommittedMfromLSU(CommittedMfromLSU),
.SquashSCWfromLSU(SquashSCWfromLSU), .SquashSCWfromLSU(SquashSCWfromLSU),
.DataMisalignedMfromLSU(DataMisalignedMfromLSU), .DataMisalignedMfromLSU(DataMisalignedMfromLSU),
@ -232,6 +239,7 @@ module wallypipelinedhart
.MemAdrM(MemAdrMtoLSU), .MemAdrM(MemAdrMtoLSU),
.WriteDataM(WriteDataMtoLSU), .WriteDataM(WriteDataMtoLSU),
.ReadDataW(ReadDataWFromLSU), .ReadDataW(ReadDataWFromLSU),
.StallW(StallWtoLSU),
.CommittedM(CommittedMfromLSU), .CommittedM(CommittedMfromLSU),
.SquashSCW(SquashSCWfromLSU), .SquashSCW(SquashSCWfromLSU),
@ -239,16 +247,19 @@ module wallypipelinedhart
.DisableTranslation(DisableTranslation), .DisableTranslation(DisableTranslation),
.DataStall(DataStall), .DataStall(DataStall),
.HPTWReady(HPTWReadyfromLSU), .HPTWReady(HPTWReadyfromLSU),
.Funct3MfromLSU(Funct3MfromLSU),
.StallWfromLSU(StallWfromLSU),
.* ); // data cache unit .* ); // data cache unit
ahblite ebu( ahblite ebu(
//.InstrReadF(1'b0), //.InstrReadF(1'b0),
//.InstrRData(InstrF), // hook up InstrF later //.InstrRData(InstrF), // hook up InstrF later
.WriteDataM(WriteDatatmpM), .WriteDataM(WriteDatatmpM),
.MemSizeM(Funct3M[1:0]), .UnsignedLoadM(Funct3M[2]), .MemSizeM(Funct3MfromLSU[1:0]), .UnsignedLoadM(Funct3MfromLSU[2]),
.Funct7M(InstrM[31:25]), .Funct7M(InstrM[31:25]),
.HRDATAW(HRDATAW), .HRDATAW(HRDATAW),
.StallW(StallWfromLSU),
.*); .*);