Split the ReadDataW bus into two parts in preparation for the data cache. On the AHB side it is now HRDATAW and on the CPU to data cache side it is ReadDataW. lsu.sv now handles the connection between the two.

Also reorganized the inputs and outputs of lsu and pagetablewalker into connects between CPU, pagetablewalker, and AHB.
Finally add DisableTranslation to TLB as teh pagetablewalker will need to force no translation when active regardless of the state of SATP.
With Kip.
This commit is contained in:
Ross Thompson 2021-06-23 16:43:22 -05:00
parent f74ecbb81e
commit 9b8bcb8e57
8 changed files with 96 additions and 55 deletions

View File

@ -62,7 +62,7 @@ module ahblite (
// Signals to PMA checker (metadata of proposed access) // Signals to PMA checker (metadata of proposed access)
output logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, output logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM,
// Return from bus // Return from bus
output logic [`XLEN-1:0] ReadDataW, output logic [`XLEN-1:0] HRDATAW,
// AHB-Lite external signals // AHB-Lite external signals
input logic [`AHBW-1:0] HRDATA, input logic [`AHBW-1:0] HRDATA,
input logic HREADY, HRESP, input logic HREADY, HRESP,
@ -87,7 +87,7 @@ module ahblite (
logic GrantData; logic GrantData;
logic [31:0] AccessAddress; logic [31:0] AccessAddress;
logic [2:0] AccessSize, PTESize, ISize; logic [2:0] AccessSize, PTESize, ISize;
logic [`AHBW-1:0] HRDATAMasked, ReadDataM, CapturedData, ReadDataWnext, WriteData; logic [`AHBW-1:0] HRDATAMasked, ReadDataM, CapturedHRDATAMasked, HRDATANext, WriteData;
logic IReady, DReady; logic IReady, DReady;
logic CaptureDataM,CapturedDataAvailable; logic CaptureDataM,CapturedDataAvailable;
@ -195,14 +195,13 @@ module ahblite (
assign MemAckW = (BusState == MEMREAD) && (NextBusState != MEMREAD) || (BusState == MEMWRITE) && (NextBusState != MEMWRITE) || assign MemAckW = (BusState == MEMREAD) && (NextBusState != MEMREAD) || (BusState == MEMWRITE) && (NextBusState != MEMWRITE) ||
((BusState == ATOMICREAD) && (NextBusState != ATOMICREAD)) || ((BusState == ATOMICWRITE) && (NextBusState != ATOMICWRITE)); ((BusState == ATOMICREAD) && (NextBusState != ATOMICREAD)) || ((BusState == ATOMICWRITE) && (NextBusState != ATOMICWRITE));
assign MMUReadPTE = HRDATA; assign MMUReadPTE = HRDATA;
assign ReadDataM = HRDATAMasked; // changed from W to M dh 2/7/2021
// Carefully decide when to update ReadDataW // Carefully decide when to update ReadDataW
// ReadDataMstored holds the most recent memory read. // ReadDataMstored holds the most recent memory read.
// We need to wait until the pipeline actually advances before we can update the contents of ReadDataW // We need to wait until the pipeline actually advances before we can update the contents of ReadDataW
// (or else the W stage will accidentally get the M stage's data when the pipeline does advance). // (or else the W stage will accidentally get the M stage's data when the pipeline does advance).
assign CaptureDataM = ((BusState == MEMREAD) && (NextBusState != MEMREAD)) || assign CaptureDataM = ((BusState == MEMREAD) && (NextBusState != MEMREAD)) ||
((BusState == ATOMICREAD) && (NextBusState != ATOMICREAD)); ((BusState == ATOMICREAD) && (NextBusState != ATOMICREAD));
flopenr #(`XLEN) ReadDataNewWReg(clk, reset, CaptureDataM, ReadDataM, CapturedData); flopenr #(`XLEN) ReadDataNewWReg(clk, reset, CaptureDataM, HRDATAMasked, CapturedHRDATAMasked);
always @(posedge HCLK, negedge HRESETn) always @(posedge HCLK, negedge HRESETn)
if (~HRESETn) if (~HRESETn)
@ -211,11 +210,11 @@ module ahblite (
CapturedDataAvailable <= #1 (StallW) ? (CaptureDataM | CapturedDataAvailable) : 1'b0; CapturedDataAvailable <= #1 (StallW) ? (CaptureDataM | CapturedDataAvailable) : 1'b0;
always_comb always_comb
casez({StallW && (BusState != ATOMICREAD),CapturedDataAvailable}) casez({StallW && (BusState != ATOMICREAD),CapturedDataAvailable})
2'b00: ReadDataWnext = ReadDataM; 2'b00: HRDATANext = HRDATAMasked;
2'b01: ReadDataWnext = CapturedData; 2'b01: HRDATANext = CapturedHRDATAMasked;
2'b1?: ReadDataWnext = ReadDataW; 2'b1?: HRDATANext = HRDATAW;
endcase endcase
flopr #(`XLEN) ReadDataOldWReg(clk, reset, ReadDataWnext, ReadDataW); flopr #(`XLEN) ReadDataOldWReg(clk, reset, HRDATANext, HRDATAW);
// Extract and sign-extend subwords if necessary // Extract and sign-extend subwords if necessary
subwordread swr(.*); subwordread swr(.*);
@ -226,7 +225,7 @@ module ahblite (
logic [`XLEN-1:0] AMOResult; logic [`XLEN-1:0] AMOResult;
// amoalu amoalu(.a(HRDATA), .b(WriteDataM), .funct(Funct7M), .width(MemSizeM), // amoalu amoalu(.a(HRDATA), .b(WriteDataM), .funct(Funct7M), .width(MemSizeM),
// .result(AMOResult)); // .result(AMOResult));
amoalu amoalu(.srca(ReadDataW), .srcb(WriteDataM), .funct(Funct7M), .width(MemSizeM), amoalu amoalu(.srca(HRDATAW), .srcb(WriteDataM), .funct(Funct7M), .width(MemSizeM),
.result(AMOResult)); .result(AMOResult));
mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, AtomicMaskedM[1], WriteData); mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, AtomicMaskedM[1], WriteData);
end else end else

View File

@ -41,16 +41,19 @@ module ieu (
output logic [2:0] Funct3E, output logic [2:0] Funct3E,
output logic [`XLEN-1:0] SrcAE, SrcBE, output logic [`XLEN-1:0] SrcAE, SrcBE,
// Memory stage interface // Memory stage interface
input logic DataMisalignedM, input logic DataMisalignedM, // from LSU
input logic DataAccessFaultM, input logic SquashSCW, // from LSU
input logic SquashSCW, output logic [1:0] MemRWM, // read/write control goes to LSU
input logic FWriteIntM, output logic [1:0] AtomicM, // atomic control goes to LSU
input logic [`XLEN-1:0] FWriteDataM, output logic [`XLEN-1:0] MemAdrM, WriteDataM, // Address and write data to LSU
output logic [1:0] MemRWM,
output logic [1:0] AtomicM, output logic [2:0] Funct3M, // size and signedness to LSU
output logic [`XLEN-1:0] MemAdrM, WriteDataM,
output logic [`XLEN-1:0] SrcAM,
output logic [2:0] Funct3M, input logic FWriteIntM, // from FPU
input logic [`XLEN-1:0] FWriteDataM, // from FPU
output logic [`XLEN-1:0] SrcAM, // to privilege and fpu
// Writeback stage // Writeback stage
input logic [`XLEN-1:0] CSRReadValW, ReadDataW, MulDivResultW, input logic [`XLEN-1:0] CSRReadValW, ReadDataW, MulDivResultW,
input logic FWriteIntW, input logic FWriteIntW,

View File

@ -122,6 +122,7 @@ module ifu (
.AtomicAccessM(1'b0), .WriteAccessM(1'b0), .ReadAccessM(1'b0), // *** is this the right way force these bits constant? should they be someething else? .AtomicAccessM(1'b0), .WriteAccessM(1'b0), .ReadAccessM(1'b0), // *** is this the right way force these bits constant? should they be someething else?
.SquashBusAccess(ISquashBusAccessF), .HSELRegions(IHSELRegionsF), .SquashBusAccess(ISquashBusAccessF), .HSELRegions(IHSELRegionsF),
.DisableTranslation(1'b0),
.*); .*);

View File

@ -33,37 +33,53 @@ module lsu (
input logic StallM, FlushM, StallW, FlushW, input logic StallM, FlushM, StallW, FlushW,
//output logic DataStall, //output logic DataStall,
// Memory Stage // Memory Stage
// connected to cpu (controls)
input logic [1:0] MemRWM, input logic [1:0] MemRWM,
input logic [`XLEN-1:0] MemAdrM,
input logic [2:0] Funct3M, input logic [2:0] Funct3M,
//input logic [`XLEN-1:0] ReadDataW,
input logic [`XLEN-1:0] WriteDataM,
input logic [1:0] AtomicM, input logic [1:0] AtomicM,
input logic CommitM, output logic CommittedM,
output logic [`PA_BITS-1:0] MemPAdrM,
output logic MemReadM, MemWriteM,
output logic [1:0] AtomicMaskedM,
output logic DataMisalignedM,
output logic CommittedM,
// Writeback Stage
input logic MemAckW,
input logic [`XLEN-1:0] ReadDataW,
output logic SquashSCW, output logic SquashSCW,
output logic DataMisalignedM,
input logic DisableTranslation,
// address and write data
input logic [`XLEN-1:0] MemAdrM,
input logic [`XLEN-1:0] WriteDataM,
output logic [`XLEN-1:0] ReadDataW, // from ahb
// cpu privilege
input logic [1:0] PrivilegeModeW,
input logic DTLBFlushM,
// faults // faults
input logic NonBusTrapM, input logic NonBusTrapM,
input logic DataAccessFaultM,
output logic DTLBLoadPageFaultM, DTLBStorePageFaultM, output logic DTLBLoadPageFaultM, DTLBStorePageFaultM,
output logic LoadMisalignedFaultM, LoadAccessFaultM, output logic LoadMisalignedFaultM, LoadAccessFaultM,
// cpu hazard unit (trap)
output logic StoreMisalignedFaultM, StoreAccessFaultM, output logic StoreMisalignedFaultM, StoreAccessFaultM,
// connect to ahb
input logic CommitM, // should this be generated in the abh interface?
output logic [`PA_BITS-1:0] MemPAdrM, // to ahb
output logic MemReadM, MemWriteM,
output logic [1:0] AtomicMaskedM,
input logic MemAckW, // from ahb
input logic [`XLEN-1:0] HRDATAW, // from ahb
// mmu management // mmu management
input logic [1:0] PrivilegeModeW,
// 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, input logic [`XLEN-1:0] SATP_REGW, // from csr
input logic STATUS_MXR, STATUS_SUM, input logic STATUS_MXR, STATUS_SUM, // from csr
input logic DTLBWriteM, DTLBFlushM, input logic DTLBWriteM,
output logic DTLBMissM, DTLBHitM, output logic DTLBMissM,
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.
@ -94,7 +110,11 @@ module lsu (
logic PMPInstrAccessFaultF, PMAInstrAccessFaultF; // *** these are just so that the mmu has somewhere to put these outputs since they aren't used in dmem logic PMPInstrAccessFaultF, PMAInstrAccessFaultF; // *** these are just so that the mmu has somewhere to put these outputs since they aren't used in dmem
// *** if you're allowed to parameterize outputs/ inputs existence, these are an easy delete. // *** if you're allowed to parameterize outputs/ inputs existence, these are an easy delete.
// for time being until we have a dcache the AHB Lite read bus HRDATAW will be connected to the
// CPU's read data input ReadDataW.
assign ReadDataW = HRDATAW;
mmu #(.ENTRY_BITS(`DTLB_ENTRY_BITS), .IMMU(0)) dmmu(.TLBAccessType(MemRWM), .VirtualAddress(MemAdrM), .Size(Funct3M[1:0]), mmu #(.ENTRY_BITS(`DTLB_ENTRY_BITS), .IMMU(0)) dmmu(.TLBAccessType(MemRWM), .VirtualAddress(MemAdrM), .Size(Funct3M[1:0]),
.PTEWriteVal(PageTableEntryM), .PageTypeWriteVal(PageTypeM), .PTEWriteVal(PageTableEntryM), .PageTypeWriteVal(PageTypeM),
.TLBWrite(DTLBWriteM), .TLBFlush(DTLBFlushM), .TLBWrite(DTLBWriteM), .TLBFlush(DTLBFlushM),
@ -135,9 +155,9 @@ module lsu (
// Determine if address is valid // Determine if address is valid
assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1]; assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1];
assign LoadAccessFaultM = DataAccessFaultM & MemRWM[1]; assign LoadAccessFaultM = MemRWM[1];
assign StoreMisalignedFaultM = DataMisalignedM & MemRWM[0]; assign StoreMisalignedFaultM = DataMisalignedM & MemRWM[0];
assign StoreAccessFaultM = DataAccessFaultM & MemRWM[0]; assign StoreAccessFaultM = MemRWM[0];
// Handle atomic load reserved / store conditional // Handle atomic load reserved / store conditional
generate generate

View File

@ -44,6 +44,7 @@ module mmu #(parameter ENTRY_BITS = 3,
// x1 - TLB is accessed for a write // x1 - TLB is accessed for a write
// 11 - TLB is accessed for both read and write // 11 - TLB is accessed for both read and write
input logic [1:0] TLBAccessType, input logic [1:0] TLBAccessType,
input logic DisableTranslation,
// Virtual address input // Virtual address input
input logic [`XLEN-1:0] VirtualAddress, input logic [`XLEN-1:0] VirtualAddress,
@ -96,4 +97,4 @@ module mmu #(parameter ENTRY_BITS = 3,
assign SquashBusAccess = PMASquashBusAccess || PMPSquashBusAccess; assign SquashBusAccess = PMASquashBusAccess || PMPSquashBusAccess;
endmodule endmodule

View File

@ -49,13 +49,19 @@ module pagetablewalker (
output logic [1:0] PageTypeF, PageTypeM, output logic [1:0] PageTypeF, PageTypeM,
output logic ITLBWriteF, DTLBWriteM, output logic ITLBWriteF, DTLBWriteM,
// Signals from ahblite (PTEs from memory)
// *** modify to send to LSU
input logic [`XLEN-1:0] MMUReadPTE, input logic [`XLEN-1:0] MMUReadPTE,
input logic MMUReady, input logic MMUReady,
// Signals to ahblite (memory addresses to access) // *** modify to send to LSU
output logic [`XLEN-1:0] MMUPAdr, output logic [`XLEN-1:0] MMUPAdr,
output logic MMUTranslate, output logic MMUTranslate, // *** rename to HPTWReq
// Stall signal // Stall signal
output logic MMUStall, output logic MMUStall,

View File

@ -65,6 +65,7 @@ module tlb #(parameter ENTRY_BITS = 3,
// x1 - TLB is accessed for a write // x1 - TLB is accessed for a write
// 11 - TLB is accessed for both read and write // 11 - TLB is accessed for both read and write
input logic [1:0] TLBAccessType, input logic [1:0] TLBAccessType,
input logic DisableTranslation,
// Virtual address input // Virtual address input
input logic [`XLEN-1:0] VirtualAddress, input logic [`XLEN-1:0] VirtualAddress,

View File

@ -153,6 +153,8 @@ module wallypipelinedhart (
logic[`XLEN-1:0] WriteDatatmpM; logic[`XLEN-1:0] WriteDatatmpM;
logic [4:0] InstrClassM; logic [4:0] InstrClassM;
logic [`XLEN-1:0] HRDATAW;
ifu ifu(.InstrInF(InstrRData), .*); // instruction fetch unit: PC, branch prediction, instruction cache ifu ifu(.InstrInF(InstrRData), .*); // instruction fetch unit: PC, branch prediction, instruction cache
@ -161,15 +163,6 @@ module wallypipelinedhart (
mux2 #(`XLEN) OutputInput2mux(WriteDataM, FWriteDataM, FMemRWM[0], WriteDatatmpM); mux2 #(`XLEN) OutputInput2mux(WriteDataM, FWriteDataM, FMemRWM[0], WriteDatatmpM);
lsu lsu(.MemRWM(MemRWM|FMemRWM), .WriteDataM(WriteDatatmpM),.*); // data cache unit
ahblite ebu(
//.InstrReadF(1'b0),
//.InstrRData(InstrF), // hook up InstrF later
.WriteDataM(WriteDatatmpM),
.MemSizeM(Funct3M[1:0]), .UnsignedLoadM(Funct3M[2]),
.Funct7M(InstrM[31:25]),
.*);
pagetablewalker pagetablewalker(.*); // can send addresses to ahblite, send out pagetablestall pagetablewalker pagetablewalker(.*); // can send addresses to ahblite, send out pagetablestall
// *** can connect to hazard unit // *** can connect to hazard unit
@ -181,6 +174,23 @@ module wallypipelinedhart (
.MemSizeM(Funct3M[1:0]), .UnsignedLoadM(Funct3M[2]), .MemSizeM(Funct3M[1:0]), .UnsignedLoadM(Funct3M[2]),
.*); */ .*); */
// arbiter between IEU and pagetablewalker
lsu lsu(.MemRWM(MemRWM|FMemRWM), .WriteDataM(WriteDatatmpM),.*,
.ReadDataW(ReadDataW),
.DisableTranslation(1'b0) // *** will connect to page table walker arbiter
); // data cache unit
ahblite ebu(
//.InstrReadF(1'b0),
//.InstrRData(InstrF), // hook up InstrF later
.WriteDataM(WriteDatatmpM),
.MemSizeM(Funct3M[1:0]), .UnsignedLoadM(Funct3M[2]),
.Funct7M(InstrM[31:25]),
.HRDATAW(HRDATAW),
.*);
muldiv mdu(.*); // multiply and divide unit muldiv mdu(.*); // multiply and divide unit