forked from Github_Repos/cvw
Don't use this branch walker still broken.
This commit is contained in:
parent
d80ebab941
commit
bc9c944ba0
@ -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}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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),
|
||||||
.*);
|
.*);
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user