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:
Jonathan Woodruff
2019-11-26 10:46:56 +00:00
parent 571904535e
commit 96d092c300
210 changed files with 14161 additions and 13470 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -36,6 +36,7 @@
`define a True
`define f True
`define d True
`define c True
//`define NUM_CORES 1 // defined in make file

View 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

View File

@@ -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