forked from Github_Repos/cvw
Merge branch 'mmu' into main
Conflicts: wally-pipelined/src/wally/wallypipelinedhart.sv
This commit is contained in:
commit
dbd5a4320e
@ -136,13 +136,13 @@ module ahblite (
|
||||
// stall signals
|
||||
// Note that we need to extend both stalls when MMUTRANSLATE goes to idle,
|
||||
// since translation might not be complete.
|
||||
assign #2 DataStall = ~TrapM && ((NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
|
||||
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE) ||
|
||||
(NextBusState == MMUTRANSLATE) || (BusState == MMUTRANSLATE));
|
||||
assign #2 DataStall = ((NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
|
||||
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE) ||
|
||||
(NextBusState == MMUTRANSLATE) || (MMUTranslate && ~MMUTranslationComplete)); // && ~TrapM
|
||||
// *** Could get finer grained stalling if we distinguish between MMU
|
||||
// instruction address translation and data address translation
|
||||
assign #1 InstrStall = ~TrapM && ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) ||
|
||||
(NextBusState == MMUTRANSLATE) || (BusState == MMUTRANSLATE));
|
||||
assign #1 InstrStall = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) ||
|
||||
(NextBusState == MMUTRANSLATE) || (MMUTranslate && ~MMUTranslationComplete)); // && ~TrapM
|
||||
|
||||
// bus outputs
|
||||
assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
|
||||
|
@ -116,7 +116,7 @@ module pagetablewalker (
|
||||
// unswizzle PTE bits
|
||||
assign {Dirty, Accessed, Global, User,
|
||||
Executable, Writable, Readable, Valid} = CurrentPTE[7:0];
|
||||
|
||||
|
||||
// Assign PTE descriptors common across all XLEN values
|
||||
assign LeafPTE = Executable | Writable | Readable;
|
||||
assign ValidPTE = Valid && ~(Writable && ~Readable);
|
||||
@ -195,6 +195,8 @@ module pagetablewalker (
|
||||
assign ITLBWriteF = ~DTLBMissM; // Prefer data over instructions
|
||||
end
|
||||
FAULT: begin
|
||||
assign TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
|
||||
assign MMUTranslationComplete = '1;
|
||||
assign InstrPageFaultM = ~DTLBMissM;
|
||||
assign LoadPageFaultM = DTLBMissM && ~MemStore;
|
||||
assign StorePageFaultM = DTLBMissM && MemStore;
|
||||
@ -206,8 +208,6 @@ module pagetablewalker (
|
||||
|
||||
// Capture page table entry from ahblite
|
||||
flopenr #(32) ptereg(HCLK, ~HRESETn, MMUReady, MMUReadPTE, SavedPTE);
|
||||
// *** Evil hack to get CurrentPTE a cycle early before it is saved.
|
||||
// Todo: Is it evil?
|
||||
mux2 #(32) ptemux(SavedPTE, MMUReadPTE, MMUReady, CurrentPTE);
|
||||
assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10];
|
||||
|
||||
@ -300,6 +300,8 @@ module pagetablewalker (
|
||||
assign ITLBWriteF = ~DTLBMissM; // Prefer data over instructions
|
||||
end
|
||||
FAULT: begin
|
||||
assign TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
|
||||
assign MMUTranslationComplete = '1;
|
||||
assign InstrPageFaultM = ~DTLBMissM;
|
||||
assign LoadPageFaultM = DTLBMissM && ~MemStore;
|
||||
assign StorePageFaultM = DTLBMissM && MemStore;
|
||||
@ -309,8 +311,6 @@ module pagetablewalker (
|
||||
|
||||
// Capture page table entry from ahblite
|
||||
flopenr #(`XLEN) ptereg(HCLK, ~HRESETn, MMUReady, MMUReadPTE, SavedPTE);
|
||||
// *** Evil hack to get CurrentPTE a cycle early before it is saved.
|
||||
// Todo: Is it evil?
|
||||
mux2 #(`XLEN) ptemux(SavedPTE, MMUReadPTE, MMUReady, CurrentPTE);
|
||||
assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10];
|
||||
|
||||
|
@ -61,7 +61,7 @@ module ifu (
|
||||
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
|
||||
);
|
||||
|
||||
@ -75,11 +75,6 @@ module ifu (
|
||||
logic [31:0] nop = 32'h00000013; // instruction for NOP
|
||||
logic [`XLEN-1:0] ITLBInstrPAdrF, ICacheInstrPAdrF;
|
||||
|
||||
// *** temporary hack until walker is hooked up -- Thomas F
|
||||
// logic [`XLEN-1:0] PageTableEntryF = '0;
|
||||
logic ITLBFlushF = '0;
|
||||
// logic ITLBWriteF = '0;
|
||||
|
||||
tlb #(3) itlb(clk, reset, SATP_REGW, PrivilegeModeW, 1'b1, PCF, PageTableEntryF, ITLBWriteF, ITLBFlushF,
|
||||
ITLBInstrPAdrF, ITLBMissF, ITLBHitF);
|
||||
|
||||
|
@ -126,25 +126,13 @@ module tlb #(parameter ENTRY_BITS = 3) (
|
||||
assign VirtualPageNumber = VirtualAddress[`VPN_BITS+11:12];
|
||||
assign PageOffset = VirtualAddress[11:0];
|
||||
|
||||
// Choose a read or write location to the entry list
|
||||
mux2 #(3) indexmux(VPNIndex, WriteIndex, TLBWrite, EntryIndex);
|
||||
|
||||
// Currently use random replacement algorithm
|
||||
tlb_rand rdm(.*);
|
||||
|
||||
tlb_ram #(ENTRY_BITS) ram(.*);
|
||||
tlb_cam #(ENTRY_BITS, `VPN_BITS) cam(.*);
|
||||
|
||||
always_comb begin
|
||||
assign PhysicalPageNumber = PageTableEntry[`PPN_BITS+9:10];
|
||||
|
||||
if (TLBHit) begin
|
||||
assign PhysicalAddressFull = {PhysicalPageNumber, PageOffset};
|
||||
end else begin
|
||||
assign PhysicalAddressFull = '0; // *** Actual behavior; disabled until walker functioning
|
||||
//assign PhysicalAddressFull = {2'b0, VirtualPageNumber, PageOffset} // *** pass through should be removed as soon as walker ready
|
||||
end
|
||||
end
|
||||
assign PhysicalAddressFull = (TLBHit) ? {PhysicalPageNumber, PageOffset} : '0;
|
||||
|
||||
generate
|
||||
if (`XLEN == 32) begin
|
||||
@ -158,9 +146,11 @@ module tlb #(parameter ENTRY_BITS = 3) (
|
||||
assign TLBMiss = ~TLBHit & ~TLBFlush & Translate & TLBAccess;
|
||||
endmodule
|
||||
|
||||
// *** use actual flop notation instead of initialbegin and alwaysff
|
||||
module tlb_ram #(parameter ENTRY_BITS = 3) (
|
||||
input clk, reset,
|
||||
input [ENTRY_BITS-1:0] EntryIndex,
|
||||
input [ENTRY_BITS-1:0] VPNIndex, // Index to read from
|
||||
input [ENTRY_BITS-1:0] WriteIndex,
|
||||
input [`XLEN-1:0] PageTableEntryWrite,
|
||||
input TLBWrite,
|
||||
|
||||
@ -171,10 +161,10 @@ module tlb_ram #(parameter ENTRY_BITS = 3) (
|
||||
|
||||
logic [`XLEN-1:0] ram [0:NENTRIES-1];
|
||||
always @(posedge clk) begin
|
||||
if (TLBWrite) ram[EntryIndex] <= PageTableEntryWrite;
|
||||
if (TLBWrite) ram[WriteIndex] <= PageTableEntryWrite;
|
||||
end
|
||||
|
||||
assign PageTableEntry = ram[EntryIndex];
|
||||
assign PageTableEntry = ram[VPNIndex];
|
||||
|
||||
initial begin
|
||||
for (int i = 0; i < NENTRIES; i++)
|
||||
|
@ -72,7 +72,7 @@ module csrs #(parameter
|
||||
assign WriteSEPCM = STrapM | (CSRSWriteM && (CSRAdrM == SEPC));
|
||||
assign WriteSCAUSEM = STrapM | (CSRSWriteM && (CSRAdrM == SCAUSE));
|
||||
assign WriteSTVALM = STrapM | (CSRSWriteM && (CSRAdrM == STVAL));
|
||||
assign WriteSATPM = STrapM | (CSRSWriteM && (CSRAdrM == SATP));
|
||||
assign WriteSATPM = CSRSWriteM && (CSRAdrM == SATP);
|
||||
assign WriteSCOUNTERENM = CSRSWriteM && (CSRAdrM == SCOUNTEREN);
|
||||
|
||||
// CSRs
|
||||
|
@ -36,6 +36,7 @@ module privileged (
|
||||
output logic [`XLEN-1:0] CSRReadValW,
|
||||
output logic [`XLEN-1:0] PrivilegedNextPCM,
|
||||
output logic RetM, TrapM,
|
||||
output logic ITLBFlushF, DTLBFlushM,
|
||||
input logic InstrValidW, FloatRegWriteW, LoadStallD, BPPredWrongM,
|
||||
input logic [3:0] InstrClassM,
|
||||
input logic PrivilegedM,
|
||||
@ -119,6 +120,8 @@ module privileged (
|
||||
|
||||
assign BreakpointFaultM = ebreakM; // could have other causes too
|
||||
assign EcallFaultM = ecallM;
|
||||
assign ITLBFlushF = sfencevmaM;
|
||||
assign DTLBFlushM = sfencevmaM;
|
||||
// *** Page faults now driven by page table walker. Might need to make the
|
||||
// below signals ORs of a walker fault and a tlb fault if both of those come in
|
||||
// assign InstrPageFaultM = 0;
|
||||
|
@ -65,7 +65,7 @@ module wallypipelinedhart (
|
||||
logic [`XLEN-1:0] SrcAE, SrcBE;
|
||||
logic [`XLEN-1:0] SrcAM;
|
||||
logic [2:0] Funct3E;
|
||||
// logic [31:0] InstrF;
|
||||
// logic [31:0] InstrF;
|
||||
logic [31:0] InstrD, InstrM;
|
||||
logic [`XLEN-1:0] PCE, PCM, PCLinkE, PCLinkW;
|
||||
logic [`XLEN-1:0] PCTargetE;
|
||||
@ -84,11 +84,11 @@ module wallypipelinedhart (
|
||||
logic PCSrcE;
|
||||
logic CSRWritePendingDEM;
|
||||
logic LoadStallD, MulDivStallD, CSRRdStallD;
|
||||
logic DivDoneE;
|
||||
logic DivBusyE;
|
||||
logic DivDoneE;
|
||||
logic DivBusyE;
|
||||
logic DivDoneW;
|
||||
logic [4:0] SetFflagsM;
|
||||
logic [2:0] FRM_REGW;
|
||||
logic DivDoneW;
|
||||
logic FloatRegWriteW;
|
||||
logic SquashSCW;
|
||||
logic [31:0] FSROutW;
|
||||
@ -98,6 +98,7 @@ module wallypipelinedhart (
|
||||
|
||||
// memory management unit signals
|
||||
logic ITLBWriteF, DTLBWriteM;
|
||||
logic ITLBFlushF, DTLBFlushM;
|
||||
logic ITLBMissF, ITLBHitF;
|
||||
logic DTLBMissM, DTLBHitM;
|
||||
logic [`XLEN-1:0] SATP_REGW;
|
||||
@ -137,15 +138,15 @@ module wallypipelinedhart (
|
||||
.Funct7M(InstrM[31:25]),
|
||||
.*);
|
||||
|
||||
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
|
||||
/*ahblite ebu(
|
||||
.InstrReadF(1'b0),
|
||||
.InstrRData(), // hook up InstrF later
|
||||
.MemSizeM(Funct3M[1:0]), .UnsignedLoadM(Funct3M[2]),
|
||||
.*); */
|
||||
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
|
||||
/*ahblite ebu(
|
||||
.InstrReadF(1'b0),
|
||||
.InstrRData(), // hook up InstrF later
|
||||
.MemSizeM(Funct3M[1:0]), .UnsignedLoadM(Funct3M[2]),
|
||||
.*); */
|
||||
|
||||
|
||||
muldiv mdu(.*); // multiply and divide unit
|
||||
|
@ -310,6 +310,7 @@ module testbench_busybear();
|
||||
`define CSRM dut.hart.priv.csr.genblk1.csrm
|
||||
`define CSRS dut.hart.priv.csr.genblk1.csrs.genblk1
|
||||
|
||||
/*
|
||||
//`CHECK_CSR(FCSR)
|
||||
`CHECK_CSR2(MCAUSE, `CSRM)
|
||||
`CHECK_CSR(MCOUNTEREN)
|
||||
@ -335,6 +336,7 @@ module testbench_busybear();
|
||||
`CHECK_CSR(SSTATUS)
|
||||
`CHECK_CSR2(STVAL, `CSRS)
|
||||
`CHECK_CSR(STVEC)
|
||||
*/
|
||||
|
||||
initial begin //this is temporary until the bug can be fixed!!!
|
||||
#11130100;
|
||||
@ -442,6 +444,10 @@ module testbench_busybear();
|
||||
(instrs <= 100000 && instrs % 10000 == 0) || (instrs <= 1000000 && instrs % 100000 == 0)) begin
|
||||
$display("loaded %0d instructions", instrs);
|
||||
end
|
||||
// TEMP
|
||||
if (instrs >= 800010) begin
|
||||
$stop;
|
||||
end
|
||||
instrs += 1;
|
||||
// are we at a branch/jump?
|
||||
casex (lastCheckInstrD[31:0])
|
||||
|
@ -367,7 +367,7 @@ string tests32i[] = {
|
||||
// if (`F_SUPPORTED) tests = {tests64f, tests};
|
||||
// if (`D_SUPPORTED) tests = {tests64d, tests};
|
||||
if (`A_SUPPORTED) tests = {tests, tests64a};
|
||||
if (`MEM_VIRTMEM) tests = {tests, tests64mmu};
|
||||
//if (`MEM_VIRTMEM) tests = {tests, tests64mmu};
|
||||
end
|
||||
// tests = {tests64a, tests};
|
||||
// tests = {tests, tests64p};
|
||||
|
Loading…
Reference in New Issue
Block a user