From c0ae2776e803a98882f7de1d3fa1757f2d26163c Mon Sep 17 00:00:00 2001 From: rsnikhil Date: Fri, 7 Feb 2020 23:10:53 -0500 Subject: [PATCH] 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 --- src_Core/CPU/CsrFile.bsv | 103 +++++++++++++++++- src_Core/Core/Trace_Data2.bsv | 10 +- src_Core/Core/Trace_Data2_to_Trace_Data.bsv | 32 ++++-- .../procs/RV64G_OOO/AluExePipeline.bsv | 5 +- .../RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv | 56 +++++++--- .../RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv | 12 +- .../RISCY_OOO/procs/lib/ReorderBuffer.bsv | 29 +++-- 7 files changed, 203 insertions(+), 44 deletions(-) diff --git a/src_Core/CPU/CsrFile.bsv b/src_Core/CPU/CsrFile.bsv index 084c72e..d18a72c 100644 --- a/src_Core/CPU/CsrFile.bsv +++ b/src_Core/CPU/CsrFile.bsv @@ -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 diff --git a/src_Core/Core/Trace_Data2.bsv b/src_Core/Core/Trace_Data2.bsv index 77c4097..3f78022 100644 --- a/src_Core/Core/Trace_Data2.bsv +++ b/src_Core/Core/Trace_Data2.bsv @@ -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); diff --git a/src_Core/Core/Trace_Data2_to_Trace_Data.bsv b/src_Core/Core/Trace_Data2_to_Trace_Data.bsv index 48d7312..8deb40a 100644 --- a/src_Core/Core/Trace_Data2_to_Trace_Data.bsv +++ b/src_Core/Core/Trace_Data2_to_Trace_Data.bsv @@ -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) diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv index 8b3c99b..a83c6c3 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv @@ -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 ); diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv index 2f12fb1..888a4a5 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv @@ -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; diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv index bab1fb3..19465c9 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv @@ -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 diff --git a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv index 247a7c4..0dde77b 100644 --- a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv @@ -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