mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
improve testbench-linux.sv to correctly load in PLIC IntEnable checkpoint and to handle edge case where interrupt is caused by enabling interrupts in SSTATUS
This commit is contained in:
parent
0d4ec9b3f9
commit
3465d8cd32
@ -98,6 +98,7 @@ with open(outDir+'checkpoint-PLIC_INT_PRIORITY', 'w') as outFile:
|
|||||||
outFile.write(stripZeroes(word[2:])+'\n')
|
outFile.write(stripZeroes(word[2:])+'\n')
|
||||||
with open(outDir+'checkpoint-PLIC_INT_ENABLE', 'w') as outFile:
|
with open(outDir+'checkpoint-PLIC_INT_ENABLE', 'w') as outFile:
|
||||||
for word in plicIntEnableArray:
|
for word in plicIntEnableArray:
|
||||||
|
word = hex(int(word,16)>>1)[2:] # right shift by 1 because source 0 does not exist
|
||||||
outFile.write(stripZeroes(word)+'\n')
|
outFile.write(stripZeroes(word)+'\n')
|
||||||
with open(outDir+'checkpoint-PLIC_THRESHOLD', 'w') as outFile:
|
with open(outDir+'checkpoint-PLIC_THRESHOLD', 'w') as outFile:
|
||||||
for word in plicIntPriorityThresholdArray:
|
for word in plicIntPriorityThresholdArray:
|
||||||
|
@ -182,6 +182,7 @@ module testbench;
|
|||||||
`define UART_LCR `UART.LCR
|
`define UART_LCR `UART.LCR
|
||||||
`define UART_MCR `UART.MCR
|
`define UART_MCR `UART.MCR
|
||||||
`define UART_SCR `UART.SCR
|
`define UART_SCR `UART.SCR
|
||||||
|
`define UART_IP `UART.INTR
|
||||||
`define PLIC dut.uncore.plic.plic
|
`define PLIC dut.uncore.plic.plic
|
||||||
`define PLIC_INT_PRIORITY `PLIC.intPriority
|
`define PLIC_INT_PRIORITY `PLIC.intPriority
|
||||||
`define PLIC_INT_ENABLE `PLIC.intEn
|
`define PLIC_INT_ENABLE `PLIC.intEn
|
||||||
@ -376,7 +377,7 @@ module testbench;
|
|||||||
`INIT_CHECKPOINT_VAL(SATP, [`XLEN-1:0]);
|
`INIT_CHECKPOINT_VAL(SATP, [`XLEN-1:0]);
|
||||||
`INIT_CHECKPOINT_VAL(PRIV, [1:0]);
|
`INIT_CHECKPOINT_VAL(PRIV, [1:0]);
|
||||||
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1);
|
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1);
|
||||||
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1],1,0);
|
`MAKE_CHECKPOINT_INIT_SIGNAL(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:0],1,0);
|
||||||
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_THRESHOLD, [2:0],1,0);
|
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_THRESHOLD, [2:0],1,0);
|
||||||
// UART checkpointing does not cover entire UART state
|
// UART checkpointing does not cover entire UART state
|
||||||
// Many UART registers are difficult to initialize because under the hood
|
// Many UART registers are difficult to initialize because under the hood
|
||||||
@ -399,6 +400,7 @@ module testbench;
|
|||||||
if(!NO_IE_MTIME_CHECKPOINT) begin
|
if(!NO_IE_MTIME_CHECKPOINT) begin
|
||||||
force `MEIP = 0;
|
force `MEIP = 0;
|
||||||
force `SEIP = 0;
|
force `SEIP = 0;
|
||||||
|
force `UART_IP = 0;
|
||||||
force `MTIP = 0;
|
force `MTIP = 0;
|
||||||
end
|
end
|
||||||
$sformat(testvectorDir,"%s/linux-testvectors/",RISCV_DIR);
|
$sformat(testvectorDir,"%s/linux-testvectors/",RISCV_DIR);
|
||||||
@ -446,6 +448,7 @@ module testbench;
|
|||||||
force {`STATUS_SPP,`STATUS_MPIE} = initMSTATUS[0][8:7];
|
force {`STATUS_SPP,`STATUS_MPIE} = initMSTATUS[0][8:7];
|
||||||
force {`STATUS_SPIE,`STATUS_UPIE,`STATUS_MIE} = initMSTATUS[0][5:3];
|
force {`STATUS_SPIE,`STATUS_UPIE,`STATUS_MIE} = initMSTATUS[0][5:3];
|
||||||
force {`STATUS_SIE,`STATUS_UIE} = initMSTATUS[0][1:0];
|
force {`STATUS_SIE,`STATUS_UIE} = initMSTATUS[0][1:0];
|
||||||
|
force `PLIC_INT_ENABLE = {initPLIC_INT_ENABLE[1][`PLIC_NUM_SRC:1],initPLIC_INT_ENABLE[0][`PLIC_NUM_SRC:1]}; // would need to expand into a generate loop to cover an arbitrary number of contexts
|
||||||
force `INSTRET = CHECKPOINT;
|
force `INSTRET = CHECKPOINT;
|
||||||
while (reset!==1) #1;
|
while (reset!==1) #1;
|
||||||
while (reset!==0) #1;
|
while (reset!==0) #1;
|
||||||
@ -455,6 +458,7 @@ module testbench;
|
|||||||
release {`STATUS_SPP,`STATUS_MPIE};
|
release {`STATUS_SPP,`STATUS_MPIE};
|
||||||
release {`STATUS_SPIE,`STATUS_UPIE,`STATUS_MIE};
|
release {`STATUS_SPIE,`STATUS_UPIE,`STATUS_MIE};
|
||||||
release {`STATUS_SIE,`STATUS_UIE};
|
release {`STATUS_SIE,`STATUS_UIE};
|
||||||
|
release `PLIC_INT_ENABLE;
|
||||||
release `INSTRET;
|
release `INSTRET;
|
||||||
end
|
end
|
||||||
// Get the E-stage trace reader ahead of the M-stage trace reader
|
// Get the E-stage trace reader ahead of the M-stage trace reader
|
||||||
@ -701,6 +705,8 @@ module testbench;
|
|||||||
force `MEIP = 0;
|
force `MEIP = 0;
|
||||||
if ((ExpectedCSRArrayValueW[NumCSRPostWIndex] & 1<<09) == 0)
|
if ((ExpectedCSRArrayValueW[NumCSRPostWIndex] & 1<<09) == 0)
|
||||||
force `SEIP = 0;
|
force `SEIP = 0;
|
||||||
|
if ((ExpectedCSRArrayValueW[NumCSRPostWIndex] & ((1<<11) | (1<<09))) == 0)
|
||||||
|
force `UART_IP = 0;
|
||||||
if ((ExpectedCSRArrayValueW[NumCSRPostWIndex] & 1<<07) == 0)
|
if ((ExpectedCSRArrayValueW[NumCSRPostWIndex] & 1<<07) == 0)
|
||||||
force `MTIP = 0;
|
force `MTIP = 0;
|
||||||
end
|
end
|
||||||
@ -724,17 +730,28 @@ module testbench;
|
|||||||
if((interruptInstrCount+1) == AttemptedInstructionCount) begin
|
if((interruptInstrCount+1) == AttemptedInstructionCount) begin
|
||||||
if(!NO_IE_MTIME_CHECKPOINT) begin
|
if(!NO_IE_MTIME_CHECKPOINT) begin
|
||||||
case (interruptCauseVal)
|
case (interruptCauseVal)
|
||||||
11: force `MEIP = 1;
|
11: begin
|
||||||
09: force `SEIP = 1;
|
force `MEIP = 1;
|
||||||
|
force `UART_IP = 1;
|
||||||
|
end
|
||||||
|
09: begin
|
||||||
|
force `SEIP = 1;
|
||||||
|
force `UART_IP = 1;
|
||||||
|
end
|
||||||
07: force `MTIP = 1;
|
07: force `MTIP = 1;
|
||||||
default: $display("Unsupported interrupt in interrupts.txt. cause = %0d",interruptCauseVal);
|
default: $display("Unsupported interrupt in interrupts.txt. cause = %0d",interruptCauseVal);
|
||||||
endcase
|
endcase
|
||||||
$display("Forcing interrupt.");
|
$display("Forcing interrupt.");
|
||||||
end
|
end
|
||||||
`SCAN_NEW_INTERRUPT
|
`SCAN_NEW_INTERRUPT
|
||||||
garbageInt = $fgets(garbageString,traceFileE);
|
#1;
|
||||||
garbageInt = $fgets(garbageString,traceFileM);
|
if ((`CSR_BASE.csrm.WriteMSTATUSM || `CSR_BASE.csrs.WriteSSTATUSM) && |(`CSR_BASE.CSRWriteValM & ~`CSR_BASE.csrm.MSTATUS_REGW & 32'h22)) begin
|
||||||
AttemptedInstructionCount += 1;
|
$display("Enabled global interrupts");
|
||||||
|
end else begin
|
||||||
|
garbageInt = $fgets(garbageString,traceFileE);
|
||||||
|
garbageInt = $fgets(garbageString,traceFileM);
|
||||||
|
AttemptedInstructionCount += 1;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user