2023-01-12 20:46:31 +00:00
|
|
|
`include "wally-config.vh"
|
|
|
|
|
|
|
|
`define NUM_REGS 32
|
|
|
|
`define NUM_CSRS 4096
|
|
|
|
|
2023-01-17 12:47:38 +00:00
|
|
|
`define PRINT_PC_INSTR 0
|
|
|
|
`define PRINT_MOST 0
|
2023-01-12 22:09:30 +00:00
|
|
|
`define PRINT_ALL 0
|
|
|
|
|
2023-01-17 12:47:38 +00:00
|
|
|
module wallyTracer(rvviTrace rvvi);
|
2023-01-12 20:46:31 +00:00
|
|
|
|
|
|
|
localparam NUMREGS = `E_SUPPORTED ? 16 : 32;
|
|
|
|
|
|
|
|
// wally specific signals
|
2023-01-12 22:09:30 +00:00
|
|
|
logic reset;
|
2023-01-12 20:46:31 +00:00
|
|
|
|
2023-01-12 22:09:30 +00:00
|
|
|
logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW;
|
|
|
|
logic [`XLEN-1:0] InstrRawD, InstrRawE, InstrRawM, InstrRawW;
|
|
|
|
logic InstrValidM, InstrValidW;
|
|
|
|
logic StallE, StallM, StallW;
|
|
|
|
logic FlushD, FlushE, FlushM, FlushW;
|
|
|
|
logic TrapM, TrapW;
|
2023-01-13 00:43:39 +00:00
|
|
|
logic IntrF, IntrD, IntrE, IntrM, IntrW;
|
2023-01-12 22:09:30 +00:00
|
|
|
logic HaltM, HaltW;
|
|
|
|
logic [1:0] PrivilegeModeW;
|
|
|
|
logic [`XLEN-1:0] rf[NUMREGS];
|
|
|
|
logic [NUMREGS-1:0] rf_wb;
|
|
|
|
logic [4:0] rf_a3;
|
|
|
|
logic rf_we3;
|
|
|
|
logic [`XLEN-1:0] frf[32];
|
|
|
|
logic [`NUM_REGS-1:0] frf_wb;
|
|
|
|
logic [4:0] frf_a4;
|
|
|
|
logic frf_we4;
|
2023-01-17 12:47:38 +00:00
|
|
|
logic [`XLEN-1:0] CSRArray [logic[11:0]];
|
2023-01-16 19:35:06 +00:00
|
|
|
logic [`XLEN-1:0] CSRArrayOld [logic[11:0]];
|
2023-01-17 12:47:38 +00:00
|
|
|
logic [`XLEN-1:0] CSR_W [logic[11:0]];
|
2023-01-13 00:43:39 +00:00
|
|
|
logic CSRWriteM, CSRWriteW;
|
|
|
|
logic [11:0] CSRAdrM, CSRAdrW;
|
2023-01-12 20:46:31 +00:00
|
|
|
|
|
|
|
assign clk = testbench.dut.clk;
|
2023-01-12 22:09:30 +00:00
|
|
|
// assign InstrValidF = testbench.dut.core.ieu.InstrValidF; // not needed yet
|
2023-01-17 12:47:38 +00:00
|
|
|
assign InstrValidD = testbench.dut.core.ieu.c.InstrValidD;
|
|
|
|
assign InstrValidE = testbench.dut.core.ieu.c.InstrValidE;
|
|
|
|
assign InstrValidM = testbench.dut.core.ieu.InstrValidM;
|
|
|
|
assign InstrRawD = testbench.dut.core.ifu.InstrRawD;
|
|
|
|
assign PCNextF = testbench.dut.core.ifu.PCNextF;
|
|
|
|
assign PCF = testbench.dut.core.ifu.PCF;
|
|
|
|
assign PCD = testbench.dut.core.ifu.PCD;
|
|
|
|
assign PCE = testbench.dut.core.ifu.PCE;
|
|
|
|
assign PCM = testbench.dut.core.ifu.PCM;
|
|
|
|
assign reset = testbench.reset;
|
|
|
|
assign StallE = testbench.dut.core.StallE;
|
|
|
|
assign StallM = testbench.dut.core.StallM;
|
|
|
|
assign StallW = testbench.dut.core.StallW;
|
|
|
|
assign FlushD = testbench.dut.core.FlushD;
|
|
|
|
assign FlushE = testbench.dut.core.FlushE;
|
|
|
|
assign FlushM = testbench.dut.core.FlushM;
|
|
|
|
assign FlushW = testbench.dut.core.FlushW;
|
|
|
|
assign TrapM = testbench.dut.core.TrapM;
|
|
|
|
assign HaltM = testbench.DCacheFlushStart;
|
2023-01-12 22:09:30 +00:00
|
|
|
assign PrivilegeModeW = testbench.dut.core.priv.priv.privmode.PrivilegeModeW;
|
2023-01-17 12:47:38 +00:00
|
|
|
assign STATUS_SXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_SXL;
|
|
|
|
assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL;
|
2023-01-12 20:46:31 +00:00
|
|
|
|
2023-01-12 22:51:51 +00:00
|
|
|
always_comb begin
|
2023-01-13 00:43:39 +00:00
|
|
|
// machine CSRs
|
|
|
|
// *** missing PMP and performance counters.
|
2023-01-12 23:04:41 +00:00
|
|
|
CSRArray[12'h300] = testbench.dut.core.priv.priv.csr.csrm.MSTATUS_REGW;
|
|
|
|
CSRArray[12'h310] = testbench.dut.core.priv.priv.csr.csrm.MSTATUSH_REGW;
|
|
|
|
CSRArray[12'h305] = testbench.dut.core.priv.priv.csr.csrm.MTVEC_REGW;
|
|
|
|
CSRArray[12'h341] = testbench.dut.core.priv.priv.csr.csrm.MEPC_REGW;
|
|
|
|
CSRArray[12'h306] = testbench.dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW;
|
|
|
|
CSRArray[12'h320] = testbench.dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW;
|
|
|
|
CSRArray[12'h302] = testbench.dut.core.priv.priv.csr.csrm.MEDELEG_REGW;
|
|
|
|
CSRArray[12'h303] = testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW;
|
|
|
|
CSRArray[12'h344] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW;
|
|
|
|
CSRArray[12'h304] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW;
|
|
|
|
CSRArray[12'h301] = testbench.dut.core.priv.priv.csr.csrm.MISA_REGW;
|
|
|
|
CSRArray[12'hF14] = testbench.dut.core.priv.priv.csr.csrm.MHARTID_REGW;
|
|
|
|
CSRArray[12'h340] = testbench.dut.core.priv.priv.csr.csrm.MSCRATCH_REGW;
|
|
|
|
CSRArray[12'h342] = testbench.dut.core.priv.priv.csr.csrm.MCAUSE_REGW;
|
|
|
|
CSRArray[12'h343] = testbench.dut.core.priv.priv.csr.csrm.MTVAL_REGW;
|
|
|
|
CSRArray[12'hF11] = 0;
|
|
|
|
CSRArray[12'hF12] = 0;
|
|
|
|
CSRArray[12'hF13] = `XLEN'h100;
|
|
|
|
CSRArray[12'hF15] = 0;
|
|
|
|
CSRArray[12'h34A] = 0;
|
2023-01-13 00:43:39 +00:00
|
|
|
// MCYCLE and MINSTRET
|
|
|
|
CSRArray[12'hB00] = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0];
|
|
|
|
CSRArray[12'hB02] = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2];
|
|
|
|
// supervisor CSRs
|
2023-01-12 23:04:41 +00:00
|
|
|
CSRArray[12'h100] = testbench.dut.core.priv.priv.csr.csrs.SSTATUS_REGW;
|
|
|
|
CSRArray[12'h104] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222;
|
|
|
|
CSRArray[12'h105] = testbench.dut.core.priv.priv.csr.csrs.STVEC_REGW;
|
|
|
|
CSRArray[12'h141] = testbench.dut.core.priv.priv.csr.csrs.SEPC_REGW;
|
|
|
|
CSRArray[12'h106] = testbench.dut.core.priv.priv.csr.csrs.SCOUNTEREN_REGW;
|
|
|
|
CSRArray[12'h180] = testbench.dut.core.priv.priv.csr.csrs.SATP_REGW;
|
|
|
|
CSRArray[12'h140] = testbench.dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW;
|
|
|
|
CSRArray[12'h143] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW;
|
|
|
|
CSRArray[12'h142] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW;
|
|
|
|
CSRArray[12'h144] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW & & 12'h222 & testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW;
|
2023-01-13 00:43:39 +00:00
|
|
|
// user CSRs
|
|
|
|
CSRArray[12'h001] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW;
|
|
|
|
CSRArray[12'h002] = testbench.dut.core.priv.priv.csr.csru.FRM_REGW;
|
|
|
|
CSRArray[12'h003] = {testbench.dut.core.priv.priv.csr.csru.FRM_REGW, testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW};
|
2023-01-12 22:51:51 +00:00
|
|
|
end
|
2023-01-12 22:35:19 +00:00
|
|
|
|
2023-01-12 22:09:30 +00:00
|
|
|
genvar index;
|
2023-01-12 20:46:31 +00:00
|
|
|
assign rf[0] = '0;
|
|
|
|
for(index = 1; index < NUMREGS; index += 1)
|
|
|
|
assign rf[index] = testbench.dut.core.ieu.dp.regf.rf[index];
|
|
|
|
|
2023-01-17 12:47:38 +00:00
|
|
|
assign rf_a3 = testbench.dut.core.ieu.dp.regf.a3;
|
2023-01-12 20:46:31 +00:00
|
|
|
assign rf_we3 = testbench.dut.core.ieu.dp.regf.we3;
|
|
|
|
|
|
|
|
always_comb begin
|
2023-01-12 22:51:51 +00:00
|
|
|
rf_wb <= '0;
|
2023-01-12 20:46:31 +00:00
|
|
|
if(rf_we3)
|
2023-01-12 22:51:51 +00:00
|
|
|
rf_wb[rf_a3] <= 1'b1;
|
2023-01-12 20:46:31 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
for(index = 0; index < NUMREGS; index += 1)
|
|
|
|
assign frf[index] = testbench.dut.core.fpu.fpu.fregfile.rf[index];
|
|
|
|
|
2023-01-17 12:47:38 +00:00
|
|
|
assign frf_a4 = testbench.dut.core.fpu.fpu.fregfile.a4;
|
2023-01-12 20:46:31 +00:00
|
|
|
assign frf_we4 = testbench.dut.core.fpu.fpu.fregfile.we4;
|
|
|
|
|
|
|
|
always_comb begin
|
2023-01-12 22:51:51 +00:00
|
|
|
frf_wb <= '0;
|
2023-01-12 20:46:31 +00:00
|
|
|
if(frf_we4)
|
2023-01-12 22:51:51 +00:00
|
|
|
frf_wb[frf_a4] <= 1'b1;
|
2023-01-12 20:46:31 +00:00
|
|
|
end
|
|
|
|
|
2023-01-17 12:47:38 +00:00
|
|
|
assign CSRAdrM = testbench.dut.core.priv.priv.csr.CSRAdrM;
|
2023-01-13 00:43:39 +00:00
|
|
|
assign CSRWriteM = testbench.dut.core.priv.priv.csr.CSRWriteM;
|
|
|
|
|
2023-01-12 20:46:31 +00:00
|
|
|
// pipeline to writeback stage
|
|
|
|
flopenrc #(`XLEN) InstrRawEReg (clk, reset, FlushE, ~StallE, InstrRawD, InstrRawE);
|
|
|
|
flopenrc #(`XLEN) InstrRawMReg (clk, reset, FlushM, ~StallM, InstrRawE, InstrRawM);
|
|
|
|
flopenrc #(`XLEN) InstrRawWReg (clk, reset, FlushW, ~StallW, InstrRawM, InstrRawW);
|
|
|
|
flopenrc #(`XLEN) PCWReg (clk, reset, FlushW, ~StallW, PCM, PCW);
|
|
|
|
flopenrc #(1) InstrValidMReg (clk, reset, FlushW, ~StallW, InstrValidM, InstrValidW);
|
|
|
|
flopenrc #(1) TrapWReg (clk, reset, 1'b0, ~StallW, TrapM, TrapW);
|
|
|
|
flopenrc #(1) HaltWReg (clk, reset, 1'b0, ~StallW, HaltM, HaltW);
|
|
|
|
|
2023-01-13 00:43:39 +00:00
|
|
|
flopenrc #(1) IntrFReg (clk, reset, 1'b0, ~StallF, TrapM, IntrF);
|
|
|
|
flopenrc #(1) IntrDReg (clk, reset, FlushD, ~StallD, IntrF, IntrD);
|
|
|
|
flopenrc #(1) IntrEReg (clk, reset, FlushE, ~StallE, IntrD, IntrE);
|
|
|
|
flopenrc #(1) IntrMReg (clk, reset, FlushM, ~StallM, IntrE, IntrM);
|
|
|
|
flopenrc #(1) IntrWReg (clk, reset, FlushW, ~StallW, IntrM, IntrW);
|
|
|
|
|
2023-01-17 12:47:38 +00:00
|
|
|
flopenrc #(12) CSRAdrWReg (clk, reset, FlushW, ~StallW, CSRAdrM, CSRAdrW);
|
|
|
|
flopenrc #(1) CSRWriteWReg (clk, reset, FlushW, ~StallW, CSRWriteM, CSRWriteW);
|
2023-01-13 00:43:39 +00:00
|
|
|
|
2023-01-12 20:46:31 +00:00
|
|
|
// Initially connecting the writeback stage signals, but may need to use M stage
|
|
|
|
// and gate on ~FlushW.
|
|
|
|
|
2023-01-17 12:47:38 +00:00
|
|
|
assign rvvi.clk = clk;
|
|
|
|
assign rvvi.valid[0][0] = InstrValidW & ~StallW & ~FlushW;
|
|
|
|
assign rvvi.order[0][0] = CSRArray[12'hB02]; // TODO: IMPERAS Should be event order
|
|
|
|
assign rvvi.insn[0][0] = InstrRawW;
|
|
|
|
assign rvvi.pc_rdata[0][0] = PCW;
|
|
|
|
assign rvvi.trap[0][0] = 0; // TODO: IMPERAS TrapW;
|
|
|
|
assign rvvi.halt[0][0] = HaltW;
|
|
|
|
assign rvvi.intr[0][0] = IntrW;
|
|
|
|
assign rvvi.mode[0][0] = PrivilegeModeW;
|
|
|
|
assign rvvi.ixl[0][0] = PrivilegeModeW == 2'b11 ? 2'b10 :
|
|
|
|
PrivilegeModeW == 2'b01 ? STATUS_SXL : STATUS_UXL;
|
|
|
|
assign rvvi.pc_wdata[0][0] = ~FlushW ? PCM :
|
|
|
|
~FlushM ? PCE :
|
|
|
|
~FlushE ? PCD :
|
|
|
|
~FlushD ? PCF : PCNextF;
|
2023-01-12 20:46:31 +00:00
|
|
|
|
2023-01-12 22:09:30 +00:00
|
|
|
for(index = 0; index < `NUM_REGS; index += 1) begin
|
2023-01-17 12:47:38 +00:00
|
|
|
assign rvvi.x_wdata[0][0][index] = rf[index];
|
|
|
|
assign rvvi.x_wb[0][0][index] = rf_wb[index];
|
|
|
|
assign rvvi.f_wdata[0][0][index] = frf[index];
|
|
|
|
assign rvvi.f_wb[0][0][index] = frf_wb[index];
|
2023-01-12 20:46:31 +00:00
|
|
|
end
|
|
|
|
|
2023-01-16 19:35:06 +00:00
|
|
|
// record previous csr value.
|
|
|
|
integer index4;
|
|
|
|
always_ff @(posedge clk) begin
|
|
|
|
for (index4 = 0; index4 < `NUM_CSRS; index4 += 1) begin
|
2023-01-17 12:47:38 +00:00
|
|
|
CSR_W[index4] = (CSRArrayOld[index4] != CSRArray[index4]) ? 1 : 0;
|
2023-01-16 19:35:06 +00:00
|
|
|
CSRArrayOld[index4] = CSRArray[index4];
|
|
|
|
end
|
|
|
|
end
|
2023-01-17 12:47:38 +00:00
|
|
|
|
2023-01-16 19:35:06 +00:00
|
|
|
// check for csr value change.
|
2023-01-17 12:47:38 +00:00
|
|
|
genvar index5;
|
|
|
|
for(index5 = 0; index5 < `NUM_CSRS; index5 += 1) begin
|
|
|
|
assign rvvi.csr_wb[0][0][index5] = CSR_W[index5];
|
|
|
|
assign rvvi.csr[0][0][index5] = CSRArray[index5];
|
2023-01-13 00:43:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
// *** implementation only cancel? so sc does not clear?
|
2023-01-17 12:47:38 +00:00
|
|
|
assign rvvi.lrsc_cancel[0][0] = '0;
|
2023-01-13 00:43:39 +00:00
|
|
|
|
2023-01-12 22:09:30 +00:00
|
|
|
integer index2;
|
2023-01-13 00:43:39 +00:00
|
|
|
|
2023-01-12 20:46:31 +00:00
|
|
|
always_ff @(posedge clk) begin
|
2023-01-17 12:47:38 +00:00
|
|
|
if(rvvi.valid[0][0]) begin
|
2023-01-12 22:09:30 +00:00
|
|
|
if(`PRINT_PC_INSTR & !(`PRINT_ALL | `PRINT_MOST))
|
2023-01-17 12:47:38 +00:00
|
|
|
$display("order = %08d, PC = %08x, insn = %08x", rvvi.order[0][0], rvvi.pc_rdata[0][0], rvvi.insn[0][0]);
|
2023-01-12 22:09:30 +00:00
|
|
|
else if(`PRINT_MOST & !`PRINT_ALL)
|
2023-01-13 00:43:39 +00:00
|
|
|
$display("order = %08d, PC = %010x, insn = %08x, trap = %1d, halt = %1d, intr = %1d, mode = %1x, ixl = %1x, pc_wdata = %010x, x%02d = %016x, f%02d = %016x, csr%03x = %016x",
|
2023-01-17 12:47:38 +00:00
|
|
|
rvvi.order[0][0], rvvi.pc_rdata[0][0], rvvi.insn[0][0], rvvi.trap[0][0], rvvi.halt[0][0], rvvi.intr[0][0], rvvi.mode[0][0], rvvi.ixl[0][0], rvvi.pc_wdata[0][0], rf_a3, rvvi.x_wdata[0][0][rf_a3], frf_a4, rvvi.f_wdata[0][0][frf_a4], CSRAdrW, rvvi.csr[0][0][CSRAdrW]);
|
2023-01-12 22:09:30 +00:00
|
|
|
else if(`PRINT_ALL) begin
|
2023-01-13 00:43:39 +00:00
|
|
|
$display("order = %08d, PC = %08x, insn = %08x, trap = %1d, halt = %1d, intr = %1d, mode = %1x, ixl = %1x, pc_wdata = %08x",
|
2023-01-17 12:47:38 +00:00
|
|
|
rvvi.order[0][0], rvvi.pc_rdata[0][0], rvvi.insn[0][0], rvvi.trap[0][0], rvvi.halt[0][0], rvvi.intr[0][0], rvvi.mode[0][0], rvvi.ixl[0][0], rvvi.pc_wdata[0][0]);
|
2023-01-12 22:09:30 +00:00
|
|
|
for(index2 = 0; index2 < `NUM_REGS; index2 += 1) begin
|
2023-01-17 12:47:38 +00:00
|
|
|
$display("x%02d = %08x", index2, rvvi.x_wdata[0][0][index2]);
|
2023-01-12 22:09:30 +00:00
|
|
|
end
|
|
|
|
for(index2 = 0; index2 < `NUM_REGS; index2 += 1) begin
|
2023-01-17 12:47:38 +00:00
|
|
|
$display("f%02d = %08x", index2, rvvi.f_wdata[0][0][index2]);
|
2023-01-12 22:09:30 +00:00
|
|
|
end
|
|
|
|
end
|
2023-01-12 20:46:31 +00:00
|
|
|
end
|
2023-01-17 12:47:38 +00:00
|
|
|
if(HaltW) $finish;
|
|
|
|
// if(HaltW) $stop;
|
|
|
|
|
2023-01-12 20:46:31 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
endmodule
|
|
|
|
|