0% found this document useful (0 votes)
494 views53 pages

Ibex Documentation: Release 0.1.dev50+g36ce999.d20191026

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
494 views53 pages

Ibex Documentation: Release 0.1.dev50+g36ce999.d20191026

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 53

Ibex Documentation

Release 0.1.dev50+g36ce999.d20191026

lowRISC

Oct 26, 2019


CONTENTS:

1 Introduction 1
1.1 Standards Compliance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 ASIC Synthesis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 FPGA Synthesis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.4 Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.5 History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.6 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Getting Started with Ibex 5


2.1 Register File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Clock Gating Cell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

3 Core Integration 7
3.1 Instantiation Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.2 Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.3 Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

4 Pipeline Details 11
4.1 Multi- and Single-Cycle Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

5 Instruction Fetch 13
5.1 Instruction-Side Memory Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
5.2 Misaligned Accesses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
5.3 Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

6 Instruction Decode and Execute 15


6.1 Instruction Decode Block (ID) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
6.2 Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
6.3 Decoder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
6.4 Register File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
6.5 Execute Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
6.6 Arithmetic Logic Unit (ALU) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
6.7 Multiplier/Divider Block (MULT/DIV) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
6.8 Control and Status Register Block (CSR) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
6.9 Load-Store Unit (LSU) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

7 Load-Store Unit 19
7.1 Data-Side Memory Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
7.2 Misaligned Accesses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
7.3 Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

i
8 Register File 23
8.1 Flip-Flop-Based Register File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
8.2 Latch-Based Register File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

9 Control and Status Registers 25


9.1 Machine Status (mstatus) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
9.2 Machine ISA Register (misa) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
9.3 Machine Interrupt Enable Register (mie) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
9.4 Machine Trap-Vector Base Address (mtvec) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
9.5 Machine Exception PC (mepc) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
9.6 Machine Cause (mcause) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
9.7 Machine Trap Value (mtval) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
9.8 Machine Interrupt Pending Register (mip) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
9.9 PMP Configuration Register (pmpcfgx) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
9.10 PMP Address Register (pmpaddrx) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
9.11 Time Registers (time(h)) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
9.12 Hardware Thread ID (mhartid) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

10 Performance Counters 31
10.1 Event Selector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
10.2 Controlling the counters from software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
10.3 Parametrization at synthesis time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

11 Exceptions and Interrupts 33


11.1 Privilege Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
11.2 Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
11.3 Recoverable Non-Maskable Interrupt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
11.4 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
11.5 Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

12 Physical Memory Protection (PMP) 35


12.1 PMP Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
12.2 PMP Granularity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

13 Debug Support 37
13.1 Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
13.2 Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

14 Tracer 39
14.1 Output file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
14.2 Trace output format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

15 RISC-V Formal Interface 41


15.1 Formal Verification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

16 Verification 43
16.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
16.2 Testbench Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
16.3 Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

17 Examples 47
17.1 FPGA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

18 Licensing 49

ii
CHAPTER

ONE

INTRODUCTION

Figure 1.1: Block Diagram

Ibex is a 2-stage in-order 32b RISC-V processor core. Ibex has been designed to be small and efficient. Via two
parameters, the core is configurable to support four ISA configurations. Figure 1.1 shows a block diagram of the core.

1.1 Standards Compliance

Ibex is a standards-compliant 32b RISC-V processor. It follows these specifications:


• RISC-V Instruction Set Manual, Volume I: User-Level ISA, document version 20190608-Base-Ratified (June 8,
2019)
• RISC-V Instruction Set Manual, Volume II: Privileged Architecture, document version 20190608-Base-Ratified
(June 8, 2019). Ibex implements the Machine ISA version 1.11.
• RISC-V External Debug Support, version 0.13.2
Many features in the RISC-V specification are optional, and Ibex can be parametrized to enable or disable some of
them.
Ibex can be parametrized to support either of the following two instruction sets.
• The RV32I Base Integer Instruction Set, version 2.1
• The RV32E Base Integer Instruction Set, version 1.9 (draft from June 8, 2019)
In addition, the following instruction set extensions are available.

Table 1.1: Ibex Instruction Set Extensions


Extension Version Configurability
C: Standard Extension for Compressed Instructions 2.0 always enabled
M: Standard Extension for Integer Multiplication and Division 2.0 optional
Zicsr: Control and Status Register Instructions 2.0 always enabled

Most content of the RISC-V privileged specification is optional. Ibex currently supports the following features accord-
ing to the RISC-V Privileged Specification, version 1.11.
• M-Mode and U-Mode
• All CSRs listed in Control and Status Registers
• Performance counters as described in Performance Counters

1
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

• Vectorized trap handling as described at Exceptions and Interrupts

1.2 ASIC Synthesis

ASIC synthesis is supported for Ibex. The whole design is completely synchronous and uses positive-edge triggered
flip-flops, except for the register file, which can be implemented either with latches or with flip-flops. See Register
File for more details. The core occupies an area of roughly 18.9 kGE when using the latch-based register file and
implementing the RV32IMC ISA, or 11.6 kGE when implementing the RV32EC ISA.

1.3 FPGA Synthesis

FPGA synthesis is supported for Ibex when the flip-flop based register file is used. Since latches are not well supported
on FPGAs, it is crucial to select the flip-flop based register file.

1.4 Contents

• Getting Started with Ibex discusses the requirements and initial steps to start using Ibex.
• Core Integration provides the instantiation template and gives descriptions of the design parameters as well as
the input and output ports.
• Ibex Pipeline described the overal pipeline structure.
• Instruction Decode and Execute describes how the Instruction Decode and Execute stage works.
• The instruction and data interfaces of Ibex are explained in Instruction Fetch and Load-Store Unit, respectively.
• The two register-file flavors are described in Register File.
• The control and status registers are explained in Control and Status Registers.
• Performance Counters gives an overview of the performance monitors and event counters available in Ibex.
• Exceptions and Interrupts deals with the infrastructure for handling exceptions and interrupts,
• Physical Memory Protection (PMP) gives a brief overview of PMP support.
• Debug Support gives a brief overview on the debug infrastructure.
• Tracer gives a brief overview of the tracer module.
• For information regarding formal verification support, check out RISC-V Formal Interface.
• Examples gives an overview of how Ibex can be used.

1.5 History

Ibex development started in 2015 under the name “Zero-riscy” as part of the PULP platform for energy-efficient
computing. Much of the code was developed by simplifying the RV32 CPU core “RI5CY” to demonstrate how small
a RISC-V CPU core could actually be [1]. To make it even smaller, support for the “E” extension was added under
the code name “Micro-riscy”. In the PULP ecosystem, the core is used as the control core for PULP, PULPino and
PULPissimo.
In December 2018 lowRISC took over the development of Zero-riscy and renamed it to Ibex.

2 Chapter 1. Introduction
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

1.6 References

1. Schiavone, Pasquale Davide, et al. “Slow and steady wins the race? A comparison of ultra-low-power RISC-
V cores for Internet-of-Things applications.” 27th International Symposium on Power and Timing Modeling,
Optimization and Simulation (PATMOS 2017)

1.6. References 3
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

4 Chapter 1. Introduction
CHAPTER

TWO

GETTING STARTED WITH IBEX

This page discusses initial steps and requirements to start using Ibex in your design.

2.1 Register File

Ibex comes with two different register file implementations. Depending on the target technology, either the implemen-
tation in ibex_register_file_ff.sv or the one in ibex_register_file_latch.sv should be selected.
For more information about the two register file implementations and their trade-offs, check out Register File.

2.2 Clock Gating Cell

Ibex requires clock gating cells. This cells are usually specific to the selected target technology and thus not provided as
part of the RTL design. It is assumed that the clock gating cell is wrapped in a module called prim_clock_gating
that has the following ports:
• clk_i: Clock Input
• en_i: Clock Enable Input
• test_en_i: Test Enable Input (activates the clock even though en_i is not set)
• clk_o: Gated Clock Output
Inside Ibex, clock gating cells are used both in ibex_core.sv and ibex_register_file_latch.sv. For
more information on the expected behavior of the clock gating cell when using the latch-based register file check out
Register File.

5
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

6 Chapter 2. Getting Started with Ibex


CHAPTER

THREE

CORE INTEGRATION

The main module is named ibex_core and can be found in ibex_core.sv. Below, the instantiation template is
given and the parameters and interfaces are described.

3.1 Instantiation Template

ibex_core #(
.PMPEnable ( 0 ),
.PMPGranularity ( 0 ),
.PMPNumRegions ( 4 ),
.MHPMCounterNum ( 0 ),
.MHPMCounterWidth ( 40 ),
.RV32E ( 0 ),
.RV32M ( 1 ),
.MultiplierImplementation ( "fast" ),
.DmHaltAddr ( 32'h1A110800 ),
.DmExceptionAddr ( 32'h1A110808 )
) u_core (
// Clock and reset
.clk_i (),
.rst_ni (),
.test_en_i (),

// Configuration
.hart_id_i (),
.boot_addr_i (),

// Instruction memory interface


.instr_req_o (),
.instr_gnt_i (),
.instr_rvalid_i (),
.instr_addr_o (),
.instr_rdata_i (),
.instr_err_i (),

// Data memory interface


.data_req_o (),
.data_gnt_i (),
.data_rvalid_i (),
.data_we_o (),
.data_be_o (),
.data_addr_o (),
(continues on next page)

7
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

(continued from previous page)


.data_wdata_o (),
.data_rdata_i (),
.data_err_i (),

// Interrupt inputs
.irq_software_i (),
.irq_timer_i (),
.irq_external_i (),
.irq_fast_i (),
.irq_nm_i (),

// Debug interface
.debug_req_i (),

// Special control signals


.fetch_enable_i (),
.core_sleep_o ()
);

3.2 Parameters

Name Type/Range Default Description


PMPEnable bit 0 Enable PMP support
PMPGranularity int (0..31) 0 Minimum granularity of PMP address matching
PMPNumRegions int (1..16) 4 Number implemented PMP regions (ignored if PM-
PEnable == 0)
MHPMCounterNum int (0..8) 0 Number of performance monitor event counters
MHPMCounterWidth int (64..1) 40 Bit width of performance monitor event counters
RV32E bit 0 RV32E mode enable (16 integer registers only)
RV32M bit 1 M(ultiply) extension enable
string
MultiplierImplementation “fast” Multiplicator type, “slow”, or “fast”
DmHaltAddr int 0x1A110800 Address to jump to when entering debug mode
DmExceptionAddr int 0x1A110808 Address to jump to when an exception occurs while in
debug mode

8 Chapter 3. Core Integration


Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

3.3 Interfaces

Signal(s) Width Dir Description


clk_i 1 in Clock signal
rst_ni 1 in Active-low asynchronous reset
test_en_i 1 in Test input, enables clock
hart_id_i 32 in Hart ID, usually static, can be read from Hardware Thread ID (mhartid)
CSR
32
boot_addr_i in First program counter after reset = boot_addr_i + 0x80, see Exceptions
and Interrupts
instr_* Instruction fetch interface, see Instruction Fetch
data_* Load-store unit interface, see Load-Store Unit
irq_* Interrupt inputs, see Exceptions and Interrupts
debug_* Debug interface, see Debug Support
1
fetch_enable_i in Enable the core, won’t fetch when 0
1
core_sleep_o out Core in WFI with no outstanding data or instruction accesses. Deasserts if
an external event (interrupt or debug req) wakes the core up

Figure 3.1: Ibex Pipeline

3.3. Interfaces 9
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

10 Chapter 3. Core Integration


CHAPTER

FOUR

PIPELINE DETAILS

Ibex has a 2-stage pipeline, the 2 stages are:


Instruction Fetch (IF) Fetches instructions from memory via a prefetch buffer, capable of fetching 1 instruction per
cycle if the instruction side memory system allows. See Instruction Fetch for details.
Instruction Decode and Execute (ID/EX) Decodes fetched instruction and immediately executes it, register read
and write all occurs in this stage. Multi-cycle instructions will stall this stage until they are complete See
Instruction Decode and Execute for details.
All instructions require two cycles minimum to pass down the pipeline. One cycle in the IF stage and one in the ID/EX
stage. Not all instructions can complete in the ID/EX stage in one cycle so will stall there until they complete. This
means the maximum IPC (Instructions per Cycle) Ibex can achieve is 1 when multi-cycle instructions aren’t used. See
Multi- and Single-Cycle Instructions below for the details.

4.1 Multi- and Single-Cycle Instructions

In the table below when an instruction stalls for X cycles X + 1 cycles pass before a new instruction enters the ID/EX
stage. Some instructions stall for a variable time, this is indicated as a range e.g. 1 - N means the instruction stalls a
minimum of 1 cycle with an indeterminate maximum cycles. Read the description for more information.

11
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

In- Stall Description


struc- Cycles
tion
Type
In- 0 Integer Computational Instructions are defined in the RISCV-V RV32I Base Integer Instruction
te- Set.
ger
Com-
pu-
ta-
tional
CSR 0 CSR Access Instruction are defined in ‘Zicsr’ of the RISC-V specification.
Ac-
cess
Load/Store
1-N Both loads and stores stall for at least one cycle to await a response. For loads this response
is the load data (which is written directly to the register file the same cycle it is received). For
stores this is whether an error was seen or not. The longer the data side memory interface takes
to receive a response the longer loads and stores will stall.
Mul- 2/3 2 for MUL, 3 for MULH. See details in Multiplier/Divider Block (MULT/DIV)
ti- (Fast
pli- Multi-
ca- plier)
tion 32
(Slow
Multi-
plier)
Di- 1 or 37 1 stall cycle if divide by 0, otherwise full long division. See details in Multiplier/Divider Block
vi- (MULT/DIV)
sion
Re-
main-
der
Jump 1 - N Minimum one cycle stall to flush the prefetch counter and begin fetching from the new Program
Counter (PC). The new PC request will appear on the instruction-side memory interface the
same cycle the jump instruction enters ID/EX. The longer the instruction-side memory interface
takes to receive data the longer the jump will stall.
Branch 0 Any branch where the condition is not met will not stall.
(Not-
Taken)
Branch 2 - N Any branch where the condition is met will stall for 2 cycles as in the first cycle the branch is in
(Taken) ID/EX the ALU is used to calculate the branch condition. The following cycle the ALU is used
again to calculate the branch target where it proceeds as Jump does above (Flush IF stage and
prefetch buffer, new PC on instruction-side memory interface the same cycle it is calculated).
The longer the instruction-side memory interface takes to receive data the longer the branch will
stall.

12 Chapter 4. Pipeline Details


CHAPTER

FIVE

INSTRUCTION FETCH

rtl/ibex_if_stage.sv.

Figure 5.1: Instruction Fetch (IF) stage

The Instruction Fetch (IF) stage of the core is able to supply one instruction to the Instruction-Decode (ID) stage per
cycle if the instruction cache or the instruction memory is able to serve one instruction per cycle.
Instructions are fetched into a prefetch buffer (rtl/ibex_prefetch_buffer.sv) for optimal performance and
timing closure reasons. This buffer simply fetches instructions linearly until it is full. The instructions themselves are
stored along with the Program Counter (PC) they came from in the fetch FIFO (rtl/ibex_fetch_fifo.sv). The
fetch FIFO has a feedthrough path so when empty a new instruction entering the FIFO is immediately made available
on the FIFO output. A localparam DEPTH gives a configurable depth which is set to 3 by default.
The top-level of the instruction fetch controls the prefetch buffer (in particular flushing it on branches/jumps/exception
and beginning prefetching from the appropriate new PC) and supplies new instructions to the ID/EX stage along with
their PC. Compressed instructions are expanded by the IF stage so the decoder can always deal with uncompressed
instructions (the ID stage still receives the compressed instruction for placing into mtval on an illegal instruction
exception).

5.1 Instruction-Side Memory Interface

The following table describes the signals that are used to fetch instructions. This interface is a simplified version of
the interface used on the data interface as described in Load-Store Unit. The main difference is that the instruction
interface does not allow for write transactions and thus needs less signals.

Signal Direction Description


instr_req_o output Request valid, must stay high until instr_gnt_i is high for
one cycle
instr_addr_o[31:0] output Address, word aligned
instr_gnt_i input The other side accepted the request. instr_req_o may be
deasserted in the next cycle.
instr_rvalid_i input instr_rdata_i holds valid data when instr_rvalid_i
is high. This signal will be high for exactly one cycle per request.
instr_rdata_i[31:0] input Data read from memory
instr_err_i input Memory access error

13
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

5.2 Misaligned Accesses

Externally, the IF interface performs word-aligned instruction fetches only. Misaligned instruction fetches are handled
by performing two separate word-aligned instruction fetches. Internally, the core can deal with both word- and half-
word-aligned instruction addresses to support compressed instructions. The LSB of the instruction address is ignored
internally.

5.3 Protocol

The protocol used to communicate with the instruction cache or the instruction memory is very similar to the protocol
used by the LSU on the data interface of Ibex. See the description of the LSU in LSU Protocol for details about this
protocol.

14 Chapter 5. Instruction Fetch


CHAPTER

SIX

INSTRUCTION DECODE AND EXECUTE

Figure 6.1: Instruction Decode and Execute

The Instruction Decode and Execute stage takes instruction data from the instruction fetch stage (which has been
converted to the uncompressed representation in the compressed instruction case). The instructions are decoded and
executed all within one cycle including the register read and write. The stage is made up of multiple sub-blocks which
are described below.

6.1 Instruction Decode Block (ID)

Source File: rtl/ibex_id_stage.sv


The Instruction Decode (ID) controls the overall decode/execution process. It contains the muxes to choose what is
sent to the ALU inputs and where the write data for the register file comes from. A small state machine is used to
control multi-cycle instructions (see Ibex Pipeline for more details), which stalls the whole stage whilst a multi-cycle
instruction is executing.

6.2 Controller

Source File: rtl/ibex_controller.sv


The Controller contains the state machine that controls the overall execution of the processor. It is responsible for:
• Handling core startup from reset
• Setting the PC for the IF stage on jump/branch
• Dealing with exceptions/interrupts (jump to appropriate PC, set relevant CSR values)
• Controlling sleep/wakeup on WFI
• Debugging control

6.3 Decoder

Source File: rtl/ibex_decoder.sv


The decoder takes uncompressed instruction data and issues appropriate control signals to the other blocks to execute
the instruction.

15
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

6.4 Register File

Source Files: rtl/ibex_register_file_ff.sv rtl/ibex_register_file_latch.sv


See Register File for more details.

6.5 Execute Block

Source File: rtl/ibex_ex_block.sv


The execute block contains the ALU and the multiplier/divider blocks, it does little beyond wiring and instantiating
these blocks.

6.6 Arithmetic Logic Unit (ALU)

Source File: rtl/ibex_alu.sv


The Arithmetic Logic Logic (ALU) is a purely combinational block that implements operations required for the Integer
Computational Instructions and the comparison operations required for the Control Transfer Instructions in the RV32I
RISC-V Specification. Other blocks use the ALU for the following tasks:
• Mult/Div uses it to perform addition as part of the multiplication and division algorithms
• It computes branch targets with a PC + Imm calculation
• It computes memory addresses for loads and stores with a Reg + Imm calculation
• The LSU uses it to increment addresses when performing two accesses to handle an unaligned access

6.7 Multiplier/Divider Block (MULT/DIV)

Source Files: rtl/ibex_multdiv_slow.sv rtl/ibex_multdiv_fast.sv


The Multiplier/Divider (MULT/DIV) is a state machine driven block to perform multiplication and division. The fast
and slow versions differ in multiplier only, both implement the same form of long division algorithm. The ALU block
is used by the long division algorithm in both the fast and slow blocks.
Fast Multiplier
• Completes multiply in 3-4 cycles using a MAC (multiply accumulate) which is capable of a 17-bit x 17-bit
multiplication with a 34-bit accumulator.
• A MUL instruction takes 3 cycles, MULH takes 4.
• This MAC is internal to the mult/div block (no external ALU use).
• Beware it is simply implemented with the * and + operators so results heavily depend upon the synthesis
tool used.
• In some cases it may be desirable to replace this with a specific implementation (such as a hard macro in
an FPGA or an explicit gate level implementation).
Slow Multiplier
• Completes multiply in 33 cycles using a Baugh-Wooley multiplier (for both MUL and MULH).
• The ALU block is used to compute additions.

16 Chapter 6. Instruction Decode and Execute


Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

Divider Both the fast and slow blocks use the same long division algorithm, it takes 37 cycles to compute (though
only requires 2 cycles when there is a divide by 0) and proceeds as follows:
• Cycle 0: Check for divide by 0
• Cycle 1: Compute absolute value of operand A (or return result on divide by 0)
• Cycle 2: Compute absolute value of operand B
• Cycles 4 - 36: Perform long division as described here: https://en.wikipedia.org/wiki/Division_algorithm#
Integer_division_(unsigned)_with_remainder.

6.8 Control and Status Register Block (CSR)

Source File: rtl/ibex_cs_registers.sv


The CSR contains all of the CSRs (control/status registers). Any CSR read/write is handled through this block. Per-
formance counters are held in this block and incremented when appropriate (this includes mcycle and minstret).
Read data from a CSR is available the same cycle it is requested. Further detail on the implemented CSRs can be
found in Control and Status Registers

6.9 Load-Store Unit (LSU)

Source File: rtl/ibex_load_store_unit.sv


The Load-Store Unit (LSU) interfaces with main memory to perform load and store operations. See Load-Store Unit
for more details.

6.8. Control and Status Register Block (CSR) 17


Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

18 Chapter 6. Instruction Decode and Execute


CHAPTER

SEVEN

LOAD-STORE UNIT

rtl/ibex_load_store_unit.sv
The Load-Store Unit (LSU) of the core takes care of accessing the data memory. Loads and stores of words (32 bit),
half words (16 bit) and bytes (8 bit) are supported.
Any load or store will stall the ID/EX stage for at least a cycle to await the response (whether that is awaiting load data
or a response indicating whether an error has been seen for a store).

7.1 Data-Side Memory Interface

Signals that are used by the LSU:

Signal Di- Description


rec-
tion
data_req_o out- Request valid, must stay high until data_gnt_i is high for one cycle
put
out-
data_addr_o[31:0] Address, word aligned
put
data_we_o out- Write Enable, high for writes, low for reads. Sent together with data_req_o
put
out-
data_be_o[3:0] Byte Enable. Is set for the bytes to write/read, sent together with data_req_o
put
out-
data_wdata_o[31:0] Data to be written to memory, sent together with data_req_o
put
data_gnt_i input The other side accepted the request. Outputs may change in the next cycle.
data_rvalid_iinput data_err_i and data_rdata_i hold valid data when data_rvalid_i is high.
This signal will be high for exactly one cycle per request.
data_err_i input Error response from the bus or the memory: request cannot be handled. High in case
of an error.
input
data_rdata_i[31:0] Data read from memory

7.2 Misaligned Accesses

The LSU is able to handle misaligned memory accesses, meaning accesses that are not aligned on natural word
boundaries. However, it does so by performing two separate word-aligned accesses. This means that at least two
cycles are needed for misaligned loads and stores.

19
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

If an error response is received for the first transaction, the second transaction will still be issued. The second trans-
action will then follow the normal bus protocol, but its response/data will be ignored. If a new load/store request is
received while waiting for an abandoned second part to complete, it will not be serviced until the state machine returns
to IDLE.

7.3 Protocol

The protocol that is used by the LSU to communicate with a memory works as follows:
1. The LSU provides a valid address in data_addr_o and sets data_req_o high. In the case of a store,
the LSU also sets data_we_o high and configures data_be_o and data_wdata_o. The memory then
answers with a data_gnt_i set high as soon as it is ready to serve the request. This may happen in the same
cycle as the request was sent or any number of cycles later.
2. After receiving a grant, the address may be changed in the next cycle by the LSU. In addition, the
data_wdata_o, data_we_o and data_be_o signals may be changed as it is assumed that the memory
has already processed and stored that information.
3. The memory answers with a data_rvalid_i set high for exactly one cycle to signal the response from the
bus or the memory using data_err_i and data_rdata_i (during the very same cycle). This may happen
one or more cycles after the grant has been received. If data_err_i is low, the request could successfully be
handled at the destination and in the case of a load, data_rdata_i contains valid data. If data_err_i is
high, an error occurred in the memory system and the core will raise an exception.
4. When multiple granted requests are outstanding, it is assumed that the memory requests will be kept in-order
and one data_rvalid_i will be signalled for each of them, in the order they were issued.
Figure 7.1, Figure 7.2 and Figure 7.3 show example-timing diagrams of the protocol.

clk

data_req_o

data_addr_o Address

data_we_o WE

data_be_o BE

data_wdata_o WData

data_gnt_i

data_rvalid_i

data_err_i Err

data_rdata_i RData

Figure 7.1: Basic Memory Transaction

20 Chapter 7. Load-Store Unit


Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

clk

data_req_o

data_addr_o Addr1 Addr2

data_we_o WE1 WE2

data_be_o BE1 BE2

data_wdata_o WData1 Wdata2

data_gnt_i

data_rvalid_i

data_err_i Err1 Err2

data_rdata_i RData1 RData2

Figure 7.2: Back-to-back Memory Transaction

clk

data_req_o

data_addr_o Address

data_we_o WE

data_be_o BE

data_wdata_o WData

data_gnt_i

data_rvalid_i

data_err_i Err

data_rdata_i RData

Figure 7.3: Slow Response Memory Transaction

7.3. Protocol 21
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

22 Chapter 7. Load-Store Unit


CHAPTER

EIGHT

REGISTER FILE

Source FIles: rtl/ibex_register_file_ff.sv rtl/ibex_register_file_latch.sv


Ibex has either 31 or 15 32-bit registers if the RV32E extension is disabled or enabled, respectively. Register x0 is
statically bound to 0 and can only be read, it does not contain any sequential logic.
The register file has two read ports and one write port, register file data is available the same cycle a read is requested.
There is no write to read forwarding path so if one register is being both read and written the read will return the
current value rather than the value being written.
There are two flavors of register file available, both having their own benefits and trade-offs.

8.1 Flip-Flop-Based Register File

The flip-flop-based register file uses regular, positive-edge-triggered flip-flops to implement the registers.
This makes it the first choice for FPGA synthesis or when simulating the design using Verilator.
To select the flip-flop-based register file, make sure to use the source file ibex_register_file_ff.sv in your
project.

8.2 Latch-Based Register File

The latch-based register file uses level-sensitive latches to implement the registers.
This allows for significant area savings compared to an implementation using regular flip-flops and thus makes the
latch-based register file the first choice for ASIC implementations. Simulation of the latch-based register file is
possible using commercial tools.

Note: The latch-based register file cannot be simulated using Verilator.

The latch-based register file can also be used for FPGA synthesis, but this is not recommended as FPGAs usually do
not well support latches.
To select the latch-based register file, make sure to use the source file ibex_register_file_latch.sv in your
project. In addition, a technology-specific clock gating cell must be provided to keep the clock inactive when the
latches are not written. This cell must be wrapped in a module called prim_clock_gating. For more information
regarding the clock gating cell, checkout Getting Started with Ibex.

Note: The latch-based register file requires the gated clock to be enabled in the cycle after the write enable we_a_i
signal was set high. This can be achieved by latching we_a_i in the clock gating cell during the low phase of clk_i.

23
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

The resulting behavior of the latch-based register file is visualized in Figure 8.1. The input data wdata_a_i is
sampled into a flip-flop-based register wdata_a_q using clk_int. The actual latch-based registers mem[1] and
mem[2] are transparent during high phases of mem_clk[1] and mem_clk[2], respectively. Their content is
sampled from wdata_a_q on falling edges of these clocks.

clk_i

we_a_i

waddr_a_i 1 2

wdata_a_i Data1 Data2

clk_int

wdata_a_q Data1 Data2

mem_clk[1]

mem[1] Data1

mem_clk[2]

mem[2] Data2

Figure 8.1: Latch-based register file operation

24 Chapter 8. Register File


CHAPTER

NINE

CONTROL AND STATUS REGISTERS

Ibex implements all the Control and Status Registers (CSRs) listed in the following table according to the RISC-V
Privileged Specification, version 1.11.

Address Name Access Description


0x300 mstatus WARL Machine Status
0x301 misa WARL Machine ISA and Extensions
0x304 mie WARL Machine Interrupt Enable Register
0x305 mtvec WARL Machine Trap-Vector Base Address
0x320 mcountinhibit RW Machine Counter-Inhibit Register
0x323 mhpmevent3 WARL Machine Performance-Monitoring Event Selec
....
0x33F mhpmevent31 WARL Machine Performance-Monitoring Event Selec
0x340 mscratch RW Machine Scratch Register
0x341 mepc WARL Machine Exception Program Counter
0x342 mcause WLRL Machine Cause Register
0x343 mtval WARL Machine Trap Value Register
0x344 mip R Machine Interrupt Pending Register
0x3A0 pmpcfg0 WARL PMP Configuration Register
....
0x3A3 pmpcfg3 WARL PMP Configuration Register
0x3B0 pmpaddr0 WARL PMP Address Register
....
0x3BF pmpaddr15 WARL PMP Address Register
0x7B0 dcsr RW Debug Control and Status Register
0x7B1 dpc RW Debug PC
0x7B2 dscratch0 RW Debug Scratch Register 0
0x7B3 dscratch1 RW Debug Scratch Register 1
0xB00 mcycle RW Machine Cycle Counter
0xB02 minstret RW Machine Instructions-Retired Counter
0xB03 mhpmcounter3 WARL Machine Performance-Monitoring Counter
....
0xB1F mhpmcounter31 WARL Machine Performance-Monitoring Counter
0xB80 mcycleh RW Upper 32 bits of mcycle
0xB82 minstreth RW Upper 32 bits of minstret
0xB83 mhpmcounter3h WARL Upper 32 bits of mhmpcounter3
....
0xB9F mhpmcounter31h WARL Upper 32 bits of mhmpcounter31
0xF14 mhartid R Hardware Thread ID

25
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

See the Performance Counters documentation for a description of the counter registers.

9.1 Machine Status (mstatus)

CSR Address: 0x300


Reset Value: 0x0000_1800

Bit# R/W Description


21 RW TW: Timeout Wait (WFI executed in User Mode will trap to Machine Mode).
17 RW MPRV: Modify Privilege (Loads and stores use MPP for privilege checking).
12:11 RW MPP: Machine Previous Privilege mode.
7 RW Previous Interrupt Enable (MPIE), i.e., before entering exception handling.
3 RW Interrupt Enable (MIE): If set to 1’b1, interrupts are globally enabled.

When an exception is encountered, mstatus.MPIE will be set to mstatus.MIE, and mstatus.MPP will be set
to the current privilege mode. When the MRET instruction is executed, the value of MPIE will be stored back to
mstatus.MIE, and the privilege mode will be restored from mstatus.MPP.
If you want to enable interrupt handling in your exception handler, set mstatus.MIE to 1’b1 inside your handler
code.
Only Machine Mode and User Mode are supported. Any write to mstatus.MPP of an unsupported value will be
interpreted as Machine Mode.

9.2 Machine ISA Register (misa)

CSR Address: 0x301


misa is a WARL register which describes the ISA supported by the hart. On Ibex, misa is hard-wired, i.e. it will
remain unchanged after any write.

9.3 Machine Interrupt Enable Register (mie)

CSR Address: 0x304


Reset Value: 0x0000_0000
mie is a WARL register which allows to individually enable/disable local interrupts. After reset, all interrupts are
disabled.

Bit# Interrupt
30:16 Machine Fast Interrupt Enables: Set bit x+16 to enable fast interrupt irq_fast_i[x].
11 Machine External Interrupt Enable (MEIE): If set, irq_external_i is enabled.
7 Machine Timer Interrupt Enable (MTIE): If set, irq_timer_i is enabled.
3 Machine Software Interrupt Enable (MSIE): if set, irq_software_i is enabled.

26 Chapter 9. Control and Status Registers


Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

9.4 Machine Trap-Vector Base Address (mtvec)

CSR Address: 0x305


Reset Value: 0x0000_0001
mtvec is a WARL register which contains the machine trap-vector base address.

Bit# Interrupt
31:2 BASE: The trap-vector base address, always aligned to 256 bytes, i.e., mtvec[7:2] is always set to 6’b0.
1:0 MODE: Always set to 2’b01 to indicate vectored interrupt handling (read-only).

9.5 Machine Exception PC (mepc)

CSR Address: 0x341


Reset Value: 0x0000_0000
When an exception is encountered, the current program counter is saved in mepc, and the core jumps to the exception
address. When an MRET instruction is executed, the value from mepc replaces the current program counter.

9.6 Machine Cause (mcause)

CSR Address: 0x342


Reset Value: 0x0000_0000

Bit# R/W Description


31 R Interrupt: This bit is set when the exception was triggered by an interrupt.
4:0 R Exception Code

When an exception is encountered, the corresponding exception code is stored in this register.

9.7 Machine Trap Value (mtval)

CSR Address: 0x343


Reset Value: 0x0000_0000
When an exception is encountered, this register can hold exception-specific information to assist software in handling
the trap.
• In the case of errors in the load-store unit mtval holds the address of the transaction causing the error.
• If this transaction is misaligned, mtval holds the address of the missing transaction part.
• In the case of illegal instruction exceptions, mtval holds the actual faulting instruction.
For all other exceptions, mtval is 0.

9.4. Machine Trap-Vector Base Address (mtvec) 27


Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

9.8 Machine Interrupt Pending Register (mip)

CSR Address: 0x344


Reset Value: 0x0000_0000
mip is a read-only register indicating pending interrupt requests. A particular bit in the register reads as one if the
corresponding interrupt input signal is high and if the interrupt is enabled in the mie CSR.

Bit# Interrupt
30:16 Machine Fast Interrupts Pending: If bit x+16 is set, fast interrupt irq_fast_i[x] is pending.
11 Machine External Interrupt Pending (MEIP): If set, irq_external_i is pending.
7 Machine Timer Interrupt Pending (MTIP): If set, irq_timer_i is pending.
3 Machine Software Interrupt Pending (MSIP): if set, irq_software_i is pending.

9.9 PMP Configuration Register (pmpcfgx)

CSR Address: 0x3A0 - 0x3A3


Reset Value: 0x0000_0000
pmpcfgx are registers to configure PMP regions. Each register configures 4 PMP regions.

31:24 23:16 15:8 7:0


pmp3cfg pmp2cfg pmp1cfg pmp0cfg

The configuration fields for each region are as follows:

Bit# Definition
7 Lock
6:5 Reserved (Read as zero)
4:3 Mode
2 Execute permission
1 Write permission
0 Read permission

Details of these configuration bits can be found in the RISC-V Privileged Specification, version 1.11 (see Physical
Memory Protection CSRs, Section 3.6.1).
Note that the combination of Write permission = 1, Read permission = 0 is reserved, and will be treated by the core as
Read/Write permission = 0.

9.10 PMP Address Register (pmpaddrx)

CSR Address: 0x3B0 - 0x3BF


Reset Value: 0x0000_0000
pmpaddrx are registers to set address matching for PMP regions.

31:0
address[33:2]

28 Chapter 9. Control and Status Registers


Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

9.11 Time Registers (time(h))

CSR Address: 0xC01 / 0xC81


The User Mode time(h) registers are not implemented in Ibex. Any access to these registers will trap. It is recom-
mended that trap handler software provides a means of accessing platform-defined mtime(h) timers where available.

9.12 Hardware Thread ID (mhartid)

CSR Address: 0xF14


Reset Value: Defined

Bit# R/W Description


10:5 R Cluster ID: ID of the cluster
3:0 R Core ID: ID of the core within the cluster

9.11. Time Registers (time(h)) 29


Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

30 Chapter 9. Control and Status Registers


CHAPTER

TEN

PERFORMANCE COUNTERS

Ibex implements performance counters according to the RISC-V Privileged Specification, version 1.11 (see Hardware
Performance Monitor, Section 3.1.11). The performance counters are placed inside the Control and Status Registers
(CSRs) and can be accessed with the CSRRW(I) and CSRRS/C(I) instructions.
Ibex implements the clock cycle counter mcycle(h), the retired instruction counter minstret(h), as well as
the 29 event counters mhpmcounter3(h) - mhpmcounter31(h) and the corresponding event selector CSRs
mhpmevent3 - mhpmevent31, and the mcountinhibit CSR to individually enable/disable the counters.
mcycle(h) and minstret(h) are always available and 64 bit wide. The mhpmcounter performance coun-
ters are optional (unavailable by default) and parametrizable in width.

10.1 Event Selector

The following events can be monitored using the performance counters of Ibex.

Event Event Name Event Description


ID/Bit
0 NumCycles Number of cycles
2 NumInstrRet Number of instructions retired
3 NumCyclesLSU Number of cycles waiting for data memory
4 NumCyclesIF Cycles waiting for instruction fetches, i.e., number of instructions wasted due to
non-ideal caching
5 NumLoads Number of data memory loads. Misaligned accesses are counted as two accesses
6 NumStores Number of data memory stores. Misaligned accesses are counted as two accesses
7 NumJumps Number of unconditional jumps (j, jal, jr, jalr)
8 NumBranches Number of branches (conditional)
9 NumBranches- Number of taken branches (conditional)
Taken
10 NumInstrRetC Number of compressed instructions retired

The event selector CSRs mhpmevent3 - mhpmevent31 define which of these events are counted by the event
counters mhpmcounter3(h) - mhpmcounter31(h). If a specific bit in an event selector CSR is set to 1, this
means that events with this ID are being counted by the counter associated with that selector CSR. If an event selector
CSR is 0, this means that the corresponding counter is not counting any event.

10.2 Controlling the counters from software

By default, all available counters are enabled after reset. They can be individually enabled/disabled by overwriting the
corresponding bit in the mcountinhibit CSR at address 0x320 as described in the RISC-V Privileged Specifica-

31
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

tion, version 1.11 (see Machine Counter-Inhibit CSR, Section 3.1.13). In particular, to enable/disable mcycle(h),
bit 0 must be written. For minstret(h), it is bit 2. For event counter mhpmcounterX(h), it is bit X.
The lower 32 bits of all counters can be accessed through the base register, whereas the upper 32 bits are accessed
through the h-register. Reads to all these registers are non-destructive.

10.3 Parametrization at synthesis time

The mcycle(h) and minstret(h) counters are always available and 64 bit wide.
The event counters mhpmcounter3(h) - mhpmcounter31(h) are parametrizable. Their width can be
parametrized between 1 and 64 bit through the WidthMHPMCounters parameter, which defaults to 40 bit wide
counters.
The number of available event counters mhpmcounterX(h) can be controlled via the NumMHPMCounters pa-
rameter. By default (NumMHPMCounters set to 0), no counters are available to software. Set NumMHPMCounters
to a value between 1 and 8 to make the counters mhpmcounter3(h) - mhpmcounter10(h) available as listed
below. Setting NumMHPMCounters to values larger than 8 does not result in any more performance counters.
Unavailable counters always read 0.
The association of events with the mphmcounter registers is hardwired as listed in the following table.

Event Counter CSR Address Event ID/Bit Event Name


mcycle(h) 0xB00 (0xB80) 0 NumCycles
minstret(h) 0xB02 (0xB82) 2 NumInstrRet
mhpmcounter3(h) 0xB03 (0xB83) 3 NumCyclesLSU
mhpmcounter4(h) 0xB04 (0xB84) 4 NumCyclesIF
mhpmcounter5(h) 0xB05 (0xB85) 5 NumLoads
mhpmcounter6(h) 0xB06 (0xB86) 6 NumStores
mhpmcounter7(h) 0xB07 (0xB87) 7 NumJumps
mhpmcounter8(h) 0xB08 (0xB88) 8 NumBranches
mhpmcounter9(h) 0xB09 (0xB89) 9 NumBranchesTaken
mhpmcounter10(h) 0xB0A (0xB8A) 10 NumInstrRetC

Similarly, the event selector CSRs are hardwired as follows. The remaining event selector CSRs are tied to 0, i.e., no
events are counted by the corresponding counters.

Event Selector CSR Address Reset Value Event ID/Bit


mhpmevent3(h) 0x323 0x0000_0008 3
mhpmevent4(h) 0x324 0x0000_0010 4
mhpmevent5(h) 0x325 0x0000_0020 5
mhpmevent6(h) 0x326 0x0000_0040 6
mhpmevent7(h) 0x327 0x0000_0080 7
mhpmevent8(h) 0x328 0x0000_0100 8
mhpmevent9(h) 0x329 0x0000_0200 9
mhpmevent10(h) 0x32A 0x0000_0400 10

32 Chapter 10. Performance Counters


CHAPTER

ELEVEN

EXCEPTIONS AND INTERRUPTS

Ibex implements trap handling for interrupts and exceptions according to the RISC-V Privileged Specification, version
1.11.
All exceptions cause the core to jump to the base address of the vector table in the mtvec CSR. Interrupts are handled
in vectored mode, i.e., the core jumps to the base address plus four times the interrupt ID.
The base address of the vector table is initialized to the boot address (must be aligned to 256 bytes, i.e., its least
significant byte must be 0x00) when the core is booting. The base address can be changed after bootup by writing to
the mtvec CSR. For more information, see the Control and Status Registers documentation.
The core starts fetching at the address made by concatenating the most significant 3 bytes of the boot address and the
reset value (0x80) as the least significant byte. It is assumed that the boot address is supplied via a register to avoid
long paths to the instruction fetch unit.

11.1 Privilege Modes

Ibex supports operation in Machine Mode (M-Mode) and User Mode (U-Mode). The core resets into M-Mode and
will jump to M-Mode on any interrupt or exception. On execution of an MRET instruction, the core will return to the
Privilege Mode stored in mstatus.MPP.

11.2 Interrupts

Ibex supports the following interrupts.

Interrupt Input Signal ID Description


irq_nm_i 31 Non-maskable interrupt (NMI)
irq_fast_i[14:0] 30:16 15 fast, local interrupts
irq_external_i 11 Connected to platform-level interrupt controller
irq_timer_i 7 Connected to timer module
irq_software_i 3 Connected to memory-mapped (inter-processor) interrupt register

All interrupts except for the non-maskable interrupt (NMI) are controlled via the mstatus, mie and mip CSRs.
After reset, all interrupts are disabled. To enable interrupts, both the global interrupt enable (MIE) bit in the mstatus
CSR and the corresponding individual interrupt enable bit in the mie CSR need to be set. For more information, see
the Control and Status Registers documentation.
If multiple interrupts are pending, the highest priority is given to the interrupt with the highest ID.

33
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

The NMI is enabled independent of the values in the mstatus and mie CSRs, and it is not visible through the mip
CSR. It has interrupt ID 31, i.e., it has the highest priority of all interrupts and the core jumps to the trap-handler base
address (in mtvec) plus 0x7C to handle the NMI.
All interrupt lines are level-sensitive. It is assumed that the interrupt handler signals completion of the handling routine
to the interrupt source, e.g., through a memory-mapped register, which then deasserts the corresponding interrupt line.
In debug mode, all interrupts including the NMI are ignored independent of mstatus.MIE and the content of the
mie CSR.

11.3 Recoverable Non-Maskable Interrupt

To support recovering from an NMI happening during a trap handling routine, Ibex features additional CSRs for back-
ing up mstatus.MPP, mstatus.MPIE, mepc and mcause. These CSRs are not accessible by software running on
the core.
These CSRs are nonstandard. For more information, see the corresponding proposal.

11.4 Exceptions

Ibex can trigger an exception due to the following exception causes:

Exception Code Description


1 Instruction access fault
2 Illegal instruction
3 Breakpoint
5 Load access fault
7 Store access fault
8 Environment call from U-Mode (ECALL)
11 Environment call from M-Mode (ECALL)

The illegal instruction exception, instruction access fault, LSU error exceptions and ECALL instruction exceptions
cannot be disabled and are always active.

11.5 Handling

Ibex does support nested interrupt/exception handling. Exceptions inside interrupt/exception handlers cause another
exception. However, exceptions during the critical part of your exception handlers, i.e. before having saved the
mepc and mstatus, will cause those CSRs to be overwritten. Interrupts during interrupt/exception handlers are thus
disabled by default, but can be explicitly enabled if desired.
When entering an interrupt/exception handler, the core sets mepc to the current program counter and saves
mstatus.MIE to mstatus.MPIE. Upon executing an MRET instruction, the core jumps to the program counter
saved in the mepc CSR and restores mstatus.MPIE to mstatus.MIE.

34 Chapter 11. Exceptions and Interrupts


CHAPTER

TWELVE

PHYSICAL MEMORY PROTECTION (PMP)

The Physical Memory Protection (PMP) unit implements region-based memory access checking in-accordance with
the RISC-V Privileged Specification, version 1.11. The following configuration parameters are available to control
PMP checking:

Parameter Default value Description


PMPEnable 0 PMP support enabled
PMPNumRegions 4 Number of implemented regions (1 - 16)
PMPGranularity 0 Minimum match granularity 2^G+2 bytes (0 - 31)

When PMPEnable is zero, the PMP module is not instantiated and all PMP registers read as zero (regardless of the
value of PMPNumRegions)

12.1 PMP Integration

Addresses from the instruction fetch unit and load-store unit are passed to the PMP module for checking, and the output
of the PMP check is used to gate the external request. To maintain consistency with external errors, the instruction
fetch unit and load-store unit progress with their request as if it was granted externally. The PMP error is registered
and consumed by the core when the data would have been consumed.

12.2 PMP Granularity

The PMP granularity parameter is used to reduce the size of the address matching comparators by increasing the
minimum region size. When the granularity is greater than zero, NA4 mode is not available and will be treated as OFF
mode.

35
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

36 Chapter 12. Physical Memory Protection (PMP)


CHAPTER

THIRTEEN

DEBUG SUPPORT

Ibex offers support for execution-based debug according to the RISC-V Debug Specification, version 0.13.

13.1 Interface

Signal Direction Description


debug_req_i input Request to enter debug mode

debug_req_i is the “debug interrupt”, issued by the debug module when the core should enter debug mode.

13.2 Parameters

Parameter Description
DmHaltAddr Address to jump to when entering debug mode
DmExceptionAddr Address to jump to when an exception occurs while in debug mode

37
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

38 Chapter 13. Debug Support


CHAPTER

FOURTEEN

TRACER

The module ibex_tracer can be used to create a log of the executed instructions. It is used by
ibex_core_tracing which forwards the RVFI signals to the tracer (see also RISC-V Formal Interface).

14.1 Output file

All traced instructions are written to a log file. By default, the log file is named trace_core_<HARTID>.log,
with <HARTID> being the 8 digit hart ID of the core being traced.
The file name base, defaulting to trace_core can be set using the ibex_tracer_file_base plusarg passed
to the simulation. For example, +ibex_tracer_file_base=ibex_my_trace will produce log files named
ibex_my_trace_<HARTID>.log. The exact syntax of passing plusargs to a simulation depends on the simulator.

14.2 Trace output format

The trace output is in tab-separated columns.


1. Time: The current simulation time.
2. Cycle: The number of cycles since the last reset.
3. PC: The program counter
4. Instr: The executed instruction (base 16). 32 bit wide instructions (8 hex digits) are uncompressed instructions,
16 bit wide instructions (4 hex digits) are compressed instructions.
5. Decoded instruction: The decoded (disassembled) instruction in a format equal to what objdump produces
when calling it like objdump -Mnumeric -Mno-aliases -D. - Unsigned numbers are given in hex
(prefixed with 0x), signed numbers are given as decimal numbers. - Numeric register names are used (e.g.
x1). - Symbolic CSR names are used. - Jump/branch targets are given as absolute address if possible (PC +
immediate).
6. Register and memory contents: For all accessed registers, the value before and after the instruction execution
is given. Writes to registers are indicated as registername=value, reads as registername:value.
For memory accesses, the address and the loaded and stored data are given.

Time Cycle PC Instr Decoded instruction Register and memory


˓→contents

130 61 00000150 4481 c.li x9,0 x9=0x00000000


132 62 00000152 00008437 lui x8,0x8 x8=0x00008000
134 63 00000156 fff40413 addi x8,x8,-1 x8:0x00008000
˓→x8=0x00007fff

(continues on next page)

39
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

(continued from previous page)


136 64 0000015a 8c65 c.and x8,x9 x8:0x00007fff
˓→x9:0x00000000 x8=0x00000000
142 67 0000015c c622 c.swsp x8,12(x2) x2:0x00002000
˓→x8:0x00000000 PA:0x0000200c store:0x00000000 load:0xffffffff

40 Chapter 14. Tracer


CHAPTER

FIFTEEN

RISC-V FORMAL INTERFACE

Ibex supports the RISC-V Formal Interface (RVFI). This interface basically decodes the current instruction and pro-
vides additional insight into the core state thereby enabling formal verification. Examples of such information include
opcode, source and destination registers, program counter, as well as address and data for memory operations.

15.1 Formal Verification

The signals provided by RVFI can be used to formally verify compliance of Ibex with the RISC-V specification.
Currently, the implementation is restricted to support the “I” and “C” extensions, and Ibex is not yet formally verified.
It predecessor “Zero-riscy” had been tested, but this required changes to the core as well as to the tool used in the
process (yosys). The formal verification of the Ibex core is work in progress.

41
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

42 Chapter 15. RISC-V Formal Interface


CHAPTER

SIXTEEN

VERIFICATION

16.1 Overview

This is a SV/UVM testbench for verification of the Ibex core. At a high level, this testbench uses the open source
RISCV-DV random instruction generator to generate compiled instruction binaries, loads them into a simple memory
model, stimulates the Ibex core to run this program in memory, and then compares the core trace log against a golden
model ISS trace log to check for correctness of execution.

16.2 Testbench Architecture

As previously mentioned, this testbench has been constructed based on its usage of the RISCV-DV random instruction
generator developed by Google. A block diagram of the testbench is below.

Figure 16.1: Architecture of the UVM testbench for Ibex core

16.2.1 Memory Interface Agents

The code can be found in the dv/uvm/common/ibex_mem_intf_agent directory. Two of these agents are instantiated
within the testbench, one for the instruction fetch interface, and the second for the LSU interface. These agents run
slave sequences that wait for memory requests from the core, and then grant the requests for instructions or for data.

16.2.2 Interrupt Interface Agent

The code can be found in the dv/uvm/common/irq_agent directory. This agent is used to drive stimulus onto the Ibex
core’s interrupt pins randomly during test execution.

16.2.3 Memory Model

The code can be found in the dv/uvm/common/mem_model directory. The testbench instantiates a single instance of
this memory model that it loads the compiled assembly test program into at the beginning of each test. This acts as a
unified instruction/data memory that serves all requests from both of the memory interface agents.

43
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

16.2.4 Test and Sequence Library

The code can be found in the dv/uvm/tests directory. The tests here are the main sources of external stimulus generation
and checking for this testbench, as the memory interface slave sequences simply serve the core’s memory requests.
The tests here are all extended from core_ibex_base_test, and coordinate the entire flow for a single test, from
loading the compiled assembly binary program into the testbench memory model, to checking the Ibex core status
during the test and dealing with test timeouts. The sequences here are used to drive interrupt and debug stimulus into
the core.

16.2.5 Testplan

The goal of this bench is to fully verify the Ibex core with 100% coverage. This includes testing all RV32IMC
instructions, privileged spec compliance, exception and interrupt testing, debug mode operation etc. The complete test
list can be found in the file dv/uvm/riscv_dv_extension/testlist.yaml.
Please note that verification is still a work in progress.

16.3 Getting Started

16.3.1 Prerequisites & Environment Setup

• VCS RTL simulator (needed to support UVM 1.2)


• RISCV-DV Prerequisites - https://github.com/google/riscv-dv#prerequisites
• GCC setup - https://github.com/google/riscv-dv#compile-generated-programs-with-gcc
• ISS setup - https://github.com/google/riscv-dv#run-iss-instruction-set-simulator-simulation - note that commit
log must be enabled in spike by passing --enable-commitlog to the configure script.

16.3.2 End-to-end RTL/ISS co-simulation flow

Figure 16.2: RTL/ISS co-simulation flow chart

44 Chapter 16. Verification


Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

Correctness checking is performed by the last stage in this flow, where the Ibex core’s trace log is compared against a
golden model ISS trace log and checked for any inconsistent instruction executions.
The flow is controlled by the Makefile found at dv/uvm/Makefile, here is the list of frequently used commands:

# Run a full regression


make

# Run a full regression, redirect the output directory


make OUT=xxx

# Run a single test


make TEST=riscv_machine_mode_rand_test ITERATIONS=1

# Run a test with a specific seed, dump waveform


make TEST=riscv_machine_mode_rand_test ITERATIONS=1 SEED=123 WAVES=1

# Verbose logging
make ... VERBOSE=1

# Run multiple tests in parallel through LSF


make ... LSF_CMD="bsub -Is"

# Get command reference of the simulation script


python3 sim.py --help

# Generate the assembly tests only


make gen

# Pass addtional options to the generator


make GEN_OPTS="xxxx" ...

# Compile and run RTL simulation


make TEST=xxx compile,rtl_sim

# Use a different ISS (default is spike)


make ... ISS=ovpsim

# Run a full regression with coverage


make COV=1

16.3.3 Run with a different RTL simulator

You can add any compile/runtime options in dv/uvm/yaml/simulator.yaml.

# Use the new RTL simulator to run


make ... SIMULATOR=xxx

16.3. Getting Started 45


Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

46 Chapter 16. Verification


CHAPTER

SEVENTEEN

EXAMPLES

To make use of Ibex it has to be integrated as described in Core Integration.

17.1 FPGA

A minimal example for the Arty A7 FPGA Development board is provided. In this example Ibex is directly linked
to a SRAM memory instance. Four LEDs from the board are connected to the data bus and are updated each time
when a word is written. The memory is separated into a instruction and data section. The instructions memory is
initialized at synthesis time by reading the output from the software build. The software writes to the data section the
complementary lower for bits of a word every second resulting in blinking LEDs.
Find the description of how to build and program the Arty board in examples/fpga/artya7-100/README.md.

47
Ibex Documentation, Release 0.1.dev50+g36ce999.d20191026

48 Chapter 17. Examples


CHAPTER

EIGHTEEN

LICENSING

Ibex is released under the Apache license, version 2.0.


Ibex can be used, modified, and distributed for any purpose (including commercial) and without any royalties. There
are some requirements on including copyright notices and the original license.
Please see the LICENSE file in the source code for the full (and legally binding) license text.
Even though the license doesn’t require it, we appreciate feedback and contributions to make Ibex work better for
everyone. Please open an issue for bug reports, questions, or suggested improvements, or a pull request if you’d like
to contribute code.

Note: Commercial support for Ibex is available from lowRISC.

49

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy