Clean up bus interface code

This commit is contained in:
David Harris 2021-02-26 01:03:47 -05:00
parent 24f767a404
commit b16846bddb
4 changed files with 6 additions and 114 deletions

View File

@ -65,7 +65,6 @@ module dmem (
// *** this is also the place to squash if the cache is hit
assign MemReadM = MemRWM[1] & ~DataMisalignedM;
assign MemWriteM = MemRWM[0] & ~DataMisalignedM;
// assign MemRWAlignedM = MemRWM & {2{~DataMisalignedM}};
// Determine if address is valid
assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1];

View File

@ -72,8 +72,6 @@ module ahblite (
logic [`AHBW-1:0] HRDATAMasked, ReadDataM, ReadDataPreW;
logic IReady, DReady;
logic CaptureDataM;
// logic [3:0] HSIZED; // size delayed by one cycle for reads
// logic [2:0] HADDRD; // address delayed for subword reads
assign HCLK = clk;
assign HRESETn = ~reset;
@ -114,8 +112,7 @@ module ahblite (
// stall signals
assign #2 DataStall = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || (NextBusState == INSTRREADMEMPENDING);
assign #1 InstrStall = (NextBusState == INSTRREAD);
// assign InstrUpdate = (BusState == INSTRREADMEMPENDING) && (NextBusState != INSTRREADMEMPENDING);
// DH 2/20/22: A cyclic path presently exists
// HREADY->NextBusState->GrantData->HSIZE->HSELUART->HREADY
// This is because the peripherals assert HREADY on the same cycle
@ -125,6 +122,7 @@ module ahblite (
// bus outputs
assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE);
assign #1 HADDR = (GrantData) ? MemPAdrM[31:0] : InstrPAdrF[31:0];
assign ISize = 3'b010; // 32 bit instructions for now; later improve for filling cache with full width; ignored on reads anyway
assign #1 HSIZE = GrantData ? {1'b0, MemSizeM} : ISize;
assign HBURST = 3'b000; // Single burst only supported; consider generalizing for cache fillsfH
assign HPROT = 4'b0011; // not used; see Section 3.7
@ -141,104 +139,12 @@ module ahblite (
// Route signals to Instruction and Data Caches
// *** assumes AHBW = XLEN
// fix harris 2/24/21 to read all WLEN bits directly for instruction
assign InstrRData = HRDATA;
assign ReadDataM = HRDATAMasked; // changed from W to M dh 2/7/2021
assign CaptureDataM = (BusState == MEMREAD) && (NextBusState != MEMREAD);
flopenr #(`XLEN) ReadDataPreWReg(clk, reset, CaptureDataM, ReadDataM, ReadDataPreW); // *** this may break when there is no instruction read after data read
flopenr #(`XLEN) ReadDataWReg(clk, reset, ~StallW, ReadDataPreW, ReadDataW);
/*
typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD} statetype;
statetype AdrState, DataState, NextAdrState; // what is happening in the first and second phases of the bus
always_ff @(posedge HCLK, negedge HRESETn)
if (~HRESETn) begin
AdrState <= IDLE; DataState <= IDLE;
HWDATA <= 0; // unnecessary but avoids x at startup
HSIZED <= 0;
HADDRD <= 0;
HWRITED <= 0;
end else begin
if (HREADY || (DataState == IDLE)) begin // only advance bus state if bus is idle or previous transaction returns ready
DataState <= AdrState;
AdrState <= NextAdrState;
if (HWRITE) HWDATA <= WriteDataM;
HSIZED <= {UnsignedLoadM, HSIZE};
HADDRD <= HADDR[2:0];
HWRITED <= HWRITE;
end
end
always_comb
if (MemReadM) NextAdrState = MEMREAD;
else if (MemWriteM) NextAdrState = MEMWRITE;
else if (InstrReadF) NextAdrState = INSTRREAD;
// else if (1) NextAdrState = INSTRREAD; // dm 2/9/2021 testing
else NextAdrState = IDLE;
// Generate acknowledges based on bus state and ready
assign MemAckW = (AdrState == MEMREAD || AdrState == MEMWRITE) && HREADY;
assign InstrAckD = (AdrState == INSTRREAD) && HREADY;
// State machines for stalls (probably can merge with FSM above***)
// Idle, DataBusy, InstrBusy. Stall while in busystate add suffixes
logic MemState, NextMemState, InstrState, NextInstrState;
flopr #(1) msreg(HCLK, ~HRESETn, NextMemState, MemState);
flopr #(1) isreg(HCLK, ~HRESETn, NextInstrState, InstrState);
/* always_ff @(posedge HCLK, negedge HRESETn)
if (~HRESETn) MemState <= 0;
else MemState <= NextMemState;
assign NextMemState = (MemState == 0 && InstrState == 0 && (MemReadM || MemWriteM)) || (MemState == 1 && ~MemAckW);
assign DataStall = NextMemState;
/* always_ff @(posedge HCLK, negedge HRESETn)
if (~HRESETn) InstrState <= 0;
else InstrState <= NextInstrState;
assign NextInstrState = (InstrState == 0 && MemState == 0 && (~MemReadM && ~MemWriteM && InstrReadF)) ||
(InstrState == 1 && ~InstrAckD) ||
(InstrState == 1 && ResolveBranchD); // dh 2/8/2021 fixing; delete this later
/* assign NextInstrState = (InstrState == 0 && MemState == 0 && (~MemReadM && ~MemWriteM)) ||
(InstrState == 1 && ~InstrAckD); // *** removed InstrReadF above dh 2/9/20
assign InstrStall = NextInstrState | MemState | NextMemState; // *** check this, explain better
// temporarily turn off stalls and check it works
//assign DataStall = 0;
//assign InstrStall = 0;
assign DReady = HREADY & GrantData; // ***unused?
assign IReady = HREADY & InstrReadF & ~GrantData; // maybe unused?***
*/
// Choose ISize based on XLen
generate
//if (`AHBW == 32) assign ISize = 3'b010; // 32-bit transfers
//else assign ISize = 3'b011; // 64-bit transfers
assign ISize = 3'b010; // 32 bit instructions for now; later improve for filling cache with full width
endgenerate
/*
// drive bus outputs
assign HADDR = GrantData ? MemPAdrM[31:0] : InstrPAdrF[31:0];
//assign HWDATA = WriteDataW;
//flop #(`XLEN) wdreg(HCLK, DWDataM, HWDATA); // delay HWDATA by 1 cycle per spec; *** assumes AHBW = XLEN
assign HWRITE = MemWriteM;
assign HSIZE = GrantData ? {1'b0, MemSizeM} : ISize;
assign HBURST = 3'b000; // Single burst only supported; consider generalizing for cache fillsfHPROT
assign HPROT = 4'b0011; // not used; see Section 3.7
assign HTRANS = InstrReadF | MemReadM | MemWriteM ? 2'b10 : 2'b00; // NONSEQ if reading or writing, IDLE otherwise
assign HMASTLOCK = 0; // no locking supported
*/
// stalls
// Stall MEM stage if data is being accessed and bus isn't yet ready
//assign DataStall = GrantData & ~HREADY;
// Stall Fetch stage if instruction should be read but reading data or bus isn't ready
//assign InstrStall = IReadF & (GrantData | ~HREADY);
// *** consider adding memory access faults based on HRESP being high
// InstrAccessFaultF, DataAccessFaultM,
subwordread swr(.*);
endmodule

View File

@ -27,13 +27,10 @@
module hazard(
// Detect hazards
// input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW,
// input logic MemReadE,
// input logic RegWriteM, RegWriteW,
input logic PCSrcE, CSRWritePendingDEM, RetM, TrapM,
input logic LoadStallD, MulDivStallD,
input logic InstrStall, DataStall,
// Stall outputs
// Stall & flush outputs
output logic StallF, StallD, StallE, StallM, StallW,
output logic FlushD, FlushE, FlushM, FlushW
);
@ -56,15 +53,10 @@ module hazard(
assign BranchFlushDE = PCSrcE | RetM | TrapM;
// changed 2/22/21 harris to turn off stallF when RetM or TrapM
// changed 2/23/21 harris to BranchFlushDEM to solve bug in ECALL about JAL being ignored
// assign StallFCause = /*InstrStall | */ CSRWritePendingDEM; // stall at fetch if unable to get the instruction,
// assign StallFCause = /*InstrStall | */ CSRWritePendingDEM & ~(RetM | TrapM); // stall at fetch if unable to get the instruction,
assign StallFCause = /*InstrStall | */ CSRWritePendingDEM & ~(BranchFlushDE); // stall at fetch if unable to get the instruction,
// or if a CSR will be written and may change system behavior
assign StallDCause = LoadStallD | MulDivStallD; // stall in decode if instruction is a load dependent on previous
assign StallFCause = CSRWritePendingDEM & ~(BranchFlushDE);
assign StallDCause = LoadStallD | MulDivStallD; // stall in decode if instruction is a load/mul dependent on previous
assign StallECause = 0;
assign StallMCause = 0; // sDataStall; // not yet used***
assign StallMCause = 0;
assign StallWCause = DataStall | InstrStall;
// Each stage stalls if the next stage is stalled or there is a cause to stall this stage.

View File

@ -74,14 +74,9 @@ module ifu (
assign PrivilegedChangePCM = RetM | TrapM;
//assign StallExceptResolveBranchesF = StallF & ~(PCSrcE | PrivilegedChangePCM);
// dh 2/8/2022 keep in instruction fetch stall mode when taking branch
//flopr #(1) rbreg(clk, reset, (PCSrcE | PrivilegedChangePCM), ResolveBranchD);
mux3 #(`XLEN) pcmux(PCPlus2or4F, PCTargetE, PrivilegedNextPCM, {PrivilegedChangePCM, PCSrcE}, UnalignedPCNextF);
assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
// flopenl #(`XLEN) pcreg(clk, reset, ~StallExceptResolveBranchesF, PCNextF, `RESET_VECTOR, PCF);
flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF);
// pcadder