wb_gpio – A Wishbone GPIO Engine for FPGAs

This is the project homepage for wb_gpio, a GPIO engine for the Wishbone bus, written in VHDL.


The wb_gpio module is a general-purpose I/O driver which can be controlled from the Wishbone bus interface. It allows the user to configure and control the I/O pins individually. Pins can be configured as inputs or outputs. The module does not support generating interrupts, e.g. when an input changes.


Using the wb_switch component in your VHDL design is as easy as declaring and instantiating any other component. Below is the VHDL entity declaration of the component.

entity wb_gpio is
generic (
     dat_sz  : natural := 8
); port (
     clk_i  : in  std_logic;
     rst_i  : in  std_logic;
     -- Whishbone Interface
     dat_i  : in  std_logic_vector((dat_sz - 1) downto 0);
     dat_o  : out std_logic_vector((dat_sz - 1) downto 0);
     adr_i  : in  std_logic_vector(1 downto 0);
     cyc_i  : in  std_logic;
     lock_i : in  std_logic;
     sel_i  : in  std_logic;
     we_i   : in  std_logic;
     ack_o  : out std_logic;
     err_o  : out std_logic;
     rty_o  : out std_logic;
     stall_o: out std_logic;
     stb_i  : in  std_logic;
     -- GPIO Interface
     gp_io  : inout std_logic_vector((dat_sz - 1) downto 0)
end wb_gpio;

Because pins configured as inputs cause the output drivers to assume a “hi-Z” state, the module’s gp_io signals should be routed to actual I/O pins on the FPGA. If you fail to do that, the synthesis tool will route the signals to IOBs which is likely to pessimize your design.

The design is customizable through generics, which are described in the following table.

dat_szWidth of Wishbone data bus. Also number of general purpose I/O pins.

The module supports Wishbone classic read and write cycles. It will generate a ack response within one clock cycle. The ackoutput is asserted as long as the module’s stb input is active. There are no errors or retry conditions generated. Because the module generates a response within one cycle, it does never drive the stall output. Nevertheless, it should support Wishbone classic pipelined read and write cycles, too, but that hasn’t been tested so far.


The module exposes four registers which are described in the table below.

0x00OutputWriting to this register causes enabled output pins to assume the written value. In other words, writing to this register adjusts all output pins. Reading from this register will return the current value of the general purpose I/O pins, independent of whether they are configured as outputs or inputs.
0x01EnableSetting a bit in this register turns the general purpose I/O pin into an output. Clearing a bit in this register turns the general purpose I/O pin into an input. This will cause the output driver to assume a “hi-Z” state. Reading the register will return the current settings.
0x02MaskSetting a bit in this register allows the corresponding output to be changed by writing to the “update” register. Reading this register will return the current settings.
0x03UpdateWriting to this register updates those output pins whose corresponding bits in the “mask” register are set. In other words, by writing to the “mask” and then to the “update” register, “update” (or sometimes also “write under mask”) semantics can be implemented, where only a single output pin is changed, while others are left untouched.


Below are the links to the VHDL file(s).


Here are a few links related to this project.