nios_gpio is a general-purpose I/O controlled by a PIO core connected to the Nios soft processor. This PIO bus controls system configuration stuff like resets, RF switches, etc. Bits 31:30 control the mode of the expansion header. These bits are set automatically when you use the bladeRF-cli (or libbladeRF) to enable the expansion board you are using (XB-100 in this case).
nios_xb_gpio_in,
nios_xb_gpio_out, and
nios_xb_gpio_dir (xb_gpio_dir) are similar to
nios_gpio except that these are internal signals that go between a (different) PIO core connected to the Nios and the actual physical signals going over the expansion header. The _dir signal controls whether the pins are inputs or outputs. Note that
xb_gpio_dir is the same as
nios_xb_gpio_dir. There is a re-assignment to
xb_gpio_dir in case the
xb_mode dictates it for whatever reason.
exp_gpio is the top-level bus representing the physical I/O pins that are routed between the FPGA and the expansion header. Note that these pins are designated as "inout" in bladerf.vhd. They are therefore bidirectional and are physically implemented in the FPGA as a tri-state buffer. A good FPGA design will split the "inout" into discrete buses: inputs, outputs, and an output_enable before it is used within the FPGA fabric. The output_enable control in this case is the
xb_gpio_dir and it controls whether the FPGA's output driver is actively driving the pin, or if it is tri-stated (high-impedance / "disconnected"), allowing the FPGA to read the value being driven by some other device connected to the pin.
Now ... with all that said, the PIO core that reads/writes these GPIO from the Nios is not intended to be used with rapidly changing signals. If you want to do that, there are a few things you can do. If you don't need the slow PIO stuff from the Nios at all, you can just get rid of it and control
exp_gpio directly in the HDL. If you will only be outputting the fast signal, you could modify the
exp_gpio output assignment to the signal you want to send out. Another option is to change the top-level direction to "out" and directly drive the bus as an output only so you don't have to worry about the tristate buffer stuff. Just be careful about the input-only pins of the XB-100 (switches and push buttons).
These options work just as well for using the expansion header as
an input bus, but remember that a fast input signal cannot be read by the PIO -- you'd have to send it to the FX3 GPIF via the RX FIFO (or some other facility that you'd have to implement). Likewise, be careful about which pins you're using because some are not designed to be used as inputs (e.g. LEDs).
That was probably way more detailed than you wanted.