Fixes so it now passes ISA test rv64uc-v-rvc ('C' extension, virtual mem). Details below.
Modified:
src_Core/CPU/CsrFile.bsv
Modified method 'trap' to use 'addr' for trap_val (MTVAL) instead of PC
for InstAccessFault and InstPageFault
src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv
Added 'tval' field to Fetch2Fetch3; set the value on TLB faults; send it out in 'FromFetchStage' struct
src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv
In rule doRenamingTrap, pass tval from FromFetchStage struct to ToReorderBuffer struct
src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv
Add 'tval' Ehr to reorderbuffer slot, to accompany 'trap' Ehr.
In method write_enq, store tval from ToReorderBuffer arg into tval Ehr.
In method read_deq, send 'tval' Ehr value into 'ToReorderBuffer' output (goes to CommitStage)
src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv
Modified rule doCommitTrap_flush to take tval from 'ToReorderBuffer' input from ROB,
for InstAccessFault and InstPageFault
LICENSE
README.md
Clarified licensing of MIT code and Bluespec code
Tests/Run_regression.py
Emptied out 'exclude_list'
builds/RV64ADFIMSU_Toooba_verilator/Makefile
Added 'C' to Makefile
This commit is contained in:
@@ -671,11 +671,13 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
tagged Exception .e: begin
|
||||
cause_code = pack(e);
|
||||
trap_val = (case(e)
|
||||
InstAddrMisaligned, InstAccessFault,
|
||||
Breakpoint, InstPageFault: return pc;
|
||||
InstAddrMisaligned, Breakpoint: return pc;
|
||||
|
||||
InstAccessFault, InstPageFault,
|
||||
LoadAddrMisaligned, LoadAccessFault,
|
||||
StoreAddrMisaligned, StoreAccessFault,
|
||||
LoadPageFault, StorePageFault: return addr;
|
||||
|
||||
default: return 0;
|
||||
endcase);
|
||||
end
|
||||
|
||||
@@ -353,7 +353,11 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
|
||||
// record trap info
|
||||
Addr vaddr = ?;
|
||||
if(x.ppc_vaddr_csrData matches tagged VAddr .va) begin
|
||||
if ( (trap == tagged Exception InstAccessFault)
|
||||
|| (trap == tagged Exception InstPageFault)) begin
|
||||
vaddr = x.tval;
|
||||
end
|
||||
else if(x.ppc_vaddr_csrData matches tagged VAddr .va) begin
|
||||
vaddr = va;
|
||||
end
|
||||
let commitTrap_val = Valid (CommitTrap {
|
||||
@@ -366,8 +370,10 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
if (verbosity > 0) begin
|
||||
$display ("instret:%0d PC:0x%0h instr:0x%08h", rg_instret, x.pc, x.orig_inst,
|
||||
" iType:", fshow (x.iType), " [doCommitTrap]");
|
||||
$display ("CommitStage.doCommitTrap: deq_data: ", fshow (x));
|
||||
$display ("CommitStage.doCommitTrap: commitTrap: ", fshow (commitTrap_val));
|
||||
end
|
||||
if (verbose) begin
|
||||
$display ("CommitStage.doCommitTrap_flush: deq_data: ", fshow (x));
|
||||
$display ("CommitStage.doCommitTrap_flush: commitTrap: ", fshow (commitTrap_val));
|
||||
end
|
||||
|
||||
// flush everything. Only increment epoch and stall fetch when we haven
|
||||
|
||||
@@ -110,11 +110,16 @@ typedef struct {
|
||||
Addr phys_pc;
|
||||
Addr pred_next_pc;
|
||||
Maybe#(Exception) cause;
|
||||
Addr tval; // in case of exception
|
||||
Bool access_mmio; // inst fetch from MMIO
|
||||
Bool decode_epoch;
|
||||
Epoch main_epoch;
|
||||
} Fetch2ToFetch3 deriving(Bits, Eq, FShow);
|
||||
|
||||
// TODO: this name 'Fetch3ToDecode' is a misnomer.
|
||||
// The struct passed from doFetch3 to doDecode is Fetch2ToFetch3 (same type as doFetch2 to doFetch3),
|
||||
// and Fetch3ToDecode is used purely internally in doDecode.
|
||||
|
||||
typedef struct {
|
||||
Addr pc;
|
||||
Addr ppc;
|
||||
@@ -134,6 +139,7 @@ typedef struct {
|
||||
Bit #(32) orig_inst; // original 16b or 32b instruction ([1:0] will distinguish 16b or 32b)
|
||||
ArchRegs regs;
|
||||
Maybe#(Exception) cause;
|
||||
Addr tval; // in case of exception
|
||||
} FromFetchStage deriving (Bits, Eq, FShow);
|
||||
|
||||
// train next addr pred (BTB)
|
||||
@@ -462,6 +468,7 @@ module mkFetchStage(FetchStage);
|
||||
|
||||
// Get TLB response
|
||||
match {.phys_pc, .cause} <- tlb_server.response.get;
|
||||
Addr tval = 0;
|
||||
|
||||
// Access main mem or boot rom if no TLB exception
|
||||
Bool access_mmio = False;
|
||||
@@ -485,12 +492,18 @@ module mkFetchStage(FetchStage);
|
||||
end
|
||||
endcase
|
||||
end
|
||||
else begin
|
||||
// TLB exception: record the request address
|
||||
Addr align32b_mask = 'h3;
|
||||
tval = (in.pc & (~ align32b_mask));
|
||||
end
|
||||
|
||||
let out = Fetch2ToFetch3 {
|
||||
pc: in.pc,
|
||||
phys_pc: phys_pc,
|
||||
pred_next_pc: in.pred_next_pc,
|
||||
cause: cause,
|
||||
tval: tval,
|
||||
access_mmio: access_mmio,
|
||||
decode_epoch: in.decode_epoch,
|
||||
main_epoch: in.main_epoch };
|
||||
@@ -645,6 +658,7 @@ module mkFetchStage(FetchStage);
|
||||
cause: fetch3In.cause
|
||||
};
|
||||
let cause = in.cause;
|
||||
Addr tval = fetch3In.tval;
|
||||
if (verbose)
|
||||
$display("Decode: %0d in = ", i, fshow (in));
|
||||
|
||||
@@ -655,9 +669,10 @@ module mkFetchStage(FetchStage);
|
||||
|
||||
let decode_result = decode(in.inst); // Decode 32b inst, or 32b expansion of 16b inst
|
||||
|
||||
// update cause if there was not an earlier detected exception
|
||||
// update cause and tval if decode exception and no earlier (TLB) exception
|
||||
if (!isValid(cause)) begin
|
||||
cause = decode_result.illegalInst ? tagged Valid IllegalInst : tagged Invalid;
|
||||
tval = fetch3In.tval;
|
||||
end
|
||||
|
||||
let dInst = decode_result.dInst;
|
||||
@@ -744,7 +759,8 @@ module mkFetchStage(FetchStage);
|
||||
dInst: dInst,
|
||||
orig_inst: inst_data[i].orig_inst,
|
||||
regs: decode_result.regs,
|
||||
cause: cause };
|
||||
cause: cause,
|
||||
tval: tval};
|
||||
out_fifo.enqS[i].enq(out);
|
||||
if (verbosity > 0)
|
||||
$display("Decode: ", fshow(out));
|
||||
|
||||
@@ -234,6 +234,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
let dInst = x.dInst;
|
||||
let arch_regs = x.regs;
|
||||
let cause = x.cause;
|
||||
let tval = x.tval;
|
||||
|
||||
if(verbose) $display("[doRenaming] trap: ", fshow(x));
|
||||
|
||||
@@ -249,6 +250,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
csr: dInst.csr,
|
||||
claimed_phy_reg: False, // no renaming is done
|
||||
trap: firstTrap,
|
||||
tval: tval,
|
||||
// default values of FullResult
|
||||
ppc_vaddr_csrData: PPC (ppc), // default use PPC
|
||||
fflags: 0,
|
||||
|
||||
@@ -51,6 +51,7 @@ typedef struct {
|
||||
Maybe#(CSR) csr;
|
||||
Bool claimed_phy_reg; // whether we need to commmit renaming
|
||||
Maybe#(Trap) trap;
|
||||
Addr tval; // in case of trap
|
||||
PPCVAddrCSRData ppc_vaddr_csrData;
|
||||
Bit#(5) fflags;
|
||||
Bool will_dirty_fpu_state; // True means 2'b11 will be written to FS
|
||||
@@ -173,6 +174,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
Reg#(Maybe#(CSR)) csr <- mkRegU;
|
||||
Reg#(Bool) claimed_phy_reg <- mkRegU;
|
||||
Ehr#(3, Maybe#(Trap)) trap <- mkEhr(?);
|
||||
Ehr#(3, Addr) tval <- mkEhr(?);
|
||||
Ehr#(TAdd#(2, aluExeNum), PPCVAddrCSRData) ppc_vaddr_csrData <- mkEhr(?);
|
||||
Ehr#(TAdd#(1, fpuMulDivExeNum), Bit#(5)) fflags <- mkEhr(?);
|
||||
Reg#(Bool) will_dirty_fpu_state <- mkRegU;
|
||||
@@ -261,6 +263,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
csr <= x.csr;
|
||||
claimed_phy_reg <= x.claimed_phy_reg;
|
||||
trap[trap_enq_port] <= x.trap;
|
||||
tval[trap_enq_port] <= x.tval;
|
||||
ppc_vaddr_csrData[pvc_enq_port] <= x.ppc_vaddr_csrData;
|
||||
fflags[fflags_enq_port] <= x.fflags;
|
||||
will_dirty_fpu_state <= x.will_dirty_fpu_state;
|
||||
@@ -293,6 +296,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
csr: csr,
|
||||
claimed_phy_reg: claimed_phy_reg,
|
||||
trap: trap[trap_deq_port],
|
||||
tval: tval[trap_deq_port],
|
||||
ppc_vaddr_csrData: ppc_vaddr_csrData[pvc_deq_port],
|
||||
fflags: fflags[fflags_deq_port],
|
||||
will_dirty_fpu_state: will_dirty_fpu_state,
|
||||
@@ -318,6 +322,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
doAssert(!isValid(trap[trap_deqLSQ_port]), "cannot have trap");
|
||||
if(cause matches tagged Valid .e) begin
|
||||
trap[trap_deqLSQ_port] <= Valid (Exception (e));
|
||||
// TODO: shouldn't we record tval here as well?
|
||||
end
|
||||
// record ld misspeculation
|
||||
ldKilled[ldKill_deqLSQ_port] <= ld_killed;
|
||||
|
||||
Reference in New Issue
Block a user