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 // *** this is also the place to squash if the cache is hit
assign MemReadM = MemRWM[1] & ~DataMisalignedM; assign MemReadM = MemRWM[1] & ~DataMisalignedM;
assign MemWriteM = MemRWM[0] & ~DataMisalignedM; assign MemWriteM = MemRWM[0] & ~DataMisalignedM;
// assign MemRWAlignedM = MemRWM & {2{~DataMisalignedM}};
// Determine if address is valid // Determine if address is valid
assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1]; assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1];

View File

@ -72,8 +72,6 @@ module ahblite (
logic [`AHBW-1:0] HRDATAMasked, ReadDataM, ReadDataPreW; logic [`AHBW-1:0] HRDATAMasked, ReadDataM, ReadDataPreW;
logic IReady, DReady; logic IReady, DReady;
logic CaptureDataM; 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 HCLK = clk;
assign HRESETn = ~reset; assign HRESETn = ~reset;
@ -114,7 +112,6 @@ module ahblite (
// stall signals // stall signals
assign #2 DataStall = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || (NextBusState == INSTRREADMEMPENDING); assign #2 DataStall = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || (NextBusState == INSTRREADMEMPENDING);
assign #1 InstrStall = (NextBusState == INSTRREAD); assign #1 InstrStall = (NextBusState == INSTRREAD);
// assign InstrUpdate = (BusState == INSTRREADMEMPENDING) && (NextBusState != INSTRREADMEMPENDING);
// DH 2/20/22: A cyclic path presently exists // DH 2/20/22: A cyclic path presently exists
// HREADY->NextBusState->GrantData->HSIZE->HSELUART->HREADY // HREADY->NextBusState->GrantData->HSIZE->HSELUART->HREADY
@ -125,6 +122,7 @@ module ahblite (
// bus outputs // bus outputs
assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE); assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE);
assign #1 HADDR = (GrantData) ? MemPAdrM[31:0] : InstrPAdrF[31:0]; 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 #1 HSIZE = GrantData ? {1'b0, MemSizeM} : ISize;
assign HBURST = 3'b000; // Single burst only supported; consider generalizing for cache fillsfH assign HBURST = 3'b000; // Single burst only supported; consider generalizing for cache fillsfH
assign HPROT = 4'b0011; // not used; see Section 3.7 assign HPROT = 4'b0011; // not used; see Section 3.7
@ -141,104 +139,12 @@ module ahblite (
// Route signals to Instruction and Data Caches // Route signals to Instruction and Data Caches
// *** assumes AHBW = XLEN // *** assumes AHBW = XLEN
// fix harris 2/24/21 to read all WLEN bits directly for instruction
assign InstrRData = HRDATA; assign InstrRData = HRDATA;
assign ReadDataM = HRDATAMasked; // changed from W to M dh 2/7/2021 assign ReadDataM = HRDATAMasked; // changed from W to M dh 2/7/2021
assign CaptureDataM = (BusState == MEMREAD) && (NextBusState != MEMREAD); 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) 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); 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(.*); subwordread swr(.*);
endmodule endmodule

View File

@ -27,13 +27,10 @@
module hazard( module hazard(
// Detect hazards // 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 PCSrcE, CSRWritePendingDEM, RetM, TrapM,
input logic LoadStallD, MulDivStallD, input logic LoadStallD, MulDivStallD,
input logic InstrStall, DataStall, input logic InstrStall, DataStall,
// Stall outputs // Stall & flush outputs
output logic StallF, StallD, StallE, StallM, StallW, output logic StallF, StallD, StallE, StallM, StallW,
output logic FlushD, FlushE, FlushM, FlushW output logic FlushD, FlushE, FlushM, FlushW
); );
@ -56,15 +53,10 @@ module hazard(
assign BranchFlushDE = PCSrcE | RetM | TrapM; assign BranchFlushDE = PCSrcE | RetM | TrapM;
// changed 2/22/21 harris to turn off stallF when RetM or TrapM assign StallFCause = CSRWritePendingDEM & ~(BranchFlushDE);
// changed 2/23/21 harris to BranchFlushDEM to solve bug in ECALL about JAL being ignored assign StallDCause = LoadStallD | MulDivStallD; // stall in decode if instruction is a load/mul dependent on previous
// 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 StallECause = 0; assign StallECause = 0;
assign StallMCause = 0; // sDataStall; // not yet used*** assign StallMCause = 0;
assign StallWCause = DataStall | InstrStall; assign StallWCause = DataStall | InstrStall;
// Each stage stalls if the next stage is stalled or there is a cause to stall this stage. // 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 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); 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 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); flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF);
// pcadder // pcadder