forked from Github_Repos/cvw
		
	Nearly complete RVVI tracer.
Missing PMP registers and performance counters other than MCYCLE and MINSTRET.
This commit is contained in:
		
							parent
							
								
									ef4c684336
								
							
						
					
					
						commit
						395b7a5b32
					
				@ -27,6 +27,7 @@ module rvviTrace #(
 | 
				
			|||||||
  logic 						 StallE, StallM, StallW;
 | 
					  logic 						 StallE, StallM, StallW;
 | 
				
			||||||
  logic 						 FlushD, FlushE, FlushM, FlushW;
 | 
					  logic 						 FlushD, FlushE, FlushM, FlushW;
 | 
				
			||||||
  logic 						 TrapM, TrapW;
 | 
					  logic 						 TrapM, TrapW;
 | 
				
			||||||
 | 
					  logic 						 IntrF, IntrD, IntrE, IntrM, IntrW;
 | 
				
			||||||
  logic 						 HaltM, HaltW;
 | 
					  logic 						 HaltM, HaltW;
 | 
				
			||||||
  logic [1:0] 					 PrivilegeModeW;
 | 
					  logic [1:0] 					 PrivilegeModeW;
 | 
				
			||||||
  logic [`XLEN-1:0] 			 rf[NUMREGS];
 | 
					  logic [`XLEN-1:0] 			 rf[NUMREGS];
 | 
				
			||||||
@ -38,24 +39,28 @@ module rvviTrace #(
 | 
				
			|||||||
  logic [4:0] 					 frf_a4;
 | 
					  logic [4:0] 					 frf_a4;
 | 
				
			||||||
  logic 						 frf_we4;
 | 
					  logic 						 frf_we4;
 | 
				
			||||||
  logic [`XLEN-1:0] 			 CSRArray [logic[11:0]];
 | 
					  logic [`XLEN-1:0] 			 CSRArray [logic[11:0]];
 | 
				
			||||||
 | 
					  logic 						 CSRWriteM, CSRWriteW;
 | 
				
			||||||
 | 
					  logic [11:0] 					 CSRAdrM, CSRAdrW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // tracer signals
 | 
					  // tracer signals
 | 
				
			||||||
  logic 						 clk;
 | 
					  logic 						 clk;
 | 
				
			||||||
  logic 						 valid;
 | 
					  logic 						 valid;
 | 
				
			||||||
  logic [63:0] 					 order      [(NHART-1):0][(RETIRE-1):0];
 | 
					  logic [63:0] 					 order      [(NHART-1):0][(RETIRE-1):0];
 | 
				
			||||||
  logic [ILEN-1:0] 				 insn [(NHART-1):0][(RETIRE-1):0];
 | 
					  logic [ILEN-1:0] 				 insn [(NHART-1):0][(RETIRE-1):0];
 | 
				
			||||||
 | 
					  logic 						 intr       [(NHART-1):0][(RETIRE-1):0];
 | 
				
			||||||
  logic [(XLEN-1):0] 			 pc_rdata   [(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 [(XLEN-1):0] 			 pc_wdata   [(NHART-1):0][(RETIRE-1):0];
 | 
				
			||||||
  logic 						 trap       [(NHART-1):0][(RETIRE-1):0];
 | 
					  logic 						 trap       [(NHART-1):0][(RETIRE-1):0];
 | 
				
			||||||
  logic 						 halt       [(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] 					 mode       [(NHART-1):0][(RETIRE-1):0];
 | 
				
			||||||
  logic [1:0] 					 ixl        [(NHART-1):0][(RETIRE-1):0];
 | 
					  logic [1:0] 					 ixl        [(NHART-1):0][(RETIRE-1):0];
 | 
				
			||||||
  logic [`NUM_REGS-1:0][(XLEN-1):0] x_wdata    [(NHART-1):0][(RETIRE-1):0];
 | 
					  logic [`NUM_REGS-1:0][(XLEN-1):0] x_wdata    [(NHART-1):0][(RETIRE-1):0];
 | 
				
			||||||
  logic [`NUM_REGS-1:0] 			x_wb       [(NHART-1):0][(RETIRE-1):0];
 | 
					  logic [`NUM_REGS-1:0] 			x_wb       [(NHART-1):0][(RETIRE-1):0];
 | 
				
			||||||
  logic [`NUM_REGS-1:0][(XLEN-1):0] f_wdata    [(NHART-1):0][(RETIRE-1):0];
 | 
					  logic [`NUM_REGS-1:0][(XLEN-1):0] f_wdata    [(NHART-1):0][(RETIRE-1):0];
 | 
				
			||||||
  logic [`NUM_REGS-1:0] 			f_wb       [(NHART-1):0][(RETIRE-1):0];
 | 
					  logic [`NUM_REGS-1:0] 			f_wb       [(NHART-1):0][(RETIRE-1):0];
 | 
				
			||||||
 | 
					  logic [4095:0][(XLEN-1):0] 		csr        [(NHART-1):0][(RETIRE-1):0];
 | 
				
			||||||
 | 
					  logic [4095:0] 					csr_wb     [(NHART-1):0][(RETIRE-1):0];
 | 
				
			||||||
 | 
					  logic 							lrsc_cancel[(NHART-1):0][(RETIRE-1):0];
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  assign clk = testbench.dut.clk;
 | 
					  assign clk = testbench.dut.clk;
 | 
				
			||||||
  //  assign InstrValidF = testbench.dut.core.ieu.InstrValidF;  // not needed yet
 | 
					  //  assign InstrValidF = testbench.dut.core.ieu.InstrValidF;  // not needed yet
 | 
				
			||||||
@ -83,7 +88,8 @@ module rvviTrace #(
 | 
				
			|||||||
  assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL;
 | 
					  assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  always_comb begin
 | 
					  always_comb begin
 | 
				
			||||||
	// machine mode CSRs
 | 
						// machine CSRs
 | 
				
			||||||
 | 
						// *** missing PMP and performance counters.
 | 
				
			||||||
	CSRArray[12'h300] = testbench.dut.core.priv.priv.csr.csrm.MSTATUS_REGW;
 | 
						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'h310] = testbench.dut.core.priv.priv.csr.csrm.MSTATUSH_REGW;
 | 
				
			||||||
	CSRArray[12'h305] = testbench.dut.core.priv.priv.csr.csrm.MTVEC_REGW;
 | 
						CSRArray[12'h305] = testbench.dut.core.priv.priv.csr.csrm.MTVEC_REGW;
 | 
				
			||||||
@ -104,7 +110,10 @@ module rvviTrace #(
 | 
				
			|||||||
	CSRArray[12'hF13] = `XLEN'h100;
 | 
						CSRArray[12'hF13] = `XLEN'h100;
 | 
				
			||||||
	CSRArray[12'hF15] = 0;
 | 
						CSRArray[12'hF15] = 0;
 | 
				
			||||||
	CSRArray[12'h34A] = 0;
 | 
						CSRArray[12'h34A] = 0;
 | 
				
			||||||
 | 
						// 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
 | 
				
			||||||
	CSRArray[12'h100] = testbench.dut.core.priv.priv.csr.csrs.SSTATUS_REGW;
 | 
						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'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'h105] = testbench.dut.core.priv.priv.csr.csrs.STVEC_REGW;
 | 
				
			||||||
@ -115,6 +124,10 @@ module rvviTrace #(
 | 
				
			|||||||
	CSRArray[12'h143] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_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'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;
 | 
						CSRArray[12'h144] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW & & 12'h222 & testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW;
 | 
				
			||||||
 | 
						// 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};
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  genvar 							index;
 | 
					  genvar 							index;
 | 
				
			||||||
@ -143,6 +156,9 @@ module rvviTrace #(
 | 
				
			|||||||
	  frf_wb[frf_a4] <= 1'b1;
 | 
						  frf_wb[frf_a4] <= 1'b1;
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assign CSRAdrM = testbench.dut.core.priv.priv.csr.CSRAdrM;
 | 
				
			||||||
 | 
					  assign CSRWriteM = testbench.dut.core.priv.priv.csr.CSRWriteM;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  // pipeline to writeback stage
 | 
					  // pipeline to writeback stage
 | 
				
			||||||
  flopenrc #(`XLEN) InstrRawEReg (clk, reset, FlushE, ~StallE, InstrRawD, InstrRawE);
 | 
					  flopenrc #(`XLEN) InstrRawEReg (clk, reset, FlushE, ~StallE, InstrRawD, InstrRawE);
 | 
				
			||||||
  flopenrc #(`XLEN) InstrRawMReg (clk, reset, FlushM, ~StallM, InstrRawE, InstrRawM);
 | 
					  flopenrc #(`XLEN) InstrRawMReg (clk, reset, FlushM, ~StallM, InstrRawE, InstrRawM);
 | 
				
			||||||
@ -152,15 +168,25 @@ module rvviTrace #(
 | 
				
			|||||||
  flopenrc #(1)     TrapWReg (clk, reset, 1'b0, ~StallW, TrapM, TrapW);
 | 
					  flopenrc #(1)     TrapWReg (clk, reset, 1'b0, ~StallW, TrapM, TrapW);
 | 
				
			||||||
  flopenrc #(1)     HaltWReg (clk, reset, 1'b0, ~StallW, HaltM, HaltW);
 | 
					  flopenrc #(1)     HaltWReg (clk, reset, 1'b0, ~StallW, HaltM, HaltW);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  flopenrc #(12) CSRAdrWReg (clk, reset, FlushW, ~StallW, CSRAdrM, CSRAdrW);
 | 
				
			||||||
 | 
					  flopenrc #(1) CSRWriteWReg (clk, reset, FlushW, ~StallW, CSRWriteM, CSRWriteW);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Initially connecting the writeback stage signals, but may need to use M stage
 | 
					  // Initially connecting the writeback stage signals, but may need to use M stage
 | 
				
			||||||
  // and gate on ~FlushW.
 | 
					  // and gate on ~FlushW.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  assign valid = InstrValidW & ~StallW & ~FlushW;
 | 
					  assign valid = InstrValidW & ~StallW & ~FlushW;
 | 
				
			||||||
 | 
					  assign order[0][0] = CSRArray[12'hB02];
 | 
				
			||||||
  assign insn[0][0] = InstrRawW;
 | 
					  assign insn[0][0] = InstrRawW;
 | 
				
			||||||
  assign pc_rdata[0][0] = PCW;
 | 
					  assign pc_rdata[0][0] = PCW;
 | 
				
			||||||
  assign trap[0][0] = TrapW;
 | 
					  assign trap[0][0] = TrapW;
 | 
				
			||||||
  assign halt[0][0] = HaltW;
 | 
					  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 intr[0][0] = IntrW;
 | 
				
			||||||
  assign mode[0][0] = PrivilegeModeW;
 | 
					  assign mode[0][0] = PrivilegeModeW;
 | 
				
			||||||
  assign ixl[0][0] = PrivilegeModeW == 2'b11 ? 2'b10 :
 | 
					  assign ixl[0][0] = PrivilegeModeW == 2'b11 ? 2'b10 :
 | 
				
			||||||
					 PrivilegeModeW == 2'b01 ? STATUS_SXL : STATUS_UXL;
 | 
										 PrivilegeModeW == 2'b01 ? STATUS_SXL : STATUS_UXL;
 | 
				
			||||||
@ -176,16 +202,38 @@ module rvviTrace #(
 | 
				
			|||||||
	assign f_wb[0][0][index] = frf_wb[index];
 | 
						assign f_wb[0][0][index] = frf_wb[index];
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  always_comb begin
 | 
				
			||||||
 | 
						csr_wb[0][0] <= '0;
 | 
				
			||||||
 | 
						if(CSRWriteW)
 | 
				
			||||||
 | 
						  csr_wb[0][0][CSRAdrW] <= 1'b1;
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  integer index3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  always_comb begin
 | 
				
			||||||
 | 
						for(index3 = 0; index3 < `NUM_CSRS; index3 += 1) begin
 | 
				
			||||||
 | 
						  if(CSRArray.exists(index3)) 
 | 
				
			||||||
 | 
							csr[0][0][index3] = CSRArray[index3];
 | 
				
			||||||
 | 
						  else 
 | 
				
			||||||
 | 
							csr[0][0][index3] = '0;
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // *** implementation only cancel? so sc does not clear?
 | 
				
			||||||
 | 
					  assign lrsc_cancel[0][0] = '0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  integer index2;
 | 
					  integer index2;
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
  always_ff @(posedge clk) begin
 | 
					  always_ff @(posedge clk) begin
 | 
				
			||||||
	if(valid) begin
 | 
						if(valid) begin
 | 
				
			||||||
	  if(`PRINT_PC_INSTR & !(`PRINT_ALL | `PRINT_MOST))
 | 
						  if(`PRINT_PC_INSTR & !(`PRINT_ALL | `PRINT_MOST))
 | 
				
			||||||
		$display("PC = %08x, insn = %08x", pc_rdata[0][0], insn[0][0]);
 | 
							$display("order = %08d, PC = %08x, insn = %08x", order[0][0], pc_rdata[0][0], insn[0][0]);
 | 
				
			||||||
	  else if(`PRINT_MOST & !`PRINT_ALL)
 | 
						  else if(`PRINT_MOST & !`PRINT_ALL)
 | 
				
			||||||
		$display("PC = %08x, insn = %08x, trap = %1d, halt = %1d, mode = %1x, ixl = %1x, pc_wdata = %08x, x%02d = %016x, f%02d = %016x", pc_rdata[0][0], insn[0][0], trap[0][0], halt[0][0], mode[0][0], ixl[0][0], pc_wdata[0][0], rf_a3, x_wdata[0][0][rf_a3], frf_a4, f_wdata[0][0][frf_a4]);
 | 
							$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", 
 | 
				
			||||||
 | 
									 order[0][0], pc_rdata[0][0], insn[0][0], trap[0][0], halt[0][0], intr[0][0], mode[0][0], ixl[0][0], pc_wdata[0][0], rf_a3, x_wdata[0][0][rf_a3], frf_a4, f_wdata[0][0][frf_a4], CSRAdrW, csr[0][0][CSRAdrW]);
 | 
				
			||||||
	  else if(`PRINT_ALL) begin
 | 
						  else if(`PRINT_ALL) begin
 | 
				
			||||||
		$display("PC = %08x, insn = %08x, trap = %1d, halt = %1d, mode = %1x, ixl = %1x, pc_wdata = %08x", pc_rdata[0][0], insn[0][0], trap[0][0], halt[0][0], mode[0][0], ixl[0][0], pc_wdata[0][0]);
 | 
							$display("order = %08d, PC = %08x, insn = %08x, trap = %1d, halt = %1d, intr = %1d, mode = %1x, ixl = %1x, pc_wdata = %08x", 
 | 
				
			||||||
 | 
									 order[0][0], pc_rdata[0][0], insn[0][0], trap[0][0], halt[0][0], intr[0][0], mode[0][0], ixl[0][0], pc_wdata[0][0]);
 | 
				
			||||||
	  	for(index2 = 0; index2 < `NUM_REGS; index2 += 1) begin
 | 
						  	for(index2 = 0; index2 < `NUM_REGS; index2 += 1) begin
 | 
				
			||||||
		  $display("x%02d = %08x", index2, x_wdata[0][0][index2]);
 | 
							  $display("x%02d = %08x", index2, x_wdata[0][0][index2]);
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
 | 
				
			|||||||
@ -92,9 +92,13 @@ module testbench;
 | 
				
			|||||||
      testadr = 0;
 | 
					      testadr = 0;
 | 
				
			||||||
      testadrNoBase = 0;
 | 
					      testadrNoBase = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  testName =     "rv64i_m/I/src/add-01.S";
 | 
						  //testName =     "rv64i_m/I/src/add-01.S";
 | 
				
			||||||
 | 
						  testName =     "rv64i_m/privilege/src/WALLY-mmu-sv48-01.S";
 | 
				
			||||||
 | 
						  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  pathname =     "../../tests/riscof/work/riscv-arch-test/";
 | 
						  //pathname =     "../../tests/riscof/work/riscv-arch-test/";
 | 
				
			||||||
 | 
						  pathname = "../../tests/riscof/work/wally-riscv-arch-test/";
 | 
				
			||||||
 | 
						  
 | 
				
			||||||
	  memfilename = {pathname, testName, "/ref/ref.elf.memfile"};
 | 
						  memfilename = {pathname, testName, "/ref/ref.elf.memfile"};
 | 
				
			||||||
      if (`BUS) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM);
 | 
					      if (`BUS) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM);
 | 
				
			||||||
	  else $error("Imperas test bench requires BUS.");
 | 
						  else $error("Imperas test bench requires BUS.");
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user