forked from Github_Repos/cvw
		
	Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally into main
This commit is contained in:
		
						commit
						e5e3f5abe6
					
				@ -4,7 +4,8 @@ set -e
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
BASEDIR=$PWD
 | 
					BASEDIR=$PWD
 | 
				
			||||||
CM_FOLDER=coremark
 | 
					CM_FOLDER=coremark
 | 
				
			||||||
RISCV=/home/ehedenberg/riscvcompiler
 | 
					#RISCV=/home/ehedenberg/riscvcompiler
 | 
				
			||||||
 | 
					RISCV=/courses/e190ax/riscvcompiler
 | 
				
			||||||
XCFLAGS="-march=rv64im"
 | 
					XCFLAGS="-march=rv64im"
 | 
				
			||||||
cd $BASEDIR/$CM_FOLDER
 | 
					cd $BASEDIR/$CM_FOLDER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										9
									
								
								wally-pipelined/src/cache/dcache.sv
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								wally-pipelined/src/cache/dcache.sv
									
									
									
									
										vendored
									
									
								
							@ -103,7 +103,7 @@ module dcache
 | 
				
			|||||||
  logic [BLOCKLEN-1:0]	       ReadDataBlockM;
 | 
					  logic [BLOCKLEN-1:0]	       ReadDataBlockM;
 | 
				
			||||||
  logic [`XLEN-1:0]	       ReadDataBlockSetsM [(WORDSPERLINE)-1:0];
 | 
					  logic [`XLEN-1:0]	       ReadDataBlockSetsM [(WORDSPERLINE)-1:0];
 | 
				
			||||||
  logic [`XLEN-1:0]	       VictimReadDataBlockSetsM [(WORDSPERLINE)-1:0];  
 | 
					  logic [`XLEN-1:0]	       VictimReadDataBlockSetsM [(WORDSPERLINE)-1:0];  
 | 
				
			||||||
  logic [`XLEN-1:0]	       ReadDataWordM, FinalReadDataWordM, ReadDataWordMuxM;
 | 
					  logic [`XLEN-1:0]	       ReadDataWordM, ReadDataWordMuxM;
 | 
				
			||||||
  logic [`XLEN-1:0]	       FinalWriteDataM, FinalAMOWriteDataM;
 | 
					  logic [`XLEN-1:0]	       FinalWriteDataM, FinalAMOWriteDataM;
 | 
				
			||||||
  logic [BLOCKLEN-1:0]	       FinalWriteDataWordsM;
 | 
					  logic [BLOCKLEN-1:0]	       FinalWriteDataWordsM;
 | 
				
			||||||
  logic [LOGWPL:0] 	       FetchCount, NextFetchCount;
 | 
					  logic [LOGWPL:0] 	       FetchCount, NextFetchCount;
 | 
				
			||||||
@ -309,7 +309,7 @@ module dcache
 | 
				
			|||||||
  subwordread subwordread(.HRDATA(ReadDataWordMuxM),
 | 
					  subwordread subwordread(.HRDATA(ReadDataWordMuxM),
 | 
				
			||||||
			  .HADDRD(MemPAdrM[2:0]),
 | 
								  .HADDRD(MemPAdrM[2:0]),
 | 
				
			||||||
			  .HSIZED({Funct3M[2], 1'b0, Funct3M[1:0]}),
 | 
								  .HSIZED({Funct3M[2], 1'b0, Funct3M[1:0]}),
 | 
				
			||||||
			  .HRDATAMasked(FinalReadDataWordM));
 | 
								  .HRDATAMasked(ReadDataM));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // This is a confusing point.
 | 
					  // This is a confusing point.
 | 
				
			||||||
  // The final read data should be updated only if the CPU's StallW is low
 | 
					  // The final read data should be updated only if the CPU's StallW is low
 | 
				
			||||||
@ -324,10 +324,9 @@ module dcache
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  flopen #(`XLEN) ReadDataWReg(.clk(clk),
 | 
					  flopen #(`XLEN) ReadDataWReg(.clk(clk),
 | 
				
			||||||
			      .en(~StallW),
 | 
								      .en(~StallW),
 | 
				
			||||||
			      .d(FinalReadDataWordM),
 | 
								      .d(ReadDataM),
 | 
				
			||||||
			      .q(ReadDataW));
 | 
								      .q(ReadDataW));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  assign ReadDataM = FinalReadDataWordM;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // write path
 | 
					  // write path
 | 
				
			||||||
  subwordwrite subwordwrite(.HRDATA(ReadDataWordM),
 | 
					  subwordwrite subwordwrite(.HRDATA(ReadDataWordM),
 | 
				
			||||||
@ -339,7 +338,7 @@ module dcache
 | 
				
			|||||||
  generate
 | 
					  generate
 | 
				
			||||||
    if (`A_SUPPORTED) begin
 | 
					    if (`A_SUPPORTED) begin
 | 
				
			||||||
      logic [`XLEN-1:0] AMOResult;
 | 
					      logic [`XLEN-1:0] AMOResult;
 | 
				
			||||||
      amoalu amoalu(.srca(FinalReadDataWordM), .srcb(WriteDataM), .funct(Funct7M), .width(Funct3M[1:0]), 
 | 
					      amoalu amoalu(.srca(ReadDataM), .srcb(WriteDataM), .funct(Funct7M), .width(Funct3M[1:0]), 
 | 
				
			||||||
                    .result(AMOResult));
 | 
					                    .result(AMOResult));
 | 
				
			||||||
      mux2 #(`XLEN) wdmux(FinalWriteDataM, AMOResult, SelAMOWrite & AtomicM[1], FinalAMOWriteDataM);
 | 
					      mux2 #(`XLEN) wdmux(FinalWriteDataM, AMOResult, SelAMOWrite & AtomicM[1], FinalAMOWriteDataM);
 | 
				
			||||||
    end else
 | 
					    end else
 | 
				
			||||||
 | 
				
			|||||||
@ -27,7 +27,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
module testbench();
 | 
					module testbench();
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  parameter waveOnICount = `BUSYBEAR*140000 + `BUILDROOT*0459700; // # of instructions at which to turn on waves in graphical sim
 | 
					  parameter waveOnICount = `BUSYBEAR*140000 + `BUILDROOT*0900000; // # of instructions at which to turn on waves in graphical sim
 | 
				
			||||||
  parameter stopICount   = `BUSYBEAR*143898 + `BUILDROOT*0000000; // # instructions at which to halt sim completely (set to 0 to let it run as far as it can)  
 | 
					  parameter stopICount   = `BUSYBEAR*143898 + `BUILDROOT*0000000; // # instructions at which to halt sim completely (set to 0 to let it run as far as it can)  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////////////////////////////////////////////////////////
 | 
					  ///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
@ -103,6 +103,7 @@ module testbench();
 | 
				
			|||||||
  logic [99:0] StartCSRexpected[63:0];
 | 
					  logic [99:0] StartCSRexpected[63:0];
 | 
				
			||||||
  string StartCSRname[99:0];
 | 
					  string StartCSRname[99:0];
 | 
				
			||||||
  integer data_file_csr, scan_file_csr;
 | 
					  integer data_file_csr, scan_file_csr;
 | 
				
			||||||
 | 
					  logic IllegalInstrFaultd;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // -----------
 | 
					  // -----------
 | 
				
			||||||
  // Error Macro
 | 
					  // Error Macro
 | 
				
			||||||
@ -153,21 +154,22 @@ module testbench();
 | 
				
			|||||||
      clk <= 1; # 5; clk <= 0; # 5;
 | 
					      clk <= 1; # 5; clk <= 0; # 5;
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // -------------------
 | 
				
			||||||
 | 
					  // Additional Hardware
 | 
				
			||||||
 | 
					  // -------------------
 | 
				
			||||||
 | 
					  always @(posedge clk)
 | 
				
			||||||
 | 
					    IllegalInstrFaultd = dut.hart.priv.IllegalInstrFaultM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // -------------------------------------
 | 
					  // -------------------------------------
 | 
				
			||||||
  // Special warnings for important faults
 | 
					  // Special warnings for important faults
 | 
				
			||||||
  // -------------------------------------
 | 
					  // -------------------------------------
 | 
				
			||||||
  always @(dut.hart.priv.csr.genblk1.csrm.MCAUSE_REGW) begin
 | 
					  always @(dut.hart.priv.csr.genblk1.csrm.MCAUSE_REGW) begin
 | 
				
			||||||
    if (dut.hart.priv.csr.genblk1.csrm.MCAUSE_REGW == 2 && instrs > 1) begin
 | 
					    if (dut.hart.priv.csr.genblk1.csrm.MCAUSE_REGW == 2 && instrs > 1) begin
 | 
				
			||||||
      $display("!!!!!! illegal instruction !!!!!!!!!!");
 | 
					      // This is sometimes okay if the source code intentionally causes it.
 | 
				
			||||||
      $display("(as a reminder, MCAUSE and MEPC are set by this)");
 | 
					      $display("Warning: illegal instruction exception at %0t ps, InstrNum %0d, PCM %x, InstrM %s", $time, instrs, dut.hart.ifu.PCM, PCtextM);
 | 
				
			||||||
      $display("at %0t ps, PCM %x, instr %0d, dut.hart.lsu.dcache.MemPAdrM %x", $time, dut.hart.ifu.PCM, instrs, dut.hart.lsu.dcache.MemPAdrM);
 | 
					 | 
				
			||||||
      `ERROR
 | 
					 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
    if (dut.hart.priv.csr.genblk1.csrm.MCAUSE_REGW == 5 && instrs != 0) begin
 | 
					    if (dut.hart.priv.csr.genblk1.csrm.MCAUSE_REGW == 5 && instrs != 0) begin
 | 
				
			||||||
      $display("!!!!!! illegal (physical) memory access !!!!!!!!!!");
 | 
					      $display("Warning: illegal physical memory access exception at %0t ps, InstrNum %0d, PCM %x, InstrM %s", $time, instrs, dut.hart.ifu.PCM, PCtextM);
 | 
				
			||||||
      $display("(as a reminder, MCAUSE and MEPC are set by this)");
 | 
					 | 
				
			||||||
      $display("at %0t ps, PCM %x, instr %0d, dut.hart.lsu.dcache.MemPAdrM %x", $time, dut.hart.ifu.PCM, instrs, dut.hart.lsu.dcache.MemPAdrM);
 | 
					 | 
				
			||||||
      `ERROR
 | 
					 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -185,8 +187,14 @@ module testbench();
 | 
				
			|||||||
      // Hack to compensate for QEMU's incorrect MSTATUS
 | 
					      // Hack to compensate for QEMU's incorrect MSTATUS
 | 
				
			||||||
      end else if (PCtextW.substr(0,3) == "csrr" && PCtextW.substr(10,16) == "mstatus") begin
 | 
					      end else if (PCtextW.substr(0,3) == "csrr" && PCtextW.substr(10,16) == "mstatus") begin
 | 
				
			||||||
        force dut.hart.ieu.dp.regf.wd3 = dut.hart.ieu.dp.WriteDataW & ~64'ha00000000;
 | 
					        force dut.hart.ieu.dp.regf.wd3 = dut.hart.ieu.dp.WriteDataW & ~64'ha00000000;
 | 
				
			||||||
      end else
 | 
					      end else release dut.hart.ieu.dp.regf.wd3;
 | 
				
			||||||
        release dut.hart.ieu.dp.regf.wd3;
 | 
					      // Hack to compensate for QEMU's correct but different MTVAL (according to spec, storing the faulting instr is an optional feature)
 | 
				
			||||||
 | 
					      if (PCtextW.substr(0,3) == "csrr" && PCtextW.substr(10,14) == "mtval") begin
 | 
				
			||||||
 | 
					        force dut.hart.ieu.dp.WriteDataW = 0;
 | 
				
			||||||
 | 
					      // Hack to compensate for QEMU's correct but different mhpmcounter's (these too are optional)
 | 
				
			||||||
 | 
					      end else if (PCtextW.substr(0,3) == "csrr" && PCtextW.substr(10,20) == "mhpmcounter") begin
 | 
				
			||||||
 | 
					        force dut.hart.ieu.dp.WriteDataW = 0;
 | 
				
			||||||
 | 
					      end else release dut.hart.ieu.dp.WriteDataW;
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -204,7 +212,6 @@ module testbench();
 | 
				
			|||||||
        lastPC2 <= lastPC;
 | 
					        lastPC2 <= lastPC;
 | 
				
			||||||
        // If PCD isn't going to be flushed
 | 
					        // If PCD isn't going to be flushed
 | 
				
			||||||
        if (~PCDwrong || lastPC == PCDexpected) begin
 | 
					        if (~PCDwrong || lastPC == PCDexpected) begin
 | 
				
			||||||
 | 
					 | 
				
			||||||
          // Stop if we've reached the end
 | 
					          // Stop if we've reached the end
 | 
				
			||||||
          if($feof(data_file_PCF)) begin
 | 
					          if($feof(data_file_PCF)) begin
 | 
				
			||||||
            $display("no more PC data to read... CONGRATULATIONS!!!");
 | 
					            $display("no more PC data to read... CONGRATULATIONS!!!");
 | 
				
			||||||
@ -253,29 +260,7 @@ module testbench();
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
          // Check if PCD is going to be flushed due to a branch or jump
 | 
					          // Check if PCD is going to be flushed due to a branch or jump
 | 
				
			||||||
          if (`BPRED_ENABLED) begin
 | 
					          if (`BPRED_ENABLED) begin
 | 
				
			||||||
            PCDwrong = dut.hart.hzu.FlushD; //Old version: dut.hart.ifu.bpred.bpred.BPPredWrongE; <-- This old version failed to account for MRET.
 | 
					            PCDwrong = dut.hart.hzu.FlushD || (PCtextE.substr(0,3) == "mret"); //Old version: dut.hart.ifu.bpred.bpred.BPPredWrongE; <-- This old version failed to account for MRET.
 | 
				
			||||||
          end else begin
 | 
					 | 
				
			||||||
            casex (lastInstrDExpected[31:0])
 | 
					 | 
				
			||||||
              32'b00000000001000000000000001110011, // URET
 | 
					 | 
				
			||||||
              32'b00010000001000000000000001110011, // SRET
 | 
					 | 
				
			||||||
              32'b00110000001000000000000001110011, // MRET
 | 
					 | 
				
			||||||
              32'bXXXXXXXXXXXXXXXXXXXXXXXXX1101111, // JAL
 | 
					 | 
				
			||||||
              32'bXXXXXXXXXXXXXXXXXXXXXXXXX1100111, // JALR
 | 
					 | 
				
			||||||
              32'bXXXXXXXXXXXXXXXXXXXXXXXXX1100011, // B
 | 
					 | 
				
			||||||
              32'bXXXXXXXXXXXXXXXX110XXXXXXXXXXX01, // C.BEQZ
 | 
					 | 
				
			||||||
              32'bXXXXXXXXXXXXXXXX111XXXXXXXXXXX01, // C.BNEZ
 | 
					 | 
				
			||||||
              32'bXXXXXXXXXXXXXXXX101XXXXXXXXXXX01: // C.J
 | 
					 | 
				
			||||||
                PCDwrong = 1;
 | 
					 | 
				
			||||||
              32'bXXXXXXXXXXXXXXXX1001000000000010, // C.EBREAK:
 | 
					 | 
				
			||||||
              32'bXXXXXXXXXXXXXXXXX000XXXXX1110011: // Something that's not CSRR*
 | 
					 | 
				
			||||||
                PCDwrong = 0; // tbh don't really know what should happen here
 | 
					 | 
				
			||||||
              32'b000110000000XXXXXXXXXXXXX1110011, // CSR* SATP, *
 | 
					 | 
				
			||||||
              32'bXXXXXXXXXXXXXXXX1000XXXXX0000010, // C.JR
 | 
					 | 
				
			||||||
              32'bXXXXXXXXXXXXXXXX1001XXXXX0000010: // C.JALR //this is RV64 only so no C.JAL
 | 
					 | 
				
			||||||
                PCDwrong = 1;
 | 
					 | 
				
			||||||
              default:
 | 
					 | 
				
			||||||
                PCDwrong = 0;
 | 
					 | 
				
			||||||
            endcase
 | 
					 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          // Check PCD, InstrD
 | 
					          // Check PCD, InstrD
 | 
				
			||||||
@ -358,9 +343,8 @@ module testbench();
 | 
				
			|||||||
      end
 | 
					      end
 | 
				
			||||||
      `SCAN_PC(data_file_PCM, scan_file_PCM, trashString, trashString, InstrMExpected, PCMexpected);
 | 
					      `SCAN_PC(data_file_PCM, scan_file_PCM, trashString, trashString, InstrMExpected, PCMexpected);
 | 
				
			||||||
      `SCAN_PC(data_file_PCW, scan_file_PCW, trashString, trashString, InstrWExpected, PCWexpected);
 | 
					      `SCAN_PC(data_file_PCW, scan_file_PCW, trashString, trashString, InstrWExpected, PCWexpected);
 | 
				
			||||||
      // If repeated instr
 | 
					      // If repeated or instruction, we want to skip over it (indicates an interrupt)
 | 
				
			||||||
      if (PCMexpected == PCWexpected) begin
 | 
					      if (PCMexpected == PCWexpected) begin
 | 
				
			||||||
        // Increment file pointers past the repeated instruction.
 | 
					 | 
				
			||||||
        `SCAN_PC(data_file_PCM, scan_file_PCM, trashString, trashString, InstrMExpected, PCMexpected);
 | 
					        `SCAN_PC(data_file_PCM, scan_file_PCM, trashString, trashString, InstrMExpected, PCMexpected);
 | 
				
			||||||
        `SCAN_PC(data_file_PCW, scan_file_PCW, trashString, trashString, InstrWExpected, PCWexpected);
 | 
					        `SCAN_PC(data_file_PCW, scan_file_PCW, trashString, trashString, InstrWExpected, PCWexpected);
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
@ -369,6 +353,11 @@ module testbench();
 | 
				
			|||||||
        `ERROR
 | 
					        `ERROR
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					    // Skip over faulting instructions because they do not make it to the W stage.
 | 
				
			||||||
 | 
					    if (IllegalInstrFaultd) begin
 | 
				
			||||||
 | 
					      `SCAN_PC(data_file_PCM, scan_file_PCM, trashString, trashString, InstrMExpected, PCMexpected);
 | 
				
			||||||
 | 
					      `SCAN_PC(data_file_PCW, scan_file_PCW, trashString, trashString, InstrWExpected, PCWexpected);
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -527,47 +516,61 @@ module testbench();
 | 
				
			|||||||
  // --------------
 | 
					  // --------------
 | 
				
			||||||
  // Checker Macros
 | 
					  // Checker Macros
 | 
				
			||||||
  // --------------
 | 
					  // --------------
 | 
				
			||||||
  string MSTATUSstring = "MSTATUS"; // string variables seem to compare more reliably than string literals (they gave me a lot of hassle), but *** there's probably a better way to do this
 | 
					  // String variables seem to compare more reliably than string literals (they gave me a lot of hassle),
 | 
				
			||||||
 | 
					  // but *** there's probably a better way to do this.
 | 
				
			||||||
 | 
					  // You can't just use the "__name" variables though because you need to declare variables before using them.
 | 
				
			||||||
 | 
					  string MSTATUSstring = "MSTATUS";
 | 
				
			||||||
  string MIPstring = "MIP";
 | 
					  string MIPstring = "MIP";
 | 
				
			||||||
 | 
					  string MEPCstring = "MEPC";
 | 
				
			||||||
 | 
					  string MCAUSEstring = "MCAUSE";
 | 
				
			||||||
 | 
					  string MTVALstring = "MTVAL";
 | 
				
			||||||
  string SEPCstring = "SEPC";
 | 
					  string SEPCstring = "SEPC";
 | 
				
			||||||
  string SCAUSEstring = "SCAUSE";
 | 
					  string SCAUSEstring = "SCAUSE";
 | 
				
			||||||
  string SSTATUSstring = "SSTATUS";
 | 
					  string SSTATUSstring = "SSTATUS";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  logic [63:0] expectedCSR;
 | 
				
			||||||
 | 
					  string expectedCSRname;
 | 
				
			||||||
  `define CHECK_CSR2(CSR, PATH) \
 | 
					  `define CHECK_CSR2(CSR, PATH) \
 | 
				
			||||||
    logic [63:0] expected``CSR``; \
 | 
					 | 
				
			||||||
    string CSR; \
 | 
					 | 
				
			||||||
    string ``CSR``name = `"CSR`"; \
 | 
					    string ``CSR``name = `"CSR`"; \
 | 
				
			||||||
    string expected``CSR``name; \
 | 
					 | 
				
			||||||
    always @(``PATH``.``CSR``_REGW) begin \
 | 
					    always @(``PATH``.``CSR``_REGW) begin \
 | 
				
			||||||
      // MIP is not checked because QEMU bodges it (MTIP in particular), and even if QEMU reported it correctly, the timing would still be off \
 | 
					      if (instrs == 0 && ~reset) begin \
 | 
				
			||||||
      if ($time > 1 && (``CSR``name != MIPstring)) begin \
 | 
					        for(integer j=0; j<totalCSR; j++) begin \
 | 
				
			||||||
        // This is some feeble hackery designed to control the order in which CSRs are checked \
 | 
					          if(!StartCSRname[j].icompare(``CSR``name)) begin \
 | 
				
			||||||
        // when multiple change at the same time. \
 | 
					            if(``PATH``.``CSR``_REGW != StartCSRexpected[j]) begin \
 | 
				
			||||||
        if (``CSR``name == SEPCstring) #1; \
 | 
					              $display("%0t ps, PCM %x %s, instr %0d: %s does not equal %s expected: %x, %x", $time, dut.hart.ifu.PCM, PCtextM, instrs, ``CSR``name, StartCSRname[j], ``PATH``.``CSR``_REGW, StartCSRexpected[j]); \
 | 
				
			||||||
        if (``CSR``name == SCAUSEstring) #2; \
 | 
					              `ERROR \
 | 
				
			||||||
        if (``CSR``name == SSTATUSstring) #3; \
 | 
					            end \
 | 
				
			||||||
        scan_file_csr = $fscanf(data_file_csr, "%s\n", expected``CSR``name); \
 | 
					          end \
 | 
				
			||||||
        scan_file_csr = $fscanf(data_file_csr, "%x\n", expected``CSR``); \
 | 
					 | 
				
			||||||
        if(expected``CSR``name.icompare(``CSR``name)) begin \
 | 
					 | 
				
			||||||
          $display("%0t ps, PCM %x %s, instr %0d: %s changed, expected %s", $time, dut.hart.ifu.PCM, PCtextM, instrs, `"CSR`", expected``CSR``name); \
 | 
					 | 
				
			||||||
        end \
 | 
					        end \
 | 
				
			||||||
        if (``CSR``name == MSTATUSstring) begin \
 | 
					        $display("CSRs' intital states look good"); \
 | 
				
			||||||
          if (``PATH``.``CSR``_REGW != ((``expected``CSR) | 64'ha00000000)) begin \
 | 
					 | 
				
			||||||
            $display("%0t ps, PCM %x %s, instr %0d: %s (should be MSTATUS) does not equal %s expected: %x, %x", $time, dut.hart.ifu.PCM, PCtextM, instrs, ``CSR``name, expected``CSR``name, ``PATH``.``CSR``_REGW, (``expected``CSR) | 64'ha00000000); \
 | 
					 | 
				
			||||||
            `ERROR \
 | 
					 | 
				
			||||||
          end \
 | 
					 | 
				
			||||||
        end else \
 | 
					 | 
				
			||||||
          if (``PATH``.``CSR``_REGW != ``expected``CSR[$bits(``PATH``.``CSR``_REGW)-1:0]) begin \
 | 
					 | 
				
			||||||
            $display("%0t ps, PCM %x %s, instr %0d: %s does not equal %s expected: %x, %x", $time, dut.hart.ifu.PCM, PCtextM, instrs, ``CSR``name, expected``CSR``name, ``PATH``.``CSR``_REGW, ``expected``CSR); \
 | 
					 | 
				
			||||||
            `ERROR \
 | 
					 | 
				
			||||||
          end \
 | 
					 | 
				
			||||||
      end else begin \
 | 
					      end else begin \
 | 
				
			||||||
        if (!(`BUILDROOT == 1 && ``CSR``name == MSTATUSstring)) begin \
 | 
					        // MIP is not checked because QEMU bodges it (MTIP in particular), and even if QEMU reported it correctly, the timing would still be off \
 | 
				
			||||||
          for(integer j=0; j<totalCSR; j++) begin \
 | 
					        // MTVAL is not checked on illegal instr faults because QEMU chooses not to implement the behavior where MTVAL is written with the faulting instruction \
 | 
				
			||||||
            if(!StartCSRname[j].icompare(``CSR``name)) begin \
 | 
					        if  (~reset && ``CSR``name != MIPstring && ~(IllegalInstrFaultd && ``CSR``name == MTVALstring)) begin \
 | 
				
			||||||
              if(``PATH``.``CSR``_REGW != StartCSRexpected[j]) begin \
 | 
					          // This is some feeble hackery designed to control the order in which CSRs are checked \
 | 
				
			||||||
                $display("%0t ps, PCM %x %s, instr %0d: %s does not equal %s expected: %x, %x", $time, dut.hart.ifu.PCM, PCtextM, instrs, ``CSR``name, StartCSRname[j], ``PATH``.``CSR``_REGW, StartCSRexpected[j]); \
 | 
					          // when multiple change at the same time. \
 | 
				
			||||||
                `ERROR \
 | 
					          // *** it would be better for each CSR to have its own testvector file \
 | 
				
			||||||
              end \
 | 
					          // so as to avoid this awkward ordering problem. \
 | 
				
			||||||
 | 
					          if (``CSR``name == MEPCstring) #1; \
 | 
				
			||||||
 | 
					          if (``CSR``name == MCAUSEstring) #2; \
 | 
				
			||||||
 | 
					          if (``CSR``name == MTVALstring) #3; \
 | 
				
			||||||
 | 
					          if (``CSR``name == SEPCstring) #1; \
 | 
				
			||||||
 | 
					          if (``CSR``name == SCAUSEstring) #2; \
 | 
				
			||||||
 | 
					          if (``CSR``name == SSTATUSstring) #3; \
 | 
				
			||||||
 | 
					          scan_file_csr = $fscanf(data_file_csr, "%s\n", expectedCSRname); \
 | 
				
			||||||
 | 
					          scan_file_csr = $fscanf(data_file_csr, "%x\n", expectedCSR); \
 | 
				
			||||||
 | 
					          if(expectedCSRname.icompare(``CSR``name)) begin \
 | 
				
			||||||
 | 
					            $display("%0t ps, PCM %x %s, instr %0d: %s changed, expected %s", $time, dut.hart.ifu.PCM, PCtextM, instrs, `"CSR`", expectedCSRname); \
 | 
				
			||||||
 | 
					          end \
 | 
				
			||||||
 | 
					          if (``CSR``name == MSTATUSstring) begin \
 | 
				
			||||||
 | 
					            if (``PATH``.``CSR``_REGW != ((expectedCSR) | 64'ha00000000)) begin \
 | 
				
			||||||
 | 
					              $display("%0t ps, PCM %x %s, instr %0d: %s (should be MSTATUS) does not equal %s expected: %x, %x", $time, dut.hart.ifu.PCM, PCtextM, instrs, ``CSR``name, expectedCSRname, ``PATH``.``CSR``_REGW, expectedCSR | 64'ha00000000); \
 | 
				
			||||||
 | 
					              `ERROR \
 | 
				
			||||||
 | 
					            end \
 | 
				
			||||||
 | 
					          end else begin \
 | 
				
			||||||
 | 
					            if (``PATH``.``CSR``_REGW != expectedCSR[$bits(``PATH``.``CSR``_REGW)-1:0]) begin \
 | 
				
			||||||
 | 
					              $display("%0t ps, PCM %x %s, instr %0d: %s does not equal %s expected: %x, %x", $time, dut.hart.ifu.PCM, PCtextM, instrs, ``CSR``name, expectedCSRname, ``PATH``.``CSR``_REGW, expectedCSR); \
 | 
				
			||||||
 | 
					              `ERROR \
 | 
				
			||||||
            end \
 | 
					            end \
 | 
				
			||||||
          end \
 | 
					          end \
 | 
				
			||||||
        end \
 | 
					        end \
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user