From ff5554ca61d22087c6cd7e882652d8285a02f73f Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 16 Jan 2024 10:43:20 -0600 Subject: [PATCH] Atomics work correctly without a d cache. --- src/ebu/buscachefsm.sv | 24 ++++++++++++++---------- src/ebu/busfsm.sv | 12 ++++++++---- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/ebu/buscachefsm.sv b/src/ebu/buscachefsm.sv index 0368164ed..8d434c678 100644 --- a/src/ebu/buscachefsm.sv +++ b/src/ebu/buscachefsm.sv @@ -66,7 +66,7 @@ module buscachefsm #( output logic [2:0] HBURST // AHB burst length ); - typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, ATOMIC_PHASE, MEM3, CACHE_FETCH, CACHE_WRITEBACK} busstatetype; + typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, ATOMIC_READ_DATA_PHASE, ATOMIC_PHASE, MEM3, CACHE_FETCH, CACHE_WRITEBACK} busstatetype; typedef enum logic [1:0] {AHB_IDLE = 2'b00, AHB_BUSY = 2'b01, AHB_NONSEQ = 2'b10, AHB_SEQ = 2'b11} ahbtranstype; busstatetype CurrState, NextState; @@ -87,13 +87,15 @@ module buscachefsm #( always_comb begin case(CurrState) - ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE; - else if (HREADY & BusWrite) NextState = CACHE_WRITEBACK; - else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH; - else NextState = ADR_PHASE; - DATA_PHASE: if(HREADY & BusAtomic) NextState = ATOMIC_PHASE; - else if(HREADY & ~BusAtomic) NextState = MEM3; + ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE; + else if (HREADY & BusWrite) NextState = CACHE_WRITEBACK; + else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH; + else NextState = ADR_PHASE; + DATA_PHASE: if(HREADY & BusAtomic) NextState = ATOMIC_READ_DATA_PHASE; + else if(HREADY & ~BusAtomic) NextState = MEM3; else NextState = DATA_PHASE; + ATOMIC_READ_DATA_PHASE: if(HREADY) NextState = ATOMIC_PHASE; + else NextState = ATOMIC_READ_DATA_PHASE; ATOMIC_PHASE: if(HREADY) NextState = MEM3; else NextState = ATOMIC_PHASE; MEM3: if(Stall) NextState = MEM3; @@ -107,7 +109,7 @@ module buscachefsm #( else if(HREADY & FinalBeatCount & BusCMOZero) NextState = MEM3; else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; else NextState = CACHE_WRITEBACK; - default: NextState = ADR_PHASE; + default: NextState = ADR_PHASE; endcase end @@ -129,6 +131,7 @@ module buscachefsm #( //(CurrState == DATA_PHASE & ~BusRW[0]) | // *** replace the next line with this. Fails uart test but i think it's a test problem not a hardware problem. (CurrState == DATA_PHASE) | (CurrState == ATOMIC_PHASE) | + (CurrState == ATOMIC_READ_DATA_PHASE) | (CurrState == CACHE_FETCH & ~FinalBeatCount) | (CurrState == CACHE_WRITEBACK & ~FinalBeatCount); @@ -136,11 +139,11 @@ module buscachefsm #( // AHB bus interface assign HTRANS = (CurrState == ADR_PHASE & HREADY & ((|BusRW) | (|CacheBusRW) | BusCMOZero) & ~Flush) | - (CurrState == DATA_PHASE & BusAtomic) | + (CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) | (CacheAccess & FinalBeatCount & |CacheBusRW & HREADY & ~Flush) ? AHB_NONSEQ : // if we have a pipelined request (CacheAccess & |BeatCount) ? (`BURST_EN ? AHB_SEQ : AHB_NONSEQ) : AHB_IDLE; - assign HWRITE = ((BusRW[0] & ~BusAtomic) | BusWrite & ~Flush) | (CurrState == DATA_PHASE & BusAtomic) | + assign HWRITE = ((BusRW[0] & ~BusAtomic) | BusWrite & ~Flush) | (CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) | (CurrState == CACHE_WRITEBACK & |BeatCount); assign HBURST = `BURST_EN & ((|CacheBusRW & ~Flush) | (CacheAccess & |BeatCount)) ? LocalBurstType : 3'b0; @@ -159,6 +162,7 @@ module buscachefsm #( assign SelBusBeat = (CurrState == ADR_PHASE & (BusRW[0] | BusWrite)) | (CurrState == DATA_PHASE & BusRW[0]) | (CurrState == ATOMIC_PHASE & BusRW[0]) | + (CurrState == ATOMIC_READ_DATA_PHASE & BusRW[0]) | (CurrState == CACHE_WRITEBACK) | (CurrState == CACHE_FETCH); diff --git a/src/ebu/busfsm.sv b/src/ebu/busfsm.sv index 126759b0d..81d11715e 100644 --- a/src/ebu/busfsm.sv +++ b/src/ebu/busfsm.sv @@ -48,7 +48,7 @@ module busfsm #( output logic HWRITE // AHB 0: Read operation 1: Write operation ); - typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, MEM3, ATOMIC_PHASE} busstatetype; + typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, MEM3, ATOMIC_READ_DATA_PHASE, ATOMIC_PHASE} busstatetype; typedef enum logic [1:0] {AHB_IDLE = 2'b00, AHB_BUSY = 2'b01, AHB_NONSEQ = 2'b10, AHB_SEQ = 2'b11} ahbtranstype; busstatetype CurrState, NextState; @@ -61,9 +61,11 @@ module busfsm #( case(CurrState) ADR_PHASE: if(HREADY & |BusRW) NextState = DATA_PHASE; else NextState = ADR_PHASE; - DATA_PHASE: if(HREADY & BusAtomic) NextState = ATOMIC_PHASE; + DATA_PHASE: if(HREADY & BusAtomic) NextState = ATOMIC_READ_DATA_PHASE; else if(HREADY & ~BusAtomic) NextState = MEM3; else NextState = DATA_PHASE; + ATOMIC_READ_DATA_PHASE: if(HREADY) NextState = ATOMIC_PHASE; + else NextState = ATOMIC_READ_DATA_PHASE; ATOMIC_PHASE: if(HREADY) NextState = MEM3; else NextState = ATOMIC_PHASE; MEM3: if(Stall) NextState = MEM3; @@ -74,13 +76,15 @@ module busfsm #( assign BusStall = (CurrState == ADR_PHASE & |BusRW) | // (CurrState == DATA_PHASE & ~BusRW[0]); // possible optimization here. fails uart test, but i'm not sure the failure is valid. + (CurrState == ATOMIC_PHASE) | + (CurrState == ATOMIC_READ_DATA_PHASE) | (CurrState == DATA_PHASE); assign BusCommitted = (CurrState != ADR_PHASE) & ~(READ_ONLY & CurrState == MEM3); assign HTRANS = (CurrState == ADR_PHASE & HREADY & |BusRW & ~Flush) | - (CurrState == DATA_PHASE & BusAtomic) ? AHB_NONSEQ : AHB_IDLE; - assign HWRITE = (BusRW[0] & ~BusAtomic) | (CurrState == DATA_PHASE & BusAtomic); + (CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) ? AHB_NONSEQ : AHB_IDLE; + assign HWRITE = (BusRW[0] & ~BusAtomic) | (CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic); assign CaptureEn = CurrState == DATA_PHASE;