Skip to content

Conversation

@SamuelRiedel
Copy link
Contributor

This PR adds support for the Zcb and Zcmp code-saving extensions. This support is implemented in a parameterizable way via the RV32ZC parameter, which allows choosing none, either, or both extensions. By default, both extensions are enabled because their combined hardware overhead is small, approximately 800 gate equivalents.

The Zcb extension introduces new compressed encodings for common instructions already supported in Ibex. The Zcmp extension introduces single compressed instructions that expand into multiple existing instructions within Ibex. For example, a stack push expands into multiple store instructions and a stack pointer update. Therefore, both extensions are implemented in the IF stage.

Adding these new instructions requires updates to the following components:

  • Ibex RTL: Implemented in this PR
  • Documentation: Updated in this PR
  • Verification: Implemented in this PR as well. Some missing parts still (see at the bottom)
    • riscv-isa-sim (Spike): Updated Spike to support those new extensions Add the Zc* extensions riscv-isa-sim#27
    • riscv-dv: Add both extensions to riscv-dv. We can either try to upstream those or create a fork. I didn't open a PR yet, but the diff is here: chipsalliance/riscv-dv@master...SamuelRiedel:riscv-dv:zcbzcmp
      • Support for Zcb extension
      • Support for the Zcmp's CMMV instructions
      • Support for Zcmp's CMPP instructions
    • Ibex co-simulation: Updated in this PR. Requires changes to get Zcmp's CMPP to work fully.
      • Support for Zcb extension
      • Support for the Zcmp's CMMV instructions
      • Support for Zcmp's CMPP instructions
  • Compiler Support: We need to update the compiler to a version that supports the Zcb and Zcmp instructions. Currently, we are still on an rather old version. The latest RISC-V GCC and Clang support those instructions already.

Missing Components and Known Issues:

  • The verification for the Zcmp's CMPP instructions (cm.push, cm.pop(ret(z))) is not fully working yet. The primary issue lies in the cosimulation interface with Spike. Checking multiple memory accesses that occur within a single step causes riscv-isa-sim to throw an error.

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.

Lots of nitty comments on the draft (sorry, but I'd started reading so thought I may as well review it properly...)

I really like this though! Thank you all so much for the improvement.

// More registers have to be stored.
// Remove the current register from `rlist`.
cm_rlist_d -= 5'd1;
// Initialize SP offset to 2.
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm sure this is right, but I haven't yet figured out how it works! Can you extend the comment slightly to explain why we start at offset 2 but will increment by just one later?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. The reason is that this will be the state for the next cycle. In this cycle, we started with an initial sp_offset of 1. So this is an implicit increment by one more here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ahhh. Thanks! And the explanation is really clear.

Really boring note, but I think you need to reflow the comment (because it gets to column 101 on line 554).

@SamuelRiedel
Copy link
Contributor Author

Lots of nitty comments on the draft (sorry, but I'd started reading so thought I may as well review it properly...)

I really like this though! Thank you all so much for the improvement.

Thank you for the feedback. Sorry for the delay in implementing it. I just pushed an updated version that should address all your comments.

This is required to ensure we can trace all expanded instructions but
also already advance the PC on the last expanded instruction
Tracking also the original instruction, not only the micro-op, allows
the DV to track whether and which instruction we are expanding
The tracer usually only sees the instructions that reach the ID stage.
Since the Zcmp instructions are expanded in the IF stage, they will be
traced as their micro-ops. This adds information in the trace from which
expanded instruction those micro-ops come from.
The handshake only considered whether the ID stage would be ready. But
the actual pipeline register will also take the `pc_set_i` signal into
account, which signals a jump. Since the compressed decoder has state
now (through the Zcmp extension), this improper handshake led to some of
the expanded instructions to get lost.

At the same time, we also take this signal into account for the enable
signal of the pipeline stage to avoid unnecessary switching.
Add a function and state to process multiple Ibex instructions that are
modeled as a single instruction in riscv-isa-sim. The current function
checks that the same registers are written overall.
Merge the two cm.mv* states into a single one. This should still be easy
to understand and saves us an extra bit in the encoding.
CmPushDecrSp: begin
// Decrement stack pointer.
instr_o = cm_sp_addi(.rlist(instr_i[7:4]),
.spimm(instr_i[3:2]),
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: The indentation needs tweaking here.

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.

3 participants