Changes that enable RVFI_DII to run.
It doesn't yet pass any set of tests, but tests do run and reduce.
This commit is contained in:
@@ -82,6 +82,10 @@ import RenameStage::*;
|
||||
import CommitStage::*;
|
||||
import Bypass::*;
|
||||
|
||||
`ifdef RVFI_DII
|
||||
import Toooba_RVFI_DII_Bridge::*;
|
||||
`endif
|
||||
|
||||
import CsrFile :: *;
|
||||
|
||||
interface CoreReq;
|
||||
@@ -132,12 +136,16 @@ interface Core;
|
||||
// debug rename
|
||||
interface CoreRenameDebug renameDebug;
|
||||
|
||||
// Bluespec: external interrupt requests targeting Machine and Supervisor modes
|
||||
// Bluespec: external interrupt requests targeting Machine and Supervisor modes
|
||||
method Action setMEIP (Bit #(1) v);
|
||||
method Action setSEIP (Bit #(1) v);
|
||||
|
||||
// Bluespec: external interrupt to enter debug mode
|
||||
// Bluespec: external interrupt to enter debug mode
|
||||
method Action setDEIP (Bit #(1) v);
|
||||
|
||||
`ifdef RVFI_DII
|
||||
interface Toooba_RVFI_DII_Server rvfi_dii_server;
|
||||
`endif
|
||||
endinterface
|
||||
|
||||
// fixpoint to instantiate modules
|
||||
@@ -164,6 +172,15 @@ module mkCore#(CoreId coreId)(Core);
|
||||
FetchStage fetchStage <- mkFetchStage;
|
||||
ITlb iTlb = fetchStage.iTlbIfc;
|
||||
ICoCache iMem = fetchStage.iMemIfc;
|
||||
|
||||
// ================================================================
|
||||
// If using Direct Instruction Injection then make a
|
||||
// bridge that can insert instructions as if it were
|
||||
// an instruction cache.
|
||||
`ifdef RVFI_DII
|
||||
Toooba_RVFI_DII_Bridge_IFC rvfi_bridge <- mkTooobaRVFIDIIBridge;
|
||||
mkConnection(rvfi_bridge.dii, fetchStage.dii);
|
||||
`endif
|
||||
|
||||
// back end
|
||||
RFileSynth rf <- mkRFileSynth;
|
||||
@@ -512,6 +529,10 @@ module mkCore#(CoreId coreId)(Core);
|
||||
endinterface);
|
||||
CommitStage commitStage <- mkCommitStage(commitInput);
|
||||
|
||||
`ifdef RVFI
|
||||
mkConnection(commitStage.rvfi, rvfi_bridge.rvfi);
|
||||
`endif
|
||||
|
||||
// send rob enq time to reservation stations
|
||||
(* fire_when_enabled, no_implicit_conditions *)
|
||||
rule sendRobEnqTime;
|
||||
@@ -968,6 +989,10 @@ module mkCore#(CoreId coreId)(Core);
|
||||
interface checkStarted = nullGet;
|
||||
`endif
|
||||
endinterface
|
||||
|
||||
`ifdef RVFI_DII
|
||||
interface Toooba_RVFI_DII_Server rvfi_dii_server = rvfi_bridge.rvfi_dii_server;
|
||||
`endif
|
||||
|
||||
// rename debug
|
||||
interface CoreRenameDebug renameDebug;
|
||||
|
||||
@@ -355,6 +355,10 @@ module mkProc (Proc_IFC);
|
||||
interface Get trace_data_out = toGet (f_trace_data);
|
||||
`endif
|
||||
|
||||
`ifdef RVFI_DII
|
||||
interface Toooba_RVFI_DII_Server rvfi_dii_server = core[0].rvfi_dii_server;
|
||||
`endif
|
||||
|
||||
// ----------------
|
||||
// Optional interface to Debug Module
|
||||
|
||||
|
||||
@@ -24,6 +24,10 @@ import DM_CPU_Req_Rsp :: *;
|
||||
import TV_Info :: *;
|
||||
`endif
|
||||
|
||||
`ifdef RVFI_DII
|
||||
import Types :: *;
|
||||
`endif
|
||||
|
||||
// ================================================================
|
||||
// CPU interface
|
||||
|
||||
@@ -81,6 +85,10 @@ interface Proc_IFC;
|
||||
interface Get #(Trace_Data) trace_data_out;
|
||||
`endif
|
||||
|
||||
`ifdef RVFI_DII
|
||||
interface Toooba_RVFI_DII_Server rvfi_dii_server;
|
||||
`endif
|
||||
|
||||
// ----------------
|
||||
// Optional interface to Debug Module
|
||||
|
||||
|
||||
@@ -488,6 +488,10 @@ module mkCoreW (CoreW_IFC #(N_External_Interrupt_Sources));
|
||||
endinterface
|
||||
`endif
|
||||
|
||||
`ifdef RVFI_DII
|
||||
interface Toooba_RVFI_DII_Server rvfi_dii_server = proc.rvfi_dii_server;
|
||||
`endif
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Optional DM interfaces
|
||||
|
||||
|
||||
@@ -40,6 +40,10 @@ import TV_Info :: *;
|
||||
import Debug_Module :: *;
|
||||
`endif
|
||||
|
||||
`ifdef RVFI_DII
|
||||
import Types :: *;
|
||||
`endif
|
||||
|
||||
// ================================================================
|
||||
// The CoreW interface
|
||||
|
||||
@@ -86,6 +90,10 @@ interface CoreW_IFC #(numeric type t_n_interrupt_sources);
|
||||
interface Get #(Info_CPU_to_Verifier) tv_verifier_info_get;
|
||||
`endif
|
||||
|
||||
`ifdef RVFI_DII
|
||||
interface Toooba_RVFI_DII_Server rvfi_dii_server;
|
||||
`endif
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Optional Debug Module interfaces
|
||||
|
||||
|
||||
@@ -39,6 +39,10 @@ import StoreBuffer::*;
|
||||
import VerificationPacket::*;
|
||||
import RenameDebugIF::*;
|
||||
|
||||
`ifdef RVFI
|
||||
import RVFI_DII :: *;
|
||||
`endif
|
||||
|
||||
typedef struct {
|
||||
// info about the inst blocking at ROB head
|
||||
Addr pc;
|
||||
@@ -112,6 +116,10 @@ interface CommitStage;
|
||||
// rename debug
|
||||
method Action startRenameDebug;
|
||||
interface Get#(RenameErrInfo) renameErr;
|
||||
`ifdef RVFI
|
||||
// RVFI trace report. Not an input?
|
||||
method Get#(Rvfi_Traces) rvfi;
|
||||
`endif
|
||||
endinterface
|
||||
|
||||
// we apply actions the end of commit rule
|
||||
@@ -122,8 +130,33 @@ typedef struct {
|
||||
Trap trap;
|
||||
} CommitTrap deriving(Bits, Eq, FShow);
|
||||
|
||||
`ifdef RVFI
|
||||
function RVFI_DII_Execution#(DataSz,DataSz) genRVFI(ToReorderBuffer rot);
|
||||
return RVFI_DII_Execution {
|
||||
rvfi_order: 0, // Instruction number? InstID maybe?
|
||||
rvfi_trap: isValid(rot.trap),
|
||||
rvfi_halt: False,
|
||||
rvfi_intr: ?,
|
||||
rvfi_insn: rot.orig_inst,
|
||||
rvfi_rs1_addr: rot.orig_inst[19:15],
|
||||
rvfi_rs2_addr: rot.orig_inst[24:20],
|
||||
rvfi_rs1_data: ?,
|
||||
rvfi_rs2_data: ?,
|
||||
rvfi_pc_rdata: rot.pc,
|
||||
rvfi_pc_wdata: rot.pc + 4,
|
||||
rvfi_mem_wdata: 0,
|
||||
rvfi_rd_addr: rot.orig_inst[11:7],
|
||||
rvfi_rd_wdata: ?,
|
||||
rvfi_mem_addr: 0,
|
||||
rvfi_mem_rmask: 0,
|
||||
rvfi_mem_wmask: 0,
|
||||
rvfi_mem_rdata: 0
|
||||
};
|
||||
endfunction
|
||||
`endif
|
||||
|
||||
module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
Bool verbose = False;
|
||||
Bool verbose = True;
|
||||
|
||||
// Bluespec: for lightweight verbosity trace
|
||||
Integer verbosity = 1;
|
||||
@@ -180,6 +213,11 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
Count#(Data) flushCacheCnt <- mkCount(0);
|
||||
`endif
|
||||
|
||||
`ifdef RVFI
|
||||
// RVFI trace report. Not an input?
|
||||
FIFO#(Rvfi_Traces) rvfiQ <- mkFIFO;
|
||||
`endif
|
||||
|
||||
// deadlock check
|
||||
`ifdef CHECK_DEADLOCK
|
||||
// timer to check deadlock
|
||||
@@ -375,6 +413,11 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
$display ("CommitStage.doCommitTrap_flush: deq_data: ", fshow (x));
|
||||
$display ("CommitStage.doCommitTrap_flush: commitTrap: ", fshow (commitTrap_val));
|
||||
end
|
||||
`ifdef RVFI
|
||||
Rvfi_Traces rvfis = replicate(RVFI_DII_Execution{rvfi_order: -1});
|
||||
rvfis[0] = genRVFI(x);
|
||||
rvfiQ.enq(rvfis);
|
||||
`endif
|
||||
|
||||
// flush everything. Only increment epoch and stall fetch when we haven
|
||||
// not done it yet (we may have already done them at rename stage)
|
||||
@@ -475,6 +518,11 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
" iType:", fshow (x.iType), " [doCommitSystemInst]");
|
||||
rg_instret <= rg_instret + 1;
|
||||
end
|
||||
`ifdef RVFI
|
||||
Rvfi_Traces rvfis = replicate(RVFI_DII_Execution{rvfi_order: -1});
|
||||
rvfis[0] = genRVFI(x);
|
||||
rvfiQ.enq(rvfis);
|
||||
`endif
|
||||
|
||||
// we claim a phy reg for every inst, so commit its renaming
|
||||
regRenamingTable.commit[0].commit;
|
||||
@@ -616,6 +664,10 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
SupCnt amoCnt = 0;
|
||||
`endif
|
||||
|
||||
`ifdef RVFI
|
||||
Rvfi_Traces rvfis = replicate(RVFI_DII_Execution{rvfi_order: -1});
|
||||
`endif
|
||||
|
||||
Bit #(64) instret = 0;
|
||||
|
||||
// compute what actions to take
|
||||
@@ -631,6 +683,9 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
end
|
||||
else begin
|
||||
if (verbose) $display("[doCommitNormalInst - %d] ", i, fshow(inst_tag), " ; ", fshow(x));
|
||||
`ifdef RVFI
|
||||
rvfis[i] = genRVFI(x);
|
||||
`endif
|
||||
|
||||
if (verbosity > 0) begin
|
||||
$display("instret:%0d PC:0x%0h instr:0x%08h", rg_instret + instret, x.pc, x.orig_inst,
|
||||
@@ -733,6 +788,9 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
supComUserCnt.incr(1);
|
||||
end
|
||||
end
|
||||
`endif
|
||||
`ifdef RVFI
|
||||
rvfiQ.enq(rvfis);
|
||||
`endif
|
||||
endrule
|
||||
|
||||
@@ -766,6 +824,10 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
endcase);
|
||||
endmethod
|
||||
|
||||
`ifdef RVFI
|
||||
method rvfi = toGet(rvfiQ);
|
||||
`endif
|
||||
|
||||
`ifdef CHECK_DEADLOCK
|
||||
interface commitInstStuck = toGet(commitInstStuckQ);
|
||||
interface commitUserInstStuck = toGet(commitUserInstStuckQ);
|
||||
|
||||
@@ -31,6 +31,7 @@ import Connectable::*;
|
||||
import Decode::*;
|
||||
import Ehr::*;
|
||||
import Fifo::*;
|
||||
import FIFOF::*;
|
||||
import GetPut::*;
|
||||
import MemoryTypes::*;
|
||||
import Types::*;
|
||||
@@ -48,6 +49,10 @@ import ITlb::*;
|
||||
import CCTypes::*;
|
||||
import L1CoCache::*;
|
||||
import MMIOInst::*;
|
||||
`ifdef RVFI_DII
|
||||
import RVFI_DII::*;
|
||||
import Types::*;
|
||||
`endif
|
||||
|
||||
// ================================================================
|
||||
// For fv_decode_C function and related types and definitions
|
||||
@@ -86,6 +91,9 @@ interface FetchStage;
|
||||
|
||||
// debug
|
||||
method FetchDebugState getFetchState;
|
||||
`ifdef RVFI_DII
|
||||
interface Client#(Dii_Id, InstsAndIDs) dii;
|
||||
`endif
|
||||
|
||||
// performance
|
||||
interface Perf#(DecStagePerfType) perf;
|
||||
@@ -296,7 +304,7 @@ module mkFetchStage(FetchStage);
|
||||
// Fetch1 < Fetch3 to avoid bypassing path on PC and epochs
|
||||
|
||||
Bool verbose = False;
|
||||
Integer verbosity = 0;
|
||||
Integer verbosity = 1;
|
||||
|
||||
// Basic State Elements
|
||||
Reg#(Bool) started <- mkReg(False);
|
||||
@@ -324,10 +332,10 @@ module mkFetchStage(FetchStage);
|
||||
Reg#(Bool) decode_epoch <- mkReg(False);
|
||||
Reg#(Epoch) f_main_epoch <- mkReg(0); // fetch estimate of main epoch
|
||||
|
||||
// Regs to hold the first half of an instruction that straddles a cache line boundary
|
||||
Reg #(Bool) rg_pending_straddle <- mkReg (False);
|
||||
Reg #(Addr) rg_half_inst_pc <- mkRegU; // The PC of the straddling instruction
|
||||
Reg #(Bit #(16)) rg_half_inst_lsbs <- mkRegU; // The 16 lsbs of the straddling instruction
|
||||
// Regs to hold the first half of an instruction that straddles a cache line boundary
|
||||
Reg #(Bool) rg_pending_straddle <- mkReg (False);
|
||||
Reg #(Addr) rg_half_inst_pc <- mkRegU; // The PC of the straddling instruction
|
||||
Reg #(Bit #(16)) rg_half_inst_lsbs <- mkRegU; // The 16 lsbs of the straddling instruction
|
||||
|
||||
// Pipeline Stage FIFOs
|
||||
Fifo#(2, Tuple2#(Bit#(TLog#(SupSize)),Fetch1ToFetch2)) f12f2 <- mkCFFifo;
|
||||
@@ -385,6 +393,25 @@ module mkFetchStage(FetchStage);
|
||||
endrule
|
||||
`endif
|
||||
|
||||
`ifdef RVFI_DII
|
||||
Fifo#(2, Dii_Id) dii_instIds <- mkCFFifo;
|
||||
Fifo#(2, InstsAndIDs) dii_insts <- mkCFFifo;
|
||||
FIFOF#(Dii_Id) flush_id <- mkUGFIFOF1; // Next sequence number to request when trapping
|
||||
Reg#(Dii_Id) dii_id_next <- mkReg(0);
|
||||
|
||||
rule feed_dii;
|
||||
if (flush_id.notEmpty) begin
|
||||
dii_instIds.enq(flush_id.first);
|
||||
if (verbosity > 0) $display("Requested from %d DII", flush_id.first);
|
||||
flush_id.deq;
|
||||
end else begin
|
||||
dii_instIds.enq(dii_id_next);
|
||||
if (verbosity > 0) $display("Requested from %d DII", dii_id_next);
|
||||
dii_id_next <= dii_id_next + 1;
|
||||
end
|
||||
endrule
|
||||
`endif
|
||||
|
||||
// Predict the next fetch-PC based only on current PC (without
|
||||
// knowing the instructions).
|
||||
// Note: this chains calls to nextAddrPred. If this is a critical-path problem,
|
||||
@@ -509,11 +536,11 @@ module mkFetchStage(FetchStage);
|
||||
main_epoch: in.main_epoch };
|
||||
f22f3.enq(tuple2(nbSup,out));
|
||||
|
||||
if (verbosity > 0) begin
|
||||
$display ("----------------");
|
||||
$display ("Fetch2: TLB response pyhs_pc 0x%0h cause ", phys_pc, fshow (cause));
|
||||
$display ("Fetch2: f2_tof3.enq: nbSup %0d out ", nbSup, fshow (out));
|
||||
end
|
||||
if (verbosity > 0) begin
|
||||
$display ("----------------");
|
||||
$display ("Fetch2: TLB response pyhs_pc 0x%0h cause ", phys_pc, fshow (cause));
|
||||
$display ("Fetch2: f2_tof3.enq: nbSup %0d out ", nbSup, fshow (out));
|
||||
end
|
||||
endrule
|
||||
|
||||
// Break out of i$
|
||||
@@ -521,7 +548,7 @@ module mkFetchStage(FetchStage);
|
||||
let {nbSup, fetch3In} = f22f3.first;
|
||||
f22f3.deq();
|
||||
if (verbosity > 0)
|
||||
$display("Fetch3: fetch3In: ", fshow (fetch3In));
|
||||
$display("Fetch3: fetch3In: ", fshow (fetch3In));
|
||||
|
||||
// Get ICache/MMIO response if no exception
|
||||
// In case of exception, we still need to process at least inst_data[0]
|
||||
@@ -538,6 +565,13 @@ module mkFetchStage(FetchStage);
|
||||
inst_d <- mem_server.response.get;
|
||||
end
|
||||
end
|
||||
|
||||
`ifdef RVFI_DII
|
||||
InstsAndIDs ii <- toGet(dii_insts).get();
|
||||
inst_d = ii.insts;
|
||||
if (verbosity > 0)
|
||||
$display("Got from DII: ", fshow (inst_d));
|
||||
`endif
|
||||
|
||||
if (fetch3In.decode_epoch != decode_epoch) begin
|
||||
// Just drop it.
|
||||
@@ -945,5 +979,12 @@ module mkFetchStage(FetchStage);
|
||||
method Bool respValid = perfReqQ.notEmpty;
|
||||
`endif
|
||||
endinterface
|
||||
|
||||
`ifdef RVFI_DII
|
||||
interface Client dii;
|
||||
interface Get request = toGet(dii_instIds);
|
||||
interface Put response = toPut(dii_insts);
|
||||
endinterface
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
`define a True
|
||||
`define f True
|
||||
`define d True
|
||||
`define c True
|
||||
|
||||
//`define NUM_CORES 1 // defined in make file
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ typedef struct {
|
||||
instance DefaultValue#(RiscVISASubset);
|
||||
function RiscVISASubset defaultValue = RiscVISASubset {
|
||||
s: True, u: True,
|
||||
m: `m , a: `a , f: `f , d: `d
|
||||
m: `m , a: `a , f: `f , d: `d, c: `c
|
||||
};
|
||||
endinstance
|
||||
|
||||
|
||||
@@ -21,8 +21,15 @@
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
`include "ProcConfig.bsv"
|
||||
|
||||
import Vector::*;
|
||||
import Assert::*;
|
||||
import ClientServer::*;
|
||||
import GetPut::*;
|
||||
`ifdef RVFI_DII
|
||||
import RVFI_DII_Types::*;
|
||||
`endif
|
||||
|
||||
typedef 64 AddrSz;
|
||||
typedef Bit#(AddrSz) Addr;
|
||||
@@ -71,3 +78,20 @@ function Action doAssert(Bool b, String s) = action if(!b) $fdisplay(stderr, "\n
|
||||
`else
|
||||
function Action doAssert(Bool b, String s) = dynamicAssert(b, s);
|
||||
`endif
|
||||
|
||||
`ifdef RVFI_DII
|
||||
typedef 8 SEQ_LEN;
|
||||
typedef UInt#(SEQ_LEN) Dii_Id;
|
||||
typedef Vector#(`sizeSup, RVFI_DII_Execution #(DataSz,DataSz)) Rvfi_Traces;
|
||||
|
||||
typedef struct {
|
||||
Vector#(`sizeSup, Maybe#(Instruction)) insts;
|
||||
Vector#(`sizeSup, Dii_Id) ids;
|
||||
} InstsAndIDs deriving(Bits, Eq, FShow);
|
||||
|
||||
interface Toooba_RVFI_DII_Server;
|
||||
interface Get#(Dii_Id) seqReq;
|
||||
interface Put#(Tuple2#(Bit#(32), Dii_Id)) inst;
|
||||
interface Get#(RVFI_DII_Execution#(DataSz, DataSz)) trace_report;
|
||||
endinterface
|
||||
`endif
|
||||
|
||||
Reference in New Issue
Block a user