[otbn] Make registers much more explicit in the ISS

This patch defines a new class for registers (called Reg, in reg.py).
It's a bit simpler than the riscvmodel version, but the big difference
is that it has no magic coercions. If you want to get the value as an
unsigned integer, you call Reg.read_unsigned. If you want set the
value as a signed integer, you call Reg.write_signed. It's all very
explicit, which should hopefully catch corner cases in the spec.

reg.py also defines a RegFile class, to hold the registers. This is
used as-is for the wide registers, but is subclassed for GPRs in
gpr.py. This allows us to give x0 and x1 special behaviour (a zeros
register and a call stack, respectively).

Most of the rest of this patch is porting the instruction definitions
in insn.py to use the new register interface. Because there are no
magic coercions, the definitions get rather longer, but they are
hopefully easier to understand.

One notable change from the previous Register class is that you get an
assertion error if you try to assign an integer that's out of range.
So state.gprs.get_reg(1).write_unsigned(1 << 32) will trigger an
error. This means that code that does arithmetic on operands generally
gains an explicit mask "foo & ((1 << 32) - 1)". This was an
intentional design decision, because it means the code in
insn.py (which defines what the instruction does) fully specifies the
semantics, rather than relying on magic inside the Register class.

Similarly, the register files no longer override __getitem__ and
__setitem__. I think the result is less magical and the syntax more
accurately shows what's actually happening in the Python simulation.
The plan is that when we do automatic extraction from the ISS to the
spec examples, we'll do some sort of transformation, turning e.g.

    val1 = state.gprs.get_reg(self.grs1).read_unsigned()
    ...
    state.gprs.get_reg(self.grd).write_unsigned(result)

to something more like

    val = unsigned(state.gprs[self.grs1])
    ...
    state.gprs[self.grd] = from_unsigned(result)

So the "trace the assignments" approach to reading the documentation
works again.

When porting the instruction definitions, I made one intentional
change to behaviour (to match the intended semantics): If a big number
ALU instruction specifies a right shift of shift_bytes, it's now a
logical right shift, rather than an arithmetic one.

I also got rid of most updates to variable values in the instruction
definitions, so they are now in a sort of "pseudo-SSA style". This
tends to be more convenient when you're looking at pseudo-code
documentation, especially when debugging or trying to write formal
definitions, because you can say "foo" rather than "the value of foo
at line 12".

Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
8 files changed
tree: 28f9499fe46dce34955da93d26c1dda15ed51e62
  1. .github/
  2. ci/
  3. doc/
  4. hw/
  5. site/
  6. sw/
  7. test/
  8. util/
  9. .clang-format
  10. .dockerignore
  11. .flake8
  12. .gitignore
  13. .style.yapf
  14. _index.md
  15. apt-requirements.txt
  16. azure-pipelines.yml
  17. check_tool_requirements.core
  18. CLA
  19. COMMITTERS
  20. CONTRIBUTING.md
  21. LICENSE
  22. meson.build
  23. meson_init.sh
  24. meson_options.txt
  25. python-requirements.txt
  26. README.md
  27. tool_requirements.py
  28. toolchain.txt
README.md

OpenTitan

OpenTitan logo

About the project

OpenTitan is an open source silicon Root of Trust (RoT) project. OpenTitan will make the silicon RoT design and implementation more transparent, trustworthy, and secure for enterprises, platform providers, and chip manufacturers. OpenTitan is administered by lowRISC CIC as a collaborative project to produce high quality, open IP for instantiation as a full-featured product. See the OpenTitan site and OpenTitan docs for more information about the project.

About this repository

This repository contains hardware, software and utilities written as part of the OpenTitan project. It is structured as monolithic repository, or “monorepo”, where all components live in one repository. It exists to enable collaboration across partners participating in the OpenTitan project.

Documentation

The project contains comprehensive documentation of all IPs and tools. You can access it online at docs.opentitan.org.

How to contribute

Have a look at CONTRIBUTING for guidelines on how to contribute code to this repository.

Licensing

Unless otherwise noted, everything in this repository is covered by the Apache License, Version 2.0 (see LICENSE for full text).