This commit is contained in:
bbracker 2022-02-25 23:51:48 +00:00
commit e3858c7008
9 changed files with 170 additions and 131 deletions

View File

@ -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}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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