mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally into main
This commit is contained in:
commit
e3858c7008
@ -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}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user