Skip to content

Conversation

@etterli
Copy link
Contributor

@etterli etterli commented Feb 2, 2026

This PR defines the new SIMD (vectorized) bignum instructions for OTBN operating on the WDRs. The new instructions operate on 8 32-bit elements per WDR:

  • bn.addv(m): Vectorized addition with optional pseudo-modulo reduction.
  • bn.subv(m): Vectorized subtraction with optional pseudo-modulo reduction
  • bn.mulv(l): Vectorized multiplication with optional 'by lane' mode.
  • bn.mulvm(l): Vectorized Montgomery multiplication (without the conditional subtraction step of Montgomery). With optional 'by lane' mode.
  • bn.trn1 / bn.trn2: Instructions to interleave vector elements. This is especially useful for NTT and INTT to shuffle the vector elements when the stride between elements is smaller than what two WDRs provide. These instructions also operate on 64-bit and 128-bit vector elements.
  • bn.shv: Vectorized logic shift instruction
  • bn.pack / bn.unpk: Instructions to pack / unpack vectors from/to 32-bit elements to/from 24-bit element vectors. This allows to save on DMEM space.

The instructions are described in more detail in hw/ip/otbn/data/bignum-insns.yml (first commit). For bn.pack / bn.unpk and bn.trn see also the programmer's manual. Alternatively one can build the documentation locally and view the generated ISA manual (use util/site/build-docs.sh serve).

When this is merged, various OTBN DV tests will fail because the Random Instruction Generator (RIG) parses the bignum-insn.yml file and will generate programs including the new instructions. This will result in failing tests because illegal instructions are encountered as these are not yet added to the simulator and RTL.

This PR will have minor conflicts with #29025 (only some documentation files). So we should agree on which to merge first (probably #29025 first).

@etterli etterli force-pushed the otbn-pqc-simd-insn branch from f0c84b5 to 81053bf Compare February 2, 2026 20:19
Copy link
Member

@nasahlpa nasahlpa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Pascal, this looks really good to me. Just a couple of nits/questions.

@etterli etterli force-pushed the otbn-pqc-simd-insn branch 4 times, most recently from 5997928 to 1c3cca1 Compare February 4, 2026 08:01
@etterli etterli added the CI:Rerun Rerun failed CI jobs label Feb 4, 2026
@github-actions github-actions bot removed the CI:Rerun Rerun failed CI jobs label Feb 4, 2026
Copy link
Member

@nasahlpa nasahlpa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing the feedback!

Copy link
Contributor

@h-filali h-filali left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @etterli this looks very good. I just have some minor comments and questions.

The vectors are multiplied elementwise and each product is truncated to the element length.
The final vector is stored in `wrd`.

This instruction stalls OTBN for 4 cycles and writes the final result to the ACC WSR.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the final result added to the accumulate WSR or just stored there? Or why are we storing to wrd and ACC?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The instruction operates over 4 cycles and after each cycle there is one vector chunk result which must be stored somewhere. It cannot be written to the WDR before the instruction finishes (otherwise the lane version won't work properly) so we store the partial results in ACC. This way we "construct" the result over multiple cycles and use ACC as buffer. At the end we still must perform a write to the desired WDR.

I agree this sentence should be extended similar to how the mulvm instructions are.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think there should be more remarks on how the partial results are accumulated?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay that makes sense. That was also what I had in mind. I think what tripped me up a bit is the fact that we are using the accumulate register even though we are not accumulating. Maybe we can mention explicitly that ACC is overwritten and we do not accumulate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"writes the final result to the ACC WSR" I think this includes these points?

@etterli etterli force-pushed the otbn-pqc-simd-insn branch from 1c3cca1 to 6505711 Compare February 6, 2026 08:45
@etterli etterli added the CI:Rerun Rerun failed CI jobs label Feb 6, 2026
@github-actions github-actions bot removed the CI:Rerun Rerun failed CI jobs label Feb 6, 2026
@vogelpi
Copy link
Contributor

vogelpi commented Feb 6, 2026

@andreaskurth this PR will break the OTBN regressions as it introduces instruction definitions which at the moment neither the RTL nor the simulator knows. And that's kind of okay as we need to split up the work into multiple PRs.

However, I think we should increase the version number and set back the design and verification stages in otbn.hjson to D1 and V1 to reflect this. In terms of version number increase: OTBN binaries and Ibex code interfacing OTBN should not change as long as the IMEM does not increase to more than 16 KiB. Right now, it's not entirely clear if 16 KiB will be enough. So, I would suggest increasing the version from 1.1.0 to 1.2.0 for now. We can always go to 2.0.0 if breaking changes get introduced. WDYT?

@etterli etterli force-pushed the otbn-pqc-simd-insn branch from 6505711 to 134ff78 Compare February 6, 2026 14:14
Copy link
Contributor

@rswarbrick rswarbrick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me: thanks!

@nasahlpa
Copy link
Member

@andreaskurth this PR will break the OTBN regressions as it introduces instruction definitions which at the moment neither the RTL nor the simulator knows. And that's kind of okay as we need to split up the work into multiple PRs.

However, I think we should increase the version number and set back the design and verification stages in otbn.hjson to D1 and V1 to reflect this. In terms of version number increase: OTBN binaries and Ibex code interfacing OTBN should not change as long as the IMEM does not increase to more than 16 KiB. Right now, it's not entirely clear if 16 KiB will be enough. So, I would suggest increasing the version from 1.1.0 to 1.2.0 for now. We can always go to 2.0.0 if breaking changes get introduced. WDYT?

Do we have an update on this?

I agree that we should move OTBN to D1/V1. I'd suggest doing this in this PR as #29232 follows afterwards.

@etterli
Copy link
Contributor Author

etterli commented Feb 10, 2026

@nasahlpa I discussed this with @vogelpi offline and we decided to increase the version to 1.2.0 and set back the development stages. I added a commit which does this.

Copy link
Contributor

@vogelpi vogelpi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The referenced commit_id is not belonging to a commit on master, but a commit in this PR. Once the PR is merged, the ID will change. This doesn't work.

@etterli
Copy link
Contributor Author

etterli commented Feb 10, 2026

@vogelpi Thanks for clarifying the process of the version increase. I have now removed the version change commit and will create a new PR once this one is merged to master.

@etterli etterli added the CI:Rerun Rerun failed CI jobs label Feb 10, 2026
@github-actions github-actions bot removed the CI:Rerun Rerun failed CI jobs label Feb 10, 2026
@vogelpi vogelpi self-requested a review February 10, 2026 08:48
@vogelpi
Copy link
Contributor

vogelpi commented Feb 10, 2026

@vogelpi Thanks for clarifying the process of the version increase. I have now removed the version change commit and will create a new PR once this one is merged to master.

Okay, sounds good. Thank you!

@etterli etterli added the CI:Rerun Rerun failed CI jobs label Feb 10, 2026
@github-actions github-actions bot removed the CI:Rerun Rerun failed CI jobs label Feb 10, 2026
This introduces vectorized (SIMD) big number instructions operating on
the 256-bit WDRs. These instructions interpret WDRs as vectors of
unsigned elements. The width of the elements is for most instructions 32
bits except for a few instructions which support also larger widths.

Signed-off-by: Pascal Etterli <[email protected]>
…lanations

Adds a simple example how to use the bn.pack and bn.unpack instructions.

Signed-off-by: Pascal Etterli <[email protected]>
This illustrates the functionlaty of the bn.trn1 and bn.trn2
instructions.

Signed-off-by: Pascal Etterli <[email protected]>
@nasahlpa nasahlpa added this pull request to the merge queue Feb 10, 2026
Merged via the queue into lowRISC:master with commit c7f8f68 Feb 10, 2026
75 of 78 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants