Files
design-verification-onboard…/testplan_initial.md
T
2026-09-27 18:05:49 -04:00

1129 lines
35 KiB
Markdown

# Fall 2026 DV Onboarding Test Plan
<!--
Make two copies of this template:
1. testplan_initial.md, submitted before implementing tests.
2. testplan_final.md, updated after implementation and coverage closure.
Keep the initial copy unchanged after review. HTML comments are editing
instructions and disappear from rendered Markdown.
-->
## NOTE: THIS IS A TEMPLATE FOR YOU TO FOLLOW. THIS IS **NOT** A COMPREHENSIVE TESTPLAN. YOU NEED TO EXTEND IT.
## Document information
| Field | Value |
| --------------------- | ------------------------------ |
| Verification engineer | Dylan Benzi, benziboy, dbenzi3 |
| Plan revision | Initial |
| Date | 2026-09-26 |
### Revision history
| Revision | Date | Changes |
| -------- | ---------- | ----------------------------------------------------------------------- |
| Initial | 2026-09-26 | Initial planned tests |
| Final | YYYY-MM-DD | <!-- Tests or constraints added after debugging and coverage review --> |
## 1. Functional tests
<!--
Plan tests for the CPU functionality supported by this onboarding. Organize
related behavior together. Include both individual instruction behavior and
multi-instruction sequences where ordering or dependencies matter.
Add as many rows and detailed test records as needed. Do not put every CPU
operation into one large program: each failure should identify a reasonably
small area to debug.
-->
### Functional-test summary
#### Implemented ISA to test
- ADD
- ADDI
- SUB
- LW
- SW
- BEQ
- SLL
- SRL
- EBREAK
| Test ID | Test name | Functionality being tested | Expected result | Status |
| ------- | ---------------------- | ---------------------------------------- | --------------------------------- | ------- |
| 1.1 | add overflow | add two regs causing an overflow | overflow discarded | Planned |
| 1.2 | addi overflow | add imm to reg causing an overflow | overflow discarded | Planned |
| 1.3 | addi negative | add negative imm | imm is subtracted | Planned |
| 1.4 | add typical | add two regs | regs added properly | Planned |
| 1.5 | addi typical | add imm to reg | imm added properly | Planned |
| 1.6 | addi negative overflow | add negative numbers causing an overflow | negative overflow wrap around | Planned |
| 1.7 | sub overflow | subtract two regs causing an overflow | negative overflow wrap around | Planned |
| 1.8 | sub typical | subtract two regs | regs subtracted properly | Planned |
| 1.9 | sll oob | shift left by larger than 2^5 bits | left shift constrainted to 2^5 | Planned |
| 1.10 | srl oob | shift right by larger than 2^5 bits | right shift constrainted to 2^5 | Planned |
| 1.11 | sll zero | shift left by zero bits | no shift | Planned |
| 1.12 | srl zero | shift right by zero bits | no shift | Planned |
| 1.13 | sll one | shift left by one bit | logical left shift by one bit | Planned |
| 1.14 | srl one | shift right by one bit | logical right shift by one bit | Planned |
| 1.15 | sll typical | shift left by <2^5 bits | correct logical left shift | Planned |
| 1.16 | srl typical | shift right by <2^5 bits | correct logical right shift | Planned |
| 1.17 | lw zero offset | lw with zero offset | zero offset computed | Planned |
| 1.18 | sw zero offset | sw with zero offset | zero offset computed + stored | Planned |
| 1.19 | lw positive | lw with positive offset | correct offset computed | Planned |
| 1.20 | sw positive | sw with positive offset | correct offset computed + stored | Planned |
| 1.21 | lw negative | lw with negative offset | correct offset computed | Planned |
| 1.22 | sw negative | sw with negative offset | correct offset computed + stored | Planned |
| 1.23 | lw x0 | lw into x0 reg | write discarded, x0 remains 0 | Planned |
| 1.24 | beq x0 | beq with both regs as x0 | take branch | Planned |
| 1.25 | beq not taken | beq with non-equal regs | branch not taken | Planned |
| 1.26 | beq typical | beq with equal regs | branch taken | Planned |
| 1.27 | ebreak immediately | ebreak as first instruction | halt CPU | Planned |
### Functional-test details
### 1.1 — `add overflow`
**Functionality:** add two registers together that would cause an overflow
**Initial state:**
- Registers: x1 = 0xFFFFFFFF, x2 = 0xFFFFFFFF
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_ADDI), .rd(2), .rs1(0), .imm(-1)),
asm_instr(.op(OP_ADD), .rd(2), .rs1(1), .rs2(2)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ------------------------------------------------------------------- |
| `x2` | `32'hFFFFFFFE` | 0xFFFFFFFF + 0xFFFFFFFF = 0x(1)FFFFFFFE, the leading 1 is truncated |
**Pass criteria:** 3 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.2 — `addi overflow`
**Functionality:** add an immediate to a register that would cause an overflow
**Initial state:**
- Registers: x1 = 0xFFFFFFFF
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_ADDI), .rd(1), .rs1(1), .imm(1)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ------------------------------------------------------------ |
| `x1` | `32'h00000000` | 0xFFFFFFFF + 0x1 = 0x(1)00000000, the leading 1 is truncated |
**Pass criteria:** 2 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.3 — `addi negative`
**Functionality:** adds a negative value to a register using addi, effectively subtracting from that register
**Initial state:**
- Registers: x1 = 0x1
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(1)),
asm_instr(.op(OP_ADDI), .rd(1), .rs1(1), .imm(-1)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | -------------------------- |
| `x1` | `32'h0` | 0x1 - 0x1 = 0x0 |
**Pass criteria:** 2 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.4 — `add typical`
**Functionality:** add two registers with values that will not cause an overflow
**Initial state:**
- Registers: x1 = 0x123, x2 = 0x123
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(0x123)),
asm_instr(.op(OP_ADDI), .rd(2), .rs1(0), .imm(0x123)),
asm_instr(.op(OP_ADD), .rd(2), .rs1(1), .rs2(2)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | -------------------------- |
| `x2` | `32'h246` | 0x123 + 0x123 = 0x246 |
**Pass criteria:** 3 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.5 — `addi typical`
**Functionality:** addi with immediate added to register without causing an overflow
**Initial state:**
- Registers: none
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(0x123)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | -------------------------- |
| `x1` | `32'h123` | 0x0 + 0x123 = 0x123 |
**Pass criteria:** 1 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.6 — `addi negative overflow`
**Functionality:** addi with a negative number causes an overflow wrap around to the register
**Initial state:**
- Registers: x1 = 0x0
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ------------------------------------------------- |
| `x1` | `32'hFFFFFFFF` | 0x0 - 0x1 = 0xFFFFFFFF, overflow back to full reg |
**Pass criteria:** 1 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.7 — `sub overflow`
**Functionality:** sub registers that would cause an overflow wrap around
**Initial state:**
- Registers: x1 = 0x1
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(1)),
asm_instr(.op(OP_SUB), .rd(1), .rs1(0), .rs2(1)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | ---------------- | ------------------------------------------- |
| `x1` | `32'hFFFFFFFF` | 0x0 - 0x1 = 0xFFFFFFFF overflow wrap around |
**Pass criteria:** 2 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.8 — `sub typical`
**Functionality:** sub two registers without causing an overflow
**Initial state:**
- Registers: x1 = 0x123, x2 = 0x23
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(0x123)),
asm_instr(.op(OP_ADDI), .rd(2), .rs1(0), .imm(0x23)),
asm_instr(.op(OP_SUB), .rd(2), .rs1(1), .rs2(2)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | -------------------------- |
| `x2` | `32'h100` | 0x123 - 0x23 = 0x100 |
**Pass criteria:** 3 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.9 — `srl oob`
**Functionality:** srl masks to bottom 5 bits of data only, cannot shift more than 31
**Initial state:**
- Registers: x1 = 0xFFFFFFFF, x2 = 0x20
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_ADDI), .rd(2), .rs1(0), .imm(32)),
asm_instr(.op(OP_SRL), .rd(1), .rs1(1), .rs2(2)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | -------------------------- |
| `x1` | `32'hFFFFFFFF` | 0x20 == 2^5 => no shift |
**Pass criteria:** 3 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.10 — `sll oob`
**Functionality:** sll masks to bottom 5 bits of data only, cannot shift more than 31
**Initial state:**
- Registers: x1 = 0xFFFFFFFF, x2 = 0x20
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_ADDI), .rd(2), .rs1(0), .imm(32)),
asm_instr(.op(OP_SLL), .rd(1), .rs1(1), .rs2(2)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | -------------------------- |
| `x1` | `32'hFFFFFFFF` | 0x20 == 2^5 => no shift |
**Pass criteria:** 3 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.11 — `sll zero`
**Functionality:** sll with zero, causing no shift
**Initial state:**
- Registers: x1 = 0xFFFFFFFF
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_SLL), .rd(1), .rs1(1), .rs2(0)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ------------------------------ |
| `x1` | `32'hFFFFFFFF` | 0xFFFFFFFF << 0x0 = 0xFFFFFFFF |
**Pass criteria:** 2 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.12 — `srl zero`
**Functionality:** srl with zero, causing no shift
**Initial state:**
- Registers: x1 = 0xFFFFFFFF
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_SRL), .rd(1), .rs1(1), .rs2(0)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ------------------------------ |
| `x1` | `32'hFFFFFFFF` | 0xFFFFFFFF << 0x0 = 0xFFFFFFFF |
**Pass criteria:** 2 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.13 — `sll one`
**Functionality:** sll with one, causing a shift once to the left
**Initial state:**
- Registers: x1 = 0xFFFFFFFF, x2 = 0x1
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_ADDI), .rd(2), .rs1(0), .imm(1)),
asm_instr(.op(OP_SLL), .rd(1), .rs1(1), .rs2(2)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ------------------------------ |
| `x1` | `32'hFFFFFFFE` | 0xFFFFFFFF << 0x1 = 0xFFFFFFFE |
**Pass criteria:** 3 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.14 — `srl one`
**Functionality:** srl with one, causing a shift once to the right
**Initial state:**
- Registers: x1 = 0xFFFFFFFF, x2 = 1
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_ADDI), .rd(2), .rs1(0), .imm(1)),
asm_instr(.op(OP_SRL), .rd(1), .rs1(1), .rs2(2)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ----------------------------- |
| `x1` | `32'h7FFFFFFF` | 0xFFFFFFFF >> 0x1 = 0x7FFFFFFF |
**Pass criteria:** 3 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.15 — `sll typical`
**Functionality:** sll with a shift greater than 1 and less than 2^5
**Initial state:**
- Registers: x1 = 0xFFFFFFFF, x2 = 0x4
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_ADDI), .rd(2), .rs1(0), .imm(4)),
asm_instr(.op(OP_SLL), .rd(1), .rs1(1), .rs2(2)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ------------------------------ |
| `x1` | `32'hFFFFFFF0` | 0xFFFFFFFF << 0x4 = 0xFFFFFFF0 |
**Pass criteria:** 3 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.16 — `srl typical`
**Functionality:** srl with a shift greater than 1 and less than 2^5
**Initial state:**
- Registers: x1 = 0xFFFFFFFF, x2 = 0x4
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_ADDI), .rd(2), .rs1(0), .imm(4)),
asm_instr(.op(OP_SRL), .rd(1), .rs1(1), .rs2(2)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ------------------------------ |
| `x1` | `32'h0FFFFFFF` | 0xFFFFFFFF >> 0x4 = 0x0FFFFFFF |
**Pass criteria:** 3 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.17 — `lw zero offset`
**Functionality:** lw with zero offset, loading in the register rs1
**Initial state:**
- Registers: none
- Data memory: dmem[0] = 0xFFFFFFFF
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_LW), .rd(1), .rs1(0), .imm(0)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | -------------------------- |
| `x1` | `32'hFFFFFFFF` | x1 = M[0] => 0xFFFFFFFF |
**Pass criteria:** 2 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.18 — `sw zero offset`
**Functionality:** sw with zero offset, storing in memory addr of rs1
**Initial state:**
- Registers: x1 = 0xFFFFFFFF
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_SW), .rs1(0), .rs2(1), .imm(0)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | -------------------------- |
| `dmem[0]` | `32'hFFFFFFFF` | M[0] = x1 => 0xFFFFFFFF |
**Pass criteria:** 2 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.19 — `lw positive`
**Functionality:** lw with a positive offset
**Initial state:**
- Registers: none
- Data memory: dmem[1] = 0xFFFFFFFF
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_LW), .rd(1), .rs1(0), .imm(4)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | -------------------------- |
| `x1` | `32'hFFFFFFFF` | x1 = dmem[1] => 0xFFFFFFFF |
**Pass criteria:** 2 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.20 — `sw positive`
**Functionality:** sw with a positive offset
**Initial state:**
- Registers: x1 = 0xFFFFFFFF
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_SW), .rs1(0), .rs2(1), .imm(4)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | -------------------------- |
| `dmem[1]` | `32'hFFFFFFFF` | dmem[1] = x1 => 0xFFFFFFFF |
**Pass criteria:** 2 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.21 — `lw negative`
**Functionality:** lw with a negative offset
**Initial state:**
- Registers: none
- Data memory: dmem[1023] = 0xFFFFFFFF
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_LW), .rd(1), .rs1(0), .imm(-1)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ----------------------------- |
| `x1` | `32'hFFFFFFFF` | x1 = dmem[1023] => 0xFFFFFFFF |
**Pass criteria:** 2 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.22 — `sw negative`
**Functionality:** sw with a negative offset
**Initial state:**
- Registers: x1 = 0xFFFFFFFF
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_SW), .rs1(0), .rs2(1), .imm(-1)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ----------------------------- |
| `dmem[1023]` | `32'hFFFFFFFF` | dmem[1023] = x1 => 0xFFFFFFFF |
**Pass criteria:** 2 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.23 — `lw x0`
**Functionality:** attempt to lw into x0 register
**Initial state:**
- Registers: none
- Data memory: dmem[0] = 0xFFFFFFFF
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_LW), .rd(0), .rs1(0), .imm(0)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | -------------------------- |
| `x0` | `32'h0` | x0 is to always remain 0 |
**Pass criteria:** 2 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.24 — `beq x0`
**Functionality:** beq with both sources as x0
**Initial state:**
- Registers: none
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_BEQ), .rs1(0), .rs2(0), .imm(8)),
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(1)),
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(2)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ------------------------------------------- |
| `x1` | `32'h2` | skip ADDI x1, x0, 1, and run ADDI x1, x0, 2 |
**Pass criteria:** 2 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.25 — `beq not taken`
**Functionality:** beq on two non-equal registers
**Initial state:**
- Registers: x1 = 0xFFFFFFFF
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_BEQ), .rs1(0), .rs2(1), .imm(8)),
asm_instr(.op(OP_ADDI), .rd(2), .rs1(0), .imm(-1)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ---------------------------------------------- |
| `x2` | `32'hFFFFFFFF` | do not skip to EBREAK, and run ADDI x2, x0, -1 |
**Pass criteria:** 3 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.26 — `beq typical`
**Functionality:** beq on two equal registers that are not x0
**Initial state:**
- Registers: x1 = 0xFFFFFFFF, x2 = 0xFFFFFFFF
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1)),
asm_instr(.op(OP_ADDI), .rd(2), .rs1(0), .imm(-1)),
asm_instr(.op(OP_BEQ), .rs1(1), .rs2(2), .imm(8)),
asm_instr(.op(OP_ADDI), .rd(3), .rs1(0), .imm(1)),
asm_instr(.op(OP_ADDI), .rd(3), .rs1(0), .imm(2)),
EBREAK_WORD
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ------------------------------------------- |
| `x3` | `32'h2` | skip ADDI x3, x0, 1, and run ADDI x3, x0, 2 |
**Pass criteria:** 4 cycle operation
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
### 1.27 — `ebreak immediately`
**Functionality:** ebreak as first instruction, subsequent instructions not run
**Initial state:**
- Registers: none
- Data memory: none
- Other setup: none
**Program:**
<!-- Use the same representation that will be placed in run_member_directed_tests(). -->
```systemverilog
prog = '{
EBREAK_WORD,
asm_instr(.op(OP_ADDI), .rd(1), .rs1(0), .imm(-1))
};
```
**Expected result:**
| Register or memory word | Expected value | Calculation or explanation |
| ----------------------- | -------------- | ------------------------------ |
| `x1` | `32'h0` | ebreak before ADDI instruction |
**Pass criteria:** ebreak takes one cycle, other instructions not run
**Final result:** <!-- Complete in testplan_final.md: pass/fail and useful log or waveform reference. -->
## 2. Constrained-random tests
### Instruction constraints
<!--
Explain the provided constraints, then record how the partial and open
constraints are completed. State what each constraint permits, excludes, or
biases and why the resulting programs remain useful and terminating.
-->
| Constraint | Provided, partial, or open | Behavior and purpose | Final implementation summary |
| --------------------- | -------------------------- | ----------------------------------------------- | ----------------------------------------------- |
| `c_opcode` | Provided | use only opcodes implemented | No member change |
| `c_reg_bias` | Provided | encourage more reg-reg collisions, test x0 r/w | No member change |
| `c_imm_range` | Partial | use only immediates that fit into instruction | separate imm_range for I/S and B types |
| `c_mem_align` | Open | force word immediates to be multiples of 4 | mask/discard 2 LSBs for lw/sw |
| `c_imm_unused` | Provided | set imm to zero if not used in instr | No member change |
| `c_branch_target` | Partial | keep the target within the program mem | % 4, ≥ 4, <prog len |
| `c_no_branch_at_end` | Provided | prevent branching at the end of the program | No member change |
| `c_branch_taken_bias` | Open | bias rs1/rs2 to being equal values to eachother | weight rs1/rs2 values to encourage equal values |
### External-port constraints
| Constraint | Provided, partial, or open | Behavior and purpose | Final implementation summary |
| ----------------- | -------------------------- | ----------------------------------------- | --------------------------------- |
| `c_align` | Provided | word align instr | No member change |
| `c_valid_window` | Partial | ensure addr is inside register file | restrict to 32 entries |
| `c_reg_read_only` | Provided | do not write to reg via port | No member change |
| `c_data_corners` | Open | bias towards specific data values to test | all 1s, all 0s, checkerboard, etc |
### Random-program test
| Item | Plan |
| ----------------------------------- | ----------------------------------------------------------- |
| Number of programs per seed | 50 |
| Program-length range | 2 ≤ len ≤ 50 |
| Information logged for reproduction | Numeric `SVSEED`, iteration, and complete generated program |
**Implementation outline:**
```systemverilog
int min_len = 2;
int max_len = 50;
int random_progs = 50;
int max_cycles = 2000;
int dmem_words = 16;
for (int i = 0; i < random_progs; i++) begin
int len = $urandom_range(min_len, max_len);
string name = $sformatf("random_gen_%0d_len_%0d", i, len);
sb.set_test(name);
drv.reset_task();
seqr.gen_program(len);
seqr.wait_for_empty();
repeat (2) @(cpu_if.cb);
drv.run_program(max_cycles);
if (drv.last_run_completed) begin
readback(2, REG_COUNT);
readback(1, dmem_words);
end else begin
$display($stime, " TB: Skipping %s readback after CPU timeout\n", name);
drv.reset_task();
end
end
```
## 3. Assertions
<!--
Plan at least two assertions in addition to the supplied example. Write the
timing rule in English first. In the final plan, include the exact SVA and
evidence from a temporary violation proving that the assertion can fire.
-->
### Assertion summary
| Assertion ID/name | Behavior checked | When it is sampled/disabled | Activating test |
| -------------------- | ------------------------- | --------------------------- | ------------------ |
| 3.1 / `X0_REMAINS_0` | x0 = 0 | posedge clk | lw_x0 |
| 3.2 / `HALT_PULSE` | halt pulses high then low | after ebreak | ebreak_immediately |
### 3.1 — `X0_REMAINS_0`
**Timing requirement in words:** on every clock pulse, check that x0 is 0
```systemverilog
X0_REMAINS_0:
assert property (@(posedge clk) disable iff (rst)
dut.register_crossbar[0] == 32'b0)
else assertion_fail("x0 is nonzero");
```
**Evidence that it detects a violation:** <!-- Temporary change, failing log/waveform, and confirmation after reverting it. -->
### 3.2 — `HALT_PULSE`
**Timing requirement in words:** halt pulses after ebreak
```systemverilog
HALT_PULSE:
assert property (@(posedge clk) disable iff (rst)
cpu_if.cpu_halted |=> !cpu_if.cpu_halted)
else assertion_fail("halt did not pulse correctly");
```
**Evidence that it detects a violation:**
## 4. Encrypted CPU Bug Hunt
### Random discovery
| Field | Evidence |
| ------------------------ | ----------------------------- |
| Discovery command | `make bug_hunt SEED=random` |
| Numeric `SVSEED` | |
| Failing iteration | |
| First failure message | |
| Reproduction command | `make bug_hunt SEED=________` |
| Reproduces consistently? | Yes / No |
**Original failing program:**
```systemverilog
prog = '{
// Paste original generated sequence
EBREAK_WORD
};
```
### Expected vs. actual
| Instruction / event | Expected | Actual | Cycle/time |
| ------------------- | -------- | ------ | ---------- |
| | | | |
**First architectural divergence:**
<!-- State the first register, memory, or control-flow result that becomes incorrect. -->
### Minimization
**Minimized reproducer:**
```systemverilog
prog = '{
// Smallest sequence that still fails
EBREAK_WORD
};
```
### Waveform evidence
Include a screenshot showing the offending instruction and the first incorrect architectural result.
### Conclusion
**Trigger:**
<!-- Smallest condition that causes the failure. -->
**Expected behavior:**
<!-- ISA-correct behavior. -->
**Observed behavior:**
<!-- What the encrypted CPU does instead. -->
**Behavioral characterization:**
<!-- One precise sentence. Do not speculate about hidden RTL. -->