Return to previous page Advance to next page
Synthesis and Simulation Design Guide
Chapter 4: Designing FPGAs with HDL

Implementing Logic with IOBs

You can move logic that is normally implemented with CLBs to IOBs. By moving logic from CLBs to IOBs, additional logic can be implemented in the available CLBs. Using IOBs also improves design performance by increasing the number of available routing resources.

The XC4000 and Spartan devices have different IOB functions. The following sections provide a general description of the IOB function in XC4000E/EX/XLA/XL/XV and Spartan devices. A description of how to manually implement additional I/O features is also provided.

XC4000E/EX/XLA/XL/XV and Spartan IOBs

You can configure XC4000E/EX/XLA/XL/XV and Spartan IOBs as input, output, or bidirectional signals. You can also specify pull-up or pull-down resistors, independent of the pin usage.

These various buffer and I/O structures can be inferred from commands executed in a script or in your synthesis tool. The Set Port Is Pad (or equivalent) command in conjunction with the Insert Pads (or equivalent) command creates the appropriate buffer structure according to the direction of the specified port in the HDL code. You can add attributes to these commands to further control pull-up, pull-down, and clock buffer insertion, as well as slew-rate control. Some tools operate on I/Os by selecting a chip level (inserts I/O) or module level (no I/O) synthesis. Also, you can add synthesis tool attributes, such as BUFFER_SIG, to ports in your VHDL code to control insertion of I/Os.

Inputs

The buffered input signal that drives the data input of a storage element can be configured as either a flip-flop or a latch. Additionally, the buffered signal can be used in conjunction with the input flip-flop or latch, or without the register.

To avoid external hold-time requirements, IOB input flip-flops and latches have a delay block between the external pin and the D input. You can remove this default delay by instantiating a flip-flop or latch with a NODELAY attribute. The NODELAY attribute decreases the setup-time requirement and introduces a small hold time.

If an IOB or register is instantiated in your HDL code, you may not be able to use the Set Port Is Pad (or equivalent) command on that port. Doing so may automatically infer a buffer on that port and create an invalid double-buffer structure. This varies with the tool you are using. Check with your synthesis vendor to see if partial instantiation interferes with automatic I/O insertion or the use of IOB registers.

Registers that connect to an input or output pad and require a Direct Clear or Preset pin are not implemented by the synthesis tool in the IOB. The VHDL emulation of GSR or GR on these registers prevents them from being pulled into the IOB. The VHDL emulation of GSR/GR through direct clear or preset pins is described in the “Simulating Your Design” chapter. If GSR/GR behavior is not completely described, automatic inferencing of GSR/GR does not occur. In this case, instantiate STARTBUF in VHDL, and fully describe the GSR/GR behavior except for registers that you want in the IOB. In VHDL, these registers do not initialize pre-route, but do indicate X's until the first data is registered. However, they do initialize properly during back-annotation. Verilog models initialize properly and do not interfere with the automatic use of IOB registers instead of CLB registers.

Outputs

The output signal that drives the programmable tristate output buffer can be a registered or a direct output. The register is a positive-edge triggered flip-flop and the clock polarity can be inverted inside the IOB. (Xilinx software automatically optimizes any inverters into the IOB.) The XC4000 and Spartan output buffers can sink 12 mA. Two adjacent outputs can be inter-connected externally to sink up to 24mA.

Note: Most FPGA synthesis tools can optimize flip-flops attached to output pads into the IOB. However, some of these tools cannot optimize flip-flops into an IOB configured as a bidirectional pad. Refer to your synthesis tool documentation for more information.

Slew Rate

Refer to your synthesis tool documentation for information on configuring I/O's, including how to control slew rate.

Pull-ups and Pull-downs

XC4000 and Spartan devices have programmable pull-up and pull-down resistors available in the I/O regardless of whether it is configured as an input, output, or bi-directional I/O. By default, all unused IOBs are configured as an input with a pull-up resistor. The value of the pull-ups and pull-downs vary depending on operating conditions and device process variances but should be approximately 50 K Ohms to 100 K Ohms. If a more precise value is required, use an external resistor. Refer to your synthesis tool documentation for information on how to specify internal pull-up or pull-down I/O resistors.

XC4000EX/XLA/XL/XV Output Multiplexer/2-Input Function Generator

A function added to XC4000EX/XLA/XL/XV families is a two input multiplexer connected to the IOB output allowing the output clock to select either the output data or the IOB clock enable as the output pad. This allows you to share output pins between two signals, effectively doubling the number of device outputs without requiring a larger device or package. Additionally, this multiplexer can be configured as a two-input function generator allowing you to implement any 2-input logic function in the IOB thus freeing up additional logic resources in the device and allowing for very fast pin-to-pin data paths.

To use the output multiplexer (OMUX), you must instantiate it in your code. See the following VHDL and Verilog examples. Instantiation of the other types of two-input output primitives (such as OAND2, OOR2, and OXOR2) are similar to these examples.

Note: Since the OMUX uses the IOB output clock and clock enable routing structures, the output flip-flop (OFD) can not be used within the same IOB. The input flip-flop (IFD) can be used if the clock enable is not used.

XC5200 IOBs

XC5200 IOBs consist of an input buffer and an output buffer that can be configured as an input, output, or bi-directional I/O. The structure of the XC5200 is similar to the XC4000 IOB except the XC5200 does not contain a register/latch. The XC5200 IOB has a programmable pull-up or pull-down resistor, and two slew rate control modes (Fast and Slow) to minimize bus transients. The input buffer can be globally configured to TTL or CMOS levels, and the output buffer can sink or source 8.0 mA.

I/O buffer structures (as with the XC4000 IOBs) can be inferred from your synthesis tool script with the Set Port Is Pad (or equivalent) command in conjunction with the Insert Pads (or equivalent) command. Controlling pull-up and pull-down insertion and slew rate control are performed as previously described for the XC4000 IOB.

The XC5200 IOB also contains a delay element so that an input signal that is directly registered or latched can have a guaranteed zero hold time at the expense of a longer setup time. You can disable this (equivalent to NODELAY in XC4000) by instantiating an IBUF_F buffer for that input port. This only needs to be done for ports that connect directly to the D input of a register in which a hold time can be tolerated.

Bi-directional I/O

You can create bi-directional I/O with one or a combination of the following methods.

Xilinx FPGA IOBs consist of a direct input path into the FPGA through an input buffer (IBUF) and an output path to the FPGA pad through a tri-stated buffer (OBUFT). The input path can be registered or latched; the output path can be registered. If you instantiate or behaviorally describe the I/O, you must describe this bi-directional path in two steps. First, describe an input path from the declared INOUT port to a logic function or register. Second, describe an output path from an internal signal or function in your code to a tri-stated output with a tri-state control signal that can be mapped to an OBUFT.

You should always describe the I/O path at the top level of your code. If the I/O path is described in a lower level module, your synthesis tool may incorrectly create the I/O structure.

Inferring Bi-directional I/O

This section includes VHDL and Verilog examples that show how to infer a bi-directional I/O. In these examples, the input path is latched by a CLB latch that is gated by the active high READ_WRITE signal.

The output consists of two latched outputs with an AND and OR, and connected to a described tri-state buffer. The active low READ_WRITE signal enables the tri-state gate.

Instantiating Bi-directional I/O

Instantiating the bi-directional I/O gives you more control over the implementation of the circuit; however, as a result, your code is more architecture-specific and usually more verbose. The VHDL and Verilog examples in this section are identical to the examples in the “Inferring Bi-directional I/O” section; however, since there is more control over the implementation, an input latch is specified rather than the CLB latch inferred in the previous examples. The following examples are a more efficient implementation of the same circuit.

When instantiating I/O primitives, do not specify the Set Port Is Pad (or equivalent) command on the instantiated ports to prevent the I/O buffers from being inferred by your synthesis tool. This precaution also prevents the creation of an illegal structure.

Using LogiBLOX to Create Bi-directional I/O

You can use LogiBLOX to create I/O structures in an FPGA. LogiBLOX gives you the same control as instantiating I/O primitives, and is usually less verbose. LogiBLOX is especially useful for bused I/O ports.

Note: Refer to the “Using LogiBLOX in HDL Designs” section section, for details on creating, instantiating, and compiling LogiBLOX modules.

Do not use the Set Port Is Pad (or equivalent) command on LogiBLOX-created ports. Also, when designing with Verilog, you must issue a Remove Design or equivalent command before writing out the .xnf files from your synthesis tool.

The following VHDL and Verilog examples show how to instantiate bi-directional I/O created with LogiBLOX. These examples produce the same results as the examples in the “Instantiating Bi-directional I/O” section.

Specifying Pad Locations

Although Xilinx recommends allowing the software to select pin locations to ensure the best possible pin placement in terms of design timing and routing resources, sometimes you must define the pad locations prior to placement and routing. You can assign pad locations either from your synthesis tool's script prior to writing out the netlist file, or from a User Constraints File (UCF). Use one or the other method, but not both. Refer to your synthesis tool documentation for the correct syntax for configuring your I/O with the PLOC property. Also, refer to The Programmable Logic Data Book or the Xilinx Web site (http://support.xilinx.com) for the pad locations for your device and package.

Moving Registers into the IOB

Note: XC5200 devices do not have input and output flip-flops.

IOBs contain an input register or latch and an output register. IOB inputs can be register or latch inputs as well as direct inputs to the device array. Registers without a direct reset or set function can be moved into IOBs. Moving registers or latches into IOBs may reduce the number of CLBs used and decreases the routing congestion. In addition, moving input registers and latches into the IOB reduces the external setup time, as shown in the following figure.

Figure 4.8 Moving Registers into the IOB

Although moving output registers into the IOB may increase the internal setup time, it may reduce the clock-to-output delay, as shown in this figure. Most FPGA synthesis tools automatically move registers into IOBs if the Preset, Clear, and Clock Enable pins are not used.

Use -pr Option with Map

Use the -pr (pack registers) option when running MAP. The -pr {i | o | b} (input | output | both) option specifies to the MAP program to move registers into IOBs under the following circumstances.

  1. The input of the register must be connected to an input port, or the Q pin must be connected to an output port. For the XC4000EX/XL/XV this applies to non-I/O latches, as well as flip-flops.

  2. IOBs must have input or output flip-flops. XC5200 devices do not have IOB flip-flops.

  3. The flip-flop does not use an asynchronous set or reset signal.

  4. In XC4000, Spartan, and XC3000 devices, a flop/latch is not added to an IOB if it has a BLKNM or LOC conflict with the IOB.

  5. In XC4000 or Spartan devices, a flop/latch is not added to an IOB if its control signals (clock or clock enable) are not compatible with those already defined in the IOB. This occurs when a flip-flop (latch) is already in the IOB with different clock or clock enable signals, or when the XC4000EX/XL/XV output MUX is used in the same IOB.

  6. In XC4000EX/XV devices, if a constant 0 or 1 is driven on the IOPAD, a flip-flop/latch with a CE is not added to the input side of the IOB.

Using Unbonded IOBs (XC4000E/EX/XLA/XL/XV and Spartan Only)

In some package/device pairs, not all pads are bonded to a package pin. You can use these unbonded IOBs and the flip-flops inside them in your design by instantiating them in the HDL code. You can implement shift registers with these unbonded IOBs. The VHDL and Verilog examples in this section show how to instantiate unbonded IOB flip-flops in a 4-bit shift register in an XC4000 device.

Note: The synthesis tool compilers cannot infer unbonded primitives. Refer to your synthesis tool documentation for a list of library primitives that can be used for instantiations.

4-bit Shift Register Using Unbonded I/O VHDL Example

-------------------------------------------------
-- UNBONDED_IO.VHD Version 1.0 --
-- XC4000 LCA has unbonded IOBs which have --
-- storage elements that can be used to build --
-- shift registers. --
-- Below is a 4-bit Shift Register using --
-- Unbonded IOB Flip Flops --
-- Xilinx HDL Synthesis Design Guide for FPGAs --
-- May 1997 --
-------------------------------------------------

Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity unbonded_io is
port (A, B: in STD_LOGIC;
CLK: in STD_LOGIC;
Q_OUT: out STD_LOGIC);
end unbonded_io;

architecture XILINX of unbonded_io is

component IFD_U -- Unbonded Input FF with INIT=Reset
port (Q: out std_logic;
D, C: in std_logic);
end component;

component IFDI_U -- Unbonded Input FF with INIT=Set
port (Q: out std_logic;
D, C: in std_logic);
end component;

component OFD_U -- Unbonded Output FF with INIT=Reset
port (Q: out std_logic;
D, C: in std_logic);
end component;

component OFDI_U -- Unbonded Output FF with INIT=Set
port (Q: out std_logic;
D, C: in std_logic);
end component;

--- Internal Signal Declarations -----
signal U_Q : STD_LOGIC_VECTOR (3 downto 0);
signal U_D : STD_LOGIC;

begin
U_D <= A and B;
Q_OUT <= U_Q(0);

U3: OFD_U port map (Q => U_Q(3),
D => U_D,
C => CLK);

U2: IFDI_U port map (Q => U_Q(2),
D => U_Q(3),
C => CLK);

U1: OFDI_U port map (Q => U_Q(1),
D => U_Q(2),
C => CLK);

U0: IFD_U port map (Q => U_Q(0),
D => U_Q(1),
C => CLK);

end XILINX;

4-bit Shift Register Using Unbonded I/O Verilog Example

         ////////////////////////////////////////////////////
// UNBONDED.V //
// XC4000 family has unbonded IOBs which have //
// storage elements that can be used to build //
// functions lie shift registers. //
// Below is a 4-bit Shift Register using Unbonded //
// IOB Flip Flops //
// HDL Synthesis Design Guide for FPGAs //
// May 1997 //
////////////////////////////////////////////////////

module unbonded_io (A, B, CLK, Q_OUT);

input A, B, CLK;
output Q_OUT;

wire[3:0] U_Q;
wire U_D;

assign U_D = A & B;
assign Q_OUT = U_Q[0];

OFD_U U3 (.Q(U_Q[3]), .D(U_D), .C(CLK));

IFDI_U U2 (.Q(U_Q[2]), .D(U_Q[3]), .C(CLK));

OFDI_U U1 (.Q(U_Q[1]), .D(U_Q[2]), .C(CLK));

IFD_U U0 (.Q(U_Q[0]), .D(U_Q[1]), .C(CLK));

endmodule