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

Using Dedicated I/O Decoders

The periphery of XC4000 family devices has four wide decoder circuits at each edge. The inputs to each decoder are any of the IOB signals on that edge plus one local interconnect per CLB row or column. Each decoder generates a High output (using a pull-up resistor) when the AND condition of the selected inputs or their complements is true. The decoder outputs drive CLB inputs so they can be combined with other logic or can be routed directly to the chip outputs.

To implement XC4000 family edge decoders in HDL, you must instantiate edge decoder primitives. The primitive names you can use vary with the synthesis tool you are using. For example, you can instantiate DECODE1_IO, DECODE1_INT, DECODE4, DECODE8, and DECODE16. These primitives are implemented using the dedicated I/O edge decoders. The XC4000 family wide decoder outputs are effectively open-drain and require a pull-up resistor to take the output High when the specified pattern is detected on the decoder inputs. To attach the pull-up resistor to the output signal, you must instantiate a PULLUP component.

The following VHDL example shows how to use the I/O edge decoders by instantiating decode primitives. Each decoder output is a function of ADR (IOB inputs) and CLB_INT (local interconnects). The AND function of each DECODE output and Chip Select (CS) serves as the source of a flip-flop Clock Enable pin. The four edge decoders in this design are placed on the same device edge. The “Schematic Block Representation of I/O Decoder” figure shows the schematic block diagram representation of this I/O decoder design.

Using Dedicated I/O Decoders VHDL Example

--Edge Decoder
--An XC4000 LCA has special decoder circuits at each edge. These decoders
--are open-drained wired-AND gates. When one or more of the inputs (I) are --Low output(O) is Low. When all of the inputs are High, the output is
--High. A pull-up resistor must be connected to the output node to achieve --a true logic High.

Library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;

entity io_decoder is
port (ADR: in std_logic_vector (4 downto 0);
CS: in std_logic;
DATA: in std_logic_vector (3 downto 0);
CLOCK: in std_logic;
QOUT: out std_logic_vector (3 downto 0));
end io_decoder;

architecture STRUCTURE of io_decoder is

COMPONENT DECODE1_IO
PORT ( I: IN std_logic;
O: OUT std_logic );
END COMPONENT;

COMPONENT DECODE1_INT
PORT ( I: IN std_logic;
O: OUT std_logic );
END COMPONENT;

COMPONENT DECODE4
PORT ( A3, A2, A1, A0: IN std_logic;
O: OUT std_logic );
END COMPONENT;

COMPONENT PULLUP
PORT ( O: OUT std_logic );
END COMPONENT;

---- Internal Signal Declarations ----------------------
signal DECODE, CLKEN, CLB_INT: std_logic_vector (3 downto 0);
signal ADR_INV, CLB_INV: std_logic_vector (3 downto 0);
begin

ADR_INV <= not ADR (3 downto 0);
CLB_INV <= not CLB_INT;

----- Instantiation of Edge Decoder: Output "DECODE(0)" ---------------
A0: DECODE4 port map (ADR(3), ADR(2), ADR(1), ADR_INV(0), DECODE(0));

A1: DECODE1_IO port map (ADR(4), DECODE(0));

A2: DECODE1_INT port map (CLB_INV(0), DECODE(0));

A3: DECODE1_INT port map (CLB_INT(1), DECODE(0));

A4: DECODE1_INT port map (CLB_INT(2), DECODE(0));

A5: DECODE1_INT port map (CLB_INT(3), DECODE(0));

A6: PULLUP port map (DECODE(0));

----- Instantiation of Edge Decoder: Output "DECODE(1)" ---------------
B0: DECODE4 port map (ADR(3), ADR(2), ADR_INV(1), ADR(0), DECODE(1));

B1: DECODE1_IO port map (ADR(4), DECODE(1));

B2: DECODE1_INT port map (CLB_INT(0), DECODE(1));

B3: DECODE1_INT port map (CLB_INV(1), DECODE(1));

B4: DECODE1_INT port map (CLB_INT(2), DECODE(1));

B5: DECODE1_INT port map (CLB_INT(3), DECODE(1));

B6: PULLUP port map (DECODE(1));

----- Instantiation of Edge Decoder: Output "DECODE(2)" ---------------
C0: DECODE4 port map (ADR(3), ADR_INV(2), ADR(1), ADR(0), DECODE(2));

C1: DECODE1_IO port map (ADR(4), DECODE(2));

C2: DECODE1_INT port map (CLB_INT(0), DECODE(2));

C3: DECODE1_INT port map (CLB_INT(1), DECODE(2));

C4: DECODE1_INT port map (CLB_INV(2), DECODE(2));

C5: DECODE1_INT port map (CLB_INT(3), DECODE(2));

C6: PULLUP port map (DECODE(2));

----- Instantiation of Edge Decoder: Output "DECODE(3)" ---------------
D0: DECODE4 port map (ADR_INV(3), ADR(2), ADR(1), ADR(0), DECODE(3));

D1: DECODE1_IO port map (ADR(4), DECODE(3));

D2: DECODE1_INT port map (CLB_INT(0), DECODE(3));

D3: DECODE1_INT port map (CLB_INT(1), DECODE(3));

D4: DECODE1_INT port map (CLB_INT(2), DECODE(3));

D5: DECODE1_INT port map (CLB_INV(3), DECODE(3));

D6: PULLUP port map (DECODE(3));

-----CLKEN is the AND function of CS & DECODE--------

CLKEN(0) <= CS and DECODE(0);
CLKEN(1) <= CS and DECODE(1);
CLKEN(2) <= CS and DECODE(2);
CLKEN(3) <= CS and DECODE(3);

--------Internal 4-bit counter --------------
process (CLOCK)
begin
if (CLOCK'event and CLOCK='1') then
CLB_INT <= CLB_INT + 1;
end if;
end process;

-------"QOUT(0)" Data Register Enabled by "CLKEN(0)"-----
process (CLOCK)
begin
if (CLOCK'event and CLOCK='1') then
if (CLKEN(0) = '1') then
QOUT(0) <= DATA(0);
end if;
end if;
end process;

-------"QOUT(1)" Data Register Enabled by "CLKEN(1)"-----
process (CLOCK)
begin
if (CLOCK'event and CLOCK='1') then
if (CLKEN(1) = '1') then
QOUT(1) <= DATA(1);
end if;
end if;
end process;

-------"QOUT(2)" Data Register Enabled by "CLKEN(2)"-----
process (CLOCK)
begin
if (CLOCK'event and CLOCK='1') then
if (CLKEN(2) = '1') then
QOUT(2) <= DATA(2);
end if;
end if;
end process;

-------"QOUT(3)" Data Register Enabled by "CLKEN(3)"-----
process (CLOCK)
begin
if (CLOCK'event and CLOCK='1') then
if (CLKEN(3) = '1') then
QOUT(3) <= DATA(3);
end if;
end if;
end process;

end STRUCTURE;


Figure 4.6 Schematic Block Representation of I/O Decoder

Note: In the previous figure, the pull-up resistors are inside the Decoder blocks.