Icicle
Introduction
Icicle is a 32-bit RISC-V soft processor and system-on-chip, primarily designed for iCE40 (including the UltraPlus series) FPGAs. It can be built with open-source tools.
The original version of Icicle was written in SystemVerilog. The current version is written in Amaranth, making the code cleaner and more flexible. Changes to the microarchitecture have made the core significantly smaller and faster.
The Pipeline
and Stage
classes are inspired by Minerva’s pipeline
system, though there are some significant differences.
Features
- RV32I instruction set
- Separate Wishbone instruction and data memory buses
Microarchitecture
Icicle uses a 6-stage pipeline, similar to a classic RISC pipeline. The main differences are summarized below:
- The addition of a PC generation stage, instead of generating the PC during the fetch stage. PC generation in the fetch stage was often on the critical path in the previous version of Icicle.
- The ALU result multiplexer has been moved to the memory stage. The execute stage was often on the critical path in previous versions of Icicle. The multiplexing can proceed in parallel with memory access, as the load-store unit can be hard-wired to the adder’s output - it never uses the output from the logic unit or barrel shifter. Despite more registers being required to retain the adder, logic and shifter outputs between stages, the size of the core is not significantly increased, as the registers can be packed in the same logic cell as the prior LUT.
- Similar to above, the register write data multiplexer has been moved to the writeback stage. The memory stage was often on the critical patch in previous versions of Icicle, and there is plenty of slack in the writeback stage: it has very little logic and the register file inputs are only required at the end of the clock cycle.
The pipeline is fully interlocked. Adding bypassing support would be complicated by the multiplexer changes described above. Furthermore, enabling bypassing in the previous version of Icicle increased the size of the core and reduced the clock frequency by a relatively significant amount on iCE40 FPGAs, which are the primary target.
Icicle is theoretically capable of issuing and retiring one instruction per cycle, if the memory bus can keep up. In reality, the IPC will be slightly lower than this due to stalls and flushes caused by data hazards and branch mispredictions.
The system-on-chip examples distributed with Icicle are currently only capable of issuing one instruction every two cycles, as:
- FPGA block RAMs are synchronous.
- Additional multiplexing logic needs to be added after the read port.
- Only a single memory bus transaction may be in flight at once.
This could be improved with:
- Negative-edge block RAMs, which Amaranth does not yet support.
- Using a pipelined memory bus that makes requests during one cycle and does not expect the response until the following cycle.
- Adding instruction and data caches and burst support.
Formal verification
Icicle supports the RISC-V Formal Interface (RVFI), allowing it to be formally verified with riscv-formal.
Size and performance
FPGA family | Logic cells | Frequency |
---|---|---|
iCE40 HX | ~1,000 | ~75 MHz |
iCE40 UP | ~1,000 | ~30 MHz |
ECP5 8_5G | ~900 | ~140 MHz |
The numbers in the table above refer to the processor core in its default configuration only. The rest of the system-on-chip is not included.
Source code
Icicle is open-source software available under the terms of the ISC license, which is similar to the 2-clause BSD license. The source code is hosted on GitHub.