forked from Github_Repos/cvw
Clean up bus interface code
This commit is contained in:
parent
24f767a404
commit
b16846bddb
@ -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];
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user