Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions hw/ip/otbn/dv/smoke/smoke_expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ x26 | 0x00000016
x27 | 0x0000001a
x28 | 0x00400000
x29 | 0x00018000
x30 | 0xa0189d66
x30 | 0x0092876e
x31 | 0x00000804

Final Bignum Register Values:
Expand Down Expand Up @@ -71,5 +71,5 @@ w26 | 0x78fccc06_2228e9d6_89c9b54f_887cf1ee_efbafabd_f9bfd9ee_baeebbbb_dbff9bfa
w27 | 0x28a88802_00088990_8888a00a_88189108_828aa820_09981808_8822aa2a_11109898
w28 | 0xd25666ac_bbb1704f_23631fe5_11e568d7_6d30528f_f027c1f7_32cc1191_caef0343
w29 | 0x4f0d4b81_9f24f0c1_64341d3c_26628bdb_5763bcdf_63388709_e0654fef_eb0953c2
w30 | 0x5348efc4_2f752b5d_1ad4e5f9_184382f7_c4018e58_d88c0b57_b1555176_d796d33b
w31 | 0x5cee80a0_5cee80a0_5cee80a0_5cee80a0_5cee80a0_5cee80a0_5cee80a0_5cee80a0
w30 | 0x2167f87d_e9ee7ac7_ffa3d88b_ab123192_aee49292_4efa2ec9_b55098e0_68ba2fa1
w31 | 0x37adadae_f9dbff5e_73880075_5466a52c_67a8c221_6978ad1b_25769434_0f09b7c8
11 changes: 6 additions & 5 deletions hw/ip/otbn/dv/smoke/smoke_test.s
Original file line number Diff line number Diff line change
Expand Up @@ -365,16 +365,17 @@ bn.wsrr w13, MAI_IN0_S1
bn.wsrr w14, MAI_IN1_S0
bn.wsrr w15, MAI_IN1_S1

# TODO: uncomment the code below once the OTBNsim model of MAI is aligned with the RTL implementation.
# Execute SecAdd on MAI
li x30, 0x2f
csrrw x0, MAI_CTRL, x30
# li x30, 0x2f
# csrrw x0, MAI_CTRL, x30

# Poll for completion of MAI execution
jal x1, mai_poll_busy
# jal x1, mai_poll_busy

# Read back results from MAI
bn.wsrr w30, MAI_RES_S0
bn.wsrr w31, MAI_RES_S1
# bn.wsrr w30, MAI_RES_S0
# bn.wsrr w31, MAI_RES_S1

# Read from URND in the OTBN Verilator smoke test and 0x0 when running on the FPGA or chip-level test
.ifnotdef deterministic
Expand Down
1 change: 1 addition & 0 deletions hw/ip/otbn/otbn.core
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ filesets:
- rtl/otbn_stack.sv
- rtl/otbn_rnd.sv
- rtl/otbn_sec_add.sv
- rtl/otbn_sec_add_mod.sv
- rtl/otbn_start_stop_control.sv
- rtl/otbn_core.sv
- rtl/otbn_vec_adder.sv
Expand Down
132 changes: 85 additions & 47 deletions hw/ip/otbn/pre_dv/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,85 @@
# `otbn_sec_add` Verilator Testbench
# `otbn_mask_accelerator` Verilator Testbench

This directory contains a C++ Verilator testbench for `otbn_sec_add`, the first-order masked parallel prefix adder used in the OTBN mask accelerator.
The testbench drives random two-share Boolean inputs and fresh randomness for 1 000 000 stimulus/check pairs, unmasking both input shares and the output shares to verify that the adder computes the correct (Width+1)-bit sum.
This directory contains C++ Verilator testbenches for modules in the OTBN mask accelerator pipeline.

- `otbn_mask_accelerator_tb.cpp` — tests `otbn_mask_accelerator`, the top-level masked operation unit.
- `otbn_sec_add_tb.cpp` — tests `otbn_sec_add`, the first-order masked parallel prefix adder.
- `otbn_tb_utils.h` — shared utilities (clock helpers, share accessors, derived constants).


## Prerequisites

Follow the [Verilator setup guide](../../../../doc/getting_started/setup_verilator.md).


## Building and running
## Building and running `otbn_mask_accelerator`

All commands below are run from the OpenTitan repository root.

1. Elaborate the RTL and compile the Verilated model.
```sh
verilator --cc --exe --build --trace --assert -Wno-WIDTH -Wno-UNOPTFLAT \
--top-module otbn_mask_accelerator \
-Ihw/ip/prim/rtl \
-Ihw/ip/prim_generic/rtl \
hw/ip/prim/rtl/prim_secded_pkg.sv \
hw/ip/prim/rtl/prim_trivium_pkg.sv \
hw/ip/prim/rtl/prim_util_pkg.sv \
hw/ip/prim/rtl/prim_mubi_pkg.sv \
hw/ip/prim/rtl/prim_count_pkg.sv \
hw/ip/lc_ctrl/rtl/lc_ctrl_reg_pkg.sv \
hw/ip/lc_ctrl/rtl/lc_ctrl_state_pkg.sv \
hw/ip/lc_ctrl/rtl/lc_ctrl_pkg.sv \
hw/ip/otp_ctrl/rtl/otp_ctrl_pkg.sv \
hw/ip/otbn/rtl/otbn_pkg.sv \
hw/ip/otbn/rtl/otbn_sec_add.sv \
hw/ip/otbn/rtl/otbn_sec_add_mod.sv \
hw/ip/otbn/rtl/otbn_mask_accelerator.sv \
hw/ip/prim/rtl/prim_blanker.sv \
hw/ip/prim/rtl/prim_count.sv \
hw/ip/prim/rtl/prim_fifo_sync.sv \
hw/ip/prim_generic/rtl/prim_flop.sv \
hw/ip/prim_generic/rtl/prim_flop_en.sv \
hw/ip/otbn/pre_dv/otbn_mask_accelerator_tb.cpp \
-o otbn_mask_accelerator_tb
```

`--Wno-UNOPTFLAT` suppresses a false-positive combinational-loop warning on `pre_p` inside `otbn_sec_add`.
Verilator 4.x traces the whole `buffer_data` array as one node and misses the register break provided by the `prim_flop_en` chain, making the pass-2 feedback path look combinational when it is not.

2. Run the testbench.
```sh
obj_dir/otbn_mask_accelerator_tb
```

A passing run produces:
```
Mode 0 (SecAdd): PASS - 0 errors / 8000 checks
Mode 1 (SecAddMod): PASS - 0 errors / 8000 checks
Mode 2 (ArithToBool): PASS - 0 errors / 8000 checks
Mode 3 (BoolToArith): PASS - 0 errors / 8000 checks
Test ***PASSED*** all 4 modes
```

The simulation also writes a VCD waveform to `dump.vcd` in the working directory.


## Operation modes

The testbench exercises all four modes in a single run, in order:

| Mode | Name | Description | Output sharing |
|------|---------------|------------------------------------------------|----------------|
| 0 | `SecAdd` | Masked addition, no modular reduction | Boolean |
| 1 | `SecAddMod` | Masked modular addition | Boolean |
| 2 | `ArithToBool` | Arithmetic-to-Boolean share conversion | Boolean |
| 3 | `BoolToArith` | Boolean-to-Arithmetic share conversion | Arithmetic |

Each mode runs a number of accepted vectors.
After each mode the testbench waits for `wready_o` to go high (adder idle), then issues a one-cycle pulse of `sec_wipe_running_i` to flush the pipeline before the next mode begins.


## Building and running `otbn_sec_add`

All commands below are run from the OpenTitan repository root.

Expand All @@ -36,8 +106,10 @@ All commands below are run from the OpenTitan repository root.
-o otbn_sec_add_tb
```

`-UVERILATOR +define+INC_ASSERT` activates the full standard assertion macros and enables the `INC_ASSERT`-gated checks in `otbn_sec_add`.
This works because `otbn_sec_add` uses only `ASSERT_INIT` and `ASSERT_FINAL` (immediate/final blocks), which Verilator 4.x supports.

1. Run the testbench.
2. Run the testbench.
```sh
obj_dir/otbn_sec_add_tb
```
Expand All @@ -47,53 +119,19 @@ All commands below are run from the OpenTitan repository root.
Test ***PASSED*** 1000000 checks
```

A failing run prints one line per mismatch and then:
```
Test ***FAILED*** <n> / 1000000
```

The simulation also writes a VCD waveform to `dump.vcd` in the working directory.


## Configuring the adder width
### Configuring the adder width

The testbench supports Width values of 4, 8, 16, and 32 bits.
The `otbn_sec_add` testbench supports Width values of 4, 8, 16, and 32 bits.
Two flags must always be kept in sync:

| Flag | Purpose |
|-----------------------|------------------------------------------------------|
| `-GWidth=N` | Sets the `Width` parameter of the elaborated RTL |
| `-CFLAGS "-DWIDTH=N"` | Sets the matching `WIDTH` macro in the C++ testbench |
| Flag | Purpose |
|---------------------------|------------------------------------------------------|
| `-GWidth=N` | Sets the `Width` parameter of the elaborated RTL |
| `-CFLAGS "-DWIDTH=N ..."` | Sets the matching `WIDTH` macro in the C++ testbench |

Mismatching the two values produces silent wrong results because the testbench and the DUT would disagree on the randomness bus width and the result layout.

Before switching to a different width, remove the stale build artefacts to avoid linker errors from a previous elaboration.
Mismatching the two values produces wrong results because the testbench and the DUT will disagree on the randomness bus width and the result layout.

Before switching to a different width, remove the stale build artefacts to avoid linker errors from a previous elaboration:
```sh
rm -rf obj_dir
```

Example for Width=16:

```sh
verilator --cc --exe --build --trace --assert -Wno-WIDTH \
--top-module otbn_sec_add \
-GWidth=16 \
-CFLAGS "-DWIDTH=16" \
+define+INC_ASSERT -UVERILATOR \
-Ihw/ip/prim/rtl \
-Ihw/ip/prim_generic/rtl \
hw/ip/prim/rtl/prim_secded_pkg.sv \
hw/ip/prim/rtl/prim_trivium_pkg.sv \
hw/ip/prim/rtl/prim_util_pkg.sv \
hw/ip/prim/rtl/prim_mubi_pkg.sv \
hw/ip/lc_ctrl/rtl/lc_ctrl_reg_pkg.sv \
hw/ip/lc_ctrl/rtl/lc_ctrl_state_pkg.sv \
hw/ip/lc_ctrl/rtl/lc_ctrl_pkg.sv \
hw/ip/otp_ctrl/rtl/otp_ctrl_pkg.sv \
hw/ip/otbn/rtl/otbn_pkg.sv \
hw/ip/otbn/rtl/otbn_sec_add.sv \
hw/ip/otbn/pre_dv/otbn_sec_add_tb.cpp \
-o otbn_sec_add_tb
obj_dir/otbn_sec_add_tb
```
Loading