Further additions to Tandem Verification trace info.
Rd value (destination register) of Integer ops supported Trap updates (priv and CSR updates) supported. Still pending: Memory ops Rd value, Fpu Rd value
This commit is contained in:
@@ -46,6 +46,22 @@ import Cur_Cycle :: *;
|
||||
|
||||
import SoC_Map :: *;
|
||||
|
||||
// ================================================================
|
||||
// Information returned on traps.
|
||||
|
||||
typedef struct {
|
||||
Addr new_pc;
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
// The fields below are for tandem verification only
|
||||
Bit #(2) prv;
|
||||
Data status;
|
||||
Data cause;
|
||||
Data epc;
|
||||
`endif
|
||||
} Trap_Updates
|
||||
deriving (Bits, FShow);
|
||||
|
||||
// ================================================================
|
||||
|
||||
interface CsrFile;
|
||||
@@ -59,7 +75,7 @@ interface CsrFile;
|
||||
|
||||
// Methods for handling traps
|
||||
method Maybe#(Interrupt) pending_interrupt;
|
||||
method ActionValue#(Addr) trap(Trap t, Addr pc, Addr faultAddr);
|
||||
method ActionValue#(Trap_Updates) trap(Trap t, Addr pc, Addr faultAddr);
|
||||
method ActionValue#(Addr) sret;
|
||||
method ActionValue#(Addr) mret;
|
||||
|
||||
@@ -276,6 +292,9 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
Reg#(Bit#(1)) sd_reg = readOnlyReg(
|
||||
((xs_reg == 2'b11) || (fs_reg == 2'b11)) ? 1 : 0
|
||||
);
|
||||
function Bit #(1) fn_sd_val (Bit #(2) xs_val, Bit #(2) fs_val);
|
||||
return (((xs_val == 2'b11) || (fs_val == 2'b11)) ? 1 : 0);
|
||||
endfunction
|
||||
Reg#(Bit#(2)) sxl_reg = readOnlyReg(getXLBits);
|
||||
Reg#(Bit#(2)) uxl_reg = readOnlyReg(getXLBits);
|
||||
Reg#(Bit#(1)) tsr_reg <- mkCsrReg(0);
|
||||
@@ -314,6 +333,25 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
ie_vec[prvM], readOnlyReg(1'b0),
|
||||
ie_vec[prvS], ie_vec[prvU]
|
||||
);
|
||||
function Data fn_mstatus_val (Bit #(2) sxl_val, Bit #(2) uxl_val,
|
||||
Bit #(1) tsr_val, Bit #(1) tw_val, Bit #(1) tvm_val,
|
||||
Bit #(1) mxr_val, Bit #(1) sum_val, Bit #(1) mprv_val,
|
||||
Bit #(2) xs_val, Bit #(2) fs_val,
|
||||
Bit #(2) mpp_val, Bit #(1) spp_val,
|
||||
Bit #(1) prev_ie_vec_prvM_val,
|
||||
Bit #(1) prev_ie_vec_prvS_val, Bit #(1) prev_ie_vec_prvU_val,
|
||||
Bit #(1) ie_vec_prvM_val,
|
||||
Bit #(1) ie_vec_prvS_val, Bit #(1) ie_vec_prvU_val);
|
||||
return {fn_sd_val (xs_val, fs_val),
|
||||
27'b0, sxl_val, uxl_val, 9'b0,
|
||||
tsr_val, tw_val, tvm_val, mxr_val, sum_val, mprv_val, xs_val, fs_val,
|
||||
mpp_val, 2'b0, spp_val,
|
||||
prev_ie_vec_prvM_val, 1'b0,
|
||||
prev_ie_vec_prvS_val, prev_ie_vec_prvU_val,
|
||||
ie_vec_prvM_val, 1'b0,
|
||||
ie_vec_prvS_val, ie_vec_prvU_val};
|
||||
endfunction
|
||||
|
||||
// misa
|
||||
Reg#(Data) misa_csr = readOnlyReg({getXLBits, 36'b0, getExtensionBits(isa)});
|
||||
// medeleg: some exceptions don't exist, fix corresponding bits to 0
|
||||
@@ -384,6 +422,10 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
Reg#(Data) mcause_csr = concatReg3(
|
||||
mcause_interrupt_reg, readOnlyReg(59'b0), mcause_code_reg
|
||||
);
|
||||
function Data fn_mcause_val (Bit #(1) mcause_interrupt_val, Bit #(4) mcause_code_val);
|
||||
return { mcause_interrupt_val, 59'b0, mcause_code_val };
|
||||
endfunction
|
||||
|
||||
// mtval (mbadaddr in spike)
|
||||
Reg#(Data) mtval_csr <- mkCsrReg(0);
|
||||
// mip
|
||||
@@ -433,6 +475,24 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
readOnlyReg(2'b0), prev_ie_vec[prvS], prev_ie_vec[prvU],
|
||||
readOnlyReg(2'b0), ie_vec[prvS], ie_vec[prvU]
|
||||
);
|
||||
function Data fn_sstatus_val (Bit #(2) uxl_val,
|
||||
Bit #(1) mxr_val, Bit #(1) sum_val,
|
||||
Bit #(2) xs_val, Bit #(2) fs_val,
|
||||
Bit #(1) spp_val,
|
||||
Bit #(1) prev_ie_vec_prvS_val,
|
||||
Bit #(1) prev_ie_vec_prvU_val,
|
||||
Bit #(1) ie_vec_prvS_val,
|
||||
Bit #(1) ie_vec_prvU_val);
|
||||
return {fn_sd_val (xs_val, fs_val),
|
||||
29'b0, uxl_val, 12'b0,
|
||||
mxr_val, sum_val, 1'b0, xs_val, fs_val,
|
||||
4'b0, spp_val,
|
||||
2'b0,
|
||||
prev_ie_vec_prvS_val, prev_ie_vec_prvU_val,
|
||||
2'b0,
|
||||
ie_vec_prvS_val, ie_vec_prvU_val};
|
||||
endfunction
|
||||
|
||||
// sie: restricted view of mie
|
||||
Reg#(Data) sie_csr = concatReg9(
|
||||
readOnlyReg(54'b0),
|
||||
@@ -468,6 +528,10 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
Reg#(Data) scause_csr = concatReg3(
|
||||
scause_interrupt_reg, readOnlyReg(59'b0), scause_code_reg
|
||||
);
|
||||
function Data fn_scause_val (Bit #(1) scause_interrupt_val, Bit #(4) scause_code_val);
|
||||
return { scause_interrupt_val, 59'b0, scause_code_val };
|
||||
endfunction
|
||||
|
||||
// stval (sbadaddr in spike)
|
||||
Reg#(Data) stval_csr <- mkCsrReg(0);
|
||||
// sip: restricted view of mip
|
||||
@@ -726,7 +790,7 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
end
|
||||
endmethod
|
||||
|
||||
method ActionValue#(Addr) trap(Trap t, Addr pc, Addr addr);
|
||||
method ActionValue#(Trap_Updates) trap(Trap t, Addr pc, Addr addr);
|
||||
// figure out trap cause & trap val
|
||||
Bit#(1) cause_interrupt = 0;
|
||||
Bit#(4) cause_code = 0;
|
||||
@@ -780,7 +844,21 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
scause_code_reg <= cause_code;
|
||||
stval_csr <= trap_val;
|
||||
// return next pc
|
||||
return getNextPc(stvec_mode_low_reg, stvec_base_hi_reg);
|
||||
// return getNextPc(stvec_mode_low_reg, stvec_base_hi_reg);
|
||||
Data sstatus_val = fn_sstatus_val (uxl_reg,
|
||||
mxr_reg, sum_reg,
|
||||
xs_reg, fs_reg,
|
||||
prv_reg [0],
|
||||
/* prev_ie_vec_[prvS] */ ie_vec[prvS],
|
||||
prev_ie_vec [prvU],
|
||||
/* ie_vec [prvS] */ 0,
|
||||
ie_vec [prvU]);
|
||||
Data scause_val = fn_scause_val (cause_interrupt, cause_code);
|
||||
return Trap_Updates {new_pc: getNextPc(stvec_mode_low_reg, stvec_base_hi_reg),
|
||||
prv: prvS,
|
||||
status: sstatus_val,
|
||||
cause: scause_val,
|
||||
epc: pc};
|
||||
end
|
||||
else begin
|
||||
// ie/prv stack
|
||||
@@ -794,7 +872,24 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
mcause_code_reg <= cause_code;
|
||||
mtval_csr <= trap_val;
|
||||
// return next pc
|
||||
return getNextPc(mtvec_mode_low_reg, mtvec_base_hi_reg);
|
||||
// return getNextPc(mtvec_mode_low_reg, mtvec_base_hi_reg);
|
||||
Data mstatus_val = fn_mstatus_val (sxl_reg, uxl_reg,
|
||||
tsr_reg, tw_reg, tvm_reg,
|
||||
mxr_reg, sum_reg, mprv_reg,
|
||||
xs_reg, fs_reg,
|
||||
/* mpp */ prv_reg, spp_reg,
|
||||
/* prev_ie_vec [prvM] */ ie_vec [prvM],
|
||||
prev_ie_vec [prvS],
|
||||
prev_ie_vec [prvU],
|
||||
/* ie_vec [prvM] */ 0,
|
||||
ie_vec [prvS],
|
||||
ie_vec [prvU]);
|
||||
Data mcause_val = fn_mcause_val (cause_interrupt, cause_code);
|
||||
return Trap_Updates {new_pc: getNextPc(mtvec_mode_low_reg, mtvec_base_hi_reg),
|
||||
prv: prvM,
|
||||
status: mstatus_val,
|
||||
cause: mcause_val,
|
||||
epc: pc};
|
||||
end
|
||||
// XXX yield load reservation should be done outside this method
|
||||
endmethod
|
||||
|
||||
@@ -27,14 +27,22 @@ typedef struct {
|
||||
Bit #(64) serial_num; // TV message serial number
|
||||
Addr pc;
|
||||
Bit #(32) orig_inst; // original 16b or 32b instruction ([1:0] will distinguish 16b or 32b)
|
||||
Maybe#(ArchRIndx) dst; // Invalid, GPR or FPR destination ("Rd")
|
||||
IType iType;
|
||||
Maybe#(ArchRIndx) dst; // Invalid, GPR or FPR destination ("Rd")
|
||||
Data dst_data;
|
||||
Maybe #(CSR) csr;
|
||||
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
|
||||
|
||||
// Trap updates
|
||||
Bit #(2) prv;
|
||||
Addr tvec;
|
||||
Data status;
|
||||
Data cause;
|
||||
Data epc;
|
||||
} Trace_Data2
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
|
||||
@@ -71,6 +71,16 @@ module mkTrace_Data2_to_Trace_Data (Trace_Data2_to_Trace_Data_IFC);
|
||||
if (serial_num == 0)
|
||||
td = mkTrace_RESET;
|
||||
|
||||
else if (isValid (td2.trap))
|
||||
td = mkTrace_TRAP (td2.tvec,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
td2.prv,
|
||||
td2.status,
|
||||
td2.cause,
|
||||
td2.epc,
|
||||
td2.tval);
|
||||
|
||||
else if (td2.ppc_vaddr_csrData matches tagged PPC .target_addr
|
||||
&&& (td2.iType == Br))
|
||||
td = mkTrace_OTHER (target_addr, isize, td2.orig_inst);
|
||||
@@ -82,7 +92,7 @@ module mkTrace_Data2_to_Trace_Data (Trace_Data2_to_Trace_Data_IFC);
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
0); // TODO: return-pc
|
||||
td2.dst_data); // return-pc
|
||||
|
||||
else if ( (td2.iType == Alu)
|
||||
|| (td2.iType == Auipc))
|
||||
@@ -90,7 +100,7 @@ module mkTrace_Data2_to_Trace_Data (Trace_Data2_to_Trace_Data_IFC);
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
0); // TODO: rd_val
|
||||
td2.dst_data); // rd_val
|
||||
|
||||
else if (td2.dst matches tagged Valid (tagged Fpu .fpr_rd)
|
||||
&&& (td2.iType == Fpu))
|
||||
@@ -98,7 +108,7 @@ module mkTrace_Data2_to_Trace_Data (Trace_Data2_to_Trace_Data_IFC);
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
fpr_rd,
|
||||
?, // TODO: rdval
|
||||
td2.dst_data, // rdval
|
||||
?, // TODO: Bit#(5) fflags
|
||||
?); // TODO: mstatus)
|
||||
|
||||
@@ -107,7 +117,7 @@ module mkTrace_Data2_to_Trace_Data (Trace_Data2_to_Trace_Data_IFC);
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
?, // TODO: rdval
|
||||
td2.dst_data, // rdval
|
||||
?, // TODO: Bit#(5) fflags
|
||||
?); // TODO: mstatus)
|
||||
|
||||
@@ -117,7 +127,7 @@ module mkTrace_Data2_to_Trace_Data (Trace_Data2_to_Trace_Data_IFC);
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
?, // TODO: rd_val
|
||||
td2.dst_data, // rd_val
|
||||
eaddr);
|
||||
|
||||
else if (td2.ppc_vaddr_csrData matches tagged VAddr .eaddr
|
||||
@@ -157,18 +167,18 @@ module mkTrace_Data2_to_Trace_Data (Trace_Data2_to_Trace_Data_IFC);
|
||||
|| (td2.iType == Sret))
|
||||
td = mkTrace_OTHER (fall_thru_PC, isize, td2.orig_inst);
|
||||
|
||||
else if ( (td2.iType == Amo)
|
||||
|| (td2.iType == Lr)
|
||||
|| (td2.iType == Sc))
|
||||
else if (td2.ppc_vaddr_csrData matches tagged VAddr .eaddr
|
||||
&&& ( (td2.iType == Amo)
|
||||
|| (td2.iType == Lr)
|
||||
|| (td2.iType == Sc)))
|
||||
td = mkTrace_AMO (fall_thru_PC,
|
||||
0, // TODO: funct3
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
0, // TODO: rd_val
|
||||
td2.dst_data, // rd_val
|
||||
0, // TODO: rs2_val
|
||||
0 // TODO: eaddr
|
||||
);
|
||||
eaddr);
|
||||
|
||||
else if ( (td2.iType == Unsupported)
|
||||
|| (td2.iType == Nop)
|
||||
|
||||
@@ -41,6 +41,8 @@ import SpecFifo::*;
|
||||
import HasSpecBits::*;
|
||||
import Bypass::*;
|
||||
|
||||
import Cur_Cycle :: *;
|
||||
|
||||
// ALU pipeline has 4 stages
|
||||
// dispatch -> reg read -> exe -> finish (write reg)
|
||||
// bypass is sent out from the end of exe stage
|
||||
@@ -139,7 +141,7 @@ interface AluExeInput;
|
||||
method Addr rob_getPC(InstTag t);
|
||||
method Addr rob_getPredPC(InstTag t);
|
||||
method Bit #(32) rob_getOrig_Inst (InstTag t);
|
||||
method Action rob_setExecuted(InstTag t, Maybe#(Data) csrData, ControlFlow cf);
|
||||
method Action rob_setExecuted(InstTag t, Data dst_data, Maybe#(Data) csrData, ControlFlow cf);
|
||||
// Fetch stage
|
||||
method Action fetch_train_predictors(FetchTrainBP train);
|
||||
|
||||
@@ -318,6 +320,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
|
||||
// update the instruction in the reorder buffer.
|
||||
inIfc.rob_setExecuted(
|
||||
x.tag,
|
||||
x.data,
|
||||
x.csrData,
|
||||
x.controlFlow
|
||||
);
|
||||
|
||||
@@ -28,6 +28,7 @@ import GetPut::*;
|
||||
import Cntrs::*;
|
||||
import ConfigReg::*;
|
||||
import FIFO::*;
|
||||
import FIFOF::*;
|
||||
import Types::*;
|
||||
import ProcTypes::*;
|
||||
import CCTypes::*;
|
||||
@@ -162,24 +163,42 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
// TODO: we could use fewer bits and allow and recognize wraparound.
|
||||
Reg #(Bit #(64)) rg_serial_num <- mkReg (0);
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
FIFOF #(ToReorderBuffer) f_rob_data <- mkFIFOF;
|
||||
`endif
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
Reg #(Run_State) rg_run_state <- mkReg (RUN_STATE_RUNNING);
|
||||
`endif
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
function Action fa_to_TV (Bit #(64) serial_num, ToReorderBuffer deq_data, Integer way);
|
||||
Integer way0 = 0;
|
||||
|
||||
function Action fa_to_TV (Integer way,
|
||||
Bit #(64) serial_num,
|
||||
ToReorderBuffer deq_data,
|
||||
Trap_Updates trap_updates);
|
||||
action
|
||||
let x = Trace_Data2 {serial_num: serial_num,
|
||||
pc: deq_data.pc,
|
||||
orig_inst: deq_data.orig_inst,
|
||||
dst: deq_data.dst,
|
||||
iType: deq_data.iType,
|
||||
dst: deq_data.dst,
|
||||
dst_data: deq_data.dst_data,
|
||||
csr: deq_data.csr,
|
||||
trap: deq_data.trap,
|
||||
tval: deq_data.tval,
|
||||
ppc_vaddr_csrData: deq_data.ppc_vaddr_csrData,
|
||||
fflags: deq_data.fflags,
|
||||
will_dirty_fpu_state: deq_data.will_dirty_fpu_state};
|
||||
will_dirty_fpu_state: deq_data.will_dirty_fpu_state,
|
||||
|
||||
// Trap updates
|
||||
prv: trap_updates.prv,
|
||||
tvec: trap_updates.new_pc,
|
||||
status: trap_updates.status,
|
||||
cause: trap_updates.cause,
|
||||
epc: trap_updates.epc
|
||||
};
|
||||
inIfc.v_to_TV [way].put (x);
|
||||
endaction
|
||||
endfunction
|
||||
@@ -187,7 +206,8 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
Reg #(Bool) rg_just_after_reset <- mkReg (True);
|
||||
|
||||
rule rl_send_tv_reset (rg_just_after_reset);
|
||||
fa_to_TV (0, ?, 0);
|
||||
Bit #(64) serial_num = 0;
|
||||
fa_to_TV (way0, serial_num, ?, ?);
|
||||
rg_just_after_reset <= False;
|
||||
rg_serial_num <= 1;
|
||||
endrule
|
||||
@@ -474,6 +494,9 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
addr: vaddr
|
||||
});
|
||||
commitTrap <= commitTrap_val;
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
f_rob_data.enq (x); // Save data to be sent to TV in rule doCommitTrap_handle, next
|
||||
`endif
|
||||
|
||||
if (verbosity >= 1) begin
|
||||
$display ("instret:%0d PC:0x%0h instr:0x%08h", rg_serial_num, x.pc, x.orig_inst,
|
||||
@@ -484,11 +507,6 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
$display ("CommitStage.doCommitTrap_flush: commitTrap: ", fshow (commitTrap_val));
|
||||
end
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
fa_to_TV (rg_serial_num, x, 0);
|
||||
`endif
|
||||
rg_serial_num <= rg_serial_num + 1;
|
||||
|
||||
// flush everything. Only increment epoch and stall fetch when we haven
|
||||
// not done it yet (we may have already done them at rename stage)
|
||||
inIfc.killAll;
|
||||
@@ -526,6 +544,11 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
// reset commitTrap
|
||||
commitTrap <= Invalid;
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
let x = f_rob_data.first;
|
||||
f_rob_data.deq;
|
||||
`endif
|
||||
|
||||
// notify commit of interrupt (so MMIO pRq may be handled)
|
||||
if(trap.trap matches tagged Interrupt .inter) begin
|
||||
inIfc.commitCsrInstOrInterrupt;
|
||||
@@ -573,8 +596,15 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
|
||||
if (! debugger_halt) begin
|
||||
// trap handling & redirect
|
||||
let new_pc <- csrf.trap(trap.trap, trap.pc, trap.addr);
|
||||
inIfc.redirectPc(new_pc);
|
||||
// let new_pc <- csrf.trap(trap.trap, trap.pc, trap.addr); // OLD: WITHOUT TV INFO
|
||||
// inIfc.redirectPc(new_pc); // OLD: WITHOUT TV INFO
|
||||
let trap_updates <- csrf.trap(trap.trap, trap.pc, trap.addr);
|
||||
inIfc.redirectPc(trap_updates.new_pc);
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
fa_to_TV (way0, rg_serial_num, x, trap_updates);
|
||||
`endif
|
||||
rg_serial_num <= rg_serial_num + 1;
|
||||
|
||||
// system consistency
|
||||
// TODO spike flushes TLB here, but perhaps it is because spike's TLB
|
||||
@@ -643,7 +673,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
end
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
fa_to_TV (rg_serial_num, x, 0);
|
||||
fa_to_TV (way0, rg_serial_num, x, ?);
|
||||
`endif
|
||||
rg_serial_num <= rg_serial_num + 1;
|
||||
|
||||
@@ -811,7 +841,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
" iType:", fshow (x.iType), " [doCommitNormalInst [%0d]]", i);
|
||||
end
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
fa_to_TV (rg_serial_num + instret, x, i);
|
||||
fa_to_TV (i, rg_serial_num + instret, x, ?);
|
||||
`endif
|
||||
instret = instret + 1;
|
||||
|
||||
|
||||
@@ -347,8 +347,9 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
// just place it in the reorder buffer
|
||||
let y = ToReorderBuffer{pc: pc,
|
||||
orig_inst: orig_inst,
|
||||
dst: arch_regs.dst,
|
||||
iType: dInst.iType,
|
||||
dst: arch_regs.dst,
|
||||
dst_data: ?, // Available only after execution
|
||||
csr: dInst.csr,
|
||||
claimed_phy_reg: False, // no renaming is done
|
||||
trap: firstTrap,
|
||||
@@ -522,8 +523,9 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
RobInstState rob_inst_state = to_exec ? NotDone : Executed;
|
||||
let y = ToReorderBuffer{pc: pc,
|
||||
orig_inst: orig_inst,
|
||||
dst: arch_regs.dst,
|
||||
iType: dInst.iType,
|
||||
dst: arch_regs.dst,
|
||||
dst_data: ?, // Available only after execution
|
||||
csr: dInst.csr,
|
||||
claimed_phy_reg: True, // XXX we always claim a free reg in rename
|
||||
trap: Invalid, // no trap
|
||||
@@ -688,8 +690,9 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
RobInstState rob_inst_state = NotDone; // mem inst always needs execution
|
||||
let y = ToReorderBuffer{pc: pc,
|
||||
orig_inst: orig_inst,
|
||||
dst: arch_regs.dst,
|
||||
iType: dInst.iType,
|
||||
dst: arch_regs.dst,
|
||||
dst_data: ?, // Available only after execution
|
||||
csr: dInst.csr,
|
||||
claimed_phy_reg: True, // XXX we always claim a free reg in rename
|
||||
trap: Invalid, // no trap
|
||||
@@ -1041,8 +1044,9 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
|
||||
let y = ToReorderBuffer{pc: pc,
|
||||
orig_inst: orig_inst,
|
||||
dst: arch_regs.dst,
|
||||
iType: dInst.iType,
|
||||
dst: arch_regs.dst,
|
||||
dst_data: ?, // Available only after execution
|
||||
csr: dInst.csr,
|
||||
claimed_phy_reg: True, // XXX we always claim a free reg in rename
|
||||
trap: Invalid, // no trap
|
||||
|
||||
@@ -31,6 +31,8 @@ import Assert::*;
|
||||
import Ehr::*;
|
||||
import RevertingVirtualReg::*;
|
||||
|
||||
import Cur_Cycle :: *;
|
||||
|
||||
// right after execution, full_result has more up-to-date data (e.g. ppc of mispredicted branch)
|
||||
// some parts of full_result are for verification
|
||||
// but some are truly used for execution
|
||||
@@ -47,8 +49,9 @@ typedef union tagged {
|
||||
typedef struct {
|
||||
Addr pc;
|
||||
Bit #(32) orig_inst; // original 16b or 32b instruction ([1:0] will distinguish 16b or 32b)
|
||||
Maybe#(ArchRIndx) dst; // Invalid, GPR or FPR destination ("Rd")
|
||||
IType iType;
|
||||
Maybe#(ArchRIndx) dst; // Invalid, GPR or FPR destination ("Rd")
|
||||
Data dst_data; // Output of instruction into destination register
|
||||
Maybe#(CSR) csr;
|
||||
Bool claimed_phy_reg; // whether we need to commmit renaming
|
||||
Maybe#(Trap) trap;
|
||||
@@ -84,7 +87,7 @@ typedef enum {
|
||||
} RobInstState deriving (Bits, Eq, FShow);
|
||||
|
||||
interface Row_setExecuted_doFinishAlu;
|
||||
method Action set(Maybe#(Data) csrData, ControlFlow cf);
|
||||
method Action set(Data dst_data, Maybe#(Data) csrData, ControlFlow cf);
|
||||
endinterface
|
||||
|
||||
interface Row_setExecuted_doFinishFpuMulDiv;
|
||||
@@ -171,8 +174,9 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
|
||||
Reg#(Addr) pc <- mkRegU;
|
||||
Reg #(Bit #(32)) orig_inst <- mkRegU;
|
||||
Reg #(Maybe #(ArchRIndx)) rg_dst_reg <- mkRegU;
|
||||
Reg#(IType) iType <- mkRegU;
|
||||
Reg #(Maybe #(ArchRIndx)) rg_dst_reg <- mkRegU;
|
||||
Reg #(Data) rg_dst_data <- mkRegU;
|
||||
Reg#(Maybe#(CSR)) csr <- mkRegU;
|
||||
Reg#(Bool) claimed_phy_reg <- mkRegU;
|
||||
Ehr#(3, Maybe#(Trap)) trap <- mkEhr(?);
|
||||
@@ -199,9 +203,12 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
Vector#(aluExeNum, Row_setExecuted_doFinishAlu) aluSetExe;
|
||||
for(Integer i = 0; i < valueof(aluExeNum); i = i+1) begin
|
||||
aluSetExe[i] = (interface Row_setExecuted_doFinishAlu;
|
||||
method Action set(Maybe#(Data) csrData, ControlFlow cf);
|
||||
method Action set(Data dst_data, Maybe#(Data) csrData, ControlFlow cf);
|
||||
// inst is done
|
||||
rob_inst_state[state_finishAlu_port(i)] <= Executed;
|
||||
rob_inst_state[state_finishAlu_port(i)] <= Executed;
|
||||
// Destination register data, for Tandem Verification
|
||||
rg_dst_data <= dst_data;
|
||||
|
||||
// update PPC or csrData (vaddr is always useless for ALU results)
|
||||
if(csrData matches tagged Valid .d) begin
|
||||
ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= CSRData (d);
|
||||
@@ -261,8 +268,9 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
method Action write_enq(ToReorderBuffer x);
|
||||
pc <= x.pc;
|
||||
orig_inst <= x.orig_inst;
|
||||
rg_dst_reg <= x.dst;
|
||||
iType <= x.iType;
|
||||
rg_dst_reg <= x.dst;
|
||||
// rg_dst_data will be written after inst execution
|
||||
csr <= x.csr;
|
||||
claimed_phy_reg <= x.claimed_phy_reg;
|
||||
trap[trap_enq_port] <= x.trap;
|
||||
@@ -295,8 +303,9 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
return ToReorderBuffer {
|
||||
pc: pc,
|
||||
orig_inst: orig_inst,
|
||||
dst: rg_dst_reg,
|
||||
iType: iType,
|
||||
dst: rg_dst_reg,
|
||||
dst_data: rg_dst_data,
|
||||
csr: csr,
|
||||
claimed_phy_reg: claimed_phy_reg,
|
||||
trap: trap[trap_deq_port],
|
||||
@@ -383,7 +392,7 @@ endinterface
|
||||
// not raise false conflicts between the superscalar enq/deq actions
|
||||
|
||||
interface ROB_setExecuted_doFinishAlu;
|
||||
method Action set(InstTag x, Maybe#(Data) csrData, ControlFlow cf);
|
||||
method Action set(InstTag x, Data dst_data, Maybe#(Data) csrData, ControlFlow cf);
|
||||
endinterface
|
||||
|
||||
interface ROB_setExecuted_doFinishFpuMulDiv;
|
||||
@@ -895,11 +904,11 @@ module mkSupReorderBuffer#(
|
||||
for(Integer i = 0; i < valueof(aluExeNum); i = i+1) begin
|
||||
aluSetExeIfc[i] = (interface ROB_setExecuted_doFinishAlu;
|
||||
method Action set(
|
||||
InstTag x, Maybe#(Data) csrData, ControlFlow cf
|
||||
InstTag x, Data dst_data, Maybe#(Data) csrData, ControlFlow cf
|
||||
) if(
|
||||
all(id, readVReg(setExeAlu_SB_enq)) // ordering: < enq
|
||||
);
|
||||
row[x.way][x.ptr].setExecuted_doFinishAlu[i].set(csrData, cf);
|
||||
row[x.way][x.ptr].setExecuted_doFinishAlu[i].set(dst_data, csrData, cf);
|
||||
endmethod
|
||||
endinterface);
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user