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