title: “Pinmux Technical Specification”

Overview

This document specifies the functionality of the pin multiplexer (pinmux) peripheral. This module conforms to the [OpenTitan guideline for peripheral device functionality.]({{< relref “doc/rm/comportability_specification” >}}). See that document for integration overview within the broader OpenTitan top level system. The module provides a mechanism to reconfigure the peripheral-to-pin mapping at runtime, which greatly enhances the system flexibility. This IP is closely related to the padctrl instance which provides additional control of pad attributes (pull-up, pull-down, open drain, drive strength, keeper and inversion). See [that spec]({{< relref “hw/ip/padctrl/doc” >}}) for more information.

Features

  • Configurable number of chip bidirectional pins

  • Configurable number of peripheral inputs and outputs

  • Programmable mapping from peripheral outputs (and output enables) to top-level outputs (and output enables)

  • Programmable mapping from top-level inputs to peripheral inputs

Description

The pinmux peripheral is a programmable module designed to wire arbitrary peripheral inputs and outputs to arbitrary multiplexable chip bidirectional pins. It gives much flexibility at the top level of the device, allowing most data pins to be flexibly wired and controlled by many peripherals. It is assumed that all available pins that the pinmux connects to are bidirectional, controlled by logic within this module. This document does not define how these are connected to pads at the toplevel, since that is governed by the padctrl IP [that spec]({{< relref “hw/ip/padctrl/doc” >}}). However, some discussion is shared in a later section.

The number of available peripheral IOs and muxed IOs is configurable, in other words modifiable at design time. This configurability is implemented by representing inputs / outputs as packed arrays, in combination with the SystemVerilog parameters NPeriphIn, NPeriphOut and NMioPads. Note however that the register file is also affected by this configuration and needs to be regenerated for each design instance.

The assignment of which peripheral output goes to the output data signal of which chip pin is programmable, in other words, modifiable by software at run time. Similarly the assignment of which peripheral input is driven by which chip input is programmable. By default, all peripheral inputs are tied to zero or one (this default is design-time programmable via the InputDefault parameter). Further, all output enables are set to zero, which essentially causes all pads to be in high-Z state after reset.

In addition to wiring programmability, each peripheral input can be set constantly to 0 or 1, and each chip output can be set constantly to 0, 1 or high-Z. Additional features such as output keeper or inversion are not provided by the pinmux since they are implemented in the padctrl IP which operates at the chip-level. This separation of physical pad attributes and logical wiring makes it possible to place the pads into an always-on domain without restricting possible power-down modes of the pinmux. One could imagine this to be a useful feature if a deep sleep mode were implemented in future; chip outputs could hold their output values and not be affected by internal power loss.

Theory of Operations

The pin multiplexor module intends to give maximum flexibility of peripheral and chip wiring to the software running on the device. The assumption is that the wiring is done once at the initialization of the application based upon usage of the device within the broader system. How this wiring is most effectively done is outside the scope of this document, but a section below briefly discusses use cases.

Block Diagram

The diagram below shows connectivity between four arbitrary chip pins, named MIO_00 .. MIO_03, and several peripheral inputs and outputs. This shows the connectivity available in all directions, as well as the control registers described later in this document. Two example peripherals (uart and spidev) are attached to the pinmux in this example, one with one input and one output, the other with three inputs and one output. The diagram also shows the padring module (from the padctrl IP) which instantiates the bidirectional chip pads with output enable control.

Pinmux Block Diagram

Note that apart from selecting a specific input pad, the periph_insel[*] signals can also be used to tie the peripheral input to 0 or 1. Likewise, the output select signals mio_outsel[*] can also be used to constantly drive an output pin to 0/1 or to put it into high-Z state (default). The output enable and the associated data signal (i.e. periph_to_mio and periph_to_mio_oe) are indexed with the same select signal to allow the peripheral hardware to determine the pad direction instead of demoting that control to software.

Additional details about the signal names and parameters are given in the sections below.

Hardware Interfaces

{{< hwcfg “hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson” >}}

Parameters

The following table lists the main parameters used throughout the pinmux design. Note that the pinmux is generated based on the system configuration, and hence these parameters are placed into a package as “localparams”.

LocalparamDefault (Max)Top EarlgreyDescription
NPeriphOut16 (-)32Number of peripheral outputs.
NPeriphIn16 (-)32Number of peripheral input.
NMioPads8 (-)32Number of muxed bidirectional pads (depending on padctrl setup).

Additional IOs

The table below lists the pinmux signals. The number of IOs is parametric, and hence the signals are stacked in packed arrays.

SignalDirectionTypeDescription
periph_to_mio_i[NPeriphOut-1:0]inputpacked logicSignals from NPeriphOut peripheral outputs coming into the pinmux.
periph_to_mio_oe_i[NPeriphOut-1:0]inputpacked logicSignals from NPeriphOut peripheral output enables coming into the pinmux.
mio_to_periph_o[NPeriphIn-1:0]outputpacked logicSignals to NPeriphIn peripherals coming from the pinmux.
mio_out_o[NMioPads-1:0]outputpacked logicSignals to NMioPads bidirectional pads as output data.
mio_oe_o[NMioPads-1:0]outputpacked logicSignals to NMioPads bidirectional pads as output enables.
mio_in_i[NMioPads-1:0]inputpacked logicSignals from NMioPads bidirectional pads as input data.

Programmers Guide

Software should determine and program the pinmux mapping at startup, or reprogram it when the functionality requirements change at runtime. This can be achieved by writing the following values to the {{< regref “PERIPH_INSEL” >}} and {{< regref “MIO_OUTSEL” >}} registers. Note that the pinmux configuration should be sequenced after any IO attribute-specific configuration in the padctrl module to avoid any unwanted electric behavior and/or contention.

periph_insel ValueSelected Input Signal
0Constant zero
1Constant one
2 + kCorresponding MIO input signal at index k

The global default at reset is 0, but the default of individual signals can be overridden at design time, if needed.

mio_outsel ValueSelected Output signal
0Constant zero
1Constant one
2High-Z
3 + kCorresponding peripheral output signal at index k

The global default at reset is 2, but the default of individual signals can be overridden at design time, if needed.

The pinmux configuration can be locked down by writing 0 to register {{< regref “REGEN” >}}. The configuration can then not be altered anymore unless the system is reset.

Register Table

The register description below matches the instance in the [Earl Grey top level design]({{< relref “hw/top_earlgrey/doc” >}}).

Similar register descriptions can be generated with different parameterizations.

{{< registers “hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson” >}}