APB GPIO

The General Purpose Input/Output (GPIO) IP block supports S/W access to read and write the values on selected I/O, and configuring selected I/O to generate interrupts.

Features

  • Configurable number of GPIO pins (Upto 128, current implementation supports 32).

  • Programmable configuration for each pin (output enable, open-drain enable).

  • Individual control for setting, clearing, or toggling output pins

  • Pin status reading capability

  • Interrupt generation capabilities with multiple configurable types:
    • Rising edge detection

    • Falling edge detection

    • Active low level detection

    • Active high level detection

  • Input synchronization to prevent metastability issues.

Block Architecture

The figure below is a high-level block diagram of the APB GPIO module:-

APB GPIO Block Diagram

The APB GPIO IP consists of the following key components:

APB control logic

The APB control logic interfaces with the APB bus to decode and execute commands. It handles CSR reads and writes according to the APB protocol, providing a standardized interface to the system.

GPIO CSR

These CSRs store the configuration for each GPIO pin, including:

  • Pin configuration (output enable, open-drain enable)

  • Input value

  • Output value

  • Interrupt type configuration

  • Interrupt enable status

Open-Drain Operation

The GPIO module supports open-drain operation for every GPIO output pin(will depend on the implementation technology). Open-drain is a specific output driver configuration where the GPIO pin can either pull the signal to ground (logic ‘0’) or release it to a high-impedance state, but cannot actively drive it to a high voltage level (logic ‘1’). This configuration requires an external pull-up resistor to achieve a logic ‘1’ state.

The external pull-up resistor must be connected between the GPIO pin and the desired high-voltage level (VDD). Without this pull-up resistor, the pin will remain in an undefined state when not actively driven low.

Input Synchronization

Metastability refers to an unstable state in which the signal fails to settle into a stable low or high level within a required time. A dual-stage synchronizer in the GPIO module prevents metastability issues when sampling external inputs by synchronizing them to the system clock domain. This synchronizer consists of two flip-flops in series, which helps to ensure that any glitches or transient signals on the GPIO inputs are filtered out before being processed by the rest of the system.

The input signals on the GPIO pins are sampled by the first flip-flop, and the output of this flip-flop is then sampled by the second flip-flop. The output of the second flip-flop is the synchronized signal that is used by the GPIO module.

Pin Direction Control

It is assumed, but not required, that each GPIO pin of the CORE-V-MCU is implemented as a bi-directional signal. To enable this, each GPIO signal is associated with three ports of the GPIO module:

  • gpio_in

  • gpio_out

  • gpio_dir

These ports are required to be connected to the appropriate IO PADS provided by the ASIC or FPGA implementation technology. The purpose of the gpio_in and gpio_out ports is self explainatory, and each can be read or written via CSRs (see APB GPIO CSRs below). The function of gpio_dir is determined by the implementation technology. The GPIO module allows gpio_dir to be configured individually for each output pin, via the two-bit DIR field of the SETDIR CSR. Below is a truth table that illustrates how SETDIR allows software to configure the value of gpio_dir.

SETDIR[DIR]

gpio_dir

2’b00

0

2’b01

1

2’b10

!gpio_out

2’b11

!gpio_out

Typically, gpio_dir is used to drive an active-low output enable of an IO PAD. In such cases, writing SETDIR[DIR][1] to 1’b0 means that software can write SETDIR[DIR][0] to enable or disable the output driver of the IO PAD.

GPIO Input

  • The GPIO module reads external signals through the gpio_in input signal.

  • The value of these signals post synchronisation is made available on the PIN0 CSR (address 0x010), allowing the software to read the status of the GPIO input pins.

  • Each bit in the PIN0 CSR corresponds to a GPIO pin(bit 0 for GPIO pin 0, bit 1 for GPIO pin 1, and so on), where a bit value of 1 indicates a high state and 0 indicates a low state.

  • The synchronized input signals are also then provided to the gpio_in_sync output signal, which is used by the Advanced Timer module for external event processing.

GPIO Output

  • The GPIO module drives external devices through the gpio_out output signal.

  • The output value of each pin can be controlled by:
    • OUTx {x = 0 to 3} CSR

    • SETGPIO, CLRGPIO and TOGGPIO

  • OUTx CSR is used to drive a group of pins, while SETGPIO, CLRGPIO and TOGGPIO are used to drive a single output pin.

  • Each bit in the OUT0 CSR corresponds to a GPIO pin(bit 0 for GPIO pin 0, bit 1 for GPIO pin 1, and so on), where a bit value of 1 sets the pin high and a bit value of 0 sets it low.

  • The SETGPIO CSR (address 0x000) sets a specified pin high.

  • The CLRGPIO CSR (address 0x004) sets a specified pin low.

  • The TOGGPIO CSR (address 0x008) toggles the state of a specified pin.

  • The gpio_out output signal reflects the current output state of the GPIO pins with output enabled via DIR bitfield of SETDIR CSR.

  • If a output is not enabled for a pin, the corresponding bit in the OUT0 CSR will be 0, as the output value is not applicable for it.

Interrupt Generation

This section describes how GPIO pins generate interrupts and the differences between edge-triggered and level-triggered behavior.

Interrupt Capability

GPIO input pins can be used to receive interrupts from external devices. Since the output value is also reflected on the corresponding input pin, even software can trigger interrupts by driving a particular output pin.

Interrupt Types

The interrupt logic detects events based on the configured type for each of the 32 pins:

  • Edge-triggered: Detects rising or falling edges

  • Level-triggered: Detects active-high or active-low levels

The interrupt type for each pin is configured through the SETINT CSR (address 0x03C), which allows the software to specify the desired interrupt behavior.

  • The interrupt type is specified using bits [19:17]:

    • 000: Active-Low level detection

    • 001: Falling edge detection

    • 010: Rising edge detection

    • 011: Both edges detection

    • 100: Active-High level detection

  • The interrupt enable status is specified using bit [16]:

    • 0: Disable interrupt for the pin

    • 1: Enable interrupt for the pin

  • The pin number is specified using bits [6:0], allowing the software to configure interrupts for individual pins.

For example, to configure GPIO input pin 0 for rising edge detection, the software would write the following values to the SETINT CSR:

` SETINT = (0b010 << 17) | (1 << 16) | (0 << 6) `

This sets the interrupt type to rising edge detection, enables the interrupt, and selects GPIO pin 0.

Interrupt Signal Behavior

When an event occurs on an input pin configured for interrupts, the interrupt logic asserts the corresponding interrupt signal for that pin. This signal is represented by the interrupt output signal, which is a 32-bit vector where each bit corresponds to a GPIO pin. For example, if GPIO pin 0 is configured for interrupts and an event occurs, the interrupt[0] signal will be asserted (set to high). This signal remains high for one clock cycle to indicate the event, after which it is cleared.

The interrupt signal is captured by the APB Event Controller for further processing. Refer to the APB Event Controller documentation for more details.

Edge vs. Level-Triggered Interrupts

The main difference between edge-triggered and level-triggered interrupts lies in how they are generated and cleared:

  • Edge-triggered interrupts are activated on signal transitions (rising or falling edges) and are automatically cleared after one clock cycle.

  • Level-triggered interrupts remain active as long as the level condition (high or low) persists, to resolve this the GPIO module blocks the level-triggered interrupt signal after it is generated once and deasserts the output interrupt.

Hence, both edge-triggered and level-triggered interrupts are asserted for one clock cycle, but level-triggered interrupts require explicit acknowledgment to allow new interrupts to be generated.

Interrupt Acknowledgment

To prevent repeated triggering from persistent level conditions, the APB GPIO disables the interrupt signal after it is generated once and deasserts the output interrupt. The APB master must acknowledge the interrupt by writing to the INTACK CSR.

Once acknowledged, the GPIO can reassert the interrupt signal if the level condition still holds true. The above is only valid for level-triggered interrupts, as edge-triggered interrupts are automatically cleared after one clock cycle.

System Architecture

The figure below depicts the connections between the GPIO and rest of the modules in CORE-V-MCU:-

APB GPIO CORE-V-MCU connections diagram

The gpio_in_sync output is directly connected to the Advanced Timer module. It provides synchronized GPIO input signals that serve as external event sources for the Advanced Timer. These signals are processed by the Advanced Timer logic and can ultimately control the up/down counter functionality. This integration enables external events captured by GPIO pins to influence timer operations.

Programming View Model

The APB GPIO IP follows a simple programming model:

GPIO Pin Configuration

Each GPIO pin can be configured individually:
  • Configure the pin direction/configuration (output enable, open-drain) using the SETDIR CSR

  • Configure interrupt behavior if necessary using the SETINT CSR

For details, please refer to the ‘Firmware Guidelines’.

GPIO Pin Control

To control GPIO pins:
  • Use SETGPIO to set a pin high

  • Use CLRGPIO to set a pin low

  • Use TOGGPIO to toggle a pin’s state

  • Use OUTx CSRs to set multiple pins at once

For details, please refer to the ‘Firmware Guidelines’.

GPIO Pin Status

To read GPIO pin status:
  • Use RDSTAT to read a selected pin’s status

  • Use PINx CSRs to read the status of multiple pins at once

For details, please refer to the ‘Firmware Guidelines’.

Interrupt Handling

When an interrupt occurs:
  • Determine the source by reading pin status

  • Handle the interrupt according to application requirements

  • Acknowledge the interrupt using the INTACK CSR in case of level-triggered interrupts.

For details, please refer to the ‘Firmware Guidelines’.

APB GPIO CSRs

The APB GPIO has a 4KB address space and the CSR interface designed using the APB protocol. There are multiple CSRs allowing the processor to read input GPIO pin states, set output pin values, and configure various GPIO settings such as interrupt behavior, pin direction etc. The CSRs are designed for 128 GPIO pins, but the current implementation supports only 32 GPIO pins.

NOTE: Several of the Event Controller CSR are volatile, meaning that their read value may be changed by the hardware. For example, the value of PIN0 CSR may change if the GPIO pin is configured as an input and the external signal changes. However, the non-volatile CSRs, as the name suggests, will retain their value until explicitly changed by the software.

SETGPIO

  • Address Offset: 0x000

  • Type: non-volatile

Field

Bits

Access

Default

Description

PIN_SELECT

[6:0]

WO

0x0

GPIO pin index, which will be set high

Only pins with output enabled can be set high

CLRGPIO

  • Address Offset: 0x004

  • Type: non-volatile

Field

Bits

Access

Default

Description

PIN_SELECT

[6:0]

WO

0x0

GPIO pin index, which will be set low

Only pins with output enabled can be set low

TOGGPIO

  • Address Offset: 0x008

  • Type: non-volatile

Field

Bits

Access

Default

Description

PIN_SELECT

[6:0]

WO

0x0

GPIO pin index, which will be toggled

Only pins with output enabled can be toggled

PIN0

  • Address Offset: 0x010

  • Type: volatile

Field

Bits

Access

Default

Description

GPIO_IN

[31:0]

RO

0x0

Read status of GPIO pins 31:0

PIN1

  • Address Offset: 0x014

  • Type: volatile

Field

Bits

Access

Default

Description

GPIO_IN

[31:0]

RO

0x0

Read status of GPIO pins 63:32 (Not supported)

PIN2

  • Address Offset: 0x018

  • Type: volatile

Field

Bits

Access

Default

Description

GPIO_IN

[31:0]

RO

0x0

Read status of GPIO pins 95:64 (Not supported)

PIN3

  • Address Offset: 0x01C

  • Type: volatile

Field

Bits

Access

Default

Description

GPIO_IN

[31:0]

RO

0x0

Read status of GPIO pins 127:96 (Not supported)

OUT0

  • Address Offset: 0x020

  • Type: volatile

Field

Bits

Access

Default

Description

GPIO_OUT

[31:0]

RW

0x0

Set value of GPIO pins 31:0. If output is enabled for the pin

OUT1

  • Address Offset: 0x024

  • Type: volatile

Field

Bits

Access

Default

Description

GPIO_OUT

[31:0]

RW

0x0

Set value of GPIO pins 63:32. If output is enabled for the pin. (Not supported)

OUT2

  • Address Offset: 0x028

  • Type: volatile

Field

Bits

Access

Default

Description

GPIO_OUT

[31:0]

RW

0x0

Set value of GPIO pins 95:64. If output is enabled for the pin. (Not supported)

OUT3

  • Address Offset: 0x02C

Field

Bits

Access

Default

Description

GPIO_OUT

[31:0]

RW

0x0

Set value of GPIO pins 127:96. If output is enabled for the pin. (Not supported)

SETSEL

  • Address Offset: 0x030

  • Type: non-volatile

Field

Bits

Access

Default

Description

PIN_SELECT

[6:0]

WO

0x0

GPIO pin number to select for reading pin using RDSTAT

RDSTAT

  • Address Offset: 0x034

  • Type: volatile

Field

Bits

Access

Default

Description

DIR

[25:24]

RO

0x0

Direction configuration for pin selected via SETSEL CSR or last selected pin.

INT_TYPE

[19:17]

RO

0x0

Interrupt type configuration for pin selected via SETSEL CSR or last selected pin.

INT_EN

[16]

RO

0x0

Interrupt enable status for pin selected via SETSEL CSR or last selected pin.

PIN_IN

[12]

RO

0x0

Input value of pin selected via SETSEL CSR or last selected pin.

PIN_OUT

[8]

RO

0x0

Output value of pin selected via SETSEL CSR or last selected pin.

Only valid when DIR value is 01

PIN_SELECT

[6:0]

RO

0x0

Currently selected pin number selected via SETSEL CSR or last selected pin.

SETDIR

  • Address Offset: 0x038

  • Type: non-volatile

Field

Bits

Access

Default

Description

DIR

[25:24]

WO

0x0

Direction Configuration:

  • 2’b00: Sets gpio_dir to 0

  • 2’b01: Sets gpio_dir to 1

  • 2’b10/2’b11: Sets gpio_dir to !gpio_out

PIN_SELECT

[6:0]

WO

0x0

GPIO pin number to configure

SETINT

  • Address Offset: 0x03C

  • Type: non-volatile

Field

Bits

Access

Default

Description

INT_TYPE

[19:17]

WO

0x0

Interrupt type:

000: Active-Low level

001: Falling edge

010: Rising edge

011: Both edges

100: Active-High level

INT_EN

[16]

WO

0x0

Interrupt enable:

0: Disable

1: Enable

PIN_SELECT

[6:0]

WO

0x0

GPIO pin number to configure interrupt

INTACK

  • Address Offset: 0x040

  • Type: non-volatile

Field

Bits

Access

Default

Description

PIN_NUM

[7:0]

WO

0x0

GPIO pin number to acknowledge interrupt

Firmware Guidelines

GPIO Pin Configuration Procedure

Configuring Pin Direction

Direction of a pin can be configured by writing to the SETDIR CSR (address 0x038).
  • To configure gpio_in as input: All pins are input by default and the input cannot be disabled.

  • To configure gpio_out as output: Place a value of 1 in bit [24] along with the pin number in bits [6:0].

  • To configure gpio_out as open-drain: Place a value of 1 in bit [25] along with the pin number in bits [6:0].

Configuring Interrupt Behavior

  • If the input pin requires interrupt capability, write to the SETINT CSR (address 0x03C).

  • Include the pin number in bits [6:0].

  • To enable interrupts, set bit [16] to 1; to disable, set to 0.

  • To configure interrupt type, set bits [19:17] as follows:
    • 000: Active-Low level detection

    • 001: Falling edge detection

    • 010: Rising edge detection

    • 011: Both edges detection

    • 100: Active-High level detection

  • If output is enabled for a pin and interrupt is also configured, then driving the pin through software will also result in interrupt generation.

GPIO Status Reading Procedure

Reading Individual Pin Status

  • First, select the desired pin by writing its number to SETSEL CSR(address 0x030).

  • Read the RDSTAT CSR (address 0x034).

  • Examine bit [12] for the current input state of the pin.

  • Examine bit [8] for the current output value.

  • Other fields provide configuration information:
    • Bits [25:24]: Direction configuration(output enabled, open-drain enabled)

    • Bits [19:17]: Interrupt type(active-low, falling edge, rising edge, both edges, or active-high)

    • Bit [16]: Interrupt enable status

Reading Multiple Pin States

  • To read the status of multiple pins at once, read the PIN0 CSR, in which each bit represents corresponding output pin.

  • A bit value of 1 indicates a high state, 0 indicates a low state.

GPIO Control Procedure

Setting Individual Pins High

  • Write the pin number to the SETGPIO CSR (address 0x000).

  • This operation sets the specified pin to a high state.

Setting Individual Pins Low

  • Write the pin number to the CLRGPIO CSR (address 0x004).

  • This operation sets the specified pin to a low state.

Toggling Individual Pins

  • Write the pin number to the TOGGPIO CSR (address 0x008).

  • This inverts the current state of the specified pin.

Controlling Multiple Pins Simultaneously

  • To control multiple pins in one operation, write to the OUT0 CSR.

  • Each bit position corresponds to the respective pin number.

  • Setting a bit to 1 drives the corresponding pin high; setting to 0 drives it low.

Interrupt Handling Procedure

Interrupt Processing

  • When an interrupt occurs, the GPIO module asserts the corresponding interrupt signal.

  • Process the interrupt according to application requirements.

  • For level-sensitive interrupts, the interrupt needs to be acknowledged/unblocked before it can be reasserted.

Interrupt Acknowledgment

  • To acknowledge the interrupt, write the pin number to the INTACK CSR (address 0x040).

  • This clears the interrupt signal for the specified pin, allowing it to be reasserted if the condition persists.

  • Note that this acknowledgment is only required for level-triggered interrupts.

Open-Drain Configuration Guidelines

Configuring Open-Drain Mode

  • Write to SETDIR with a value of 1 in bit [25] enabling open drain configuration.

  • Include the pin number in bits [6:0].

Using Open-Drain Pins

  • To drive the pin low: Use SETGPIO or write a 1 to the corresponding bit in OUT0.

  • To place the pin in high-impedance state: Use CLRGPIO or write a 0 to the corresponding bit in OUT0.

  • Ensure an external pull-up resistor is connected to the pin to achieve a high state when not driven low.

Pin Diagram

The figure below represents the input and output pins for the APB GPIO:-

APB GPIO Pin Diagram

Clock and Reset

  • HCLK: System clock input; provided by APB FLL.

  • HRESETn: Active-low reset signal for initializing all internal CSRs and logic.

  • dft_cg_enable_i: Clock gating enable input for DFT or low-power scenarios; Always 0 in the current implementation.

APB Interface Signals

  • PADDR[11:0]: APB address bus input

  • PWDATA[31:0]: APB write data bus input

  • PWRITE: APB write control input (high for write, low for read)

  • PSEL: APB peripheral select input

  • PENABLE: APB enable input

  • PRDATA: APB write data bus input

  • PREADY: APB ready output to indicate transfer completion

  • PSLVERR: APB error response output signal

GPIO Data Signals

  • gpio_in[31:0]: External GPIO input values from the physical pins; provided by external devices.

  • gpio_in_sync[31:0]: Synchronized version of gpio_in, provides the external signals to Advanced timer block.

  • gpio_out[31:0]: Output values driven onto physical GPIO pins, if pin is configured as outputs; provided to external devices.

  • gpio_dir[31:0]: Direction control per pin; provided to external devices.

Interrupt Signals

  • interrupt[31:0]: Per-pin interrupt outputs, asserted based on edge or level-triggered conditions; provided to APB Event Controller.