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

@ -46,7 +46,7 @@ module lsu (
// 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,
@ -65,6 +65,8 @@ module lsu (
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
@ -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,6 +58,7 @@ 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,
@ -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;
@ -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),
@ -217,6 +223,7 @@ module wallypipelinedhart
.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),
@ -240,15 +248,18 @@ module wallypipelinedhart
.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),
.*); .*);