mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	change CHECKPOINT to be a parameter (not a macro) so that do scripts can control it; clean up checkpoint initialization macros
This commit is contained in:
		
							parent
							
								
									9b98a499d7
								
							
						
					
					
						commit
						8c4e6baf48
					
				| @ -34,10 +34,10 @@ def getBuildrootTC(short): | |||||||
|     INSTR_LIMIT = 100000 # multiple of 100000 |     INSTR_LIMIT = 100000 # multiple of 100000 | ||||||
|     MAX_EXPECTED = 3000000 |     MAX_EXPECTED = 3000000 | ||||||
|     if short: |     if short: | ||||||
|         BRcmd="vsim > {} -c <<!\ndo wally-buildroot-batch.do "+str(INSTR_LIMIT)+"\n!" |         BRcmd="vsim > {} -c <<!\ndo wally-buildroot-batch.do "+str(INSTR_LIMIT)+" 1 0\n!" | ||||||
|         BRgrepstr=str(INSTR_LIMIT)+" instructions" |         BRgrepstr=str(INSTR_LIMIT)+" instructions" | ||||||
|     else: |     else: | ||||||
|         BRcmd="vsim > {} -c <<!\ndo wally-buildroot-batch.do 0\n!" |         BRcmd="vsim > {} -c <<!\ndo wally-buildroot-batch.do 0 1 0\n!" | ||||||
|         BRgrepstr=str(MAX_EXPECTED)+" instructions" |         BRgrepstr=str(MAX_EXPECTED)+" instructions" | ||||||
|     return  TestCase(name="buildroot",cmd=BRcmd,grepstr=BRgrepstr) |     return  TestCase(name="buildroot",cmd=BRcmd,grepstr=BRgrepstr) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1 +1,33 @@ | |||||||
| vsim -do wally-buildroot.do | #!/bin/bash | ||||||
|  | 
 | ||||||
|  | # Defaults | ||||||
|  | INSTR_LIMIT=0 | ||||||
|  | INSTR_WAVEON=1 | ||||||
|  | CHECKPOINT=0 | ||||||
|  | 
 | ||||||
|  | # Arg Parsing | ||||||
|  | for i in "$@"; do | ||||||
|  |   case $i in | ||||||
|  |     --INSTR_LIMIT=*) | ||||||
|  |       INSTR_LIMIT="${i#*=}" | ||||||
|  |       shift # past argument=value | ||||||
|  |       ;; | ||||||
|  |     --INSTR_WAVEON=*) | ||||||
|  |       INSTR_WAVEON="${i#*=}" | ||||||
|  |       shift # past argument=value | ||||||
|  |       ;; | ||||||
|  |     --CHECKPOINT=*) | ||||||
|  |       CHECKPOINT="${i#*=}" | ||||||
|  |       shift # past argument=value | ||||||
|  |       ;; | ||||||
|  |     *) | ||||||
|  |       # unknown option | ||||||
|  |       ;; | ||||||
|  |   esac | ||||||
|  | done | ||||||
|  | 
 | ||||||
|  | echo "INSTR_LIMIT  = ${INSTR_LIMIT}" | ||||||
|  | echo "INSTR_WAVEON = ${INSTR_WAVEON}" | ||||||
|  | echo "CHECKPOINT   = ${CHECKPOINT}" | ||||||
|  | 
 | ||||||
|  | vsim -do wally-buildroot.do $INSTR_LIMIT $INSTR_WAVEON $CHECKPOINT | ||||||
|  | |||||||
| @ -1,4 +1,35 @@ | |||||||
| INSTR_LIMIT=${1:-0} | #!/bin/bash | ||||||
|  | 
 | ||||||
|  | # Defaults | ||||||
|  | INSTR_LIMIT=0 | ||||||
|  | INSTR_WAVEON=1 | ||||||
|  | CHECKPOINT=0 | ||||||
|  | 
 | ||||||
|  | # Arg Parsing | ||||||
|  | for i in "$@"; do | ||||||
|  |   case $i in | ||||||
|  |     --INSTR_LIMIT=*) | ||||||
|  |       INSTR_LIMIT="${i#*=}" | ||||||
|  |       shift # past argument=value | ||||||
|  |       ;; | ||||||
|  |     --INSTR_WAVEON=*) | ||||||
|  |       INSTR_WAVEON="${i#*=}" | ||||||
|  |       shift # past argument=value | ||||||
|  |       ;; | ||||||
|  |     --CHECKPOINT=*) | ||||||
|  |       CHECKPOINT="${i#*=}" | ||||||
|  |       shift # past argument=value | ||||||
|  |       ;; | ||||||
|  |     *) | ||||||
|  |       # unknown option | ||||||
|  |       ;; | ||||||
|  |   esac | ||||||
|  | done | ||||||
|  | 
 | ||||||
|  | echo "INSTR_LIMIT  = ${INSTR_LIMIT}" | ||||||
|  | echo "INSTR_WAVEON = ${INSTR_WAVEON}" | ||||||
|  | echo "CHECKPOINT   = ${CHECKPOINT}" | ||||||
|  | 
 | ||||||
| vsim -c <<! | vsim -c <<! | ||||||
| do wally-buildroot-batch.do $INSTR_LIMIT | do wally-buildroot-batch.do $INSTR_LIMIT $INSTR_WAVEON $CHECKPOINT | ||||||
| ! | ! | ||||||
|  | |||||||
| @ -29,8 +29,7 @@ vlog -lint +incdir+../config/buildroot +incdir+../config/shared ../testbench/tes | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # start and run simulation | # start and run simulation | ||||||
| # remove +acc flag for faster sim during regressions if there is no need to access internal signals | vopt work.testbench -G INSTR_LIMIT=$1 -G INSTR_WAVEON=$2 -G CHECKPOINT=$3 -o workopt  | ||||||
| vopt work.testbench -G INSTR_LIMIT=$1 -o workopt  |  | ||||||
| 
 | 
 | ||||||
| vsim workopt -suppress 8852,12070 | vsim workopt -suppress 8852,12070 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -30,7 +30,7 @@ vlog -lint +incdir+../config/buildroot +incdir+../config/shared ../testbench/tes | |||||||
| 
 | 
 | ||||||
| # start and run simulation | # start and run simulation | ||||||
| # remove +acc flag for faster sim during regressions if there is no need to access internal signals | # remove +acc flag for faster sim during regressions if there is no need to access internal signals | ||||||
| vopt +acc work.testbench -o workopt  | vopt +acc work.testbench -G INSTR_LIMIT=$1 -G INSTR_WAVEON=$2 -G CHECKPOINT=$3 -o workopt  | ||||||
| 
 | 
 | ||||||
| vsim workopt -suppress 8852,12070 | vsim workopt -suppress 8852,12070 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -35,20 +35,15 @@ | |||||||
| // 3: halt on all disagreements with QEMU
 | // 3: halt on all disagreements with QEMU
 | ||||||
| // 4: print memory accesses whenever they happen
 | // 4: print memory accesses whenever they happen
 | ||||||
| // 5: print everything
 | // 5: print everything
 | ||||||
| //
 |  | ||||||
| // uncomment the following line to activate checkpoint
 |  | ||||||
| `define CHECKPOINT 8500000 |  | ||||||
| `ifdef CHECKPOINT |  | ||||||
|     `define CHECKPOINT_DIR {`LINUX_TEST_VECTORS, "checkpoint", `"`CHECKPOINT`", "/"} |  | ||||||
| `endif |  | ||||||
| 
 | 
 | ||||||
| module testbench(); | module testbench(); | ||||||
|   ///////////////////////////////////////////////////////////////////////////////
 |   ///////////////////////////////////////////////////////////////////////////////
 | ||||||
|   /////////////////////////////////// CONFIG ////////////////////////////////////
 |   /////////////////////////////////// CONFIG ////////////////////////////////////
 | ||||||
|   ///////////////////////////////////////////////////////////////////////////////
 |   ///////////////////////////////////////////////////////////////////////////////
 | ||||||
|   parameter INSTR_LIMIT = 0; // # of instructions at which to stop
 |   // Recommend setting all of these in do script using -G option
 | ||||||
|   parameter INSTR_WAVEON = 8.7e6;//(INSTR_LIMIT > 10000) ? INSTR_LIMIT-10000 : 1; // # of instructions at which to turn on waves in graphical sim
 |   parameter INSTR_LIMIT  = 0; // # of instructions at which to stop
 | ||||||
|   //parameter CHECKPOINT = 0;
 |   parameter INSTR_WAVEON = 0; // # of instructions at which to turn on waves in graphical sim
 | ||||||
|  |   parameter CHECKPOINT   = 0; | ||||||
| 
 | 
 | ||||||
|   ///////////////////////////////////////////////////////////////////////////////
 |   ///////////////////////////////////////////////////////////////////////////////
 | ||||||
|   ////////////////////////////////// HARDWARE ///////////////////////////////////
 |   ////////////////////////////////// HARDWARE ///////////////////////////////////
 | ||||||
| @ -80,7 +75,8 @@ module testbench(); | |||||||
|                         .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, |                         .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, | ||||||
|                         .UARTSin, .UARTSout); |                         .UARTSin, .UARTSout); | ||||||
| 
 | 
 | ||||||
|   // Write Back stage signals not needed by Wally itself
 |   // Write Back stage signals not needed by Wally itself 
 | ||||||
|  |   parameter nop = 'h13; | ||||||
|   logic [`XLEN-1:0] PCW; |   logic [`XLEN-1:0] PCW; | ||||||
|   logic [31:0]      InstrW; |   logic [31:0]      InstrW; | ||||||
|   logic             InstrValidW; |   logic             InstrValidW; | ||||||
| @ -103,6 +99,9 @@ module testbench(); | |||||||
|   integer errorCount = 0; |   integer errorCount = 0; | ||||||
|   integer fault; |   integer fault; | ||||||
|   string  ProgramAddrMapFile, ProgramLabelMapFile; |   string  ProgramAddrMapFile, ProgramLabelMapFile; | ||||||
|  |   // Checkpointing
 | ||||||
|  |   string checkpointDir; | ||||||
|  |   logic [1:0] initPriv; | ||||||
|   // Signals used to parse the trace file
 |   // Signals used to parse the trace file
 | ||||||
|   integer           data_file_all; |   integer           data_file_all; | ||||||
|   string            name; |   string            name; | ||||||
| @ -207,30 +206,111 @@ module testbench(); | |||||||
|   ///////////////////////////////////////////////////////////////////////////////
 |   ///////////////////////////////////////////////////////////////////////////////
 | ||||||
|   /////////////////////////////// INITIALIZATION ////////////////////////////////
 |   /////////////////////////////// INITIALIZATION ////////////////////////////////
 | ||||||
|   ///////////////////////////////////////////////////////////////////////////////
 |   ///////////////////////////////////////////////////////////////////////////////
 | ||||||
|  |   // Checkpoint initializations
 | ||||||
|  |   `define MAKE_CHECKPOINT_INIT_SIGNAL(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \ | ||||||
|  |     logic DIM init``SIGNAL[ARRAY_MAX:ARRAY_MIN]; \ | ||||||
|  |     initial begin \ | ||||||
|  |       #1; \ | ||||||
|  |       if (CHECKPOINT!=0) $readmemh({checkpointDir,"checkpoint-",`"SIGNAL`"}, init``SIGNAL); \ | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |   `define INIT_CHECKPOINT_SIMPLE_ARRAY(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \ | ||||||
|  |     `MAKE_CHECKPOINT_INIT_SIGNAL(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \ | ||||||
|  |     initial begin \ | ||||||
|  |       if (CHECKPOINT!=0) begin \ | ||||||
|  |         force `SIGNAL = init``SIGNAL[ARRAY_MAX:ARRAY_MIN]; \ | ||||||
|  |         #23; \ | ||||||
|  |         release `SIGNAL; \ | ||||||
|  |       end \ | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |   // For the annoying case where the pathname to the array elements includes
 | ||||||
|  |   // a "genblk<i>" in the signal name
 | ||||||
|  |   `define INIT_CHECKPOINT_GENBLK_ARRAY(SIGNAL_BASE,SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \ | ||||||
|  |     `MAKE_CHECKPOINT_INIT_SIGNAL(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \ | ||||||
|  |     for (i=ARRAY_MIN; i<ARRAY_MAX+1; i=i+1) begin \ | ||||||
|  |       initial begin \ | ||||||
|  |         if (CHECKPOINT!=0) begin \ | ||||||
|  |           force `SIGNAL_BASE[i].`SIGNAL = init``SIGNAL[i]; \ | ||||||
|  |           #23; \ | ||||||
|  |           release `SIGNAL_BASE[i].`SIGNAL; \ | ||||||
|  |         end \ | ||||||
|  |       end \ | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |   // Note that dimension usage is very intentional here.
 | ||||||
|  |   // We are dancing around (un)packed type requirements.
 | ||||||
|  |   `define INIT_CHECKPOINT_VAL(SIGNAL,DIM) \ | ||||||
|  |     `MAKE_CHECKPOINT_INIT_SIGNAL(SIGNAL,DIM,0,0) \ | ||||||
|  |     initial begin \ | ||||||
|  |       if (CHECKPOINT!=0) begin \ | ||||||
|  |         force `SIGNAL = init``SIGNAL[0]; \ | ||||||
|  |         #23; \ | ||||||
|  |         release `SIGNAL; \ | ||||||
|  |       end \ | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |   `INIT_CHECKPOINT_SIMPLE_ARRAY(RF,         [`XLEN-1:0],31,1); | ||||||
|  |   `INIT_CHECKPOINT_SIMPLE_ARRAY(HPMCOUNTER, [`XLEN-1:0],`COUNTERS-1,3); | ||||||
|  |   generate | ||||||
|  |     genvar i; | ||||||
|  |     `INIT_CHECKPOINT_GENBLK_ARRAY(PMP_BASE, PMPCFG,  [7:0],`PMP_ENTRIES-1,0); | ||||||
|  |     `INIT_CHECKPOINT_GENBLK_ARRAY(PMP_BASE, PMPADDR, [`XLEN-1:0],`PMP_ENTRIES-1,0); | ||||||
|  |   endgenerate | ||||||
|  |   `INIT_CHECKPOINT_VAL(PC,         [`XLEN-1:0]); | ||||||
|  |   `INIT_CHECKPOINT_VAL(MEDELEG,    [`XLEN-1:0]); | ||||||
|  |   `INIT_CHECKPOINT_VAL(MIE,        [11:0]); | ||||||
|  |   `INIT_CHECKPOINT_VAL(MIP,        [11:0]); | ||||||
|  |   `INIT_CHECKPOINT_VAL(MCAUSE,     [`XLEN-1:0]); | ||||||
|  |   `INIT_CHECKPOINT_VAL(SCAUSE,     [`XLEN-1:0]); | ||||||
|  |   `INIT_CHECKPOINT_VAL(MEPC,       [`XLEN-1:0]); | ||||||
|  |   `INIT_CHECKPOINT_VAL(SEPC,       [`XLEN-1:0]); | ||||||
|  |   `INIT_CHECKPOINT_VAL(MCOUNTEREN, [31:0]); | ||||||
|  |   `INIT_CHECKPOINT_VAL(SCOUNTEREN, [31:0]); | ||||||
|  |   `INIT_CHECKPOINT_VAL(MSCRATCH,   [`XLEN-1:0]); | ||||||
|  |   `INIT_CHECKPOINT_VAL(SSCRATCH,   [`XLEN-1:0]); | ||||||
|  |   `INIT_CHECKPOINT_VAL(MTVEC,      [`XLEN-1:0]); | ||||||
|  |   `INIT_CHECKPOINT_VAL(STVEC,      [`XLEN-1:0]); | ||||||
|  |   `INIT_CHECKPOINT_VAL(SATP,       [`XLEN-1:0]); | ||||||
|  |   `MAKE_CHECKPOINT_INIT_SIGNAL(MSTATUS, [`XLEN-1:0],0,0); | ||||||
|  | 
 | ||||||
|  |   assign initPriv = (initPC[0][`XLEN-1]) ? 2'h2 : 2'h3; // *** a hacky way to detect initial privilege level
 | ||||||
|   initial begin |   initial begin | ||||||
|  |     force dut.hart.priv.SwIntM = 0; | ||||||
|  |     force dut.hart.priv.TimerIntM = 0; | ||||||
|  |     force dut.hart.priv.ExtIntM = 0;     | ||||||
|     $readmemh({`LINUX_TEST_VECTORS,"bootmem.txt"}, dut.uncore.bootdtim.bootdtim.RAM, 'h1000 >> 3); |     $readmemh({`LINUX_TEST_VECTORS,"bootmem.txt"}, dut.uncore.bootdtim.bootdtim.RAM, 'h1000 >> 3); | ||||||
|     `ifdef CHECKPOINT |  | ||||||
|       $readmemh({`CHECKPOINT_DIR,"ram.txt"}, dut.uncore.dtim.RAM); |  | ||||||
|     `else |  | ||||||
|       $readmemh({`LINUX_TEST_VECTORS,"ram.txt"}, dut.uncore.dtim.RAM); |  | ||||||
|     `endif |  | ||||||
|     $readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem); |     $readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem); | ||||||
|     $readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.bpred.TargetPredictor.memory.mem); |     $readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.bpred.TargetPredictor.memory.mem); | ||||||
|     ProgramAddrMapFile = {`LINUX_TEST_VECTORS,"vmlinux.objdump.addr"}; |     ProgramAddrMapFile = {`LINUX_TEST_VECTORS,"vmlinux.objdump.addr"}; | ||||||
|     ProgramLabelMapFile = {`LINUX_TEST_VECTORS,"vmlinux.objdump.lab"}; |     ProgramLabelMapFile = {`LINUX_TEST_VECTORS,"vmlinux.objdump.lab"}; | ||||||
|     `ifdef CHECKPOINT |     if (CHECKPOINT==0) begin // normal
 | ||||||
|       data_file_all = $fopen({`CHECKPOINT_DIR,"all.txt"}, "r"); |       $readmemh({`LINUX_TEST_VECTORS,"ram.txt"}, dut.uncore.dtim.RAM); | ||||||
|     `else |  | ||||||
|       data_file_all = $fopen({`LINUX_TEST_VECTORS,"all.txt"}, "r"); |       data_file_all = $fopen({`LINUX_TEST_VECTORS,"all.txt"}, "r"); | ||||||
|     `endif |  | ||||||
|     `ifdef CHECKPOINT |  | ||||||
|       InstrCountW = `CHECKPOINT; |  | ||||||
|     `else |  | ||||||
|       InstrCountW = '0; |       InstrCountW = '0; | ||||||
|     `endif |     end else begin // checkpoint
 | ||||||
|     force dut.hart.priv.SwIntM = 0; |       $sformat(checkpointDir,"checkpoint%0d/",CHECKPOINT); | ||||||
|     force dut.hart.priv.TimerIntM = 0; |       checkpointDir = {`LINUX_TEST_VECTORS,checkpointDir}; | ||||||
|     force dut.hart.priv.ExtIntM = 0;     |       $readmemh({checkpointDir,"ram.txt"}, dut.uncore.dtim.RAM); | ||||||
|  |       data_file_all = $fopen({checkpointDir,"all.txt"}, "r"); | ||||||
|  |       InstrCountW = CHECKPOINT; | ||||||
|  |       // manual checkpoint initializations that don't neatly fit into MACRO
 | ||||||
|  |       force {`STATUS_TSR,`STATUS_TW,`STATUS_TVM,`STATUS_MXR,`STATUS_SUM,`STATUS_MPRV} = initMSTATUS[0][22:17]; | ||||||
|  |       force {`STATUS_FS,`STATUS_MPP} = initMSTATUS[0][14:11]; | ||||||
|  |       force {`STATUS_SPP,`STATUS_MPIE} = initMSTATUS[0][8:7]; | ||||||
|  |       force {`STATUS_SPIE,`STATUS_UPIE,`STATUS_MIE} = initMSTATUS[0][5:3]; | ||||||
|  |       force {`STATUS_SIE,`STATUS_UIE} = initMSTATUS[0][1:0]; | ||||||
|  |       force `INSTRET = CHECKPOINT; | ||||||
|  |       force `CURR_PRIV = initPriv; | ||||||
|  |       #23; | ||||||
|  |       release {`STATUS_TSR,`STATUS_TW,`STATUS_TVM,`STATUS_MXR,`STATUS_SUM,`STATUS_MPRV}; | ||||||
|  |       release {`STATUS_FS,`STATUS_MPP}; | ||||||
|  |       release {`STATUS_SPP,`STATUS_MPIE}; | ||||||
|  |       release {`STATUS_SPIE,`STATUS_UPIE,`STATUS_MIE}; | ||||||
|  |       release {`STATUS_SIE,`STATUS_UIE}; | ||||||
|  |       release `INSTRET; | ||||||
|  |       release `CURR_PRIV; | ||||||
|  |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   ///////////////////////////////////////////////////////////////////////////////
 |   ///////////////////////////////////////////////////////////////////////////////
 | ||||||
| @ -473,94 +553,6 @@ module testbench(); | |||||||
|                             .ProgramLabelMapFile(ProgramLabelMapFile)); |                             .ProgramLabelMapFile(ProgramLabelMapFile)); | ||||||
|    |    | ||||||
| 
 | 
 | ||||||
|   `ifdef CHECKPOINT |  | ||||||
|      |  | ||||||
|     `define INIT_CHECKPOINT_VAL(SIGNAL_BASE,SIGNAL,DIM,LARGE_INDEX,SMALL_INDEX) \ |  | ||||||
|       logic DIM init``SIGNAL [LARGE_INDEX:SMALL_INDEX]; \ |  | ||||||
|       initial $readmemh({`CHECKPOINT_DIR,"checkpoint-",`"SIGNAL`"}, init``SIGNAL); \ |  | ||||||
|       for (i=SMALL_INDEX; i<LARGE_INDEX+1; i=i+1) begin \ |  | ||||||
|         initial begin \ |  | ||||||
|           force `SIGNAL_BASE[i].`SIGNAL = init``SIGNAL[i]; \ |  | ||||||
|           #23; \ |  | ||||||
|           release `SIGNAL_BASE[i].`SIGNAL; \ |  | ||||||
|         end \ |  | ||||||
|       end |  | ||||||
| 
 |  | ||||||
|     `define INIT_CHECKPOINT_SIMPLE_ARRAY(SIGNAL,DIM,FIRST_INDEX,LAST_INDEX) \ |  | ||||||
|       logic DIM init``SIGNAL [FIRST_INDEX:LAST_INDEX]; \ |  | ||||||
|       initial begin \ |  | ||||||
|         $readmemh({`CHECKPOINT_DIR,"checkpoint-",`"SIGNAL`"}, init``SIGNAL); \ |  | ||||||
|         force `SIGNAL = init``SIGNAL; \ |  | ||||||
|         #23; \ |  | ||||||
|         release `SIGNAL; \ |  | ||||||
|       end |  | ||||||
| 
 |  | ||||||
|     `define INIT_CHECKPOINT_VAL_SINGLE(SIGNAL,DIM) \ |  | ||||||
|       logic DIM init``SIGNAL[0:0]; \ |  | ||||||
|       initial begin \ |  | ||||||
|         $readmemh({`CHECKPOINT_DIR,"checkpoint-",`"SIGNAL`"}, init``SIGNAL); \ |  | ||||||
|         force `SIGNAL = init``SIGNAL[0]; \ |  | ||||||
|         #23; \ |  | ||||||
|         release `SIGNAL; \ |  | ||||||
|       end |  | ||||||
| 
 |  | ||||||
|     `define MAKE_INIT_SIGNAL(SIGNAL,DIM) \ |  | ||||||
|       logic DIM init``SIGNAL[0:0]; \ |  | ||||||
|       initial begin \ |  | ||||||
|         $readmemh({`CHECKPOINT_DIR,"checkpoint-",`"SIGNAL`"}, init``SIGNAL); \ |  | ||||||
|       end |  | ||||||
| 
 |  | ||||||
|     generate |  | ||||||
|     genvar i; |  | ||||||
|     `INIT_CHECKPOINT_SIMPLE_ARRAY(RF,         [`XLEN-1:0],31,1); |  | ||||||
|     `INIT_CHECKPOINT_SIMPLE_ARRAY(HPMCOUNTER, [`XLEN-1:0],`COUNTERS-1,3); |  | ||||||
|     `INIT_CHECKPOINT_VAL(PMP_BASE, PMPCFG,  [7:0],`PMP_ENTRIES-1,0); |  | ||||||
|     `INIT_CHECKPOINT_VAL(PMP_BASE, PMPADDR, [`XLEN-1:0],`PMP_ENTRIES-1,0); |  | ||||||
|     endgenerate |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(PC,         [`XLEN-1:0]); |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(MEDELEG,    [`XLEN-1:0]); |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(MIE,        [11:0]); |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(MIP,        [11:0]); |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(MCAUSE,     [`XLEN-1:0]); |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(SCAUSE,     [`XLEN-1:0]); |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(MEPC,       [`XLEN-1:0]); |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(SEPC,       [`XLEN-1:0]); |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(MCOUNTEREN, [31:0]); |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(SCOUNTEREN, [31:0]); |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(MSCRATCH,   [`XLEN-1:0]); |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(SSCRATCH,   [`XLEN-1:0]); |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(MTVEC,      [`XLEN-1:0]); |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(STVEC,      [`XLEN-1:0]); |  | ||||||
|     `INIT_CHECKPOINT_VAL_SINGLE(SATP,       [`XLEN-1:0]); |  | ||||||
|     `MAKE_INIT_SIGNAL(MSTATUS,      [`XLEN-1:0]); |  | ||||||
|     initial begin |  | ||||||
|       force {`STATUS_TSR,`STATUS_TW,`STATUS_TVM,`STATUS_MXR,`STATUS_SUM,`STATUS_MPRV} = initMSTATUS[0][22:17]; |  | ||||||
|       force {`STATUS_FS,`STATUS_MPP} = initMSTATUS[0][14:11]; |  | ||||||
|       force {`STATUS_SPP,`STATUS_MPIE} = initMSTATUS[0][8:7]; |  | ||||||
|       force {`STATUS_SPIE,`STATUS_UPIE,`STATUS_MIE} = initMSTATUS[0][5:3]; |  | ||||||
|       force {`STATUS_SIE,`STATUS_UIE} = initMSTATUS[0][1:0]; |  | ||||||
|       #23; |  | ||||||
|       release {`STATUS_TSR,`STATUS_TW,`STATUS_TVM,`STATUS_MXR,`STATUS_SUM,`STATUS_MPRV}; |  | ||||||
|       release {`STATUS_FS,`STATUS_MPP}; |  | ||||||
|       release {`STATUS_SPP,`STATUS_MPIE}; |  | ||||||
|       release {`STATUS_SPIE,`STATUS_UPIE,`STATUS_MIE}; |  | ||||||
|       release {`STATUS_SIE,`STATUS_UIE}; |  | ||||||
|     end |  | ||||||
|     logic [1:0] initPriv; |  | ||||||
|     assign initPriv = (initPC[0][`XLEN-1]) ? 2'h2 : 2'h3; // *** a hacky way to detect privilege level
 |  | ||||||
|     initial begin |  | ||||||
|       force `CURR_PRIV = initPriv; |  | ||||||
|       #23; |  | ||||||
|       release `CURR_PRIV; |  | ||||||
|     end |  | ||||||
|     initial begin |  | ||||||
|       force `INSTRET = `CHECKPOINT; |  | ||||||
|       #23; |  | ||||||
|       release `INSTRET; |  | ||||||
|     end |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|   `endif |  | ||||||
|    |    | ||||||
| 
 | 
 | ||||||
|   ///////////////////////////////////////////////////////////////////////////////
 |   ///////////////////////////////////////////////////////////////////////////////
 | ||||||
| @ -641,4 +633,3 @@ module testbench(); | |||||||
|     end |     end | ||||||
|   endfunction |   endfunction | ||||||
| endmodule | endmodule | ||||||
| 
 |  | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user