diff --git a/sim/Makefile b/sim/Makefile index 658cc6a15..5889d1df9 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -18,7 +18,6 @@ all: riscoftests memfiles coveragetests wally-riscv-arch-test: wallyriscoftests memfiles coverage: cov/rv64gc_arch64i.ucdb - #make -C ../tests/coverage --jobs #iter-elf.bash --cover --search ../tests/coverage vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb -logfile cov/log # vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb cov/buildroot_buildroot.ucdb riscv.ucdb -logfile cov/log @@ -60,4 +59,4 @@ memfiles: make -f makefile-memfile wally-sim-files --jobs coveragetests: - make -C ../tests/coverage/ + make -C ../tests/coverage/ --jobs diff --git a/src/ebu/ahbcacheinterface.sv b/src/ebu/ahbcacheinterface.sv index 78b0d15e8..5f2dff313 100644 --- a/src/ebu/ahbcacheinterface.sv +++ b/src/ebu/ahbcacheinterface.sv @@ -65,6 +65,7 @@ module ahbcacheinterface #( input logic [PA_BITS-1:0] PAdr, // Physical address of uncached memory operation input logic [LLEN-1:0] WriteDataM, // IEU write data for uncached store input logic [1:0] BusRW, // Uncached memory operation read/write control: 10: read, 01: write + input logic BusAtomic, // Uncache atomic memory operation input logic [2:0] Funct3, // Size of uncached memory operation input logic BusCMOZero, // Uncached cbo.zero must write zero to full sized cacheline without going through the cache @@ -121,7 +122,7 @@ module ahbcacheinterface #( flopen #(AHBW/8) HWSTRBReg(HCLK, HREADY, BusByteMaskM[AHBW/8-1:0], HWSTRB); buscachefsm #(BeatCountThreshold, AHBWLOGBWPL, READ_ONLY_CACHE) AHBBuscachefsm( - .HCLK, .HRESETn, .Flush, .BusRW, .Stall, .BusCommitted, .BusStall, .CaptureEn, .SelBusBeat, + .HCLK, .HRESETn, .Flush, .BusRW, .BusAtomic, .Stall, .BusCommitted, .BusStall, .CaptureEn, .SelBusBeat, .CacheBusRW, .BusCMOZero, .CacheBusAck, .BeatCount, .BeatCountDelayed, .HREADY, .HTRANS, .HWRITE, .HBURST); endmodule diff --git a/src/ebu/buscachefsm.sv b/src/ebu/buscachefsm.sv index f7b03e198..0368164ed 100644 --- a/src/ebu/buscachefsm.sv +++ b/src/ebu/buscachefsm.sv @@ -42,6 +42,7 @@ module buscachefsm #( input logic Stall, // Core pipeline is stalled input logic Flush, // Pipeline stage flush. Prevents bus transaction from starting input logic [1:0] BusRW, // Uncached memory operation read/write control: 10: read, 01: write + input logic BusAtomic, // Uncache atomic memory operation input logic BusCMOZero, // Uncached cbo.zero must write zero to full sized cacheline without going through the cache output logic BusStall, // Bus is busy with an in flight memory operation output logic BusCommitted, // Bus is busy with an in flight memory operation and it is not safe to take an interrupt @@ -65,7 +66,7 @@ module buscachefsm #( output logic [2:0] HBURST // AHB burst length ); - typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, MEM3, CACHE_FETCH, CACHE_WRITEBACK} busstatetype; + typedef enum logic [2:0] {ADR_PHASE, 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,22 +88,25 @@ 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 & BusWrite) NextState = CACHE_WRITEBACK; else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH; else NextState = ADR_PHASE; - DATA_PHASE: if(HREADY) NextState = MEM3; - else NextState = DATA_PHASE; - MEM3: if(Stall) NextState = MEM3; - else NextState = ADR_PHASE; - CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK; - else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; - else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; - else NextState = CACHE_FETCH; - CACHE_WRITEBACK: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK; - else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; - else if(HREADY & FinalBeatCount & BusCMOZero) NextState = MEM3; - else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; - else NextState = CACHE_WRITEBACK; + DATA_PHASE: if(HREADY & BusAtomic) NextState = ATOMIC_PHASE; + else if(HREADY & ~BusAtomic) NextState = MEM3; + else NextState = DATA_PHASE; + ATOMIC_PHASE: if(HREADY) NextState = MEM3; + else NextState = ATOMIC_PHASE; + MEM3: if(Stall) NextState = MEM3; + else NextState = ADR_PHASE; + CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK; + else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; + else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; + else NextState = CACHE_FETCH; + CACHE_WRITEBACK: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK; + else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; + else if(HREADY & FinalBeatCount & BusCMOZero) NextState = MEM3; + else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; + else NextState = CACHE_WRITEBACK; default: NextState = ADR_PHASE; endcase end @@ -124,17 +128,20 @@ module buscachefsm #( assign BusStall = (CurrState == ADR_PHASE & ((|BusRW) | (|CacheBusRW) | BusCMOZero)) | //(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 == CACHE_FETCH & ~FinalBeatCount) | - (CurrState == CACHE_WRITEBACK & ~FinalBeatCount); + (CurrState == ATOMIC_PHASE) | + (CurrState == CACHE_FETCH & ~FinalBeatCount) | + (CurrState == CACHE_WRITEBACK & ~FinalBeatCount); assign BusCommitted = (CurrState != ADR_PHASE) & ~(READ_ONLY_CACHE & CurrState == MEM3); // AHB bus interface assign HTRANS = (CurrState == ADR_PHASE & HREADY & ((|BusRW) | (|CacheBusRW) | BusCMOZero) & ~Flush) | + (CurrState == 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] | BusWrite & ~Flush) | (CurrState == CACHE_WRITEBACK & |BeatCount); + assign HWRITE = ((BusRW[0] & ~BusAtomic) | BusWrite & ~Flush) | (CurrState == DATA_PHASE & BusAtomic) | + (CurrState == CACHE_WRITEBACK & |BeatCount); assign HBURST = `BURST_EN & ((|CacheBusRW & ~Flush) | (CacheAccess & |BeatCount)) ? LocalBurstType : 3'b0; always_comb begin @@ -151,6 +158,7 @@ module buscachefsm #( assign CacheBusAck = (CacheAccess & HREADY & FinalBeatCount & ~BusCMOZero); assign SelBusBeat = (CurrState == ADR_PHASE & (BusRW[0] | BusWrite)) | (CurrState == DATA_PHASE & BusRW[0]) | + (CurrState == ATOMIC_PHASE & BusRW[0]) | (CurrState == CACHE_WRITEBACK) | (CurrState == CACHE_FETCH); diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index e6e4de78a..9900daaad 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -258,7 +258,7 @@ module ifu import cvw::*; #(parameter cvw_t P) ( .HRDATA, .Flush(FlushD), .CacheBusRW, .BusCMOZero(1'b0), .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(), .Funct3(3'b010), .HADDR(IFUHADDR), .HREADY(IFUHREADY), .HWRITE(IFUHWRITE), .CacheBusAdr(ICacheBusAdr), - .BeatCount(), .Cacheable(CacheableF), .SelBusBeat(), .WriteDataM('0), + .BeatCount(), .Cacheable(CacheableF), .SelBusBeat(), .WriteDataM('0), .BusAtomic('0), .CacheBusAck(ICacheBusAck), .HWDATA(), .CacheableOrFlushCacheM(1'b0), .CacheReadDataWordM('0), .FetchBuffer, .PAdr(PCPF), .BusRW, .Stall(GatedStallD), diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index c36e54f07..05fa773fe 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -308,13 +308,16 @@ module lsu import cvw::*; #(parameter cvw_t P) ( logic [1:0] CacheBusRWTemp; logic BusCMOZero; logic [3:0] CacheCMOpM; + logic BusAtomic; if(P.ZICBOZ_SUPPORTED) begin assign BusCMOZero = CMOpM[3] & ~CacheableM; - assign CacheCMOpM = CacheableM ? CMOpM : '0; + assign CacheCMOpM = CacheableM ? CMOpM : '0; + assign BusAtomic = AtomicM[1] & ~CacheableM; end else begin assign BusCMOZero = '0; - assign CacheCMOpM = '0; + assign CacheCMOpM = '0; + assign BusAtomic = '0; end assign BusRW = ~CacheableM & ~SelDTIM ? LSURWM : '0; assign CacheableOrFlushCacheM = CacheableM | FlushDCacheM; @@ -343,7 +346,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( .HRDATA, .HWDATA(LSUHWDATA), .HWSTRB(LSUHWSTRB), .HSIZE(LSUHSIZE), .HBURST(LSUHBURST), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HREADY(LSUHREADY), .BeatCount, .SelBusBeat, .CacheReadDataWordM(DCacheReadDataWordM[P.LLEN-1:0]), .WriteDataM(LSUWriteDataM), - .Funct3(LSUFunct3M), .HADDR(LSUHADDR), .CacheBusAdr(DCacheBusAdr), .CacheBusRW, .BusCMOZero, .CacheableOrFlushCacheM, + .Funct3(LSUFunct3M), .HADDR(LSUHADDR), .CacheBusAdr(DCacheBusAdr), .CacheBusRW, .BusAtomic, .BusCMOZero, .CacheableOrFlushCacheM, .CacheBusAck(DCacheBusAck), .FetchBuffer, .PAdr(PAdrM), .Cacheable(CacheableOrFlushCacheM), .BusRW, .Stall(GatedStallW), .BusStall, .BusCommitted(BusCommittedM));