diff --git a/pipelined/testbench/common/rvvitrace.sv b/pipelined/testbench/common/rvvitrace.sv new file mode 100644 index 000000000..3cc76be7f --- /dev/null +++ b/pipelined/testbench/common/rvvitrace.sv @@ -0,0 +1,151 @@ +`include "wally-config.vh" + +`define NUM_REGS 32 +`define NUM_CSRS 4096 + +module rvviTrace #( + parameter int ILEN = `XLEN, // Instruction length in bits + parameter int XLEN = `XLEN, // GPR length in bits + parameter int FLEN = `FLEN, // FPR length in bits + parameter int VLEN = 0, // Vector register size in bits + parameter int NHART = 1, // Number of harts reported + parameter int RETIRE = 1) // Number of instructions that can retire during valid event + (); + + localparam NUMREGS = `E_SUPPORTED ? 16 : 32; + + // wally specific signals + logic reset; + + 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; + 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 [31:0] frf_wb; + logic [4:0] frf_a4; + logic frf_we4; + + + + // tracer signals + logic clk; + logic valid; + logic [ILEN-1:0] insn [(NHART-1):0][(RETIRE-1):0]; + logic [(XLEN-1):0] pc_rdata [(NHART-1):0][(RETIRE-1):0]; + logic [(XLEN-1):0] pc_wdata [(NHART-1):0][(RETIRE-1):0]; + logic trap [(NHART-1):0][(RETIRE-1):0]; + logic halt [(NHART-1):0][(RETIRE-1):0]; + logic intr [(NHART-1):0][(RETIRE-1):0]; + logic [1:0] mode [(NHART-1):0][(RETIRE-1):0]; + logic [1:0] ixl [(NHART-1):0][(RETIRE-1):0]; + logic [31:0][(XLEN-1):0] x_wdata [(NHART-1):0][(RETIRE-1):0]; + logic [31:0] x_wb [(NHART-1):0][(RETIRE-1):0]; + logic [31:0][(XLEN-1):0] f_wdata [(NHART-1):0][(RETIRE-1):0]; + logic [31:0] f_wb [(NHART-1):0][(RETIRE-1):0]; + + assign clk = testbench.dut.clk; +// assign InstrValidF = testbench.dut.core.ieu.InstrValidF; // not needed yet + 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; + assign STATUS_SXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_SXL; + assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL; + + genvar index; + assign rf[0] = '0; + for(index = 1; index < NUMREGS; index += 1) + assign rf[index] = testbench.dut.core.ieu.dp.regf.rf[index]; + + assign rf_a3 = testbench.dut.core.ieu.dp.regf.a3; + assign rf_we3 = testbench.dut.core.ieu.dp.regf.we3; + + always_comb begin + rf_wb = '0; + if(rf_we3) + rf_wb[rf_a3] = 1'b1; + end + + for(index = 0; index < NUMREGS; index += 1) + assign frf[index] = testbench.dut.core.fpu.fpu.fregfile.rf[index]; + + assign frf_a4 = testbench.dut.core.fpu.fpu.fregfile.a4; + assign frf_we4 = testbench.dut.core.fpu.fpu.fregfile.we4; + + always_comb begin + frf_wb = '0; + if(frf_we4) + frf_wb[frf_a4] = 1'b1; + end + + // 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); + + // Initially connecting the writeback stage signals, but may need to use M stage + // and gate on ~FlushW. + + assign valid = InstrValidW & ~StallW & ~FlushW; + assign insn[0][0] = InstrRawW; + assign pc_rdata[0][0] = PCW; + assign trap[0][0] = TrapW; + assign halt[0][0] = HaltW; + assign intr[0][0] = '0; // *** first retired instruction of trap handler. Not sure how i'm going to get this yet. + assign mode[0][0] = PrivilegeModeW; + assign ixl[0][0] = PrivilegeModeW == 2'b11 ? `XLEN : + PrivilegeModeW == 2'b01 ? STATUS_SXL : STATUS_UXL; + assign pc_wdata[0][0] = ~FlushW ? PCM : + ~FlushM ? PCE : + ~FlushE ? PCD : + ~FlushD ? PCF : PCNextF; + + for(index = 0; index < NUMREGS; index += 1) begin + assign x_wdata[index][0][0] = rf[index]; + assign x_wb[index][0][0] = rf_wb[index]; + assign f_wdata[index][0][0] = frf[index]; + assign f_wb[index][0][0] = frf_wb[index]; + end + + + + + always_ff @(posedge clk) begin + if(valid) begin + $display("PC = %08x, insn = %08x, trap = %1d, halt = %1d", pc_rdata[0][0], insn[0][0], trap[0][0], halt[0][0]); + end + if(HaltW) $stop(); + end + + + +endmodule + diff --git a/pipelined/testbench/testbench_imperas.sv b/pipelined/testbench/testbench_imperas.sv index d55cc6759..e8f014b8a 100644 --- a/pipelined/testbench/testbench_imperas.sv +++ b/pipelined/testbench/testbench_imperas.sv @@ -181,10 +181,6 @@ module testbench; InReset = 0; ResetCount = 0; end - end else begin - if(DCacheFlushStart) begin - $stop; - end end end // always @ (negedge clk)