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

View File

@ -1,3 +1,6 @@
IMAGES := ${RISCV}/buildroot/output/images
DIS := ${IMAGES}/disassembly
all: all:
make disassemble make disassemble
make generate make generate
@ -7,15 +10,28 @@ generate:
dtc -I dts -O dtb ../devicetree/wally-virt.dts > ${RISCV}/buildroot/output/images/wally-virt.dtb dtc -I dts -O dtb ../devicetree/wally-virt.dts > ${RISCV}/buildroot/output/images/wally-virt.dtb
disassemble: disassemble:
mkdir ${RISCV}/buildroot/output/images/disassembly mkdir -p ${DIS}
# fw_jump # disassemblies
riscv64-unknown-elf-objdump -D ${RISCV}/buildroot/output/images/fw_jump.elf >> ${RISCV}/buildroot/output/images/disassembly/fw_jump.objdump make -j ${DIS}/fw_jump.objdump ${DIS}/vmlinux.objdump ${DIS}/busybox.objdump
# vmlinux
riscv64-unknown-elf-objdump -D ${RISCV}/buildroot/output/images/vmlinux >> ${RISCV}/buildroot/output/images/disassembly/vmlinux.objdump
# filesystem # filesystem
mkdir ${RISCV}/buildroot/output/images/disassembly/rootfs make ${DIS}/rootfs/bin/busybox
-cd ${RISCV}/buildroot/output/images/disassembly/rootfs; cpio -idv < ../../rootfs.cpio # 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: clean:
rm ${RISCV}/buildroot/output/images/wally-virt.dtb rm -f ${IMAGES}/wally-virt.dtb
rm -rf ${RISCV}/buildroot/output/images/disassembly 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 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 vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084
#-- Run the Simulation #-- Run the Simulation
run -all
add log -recursive /* add log -recursive /*
do linux-wave.do do linux-wave.do
run -all run -all

View File

@ -76,15 +76,14 @@ module ifu (
input logic [1:0] STATUS_MPP, input logic [1:0] STATUS_MPP,
input logic ITLBWriteF, ITLBFlushF, input logic ITLBWriteF, ITLBFlushF,
output logic ITLBMissF, InstrDAPageFaultF, 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 [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0],
output logic InstrAccessFaultF, output logic InstrAccessFaultF,
output logic ICacheAccess, output logic ICacheAccess,
output logic ICacheMiss output logic ICacheMiss
); );
localparam CACHE_ENABLED = `IMEM == `MEM_CACHE;
(* mark_debug = "true" *) logic [`XLEN-1:0] PCCorrectE, UnalignedPCNextF, PCNextF; (* mark_debug = "true" *) logic [`XLEN-1:0] PCCorrectE, UnalignedPCNextF, PCNextF;
logic BranchMisalignedFaultE; logic BranchMisalignedFaultE;
logic PrivilegedChangePCM; logic PrivilegedChangePCM;
logic IllegalCompInstrD; logic IllegalCompInstrD;
@ -120,14 +119,14 @@ module ifu (
assign PCFExt = {2'b00, PCFSpill}; assign PCFExt = {2'b00, PCFSpill};
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Spill Support *** add other banners // Spill Support
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
if(`C_SUPPORTED) begin : SpillSupport if(`C_SUPPORTED) begin : SpillSupport
spillsupport spillsupport(.clk, .reset, .StallF, .PCF, .PCPlusUpperF, .PCNextF, .InstrRawF, spillsupport spillsupport(.clk, .reset, .StallF, .PCF, .PCPlusUpperF, .PCNextF, .InstrRawF,
.IFUCacheBusStallF, .ITLBMissF, .PCNextFSpill, .PCFSpill, .InstrDAPageFaultF, .IFUCacheBusStallF, .ITLBMissF, .PCNextFSpill, .PCFSpill,
.SelNextSpillF, .PostSpillInstrRawF, .CompressedF); .SelNextSpillF, .PostSpillInstrRawF, .CompressedF);
end else begin : NoSpillSupport end else begin : NoSpillSupport
assign PCNextFSpill = PCNextF; assign PCNextFSpill = PCNextF;
assign PCFSpill = PCF; assign PCFSpill = PCF;
@ -161,7 +160,7 @@ module ifu (
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW); .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
end else begin end else begin
assign {ITLBMissF, InstrAccessFaultF, InstrPageFaultF} = '0; assign {ITLBMissF, InstrAccessFaultF, InstrPageFaultF, InstrDAPageFaultF} = '0;
assign PCPF = PCFExt[`PA_BITS-1:0]; assign PCPF = PCFExt[`PA_BITS-1:0];
assign CacheableF = '1; assign CacheableF = '1;
end end
@ -182,8 +181,8 @@ module ifu (
.DCacheCommittedM(), .DCacheMiss(ICacheMiss), .DCacheAccess(ICacheAccess)); .DCacheCommittedM(), .DCacheMiss(ICacheMiss), .DCacheAccess(ICacheAccess));
end else begin : bus end else begin : bus
localparam integer WORDSPERLINE = (`IMEM == `MEM_CACHE) ? `ICACHE_LINELENINBITS/`XLEN : 1; localparam integer WORDSPERLINE = (CACHE_ENABLED) ? `ICACHE_LINELENINBITS/`XLEN : 1;
localparam integer LINELEN = (`IMEM == `MEM_CACHE) ? `ICACHE_LINELENINBITS : `XLEN; localparam integer LINELEN = (CACHE_ENABLED) ? `ICACHE_LINELENINBITS : `XLEN;
localparam integer LOGWPL = (`DMEM == `MEM_CACHE) ? $clog2(WORDSPERLINE) : 1; localparam integer LOGWPL = (`DMEM == `MEM_CACHE) ? $clog2(WORDSPERLINE) : 1;
logic [LINELEN-1:0] ReadDataLine; logic [LINELEN-1:0] ReadDataLine;
logic [LINELEN-1:0] ICacheBusWriteData; logic [LINELEN-1:0] ICacheBusWriteData;
@ -193,7 +192,7 @@ module ifu (
logic [31:0] temp; logic [31:0] temp;
logic SelUncachedAdr; logic SelUncachedAdr;
busdp #(WORDSPERLINE, LINELEN, LOGWPL) busdp #(WORDSPERLINE, LINELEN, LOGWPL, CACHE_ENABLED)
busdp(.clk, .reset, busdp(.clk, .reset,
.LSUBusHRDATA(IFUBusHRDATA), .LSUBusAck(IFUBusAck), .LSUBusWrite(), .LSUBusWriteCrit(), .LSUBusHRDATA(IFUBusHRDATA), .LSUBusAck(IFUBusAck), .LSUBusWrite(), .LSUBusWriteCrit(),
.LSUBusRead(IFUBusRead), .LSUBusSize(), .LSUBusRead(IFUBusRead), .LSUBusSize(),
@ -210,7 +209,7 @@ module ifu (
.s(SelUncachedAdr), .y(AllInstrRawF[31:0])); .s(SelUncachedAdr), .y(AllInstrRawF[31:0]));
if(`IMEM == `MEM_CACHE) begin : icache if(CACHE_ENABLED) begin : icache
logic [1:0] IFURWF; logic [1:0] IFURWF;
assign IFURWF = CacheableF ? 2'b10 : 2'b00; assign IFURWF = CacheableF ? 2'b10 : 2'b00;
@ -247,18 +246,28 @@ module ifu (
flopenl #(32) AlignedInstrRawDFlop(clk, reset, ~StallD, FlushD ? nop : PostSpillInstrRawF, nop, InstrRawD); flopenl #(32) AlignedInstrRawDFlop(clk, reset, ~StallD, FlushD ? nop : PostSpillInstrRawF, nop, InstrRawD);
////////////////////////////////////////////////////////////////////////////////////////////////
// PCNextF logic
////////////////////////////////////////////////////////////////////////////////////////////////
assign PrivilegedChangePCM = RetM | TrapM; 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) pcmux1(.d0(PCNext0F), .d1(PCCorrectE), .s(BPPredWrongE), .y(PCNext1F));
mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(PCBPWrongInvalidate), .s(InvalidateICacheM), .y(PCNext2F)); if(CACHE_ENABLED)
mux2 #(`XLEN) pcmux3(.d0(PCNext2F), .d1(PrivilegedNextPCM), .s(PrivilegedChangePCM), .y(UnalignedPCNextF)); 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 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); flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF);
// branch and jump predictor ////////////////////////////////////////////////////////////////////////////////////////////////
// Branch and Jump Predictor
////////////////////////////////////////////////////////////////////////////////////////////////
if (`BPRED_ENABLED) begin : bpred if (`BPRED_ENABLED) begin : bpred
logic BPPredWrongM; logic BPPredWrongM;
logic SelBPPredF; logic SelBPPredF;
@ -295,6 +304,9 @@ module ifu (
else PCPlus2or4F = {PCF[`XLEN-1:2], 2'b10}; else PCPlus2or4F = {PCF[`XLEN-1:2], 2'b10};
else PCPlus2or4F = {PCPlusUpperF, PCF[1:0]}; // add 4 else PCPlus2or4F = {PCPlusUpperF, PCF[1:0]}; // add 4
////////////////////////////////////////////////////////////////////////////////////////////////
// Decode stage pipeline register and compressed instruction decoding.
////////////////////////////////////////////////////////////////////////////////////////////////
// Decode stage pipeline register and logic // Decode stage pipeline register and logic
flopenrc #(`XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD); flopenrc #(`XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD);

View File

@ -42,6 +42,7 @@ module spillsupport (
input logic [31:0] InstrRawF, input logic [31:0] InstrRawF,
input logic IFUCacheBusStallF, input logic IFUCacheBusStallF,
input logic ITLBMissF, input logic ITLBMissF,
input logic InstrDAPageFaultF,
output logic [`XLEN-1:0] PCNextFSpill, output logic [`XLEN-1:0] PCNextFSpill,
output logic [`XLEN-1:0] PCFSpill, output logic [`XLEN-1:0] PCFSpill,
output logic SelNextSpillF, output logic SelNextSpillF,
@ -50,44 +51,41 @@ module spillsupport (
localparam integer SPILLTHRESHOLD = (`IMEM == `MEM_CACHE) ? `ICACHE_LINELENINBITS/32 : 1; localparam integer SPILLTHRESHOLD = (`IMEM == `MEM_CACHE) ? `ICACHE_LINELENINBITS/32 : 1;
logic [`XLEN-1:0] PCPlus2F; logic [`XLEN-1:0] PCPlus2F;
logic TakeSpillF; logic TakeSpillF;
logic SpillF; logic SpillF;
logic SelSpillF, SpillSaveF; logic SelSpillF, SpillSaveF;
logic [15:0] SpillDataLine0; 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 mux2 #(`XLEN) pcplus2mux(.d0({PCF[`XLEN-1:2], 2'b10}), .d1({PCPlusUpperF, 2'b00}),
// this exists only if there are compressed instructions. .s(PCF[1]), .y(PCPlus2F));
// reuse PC+2/4 circuitry to avoid needing a second CPA to add 2 mux2 #(`XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelNextSpillF),
mux2 #(`XLEN) pcplus2mux(.d0({PCF[`XLEN-1:2], 2'b10}), .d1({PCPlusUpperF, 2'b00}), .s(PCF[1]), .y(PCPlus2F)); .y(PCNextFSpill));
mux2 #(`XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelNextSpillF), .y(PCNextFSpill));
mux2 #(`XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCFSpill)); mux2 #(`XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCFSpill));
assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1]; assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1];
assign TakeSpillF = SpillF & ~IFUCacheBusStallF & ~(ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF));
typedef enum logic [1:0] {STATE_SPILL_READY, STATE_SPILL_SPILL} statetype;
(* mark_debug = "true" *) statetype CurrState, NextState;
always_ff @(posedge clk) always_ff @(posedge clk)
if (reset) CurrState <= #1 STATE_SPILL_READY; if (reset) CurrState <= #1 STATE_READY;
else CurrState <= #1 NextState; else CurrState <= #1 NextState;
assign TakeSpillF = SpillF & ~IFUCacheBusStallF & ~ITLBMissF;
always_comb begin always_comb begin
case (CurrState) case (CurrState)
STATE_SPILL_READY: if (TakeSpillF) NextState = STATE_SPILL_SPILL; STATE_READY: if (TakeSpillF) NextState = STATE_SPILL;
else NextState = STATE_SPILL_READY; else NextState = STATE_READY;
STATE_SPILL_SPILL: if(IFUCacheBusStallF | StallF) NextState = STATE_SPILL_SPILL; STATE_SPILL: if(IFUCacheBusStallF | StallF) NextState = STATE_SPILL;
else NextState = STATE_SPILL_READY; else NextState = STATE_READY;
default: NextState = STATE_SPILL_READY; default: NextState = STATE_READY;
endcase endcase
end end
assign SelSpillF = (CurrState == STATE_SPILL_SPILL); assign SelSpillF = (CurrState == STATE_SPILL);
assign SelNextSpillF = (CurrState == STATE_SPILL_READY & TakeSpillF) | assign SelNextSpillF = (CurrState == STATE_READY & TakeSpillF) |
(CurrState == STATE_SPILL_SPILL & IFUCacheBusStallF); (CurrState == STATE_SPILL & IFUCacheBusStallF);
assign SpillSaveF = (CurrState == STATE_SPILL_READY) & TakeSpillF; assign SpillSaveF = (CurrState == STATE_READY) & TakeSpillF;
flopenr #(16) SpillInstrReg(.clk(clk), flopenr #(16) SpillInstrReg(.clk(clk),
.en(SpillSaveF), .en(SpillSaveF),
@ -95,7 +93,8 @@ module spillsupport (
.d((`IMEM == `MEM_CACHE) ? InstrRawF[15:0] : InstrRawF[31:16]), .d((`IMEM == `MEM_CACHE) ? InstrRawF[15:0] : InstrRawF[31:16]),
.q(SpillDataLine0)); .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; assign CompressedF = PostSpillInstrRawF[1:0] != 2'b11;
endmodule endmodule

View File

@ -34,7 +34,7 @@
`include "wally-config.vh" `include "wally-config.vh"
module busdp #(parameter WORDSPERLINE, LINELEN, LOGWPL, LSU=0) module busdp #(parameter WORDSPERLINE, LINELEN, LOGWPL, CACHE_ENABLED)
( (
input logic clk, reset, input logic clk, reset,
// bus interface // bus interface
@ -66,21 +66,21 @@ module busdp #(parameter WORDSPERLINE, LINELEN, LOGWPL, LSU=0)
output logic BusCommittedM); 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; logic [`PA_BITS-1:0] LocalLSUBusAdr;
genvar index; genvar index;
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
flopen #(`XLEN) fb(.clk, .en(LSUBusAck & LSUBusRead & (index == WordCount)), logic [WORDSPERLINE-1:0] CaptureWord;
.d(LSUBusHRDATA), .q(DCacheBusWriteData[(index+1)*`XLEN-1:index*`XLEN])); 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 end
mux2 #(`PA_BITS) localadrmux(DCacheBusAdr, LSUPAdrM, SelUncachedAdr, LocalLSUBusAdr); mux2 #(`PA_BITS) localadrmux(DCacheBusAdr, LSUPAdrM, SelUncachedAdr, LocalLSUBusAdr);
assign LSUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + 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)); .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, busfsm(.clk, .reset, .IgnoreRequest, .LSURWM, .DCacheFetchLine, .DCacheWriteLine,
.LSUBusAck, .CPUBusy, .CacheableM, .BusStall, .LSUBusWrite, .LSUBusWriteCrit, .LSUBusRead, .LSUBusAck, .CPUBusy, .CacheableM, .BusStall, .LSUBusWrite, .LSUBusWriteCrit, .LSUBusRead,
.DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount); .DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount);

View File

@ -32,7 +32,7 @@
module busfsm #(parameter integer WordCountThreshold, module busfsm #(parameter integer WordCountThreshold,
parameter integer LOGWPL, parameter logic CacheEnabled ) parameter integer LOGWPL, parameter logic CACHE_ENABLED )
(input logic clk, (input logic clk,
input logic reset, input logic reset,
@ -88,7 +88,7 @@ module busfsm #(parameter integer WordCountThreshold,
assign WordCountFlag = (WordCount == WordCountThreshold[LOGWPL-1:0]); assign WordCountFlag = (WordCount == WordCountThreshold[LOGWPL-1:0]);
assign CntEn = PreCntEn & LSUBusAck; assign CntEn = PreCntEn & LSUBusAck;
assign UnCachedAccess = ~CacheEnabled | ~CacheableM; assign UnCachedAccess = ~CACHE_ENABLED | ~CacheableM;
always_ff @(posedge clk) always_ff @(posedge clk)
if (reset) BusCurrState <= #1 STATE_BUS_READY; if (reset) BusCurrState <= #1 STATE_BUS_READY;
@ -96,27 +96,27 @@ module busfsm #(parameter integer WordCountThreshold,
always_comb begin always_comb begin
case(BusCurrState) case(BusCurrState)
STATE_BUS_READY: if(IgnoreRequest) BusNextState = STATE_BUS_READY; STATE_BUS_READY: if(IgnoreRequest) BusNextState = STATE_BUS_READY;
else if(LSURWM[0] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_WRITE; else if(LSURWM[0] & UnCachedAccess) BusNextState = STATE_BUS_UNCACHED_WRITE;
else if(LSURWM[1] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_READ; else if(LSURWM[1] & UnCachedAccess) BusNextState = STATE_BUS_UNCACHED_READ;
else if(DCacheFetchLine) BusNextState = STATE_BUS_FETCH; else if(DCacheFetchLine) BusNextState = STATE_BUS_FETCH;
else if(DCacheWriteLine) BusNextState = STATE_BUS_WRITE; else if(DCacheWriteLine) BusNextState = STATE_BUS_WRITE;
else BusNextState = STATE_BUS_READY; else BusNextState = STATE_BUS_READY;
STATE_BUS_UNCACHED_WRITE: if(LSUBusAck) BusNextState = STATE_BUS_UNCACHED_WRITE_DONE; STATE_BUS_UNCACHED_WRITE: if(LSUBusAck) BusNextState = STATE_BUS_UNCACHED_WRITE_DONE;
else BusNextState = STATE_BUS_UNCACHED_WRITE; else BusNextState = STATE_BUS_UNCACHED_WRITE;
STATE_BUS_UNCACHED_READ: if(LSUBusAck) BusNextState = STATE_BUS_UNCACHED_READ_DONE; STATE_BUS_UNCACHED_READ: if(LSUBusAck) BusNextState = STATE_BUS_UNCACHED_READ_DONE;
else BusNextState = STATE_BUS_UNCACHED_READ; else BusNextState = STATE_BUS_UNCACHED_READ;
STATE_BUS_UNCACHED_WRITE_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; STATE_BUS_UNCACHED_WRITE_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
else BusNextState = STATE_BUS_READY; else BusNextState = STATE_BUS_READY;
STATE_BUS_UNCACHED_READ_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; STATE_BUS_UNCACHED_READ_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
else BusNextState = STATE_BUS_READY; else BusNextState = STATE_BUS_READY;
STATE_BUS_CPU_BUSY: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; STATE_BUS_CPU_BUSY: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
else BusNextState = STATE_BUS_READY; else BusNextState = STATE_BUS_READY;
STATE_BUS_FETCH: if (WordCountFlag & LSUBusAck) BusNextState = STATE_BUS_READY; STATE_BUS_FETCH: if (WordCountFlag & LSUBusAck) BusNextState = STATE_BUS_READY;
else BusNextState = STATE_BUS_FETCH; else BusNextState = STATE_BUS_FETCH;
STATE_BUS_WRITE: if(WordCountFlag & LSUBusAck) BusNextState = STATE_BUS_READY; STATE_BUS_WRITE: if(WordCountFlag & LSUBusAck) BusNextState = STATE_BUS_READY;
else BusNextState = STATE_BUS_WRITE; else BusNextState = STATE_BUS_WRITE;
default: BusNextState = STATE_BUS_READY; default: BusNextState = STATE_BUS_READY;
endcase endcase
end end
@ -128,14 +128,14 @@ module busfsm #(parameter integer WordCountThreshold,
(BusCurrState == STATE_BUS_FETCH) | (BusCurrState == STATE_BUS_FETCH) |
(BusCurrState == STATE_BUS_WRITE); (BusCurrState == STATE_BUS_WRITE);
assign PreCntEn = 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); (BusCurrState == STATE_BUS_UNCACHED_WRITE);
assign LSUBusWrite = UnCachedLSUBusWrite | (BusCurrState == STATE_BUS_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_UNCACHED_WRITE) |
(BusCurrState == STATE_BUS_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); (BusCurrState == STATE_BUS_UNCACHED_READ);
assign LSUBusRead = UnCachedLSUBusRead | (BusCurrState == STATE_BUS_FETCH) | (BusCurrState == STATE_BUS_READY & DCacheFetchLine); 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_READ_DONE |
BusCurrState == STATE_BUS_UNCACHED_WRITE | BusCurrState == STATE_BUS_UNCACHED_WRITE |
BusCurrState == STATE_BUS_UNCACHED_WRITE_DONE) | BusCurrState == STATE_BUS_UNCACHED_WRITE_DONE) |
~CacheEnabled; // if no dcache always select uncachedadr. ~CACHE_ENABLED; // if no dcache always select uncachedadr.
endmodule endmodule

View File

@ -31,33 +31,44 @@
`include "wally-config.vh" `include "wally-config.vh"
module interlockfsm module interlockfsm(
(input logic clk, input logic clk,
input logic reset, input logic reset,
input logic AnyCPUReqM, input logic [1:0] MemRWM,
input logic ITLBMissOrDAFaultF, input logic [1:0] AtomicM,
input logic ITLBWriteF, input logic ITLBMissOrDAFaultF,
input logic DTLBMissOrDAFaultM, input logic ITLBWriteF,
input logic DTLBWriteM, input logic DTLBMissOrDAFaultM,
input logic TrapM, input logic DTLBWriteM,
input logic DCacheStallM, input logic TrapM,
input logic DCacheStallM,
output logic InterlockStall, output logic InterlockStall,
output logic SelReplayCPURequest, output logic SelReplayCPURequest,
output logic SelHPTW, output logic SelHPTW,
output logic IgnoreRequestTLB, output logic IgnoreRequestTLB,
output logic IgnoreRequestTrapM); output logic IgnoreRequestTrapM);
logic ToITLBMiss;
logic ToITLBMissNoReplay;
logic ToDTLBMiss;
logic ToBoth;
logic AnyCPUReqM;
typedef enum logic[2:0] {STATE_T0_READY, typedef enum logic[2:0] {STATE_T0_READY,
STATE_T0_REPLAY, STATE_T0_REPLAY,
STATE_T3_DTLB_MISS, STATE_T3_DTLB_MISS,
STATE_T4_ITLB_MISS, STATE_T4_ITLB_MISS,
STATE_T5_ITLB_MISS, STATE_T5_ITLB_MISS,
STATE_T7_DITLB_MISS} statetype; STATE_T7_DITLB_MISS} statetype;
(* mark_debug = "true" *) statetype InterlockCurrState, InterlockNextState; (* 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) always_ff @(posedge clk)
if (reset) InterlockCurrState <= #1 STATE_T0_READY; if (reset) InterlockCurrState <= #1 STATE_T0_READY;
@ -65,23 +76,23 @@ module interlockfsm
always_comb begin always_comb begin
case(InterlockCurrState) case(InterlockCurrState)
STATE_T0_READY: if (TrapM) InterlockNextState = STATE_T0_READY; STATE_T0_READY: if (TrapM) InterlockNextState = STATE_T0_READY;
else if(~ITLBMissOrDAFaultF & DTLBMissOrDAFaultM & AnyCPUReqM) InterlockNextState = STATE_T3_DTLB_MISS; else if(ToDTLBMiss) InterlockNextState = STATE_T3_DTLB_MISS;
else if(ITLBMissOrDAFaultF & ~DTLBMissOrDAFaultM & ~AnyCPUReqM) InterlockNextState = STATE_T4_ITLB_MISS; else if(ToITLBMissNoReplay) InterlockNextState = STATE_T4_ITLB_MISS;
else if(ITLBMissOrDAFaultF & ~DTLBMissOrDAFaultM & AnyCPUReqM) InterlockNextState = STATE_T5_ITLB_MISS; else if(ToITLBMiss) InterlockNextState = STATE_T5_ITLB_MISS;
else if(ITLBMissOrDAFaultF & DTLBMissOrDAFaultM & AnyCPUReqM) InterlockNextState = STATE_T7_DITLB_MISS; else if(ToBoth) InterlockNextState = STATE_T7_DITLB_MISS;
else InterlockNextState = STATE_T0_READY; else InterlockNextState = STATE_T0_READY;
STATE_T0_REPLAY: if(DCacheStallM) InterlockNextState = STATE_T0_REPLAY; STATE_T0_REPLAY: if(DCacheStallM) InterlockNextState = STATE_T0_REPLAY;
else InterlockNextState = STATE_T0_READY; else InterlockNextState = STATE_T0_READY;
STATE_T3_DTLB_MISS: if(DTLBWriteM) InterlockNextState = STATE_T0_REPLAY; STATE_T3_DTLB_MISS: if(DTLBWriteM) InterlockNextState = STATE_T0_REPLAY;
else InterlockNextState = STATE_T3_DTLB_MISS; else InterlockNextState = STATE_T3_DTLB_MISS;
STATE_T4_ITLB_MISS: if(ITLBWriteF) InterlockNextState = STATE_T0_READY; STATE_T4_ITLB_MISS: if(ITLBWriteF) InterlockNextState = STATE_T0_READY;
else InterlockNextState = STATE_T4_ITLB_MISS; else InterlockNextState = STATE_T4_ITLB_MISS;
STATE_T5_ITLB_MISS: if(ITLBWriteF) InterlockNextState = STATE_T0_REPLAY; STATE_T5_ITLB_MISS: if(ITLBWriteF) InterlockNextState = STATE_T0_REPLAY;
else InterlockNextState = STATE_T5_ITLB_MISS; else InterlockNextState = STATE_T5_ITLB_MISS;
STATE_T7_DITLB_MISS: if(DTLBWriteM) InterlockNextState = STATE_T5_ITLB_MISS; STATE_T7_DITLB_MISS: if(DTLBWriteM) InterlockNextState = STATE_T5_ITLB_MISS;
else InterlockNextState = STATE_T7_DITLB_MISS; else InterlockNextState = STATE_T7_DITLB_MISS;
default: InterlockNextState = STATE_T0_READY; default: InterlockNextState = STATE_T0_READY;
endcase endcase
end // always_comb 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. 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 [`XLEN+1:0] IEUAdrExtM;
logic [`PA_BITS-1:0] LSUPAdrM; logic [`PA_BITS-1:0] LSUPAdrM;
logic DTLBMissM; logic DTLBMissM;
@ -192,9 +193,9 @@ module lsu (
.DCacheMiss, .DCacheAccess); .DCacheMiss, .DCacheAccess);
assign SelUncachedAdr = '0; // value does not matter. assign SelUncachedAdr = '0; // value does not matter.
end else begin : bus end else begin : bus
localparam integer WORDSPERLINE = (`DMEM == `MEM_CACHE) ? `DCACHE_LINELENINBITS/`XLEN : 1; localparam integer WORDSPERLINE = (CACHE_ENABLED) ? `DCACHE_LINELENINBITS/`XLEN : 1;
localparam integer LINELEN = (`DMEM == `MEM_CACHE) ? `DCACHE_LINELENINBITS : `XLEN; localparam integer LINELEN = (CACHE_ENABLED) ? `DCACHE_LINELENINBITS : `XLEN;
localparam integer LOGWPL = (`DMEM == `MEM_CACHE) ? $clog2(WORDSPERLINE) : 1; localparam integer LOGWPL = (CACHE_ENABLED) ? $clog2(WORDSPERLINE) : 1;
logic [LINELEN-1:0] ReadDataLineM; logic [LINELEN-1:0] ReadDataLineM;
logic [LINELEN-1:0] DCacheBusWriteData; logic [LINELEN-1:0] DCacheBusWriteData;
logic [`PA_BITS-1:0] DCacheBusAdr; logic [`PA_BITS-1:0] DCacheBusAdr;
@ -206,7 +207,7 @@ module lsu (
logic SelBus; logic SelBus;
logic [LOGWPL-1:0] WordCount; logic [LOGWPL-1:0] WordCount;
busdp #(WORDSPERLINE, LINELEN, LOGWPL, 1) busdp( busdp #(WORDSPERLINE, LINELEN, LOGWPL, CACHE_ENABLED) busdp(
.clk, .reset, .clk, .reset,
.LSUBusHRDATA, .LSUBusAck, .LSUBusWrite, .LSUBusRead, .LSUBusSize, .LSUBusHRDATA, .LSUBusAck, .LSUBusWrite, .LSUBusRead, .LSUBusSize,
.WordCount, .LSUBusWriteCrit, .WordCount, .LSUBusWriteCrit,
@ -224,7 +225,7 @@ module lsu (
.y(WordOffsetAddr)); // *** can reduce width of mux. only need the offset. .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; logic [1:0] RW, Atomic;
assign RW = CacheableM ? LSURWM : 2'b00; // AND gate assign RW = CacheableM ? LSURWM : 2'b00; // AND gate
assign Atomic = CacheableM ? LSUAtomicM : 2'b00; // AND gate assign Atomic = CacheableM ? LSUAtomicM : 2'b00; // AND gate

View File

@ -78,13 +78,12 @@ module lsuvirtmem(
logic ITLBMissOrDAFaultF, ITLBMissOrDAFaultNoTrapF; logic ITLBMissOrDAFaultF, ITLBMissOrDAFaultNoTrapF;
logic DTLBMissOrDAFaultM, DTLBMissOrDAFaultNoTrapM; logic DTLBMissOrDAFaultM, DTLBMissOrDAFaultNoTrapM;
assign AnyCPUReqM = (|MemRWM) | (|AtomicM);
assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF); assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF);
assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM); assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM);
assign ITLBMissOrDAFaultNoTrapF = ITLBMissOrDAFaultF & ~TrapM; assign ITLBMissOrDAFaultNoTrapF = ITLBMissOrDAFaultF & ~TrapM;
assign DTLBMissOrDAFaultNoTrapM = DTLBMissOrDAFaultM & ~TrapM; assign DTLBMissOrDAFaultNoTrapM = DTLBMissOrDAFaultM & ~TrapM;
interlockfsm interlockfsm ( interlockfsm interlockfsm (
.clk, .reset, .AnyCPUReqM, .ITLBMissOrDAFaultF, .ITLBWriteF, .clk, .reset, .MemRWM, .AtomicM, .ITLBMissOrDAFaultF, .ITLBWriteF,
.DTLBMissOrDAFaultM, .DTLBWriteM, .TrapM, .DCacheStallM, .DTLBMissOrDAFaultM, .DTLBWriteM, .TrapM, .DCacheStallM,
.InterlockStall, .SelReplayCPURequest, .SelHPTW, .IgnoreRequestTLB, .IgnoreRequestTrapM); .InterlockStall, .SelReplayCPURequest, .SelHPTW, .IgnoreRequestTLB, .IgnoreRequestTrapM);
hptw hptw( // *** remove logic from (), mention this in style guide CH3 hptw hptw( // *** remove logic from (), mention this in style guide CH3