diff --git a/pipelined/src/uncore/ram_ahb.sv b/pipelined/src/uncore/ram_ahb.sv index 37e702d9..7fbcd1ca 100644 --- a/pipelined/src/uncore/ram_ahb.sv +++ b/pipelined/src/uncore/ram_ahb.sv @@ -51,10 +51,17 @@ module ram_ahb #(parameter BASE=0, RANGE = 65535) ( logic initTrans; logic memwrite, memwriteD, memread; logic nextHREADYRam; + logic HREADYRam_TEMP; // *** eventurally remove + logic [`XLEN-1:0] HREADRam_TEMP; + logic DelayReady; + + logic [7:0] CycleThreshold; + assign CycleThreshold = 3; + // a new AHB transactions starts when HTRANS requests a transaction, // the peripheral is selected, and the previous transaction is completing - assign initTrans = HREADY & HSELRam & HTRANS[1]; + assign initTrans = HREADY & HSELRam & HTRANS[1] ; assign memwrite = initTrans & HWRITE; assign memread = initTrans & ~HWRITE; @@ -62,8 +69,12 @@ module ram_ahb #(parameter BASE=0, RANGE = 65535) ( flopenr #(`PA_BITS) haddrreg(HCLK, ~HRESETn, HREADY, HADDR, HADDRD); // Stall on a read after a write because the RAM can't take both adddresses on the same cycle - assign nextHREADYRam = ~(memwriteD & memread); - flopr #(1) readyreg(HCLK, ~HRESETn, nextHREADYRam, HREADYRam); + assign nextHREADYRam = (~(memwriteD & memread)) & ~DelayReady; + flopr #(1) readyreg(HCLK, ~HRESETn, nextHREADYRam, HREADYRam_TEMP); + + // *** bug extra delay for testing. + //flopr #(1) readyreg2(HCLK, ~HRESETn, HREADYRam_TEMP, HREADYRam); + assign HREADYRam = HREADYRam_TEMP; assign HRESPRam = 0; // OK // On writes or during a wait state, use address delayed by one cycle to sync RamAddr with HWDATA or hold stalled address @@ -71,6 +82,43 @@ module ram_ahb #(parameter BASE=0, RANGE = 65535) ( // single-ported RAM bram1p1rw #(`XLEN/8, 8, ADDR_WIDTH, `FPGA) - memory(.clk(HCLK), .we(memwriteD), .bwe(HWSTRB), .addr(RamAddr[ADDR_WIDTH+OFFSET-1:OFFSET]), .dout(HREADRam), .din(HWDATA)); + memory(.clk(HCLK), .we(memwriteD), .bwe(HWSTRB), .addr(RamAddr[ADDR_WIDTH+OFFSET-1:OFFSET]), .dout(HREADRam_TEMP), .din(HWDATA)); + + // *** also temporary +// flop #(`XLEN) HREADRamReg(HCLK, HREADRam_TEMP, HREADRam); + assign HREADRam = HREADRam_TEMP; + + // **** temporary + logic [7:0] NextCycle, Cycle; + logic CntEn, CntRst; + logic CycleFlag; + + flopenr #(8) counter (HCLK, ~HRESETn | CntRst, CntEn, NextCycle, Cycle); + assign NextCycle = Cycle + 1'b1; + + + typedef enum logic {READY, DELAY} statetype; + statetype CurrState, NextState; + + always_ff @(posedge HCLK) + if (~HRESETn) CurrState <= #1 READY; + else CurrState <= #1 NextState; + + always_comb begin + case(CurrState) + READY: if(initTrans & ~CycleFlag) NextState = DELAY; + else NextState = READY; + DELAY: if(CycleFlag) NextState = READY; + else NextState = DELAY; + default: NextState = READY; + endcase + end + + assign CycleFlag = Cycle == CycleThreshold; + assign CntEn = NextState == DELAY; + assign DelayReady = NextState == DELAY; + assign CntRst = NextState == READY; + + endmodule diff --git a/pipelined/src/uncore/uncore.sv b/pipelined/src/uncore/uncore.sv index 938ebf8c..eeaec9fa 100644 --- a/pipelined/src/uncore/uncore.sv +++ b/pipelined/src/uncore/uncore.sv @@ -197,7 +197,12 @@ module uncore ( HSELNoneD; // don't lock up the bus if no region is being accessed // Address Decoder Delay (figure 4-2 in spec) - flopr #(11) hseldelayreg(HCLK, ~HRESETn, HSELRegions, {HSELDTIMD, HSELIROMD, HSELEXTD, HSELBootRomD, HSELRamD, HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD, HSELNoneD}); + // The select for HREADY needs to be based on the address phase address. If the device + // takes more than 1 cycle to repsond it needs to hold on to the old select until the + // device is ready. Hense this register must be selectively enabled by HREADY. + // However on reset None must be seleted. + flopenr #(10) hseldelayreg(HCLK, ~HRESETn, HREADY, HSELRegions[10:1], {HSELDTIMD, HSELIROMD, HSELEXTD, HSELBootRomD, HSELRamD, HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD}); + flopenl #(1) hseldelayreg2(HCLK, ~HRESETn, HREADY, HSELRegions[0], 1'b1, HSELNoneD); flopr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HSELBRIDGE, HSELBRIDGED); endmodule