diff --git a/linux/buildroot-scripts/Makefile b/linux/buildroot-scripts/Makefile index b0e3bdf9b..53673c9c2 100644 --- a/linux/buildroot-scripts/Makefile +++ b/linux/buildroot-scripts/Makefile @@ -1,3 +1,6 @@ +IMAGES := ${RISCV}/buildroot/output/images +DIS := ${IMAGES}/disassembly + all: make disassemble make generate @@ -7,15 +10,28 @@ generate: dtc -I dts -O dtb ../devicetree/wally-virt.dts > ${RISCV}/buildroot/output/images/wally-virt.dtb disassemble: - mkdir ${RISCV}/buildroot/output/images/disassembly - # fw_jump - riscv64-unknown-elf-objdump -D ${RISCV}/buildroot/output/images/fw_jump.elf >> ${RISCV}/buildroot/output/images/disassembly/fw_jump.objdump - # vmlinux - riscv64-unknown-elf-objdump -D ${RISCV}/buildroot/output/images/vmlinux >> ${RISCV}/buildroot/output/images/disassembly/vmlinux.objdump + mkdir -p ${DIS} + # disassemblies + make -j ${DIS}/fw_jump.objdump ${DIS}/vmlinux.objdump ${DIS}/busybox.objdump # filesystem - mkdir ${RISCV}/buildroot/output/images/disassembly/rootfs - -cd ${RISCV}/buildroot/output/images/disassembly/rootfs; cpio -idv < ../../rootfs.cpio + make ${DIS}/rootfs/bin/busybox + # mkdir -p ${DIS}/rootfs + # -cd ${DIS}/rootfs; cpio -id --nonmatching 'dev/console' < ../../rootfs.cpio + +${DIS}/fw_jump.objdump: ${IMAGES}/fw_jump.elf + riscv64-unknown-elf-objdump -D ${IMAGES}/fw_jump.elf >> ${DIS}/fw_jump.objdump + +${DIS}/vmlinux.objdump: ${IMAGES}/vmlinux + riscv64-unknown-elf-objdump -D ${IMAGES}/vmlinux >> ${DIS}/vmlinux.objdump + +${DIS}/busybox.objdump: ${DIS}/rootfs/bin/busybox + riscv64-unknown-elf-objdump -D ${DIS}/rootfs/bin/busybox >> ${DIS}/busybox.objdump + +${DIS}/rootfs/bin/busybox: + mkdir -p ${DIS}/rootfs + -cd ${DIS}/rootfs; cpio -id --nonmatching 'dev/console' < ../../rootfs.cpio + clean: - rm ${RISCV}/buildroot/output/images/wally-virt.dtb - rm -rf ${RISCV}/buildroot/output/images/disassembly + rm -f ${IMAGES}/wally-virt.dtb + rm -rf ${DIS} diff --git a/pipelined/regression/wally-pipelined.do b/pipelined/regression/wally-pipelined.do index db50042e9..f558d56f4 100644 --- a/pipelined/regression/wally-pipelined.do +++ b/pipelined/regression/wally-pipelined.do @@ -37,7 +37,8 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G INSTR_LIMIT=$3 -G INSTR_WAVEON=$4 -G CHECKPOINT=$5 -o testbenchopt vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084 - #-- Run the Simulation + #-- Run the Simulation + run -all add log -recursive /* do linux-wave.do run -all diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index 96bbdcbbc..62518b263 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -76,15 +76,14 @@ module ifu ( input logic [1:0] STATUS_MPP, input logic ITLBWriteF, ITLBFlushF, output logic ITLBMissF, InstrDAPageFaultF, - // pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], output logic InstrAccessFaultF, output logic ICacheAccess, output logic ICacheMiss ); - -(* mark_debug = "true" *) logic [`XLEN-1:0] PCCorrectE, UnalignedPCNextF, PCNextF; + localparam CACHE_ENABLED = `IMEM == `MEM_CACHE; + (* mark_debug = "true" *) logic [`XLEN-1:0] PCCorrectE, UnalignedPCNextF, PCNextF; logic BranchMisalignedFaultE; logic PrivilegedChangePCM; logic IllegalCompInstrD; @@ -120,14 +119,14 @@ module ifu ( assign PCFExt = {2'b00, PCFSpill}; ///////////////////////////////////////////////////////////////////////////////////////////// - // Spill Support *** add other banners + // Spill Support ///////////////////////////////////////////////////////////////////////////////////////////// if(`C_SUPPORTED) begin : SpillSupport spillsupport spillsupport(.clk, .reset, .StallF, .PCF, .PCPlusUpperF, .PCNextF, .InstrRawF, - .IFUCacheBusStallF, .ITLBMissF, .PCNextFSpill, .PCFSpill, - .SelNextSpillF, .PostSpillInstrRawF, .CompressedF); + .InstrDAPageFaultF, .IFUCacheBusStallF, .ITLBMissF, .PCNextFSpill, .PCFSpill, + .SelNextSpillF, .PostSpillInstrRawF, .CompressedF); end else begin : NoSpillSupport assign PCNextFSpill = PCNextF; assign PCFSpill = PCF; @@ -161,7 +160,7 @@ module ifu ( .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW); end else begin - assign {ITLBMissF, InstrAccessFaultF, InstrPageFaultF} = '0; + assign {ITLBMissF, InstrAccessFaultF, InstrPageFaultF, InstrDAPageFaultF} = '0; assign PCPF = PCFExt[`PA_BITS-1:0]; assign CacheableF = '1; end @@ -182,8 +181,8 @@ module ifu ( .DCacheCommittedM(), .DCacheMiss(ICacheMiss), .DCacheAccess(ICacheAccess)); end else begin : bus - localparam integer WORDSPERLINE = (`IMEM == `MEM_CACHE) ? `ICACHE_LINELENINBITS/`XLEN : 1; - localparam integer LINELEN = (`IMEM == `MEM_CACHE) ? `ICACHE_LINELENINBITS : `XLEN; + localparam integer WORDSPERLINE = (CACHE_ENABLED) ? `ICACHE_LINELENINBITS/`XLEN : 1; + localparam integer LINELEN = (CACHE_ENABLED) ? `ICACHE_LINELENINBITS : `XLEN; localparam integer LOGWPL = (`DMEM == `MEM_CACHE) ? $clog2(WORDSPERLINE) : 1; logic [LINELEN-1:0] ReadDataLine; logic [LINELEN-1:0] ICacheBusWriteData; @@ -193,7 +192,7 @@ module ifu ( logic [31:0] temp; logic SelUncachedAdr; - busdp #(WORDSPERLINE, LINELEN, LOGWPL) + busdp #(WORDSPERLINE, LINELEN, LOGWPL, CACHE_ENABLED) busdp(.clk, .reset, .LSUBusHRDATA(IFUBusHRDATA), .LSUBusAck(IFUBusAck), .LSUBusWrite(), .LSUBusWriteCrit(), .LSUBusRead(IFUBusRead), .LSUBusSize(), @@ -210,7 +209,7 @@ module ifu ( .s(SelUncachedAdr), .y(AllInstrRawF[31:0])); - if(`IMEM == `MEM_CACHE) begin : icache + if(CACHE_ENABLED) begin : icache logic [1:0] IFURWF; assign IFURWF = CacheableF ? 2'b10 : 2'b00; @@ -247,18 +246,28 @@ module ifu ( flopenl #(32) AlignedInstrRawDFlop(clk, reset, ~StallD, FlushD ? nop : PostSpillInstrRawF, nop, InstrRawD); + //////////////////////////////////////////////////////////////////////////////////////////////// + // PCNextF logic + //////////////////////////////////////////////////////////////////////////////////////////////// + assign PrivilegedChangePCM = RetM | TrapM; - // *** look at moves pcmux2 and pcmux3 to generates as they are needed only on supporting caches and - // privilege instructions respectively. mux2 #(`XLEN) pcmux1(.d0(PCNext0F), .d1(PCCorrectE), .s(BPPredWrongE), .y(PCNext1F)); - mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(PCBPWrongInvalidate), .s(InvalidateICacheM), .y(PCNext2F)); - mux2 #(`XLEN) pcmux3(.d0(PCNext2F), .d1(PrivilegedNextPCM), .s(PrivilegedChangePCM), .y(UnalignedPCNextF)); + if(CACHE_ENABLED) + mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(PCBPWrongInvalidate), .s(InvalidateICacheM), + .y(PCNext2F)); + else assign PCNext2F = PCNext1F; + if(`ZICSR_SUPPORTED) + mux2 #(`XLEN) pcmux3(.d0(PCNext2F), .d1(PrivilegedNextPCM), .s(PrivilegedChangePCM), + .y(UnalignedPCNextF)); + else assign UnalignedPCNextF = PCNext2F; assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF); - // branch and jump predictor + //////////////////////////////////////////////////////////////////////////////////////////////// + // Branch and Jump Predictor + //////////////////////////////////////////////////////////////////////////////////////////////// if (`BPRED_ENABLED) begin : bpred logic BPPredWrongM; logic SelBPPredF; @@ -295,6 +304,9 @@ module ifu ( else PCPlus2or4F = {PCF[`XLEN-1:2], 2'b10}; else PCPlus2or4F = {PCPlusUpperF, PCF[1:0]}; // add 4 + //////////////////////////////////////////////////////////////////////////////////////////////// + // Decode stage pipeline register and compressed instruction decoding. + //////////////////////////////////////////////////////////////////////////////////////////////// // Decode stage pipeline register and logic flopenrc #(`XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD); diff --git a/pipelined/src/ifu/spillsupport.sv b/pipelined/src/ifu/spillsupport.sv index a55155513..db9ed8e28 100644 --- a/pipelined/src/ifu/spillsupport.sv +++ b/pipelined/src/ifu/spillsupport.sv @@ -42,6 +42,7 @@ module spillsupport ( input logic [31:0] InstrRawF, input logic IFUCacheBusStallF, input logic ITLBMissF, + input logic InstrDAPageFaultF, output logic [`XLEN-1:0] PCNextFSpill, output logic [`XLEN-1:0] PCFSpill, output logic SelNextSpillF, @@ -50,44 +51,41 @@ module spillsupport ( localparam integer SPILLTHRESHOLD = (`IMEM == `MEM_CACHE) ? `ICACHE_LINELENINBITS/32 : 1; - logic [`XLEN-1:0] PCPlus2F; - logic TakeSpillF; - logic SpillF; - logic SelSpillF, SpillSaveF; - logic [15:0] SpillDataLine0; + logic [`XLEN-1:0] PCPlus2F; + logic TakeSpillF; + logic SpillF; + logic SelSpillF, SpillSaveF; + logic [15:0] SpillDataLine0; + typedef enum logic [1:0] {STATE_READY, STATE_SPILL} statetype; + (* mark_debug = "true" *) statetype CurrState, NextState; - // *** PLACE ALL THIS IN A MODULE - // this exists only if there are compressed instructions. - // reuse PC+2/4 circuitry to avoid needing a second CPA to add 2 - mux2 #(`XLEN) pcplus2mux(.d0({PCF[`XLEN-1:2], 2'b10}), .d1({PCPlusUpperF, 2'b00}), .s(PCF[1]), .y(PCPlus2F)); - mux2 #(`XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelNextSpillF), .y(PCNextFSpill)); + mux2 #(`XLEN) pcplus2mux(.d0({PCF[`XLEN-1:2], 2'b10}), .d1({PCPlusUpperF, 2'b00}), + .s(PCF[1]), .y(PCPlus2F)); + mux2 #(`XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelNextSpillF), + .y(PCNextFSpill)); mux2 #(`XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCFSpill)); assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1]; - - typedef enum logic [1:0] {STATE_SPILL_READY, STATE_SPILL_SPILL} statetype; - (* mark_debug = "true" *) statetype CurrState, NextState; - + assign TakeSpillF = SpillF & ~IFUCacheBusStallF & ~(ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF)); + always_ff @(posedge clk) - if (reset) CurrState <= #1 STATE_SPILL_READY; + if (reset) CurrState <= #1 STATE_READY; else CurrState <= #1 NextState; - assign TakeSpillF = SpillF & ~IFUCacheBusStallF & ~ITLBMissF; - always_comb begin case (CurrState) - STATE_SPILL_READY: if (TakeSpillF) NextState = STATE_SPILL_SPILL; - else NextState = STATE_SPILL_READY; - STATE_SPILL_SPILL: if(IFUCacheBusStallF | StallF) NextState = STATE_SPILL_SPILL; - else NextState = STATE_SPILL_READY; - default: NextState = STATE_SPILL_READY; + STATE_READY: if (TakeSpillF) NextState = STATE_SPILL; + else NextState = STATE_READY; + STATE_SPILL: if(IFUCacheBusStallF | StallF) NextState = STATE_SPILL; + else NextState = STATE_READY; + default: NextState = STATE_READY; endcase end - assign SelSpillF = (CurrState == STATE_SPILL_SPILL); - assign SelNextSpillF = (CurrState == STATE_SPILL_READY & TakeSpillF) | - (CurrState == STATE_SPILL_SPILL & IFUCacheBusStallF); - assign SpillSaveF = (CurrState == STATE_SPILL_READY) & TakeSpillF; + assign SelSpillF = (CurrState == STATE_SPILL); + assign SelNextSpillF = (CurrState == STATE_READY & TakeSpillF) | + (CurrState == STATE_SPILL & IFUCacheBusStallF); + assign SpillSaveF = (CurrState == STATE_READY) & TakeSpillF; flopenr #(16) SpillInstrReg(.clk(clk), .en(SpillSaveF), @@ -95,7 +93,8 @@ module spillsupport ( .d((`IMEM == `MEM_CACHE) ? InstrRawF[15:0] : InstrRawF[31:16]), .q(SpillDataLine0)); - assign PostSpillInstrRawF = SpillF ? {InstrRawF[15:0], SpillDataLine0} : InstrRawF; + mux2 #(32) postspillmux(.d0(InstrRawF), .d1({InstrRawF[15:0], SpillDataLine0}), .s(SpillF), + .y(PostSpillInstrRawF)); assign CompressedF = PostSpillInstrRawF[1:0] != 2'b11; endmodule diff --git a/pipelined/src/lsu/busdp.sv b/pipelined/src/lsu/busdp.sv index d3bfed681..66e41675d 100644 --- a/pipelined/src/lsu/busdp.sv +++ b/pipelined/src/lsu/busdp.sv @@ -34,7 +34,7 @@ `include "wally-config.vh" -module busdp #(parameter WORDSPERLINE, LINELEN, LOGWPL, LSU=0) +module busdp #(parameter WORDSPERLINE, LINELEN, LOGWPL, CACHE_ENABLED) ( input logic clk, reset, // bus interface @@ -66,21 +66,21 @@ module busdp #(parameter WORDSPERLINE, LINELEN, LOGWPL, LSU=0) output logic BusCommittedM); - localparam integer WordCountThreshold = (`DMEM == `MEM_CACHE) ? WORDSPERLINE - 1 : 0; - + localparam integer WordCountThreshold = CACHE_ENABLED ? WORDSPERLINE - 1 : 0; logic [`PA_BITS-1:0] LocalLSUBusAdr; genvar index; - for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer - flopen #(`XLEN) fb(.clk, .en(LSUBusAck & LSUBusRead & (index == WordCount)), - .d(LSUBusHRDATA), .q(DCacheBusWriteData[(index+1)*`XLEN-1:index*`XLEN])); + logic [WORDSPERLINE-1:0] CaptureWord; + assign CaptureWord[index] = LSUBusAck & LSUBusRead & (index == WordCount); + flopen #(`XLEN) fb(.clk, .en(CaptureWord[index]), .d(LSUBusHRDATA), + .q(DCacheBusWriteData[(index+1)*`XLEN-1:index*`XLEN])); end mux2 #(`PA_BITS) localadrmux(DCacheBusAdr, LSUPAdrM, SelUncachedAdr, LocalLSUBusAdr); assign LSUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLSUBusAdr; - mux2 #(3) lsubussizemux(.d0(`XLEN == 32 ? 3'b010 : 3'b011), .d1(LSUFunct3M), + mux2 #(3) lsubussizemux(.d0(`XLEN == 32 ? 3'b010 : 3'b011), .d1(LSUFunct3M), .s(SelUncachedAdr), .y(LSUBusSize)); - busfsm #(WordCountThreshold, LOGWPL, (`DMEM == `MEM_CACHE)) // *** cleanup Icache? must fix. + busfsm #(WordCountThreshold, LOGWPL, CACHE_ENABLED) busfsm(.clk, .reset, .IgnoreRequest, .LSURWM, .DCacheFetchLine, .DCacheWriteLine, .LSUBusAck, .CPUBusy, .CacheableM, .BusStall, .LSUBusWrite, .LSUBusWriteCrit, .LSUBusRead, .DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount); diff --git a/pipelined/src/lsu/busfsm.sv b/pipelined/src/lsu/busfsm.sv index 837326d51..3b3a38a8f 100644 --- a/pipelined/src/lsu/busfsm.sv +++ b/pipelined/src/lsu/busfsm.sv @@ -32,7 +32,7 @@ module busfsm #(parameter integer WordCountThreshold, - parameter integer LOGWPL, parameter logic CacheEnabled ) + parameter integer LOGWPL, parameter logic CACHE_ENABLED ) (input logic clk, input logic reset, @@ -88,7 +88,7 @@ module busfsm #(parameter integer WordCountThreshold, assign WordCountFlag = (WordCount == WordCountThreshold[LOGWPL-1:0]); assign CntEn = PreCntEn & LSUBusAck; - assign UnCachedAccess = ~CacheEnabled | ~CacheableM; + assign UnCachedAccess = ~CACHE_ENABLED | ~CacheableM; always_ff @(posedge clk) if (reset) BusCurrState <= #1 STATE_BUS_READY; @@ -96,27 +96,27 @@ module busfsm #(parameter integer WordCountThreshold, always_comb begin case(BusCurrState) - STATE_BUS_READY: if(IgnoreRequest) BusNextState = STATE_BUS_READY; - else if(LSURWM[0] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_WRITE; - else if(LSURWM[1] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_READ; + STATE_BUS_READY: if(IgnoreRequest) BusNextState = STATE_BUS_READY; + else if(LSURWM[0] & UnCachedAccess) BusNextState = STATE_BUS_UNCACHED_WRITE; + else if(LSURWM[1] & UnCachedAccess) BusNextState = STATE_BUS_UNCACHED_READ; else if(DCacheFetchLine) BusNextState = STATE_BUS_FETCH; else if(DCacheWriteLine) BusNextState = STATE_BUS_WRITE; - else BusNextState = STATE_BUS_READY; - STATE_BUS_UNCACHED_WRITE: if(LSUBusAck) BusNextState = STATE_BUS_UNCACHED_WRITE_DONE; - else BusNextState = STATE_BUS_UNCACHED_WRITE; - STATE_BUS_UNCACHED_READ: if(LSUBusAck) BusNextState = STATE_BUS_UNCACHED_READ_DONE; - else BusNextState = STATE_BUS_UNCACHED_READ; - STATE_BUS_UNCACHED_WRITE_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; - else BusNextState = STATE_BUS_READY; - STATE_BUS_UNCACHED_READ_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; - else BusNextState = STATE_BUS_READY; - STATE_BUS_CPU_BUSY: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; - else BusNextState = STATE_BUS_READY; - STATE_BUS_FETCH: if (WordCountFlag & LSUBusAck) BusNextState = STATE_BUS_READY; - else BusNextState = STATE_BUS_FETCH; - STATE_BUS_WRITE: if(WordCountFlag & LSUBusAck) BusNextState = STATE_BUS_READY; - else BusNextState = STATE_BUS_WRITE; - default: BusNextState = STATE_BUS_READY; + else BusNextState = STATE_BUS_READY; + STATE_BUS_UNCACHED_WRITE: if(LSUBusAck) BusNextState = STATE_BUS_UNCACHED_WRITE_DONE; + else BusNextState = STATE_BUS_UNCACHED_WRITE; + STATE_BUS_UNCACHED_READ: if(LSUBusAck) BusNextState = STATE_BUS_UNCACHED_READ_DONE; + else BusNextState = STATE_BUS_UNCACHED_READ; + STATE_BUS_UNCACHED_WRITE_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; + else BusNextState = STATE_BUS_READY; + STATE_BUS_UNCACHED_READ_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; + else BusNextState = STATE_BUS_READY; + STATE_BUS_CPU_BUSY: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; + else BusNextState = STATE_BUS_READY; + STATE_BUS_FETCH: if (WordCountFlag & LSUBusAck) BusNextState = STATE_BUS_READY; + else BusNextState = STATE_BUS_FETCH; + STATE_BUS_WRITE: if(WordCountFlag & LSUBusAck) BusNextState = STATE_BUS_READY; + else BusNextState = STATE_BUS_WRITE; + default: BusNextState = STATE_BUS_READY; endcase end @@ -128,14 +128,14 @@ module busfsm #(parameter integer WordCountThreshold, (BusCurrState == STATE_BUS_FETCH) | (BusCurrState == STATE_BUS_WRITE); assign PreCntEn = BusCurrState == STATE_BUS_FETCH | BusCurrState == STATE_BUS_WRITE; - assign UnCachedLSUBusWrite = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (LSURWM[0] & ~IgnoreRequest)) | + assign UnCachedLSUBusWrite = (BusCurrState == STATE_BUS_READY & UnCachedAccess & LSURWM[0] & ~IgnoreRequest) | (BusCurrState == STATE_BUS_UNCACHED_WRITE); assign LSUBusWrite = UnCachedLSUBusWrite | (BusCurrState == STATE_BUS_WRITE); - assign LSUBusWriteCrit = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (LSURWM[0])) | + assign LSUBusWriteCrit = (BusCurrState == STATE_BUS_READY & UnCachedAccess & LSURWM[0]) | (BusCurrState == STATE_BUS_UNCACHED_WRITE) | (BusCurrState == STATE_BUS_WRITE); - assign UnCachedLSUBusRead = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (|LSURWM[1] & IgnoreRequest)) | + assign UnCachedLSUBusRead = (BusCurrState == STATE_BUS_READY & UnCachedAccess & LSURWM[1] & IgnoreRequest) | (BusCurrState == STATE_BUS_UNCACHED_READ); assign LSUBusRead = UnCachedLSUBusRead | (BusCurrState == STATE_BUS_FETCH) | (BusCurrState == STATE_BUS_READY & DCacheFetchLine); @@ -147,5 +147,5 @@ module busfsm #(parameter integer WordCountThreshold, BusCurrState == STATE_BUS_UNCACHED_READ_DONE | BusCurrState == STATE_BUS_UNCACHED_WRITE | BusCurrState == STATE_BUS_UNCACHED_WRITE_DONE) | - ~CacheEnabled; // if no dcache always select uncachedadr. + ~CACHE_ENABLED; // if no dcache always select uncachedadr. endmodule diff --git a/pipelined/src/lsu/interlockfsm.sv b/pipelined/src/lsu/interlockfsm.sv index 29b060caf..43bf3d284 100644 --- a/pipelined/src/lsu/interlockfsm.sv +++ b/pipelined/src/lsu/interlockfsm.sv @@ -31,33 +31,44 @@ `include "wally-config.vh" -module interlockfsm - (input logic clk, - input logic reset, - input logic AnyCPUReqM, - input logic ITLBMissOrDAFaultF, - input logic ITLBWriteF, - input logic DTLBMissOrDAFaultM, - input logic DTLBWriteM, - input logic TrapM, - input logic DCacheStallM, +module interlockfsm( + input logic clk, + input logic reset, + input logic [1:0] MemRWM, + input logic [1:0] AtomicM, + input logic ITLBMissOrDAFaultF, + input logic ITLBWriteF, + input logic DTLBMissOrDAFaultM, + input logic DTLBWriteM, + input logic TrapM, + input logic DCacheStallM, - output logic InterlockStall, - output logic SelReplayCPURequest, - output logic SelHPTW, - output logic IgnoreRequestTLB, - output logic IgnoreRequestTrapM); + output logic InterlockStall, + output logic SelReplayCPURequest, + output logic SelHPTW, + output logic IgnoreRequestTLB, + output logic IgnoreRequestTrapM); + logic ToITLBMiss; + logic ToITLBMissNoReplay; + logic ToDTLBMiss; + logic ToBoth; + logic AnyCPUReqM; - typedef enum logic[2:0] {STATE_T0_READY, - STATE_T0_REPLAY, - STATE_T3_DTLB_MISS, - STATE_T4_ITLB_MISS, - STATE_T5_ITLB_MISS, - STATE_T7_DITLB_MISS} statetype; + typedef enum logic[2:0] {STATE_T0_READY, + STATE_T0_REPLAY, + STATE_T3_DTLB_MISS, + STATE_T4_ITLB_MISS, + STATE_T5_ITLB_MISS, + STATE_T7_DITLB_MISS} statetype; (* mark_debug = "true" *) statetype InterlockCurrState, InterlockNextState; + assign AnyCPUReqM = (|MemRWM) | (|AtomicM); + assign ToITLBMiss = ITLBMissOrDAFaultF & ~DTLBMissOrDAFaultM & AnyCPUReqM; + assign ToITLBMissNoReplay = ITLBMissOrDAFaultF & ~DTLBMissOrDAFaultM & ~AnyCPUReqM; + assign ToDTLBMiss = ~ITLBMissOrDAFaultF & DTLBMissOrDAFaultM & AnyCPUReqM; + assign ToBoth = ITLBMissOrDAFaultF & DTLBMissOrDAFaultM & AnyCPUReqM; always_ff @(posedge clk) if (reset) InterlockCurrState <= #1 STATE_T0_READY; @@ -65,23 +76,23 @@ module interlockfsm always_comb begin case(InterlockCurrState) - STATE_T0_READY: if (TrapM) InterlockNextState = STATE_T0_READY; - else if(~ITLBMissOrDAFaultF & DTLBMissOrDAFaultM & AnyCPUReqM) InterlockNextState = STATE_T3_DTLB_MISS; - else if(ITLBMissOrDAFaultF & ~DTLBMissOrDAFaultM & ~AnyCPUReqM) InterlockNextState = STATE_T4_ITLB_MISS; - else if(ITLBMissOrDAFaultF & ~DTLBMissOrDAFaultM & AnyCPUReqM) InterlockNextState = STATE_T5_ITLB_MISS; - else if(ITLBMissOrDAFaultF & DTLBMissOrDAFaultM & AnyCPUReqM) InterlockNextState = STATE_T7_DITLB_MISS; - else InterlockNextState = STATE_T0_READY; - STATE_T0_REPLAY: if(DCacheStallM) InterlockNextState = STATE_T0_REPLAY; - else InterlockNextState = STATE_T0_READY; - STATE_T3_DTLB_MISS: if(DTLBWriteM) InterlockNextState = STATE_T0_REPLAY; - else InterlockNextState = STATE_T3_DTLB_MISS; - STATE_T4_ITLB_MISS: if(ITLBWriteF) InterlockNextState = STATE_T0_READY; - else InterlockNextState = STATE_T4_ITLB_MISS; - STATE_T5_ITLB_MISS: if(ITLBWriteF) InterlockNextState = STATE_T0_REPLAY; - else InterlockNextState = STATE_T5_ITLB_MISS; - STATE_T7_DITLB_MISS: if(DTLBWriteM) InterlockNextState = STATE_T5_ITLB_MISS; - else InterlockNextState = STATE_T7_DITLB_MISS; - default: InterlockNextState = STATE_T0_READY; + STATE_T0_READY: if (TrapM) InterlockNextState = STATE_T0_READY; + else if(ToDTLBMiss) InterlockNextState = STATE_T3_DTLB_MISS; + else if(ToITLBMissNoReplay) InterlockNextState = STATE_T4_ITLB_MISS; + else if(ToITLBMiss) InterlockNextState = STATE_T5_ITLB_MISS; + else if(ToBoth) InterlockNextState = STATE_T7_DITLB_MISS; + else InterlockNextState = STATE_T0_READY; + STATE_T0_REPLAY: if(DCacheStallM) InterlockNextState = STATE_T0_REPLAY; + else InterlockNextState = STATE_T0_READY; + STATE_T3_DTLB_MISS: if(DTLBWriteM) InterlockNextState = STATE_T0_REPLAY; + else InterlockNextState = STATE_T3_DTLB_MISS; + STATE_T4_ITLB_MISS: if(ITLBWriteF) InterlockNextState = STATE_T0_READY; + else InterlockNextState = STATE_T4_ITLB_MISS; + STATE_T5_ITLB_MISS: if(ITLBWriteF) InterlockNextState = STATE_T0_REPLAY; + else InterlockNextState = STATE_T5_ITLB_MISS; + STATE_T7_DITLB_MISS: if(DTLBWriteM) InterlockNextState = STATE_T5_ITLB_MISS; + else InterlockNextState = STATE_T7_DITLB_MISS; + default: InterlockNextState = STATE_T0_READY; endcase end // always_comb diff --git a/pipelined/src/lsu/lsu.sv b/pipelined/src/lsu/lsu.sv index 48ca50a7d..d980f0216 100644 --- a/pipelined/src/lsu/lsu.sv +++ b/pipelined/src/lsu/lsu.sv @@ -82,6 +82,7 @@ module lsu ( input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0] // *** this one especially has a large note attached to it in pmpchecker. ); + localparam CACHE_ENABLED = `DMEM == `MEM_CACHE; logic [`XLEN+1:0] IEUAdrExtM; logic [`PA_BITS-1:0] LSUPAdrM; logic DTLBMissM; @@ -192,9 +193,9 @@ module lsu ( .DCacheMiss, .DCacheAccess); assign SelUncachedAdr = '0; // value does not matter. end else begin : bus - localparam integer WORDSPERLINE = (`DMEM == `MEM_CACHE) ? `DCACHE_LINELENINBITS/`XLEN : 1; - localparam integer LINELEN = (`DMEM == `MEM_CACHE) ? `DCACHE_LINELENINBITS : `XLEN; - localparam integer LOGWPL = (`DMEM == `MEM_CACHE) ? $clog2(WORDSPERLINE) : 1; + localparam integer WORDSPERLINE = (CACHE_ENABLED) ? `DCACHE_LINELENINBITS/`XLEN : 1; + localparam integer LINELEN = (CACHE_ENABLED) ? `DCACHE_LINELENINBITS : `XLEN; + localparam integer LOGWPL = (CACHE_ENABLED) ? $clog2(WORDSPERLINE) : 1; logic [LINELEN-1:0] ReadDataLineM; logic [LINELEN-1:0] DCacheBusWriteData; logic [`PA_BITS-1:0] DCacheBusAdr; @@ -206,7 +207,7 @@ module lsu ( logic SelBus; logic [LOGWPL-1:0] WordCount; - busdp #(WORDSPERLINE, LINELEN, LOGWPL, 1) busdp( + busdp #(WORDSPERLINE, LINELEN, LOGWPL, CACHE_ENABLED) busdp( .clk, .reset, .LSUBusHRDATA, .LSUBusAck, .LSUBusWrite, .LSUBusRead, .LSUBusSize, .WordCount, .LSUBusWriteCrit, @@ -224,7 +225,7 @@ module lsu ( .y(WordOffsetAddr)); // *** can reduce width of mux. only need the offset. - if(`DMEM == `MEM_CACHE) begin : dcache + if(CACHE_ENABLED) begin : dcache logic [1:0] RW, Atomic; assign RW = CacheableM ? LSURWM : 2'b00; // AND gate assign Atomic = CacheableM ? LSUAtomicM : 2'b00; // AND gate diff --git a/pipelined/src/lsu/lsuvirtmen.sv b/pipelined/src/lsu/lsuvirtmen.sv index 1e32bd9f4..0db6ebb16 100644 --- a/pipelined/src/lsu/lsuvirtmen.sv +++ b/pipelined/src/lsu/lsuvirtmen.sv @@ -78,13 +78,12 @@ module lsuvirtmem( logic ITLBMissOrDAFaultF, ITLBMissOrDAFaultNoTrapF; logic DTLBMissOrDAFaultM, DTLBMissOrDAFaultNoTrapM; - assign AnyCPUReqM = (|MemRWM) | (|AtomicM); assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF); assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM); assign ITLBMissOrDAFaultNoTrapF = ITLBMissOrDAFaultF & ~TrapM; assign DTLBMissOrDAFaultNoTrapM = DTLBMissOrDAFaultM & ~TrapM; interlockfsm interlockfsm ( - .clk, .reset, .AnyCPUReqM, .ITLBMissOrDAFaultF, .ITLBWriteF, + .clk, .reset, .MemRWM, .AtomicM, .ITLBMissOrDAFaultF, .ITLBWriteF, .DTLBMissOrDAFaultM, .DTLBWriteM, .TrapM, .DCacheStallM, .InterlockStall, .SelReplayCPURequest, .SelHPTW, .IgnoreRequestTLB, .IgnoreRequestTrapM); hptw hptw( // *** remove logic from (), mention this in style guide CH3