General Description: I am using a bus of flip-flops that must be placed in the IOBs of a device. The outputs of these FFs should placed into 3-state conditions, and the enable signal of the 3-state buffer should be registered.
If one bus is used for the registered enable-signal, all but one of the enable-FFs are optimized out. As the output-load of the last FF is now not 1, it cannot be put into the IOBs. What can I do about this?
Solution
The solution is not to create a bus of FFs for the enable signal, but rather to create one flip-flop and place the IOB attribute on it. Then, activate the switch to put the registers/latches into the IOBs in the synthesis properties -- this will duplicate the single FF and put it into the IOBs.
To enable the synthesis properties to automatically push flip-flops into the IOB (this is the default behavior):
1. Highlight the Synthesize process. 2. Right-click on the Synthesize process and select "Properties". 3. Select the Xilinx-Specific Options tab. 4. Change the "Pack I/O Registers into IOBs" field to either "Auto" (the default setting) or "Yes".
The following code illustrates an 8-bit-wide bus for which the outputs are put into 3-state conditions by registers.
NOTE: The enable line of the 3-state buffer should be active Low.
VHDL:
library ieee; use ieee.std_logic_1164.all;
entity tri_iob is port(CLK, SEL : in std_logic; DI : in std_logic_vector (7 downto 0); DO : out std_logic_vector (7 downto 0)); end tri_iob;
architecture arch_tri_iob of tri_iob is signal tmp1: std_logic_vector(7 downto 0); signal tmp2: std_logic; signal inp_ffs: std_logic_vector(7 downto 0);
attribute IOB : string; attribute IOB of tmp2 : signal is "true";
begin process (CLK) begin if (CLK'event and CLK='1') then inp_ffs<=DI; tmp1<=inp_ffs; end if; end process;
process (CLK) begin if (CLK'event and CLK='1') then tmp2<=SEL; end if; end process;
DO <= tmp1 when tmp2='0' else (others=>'Z');
end arch_tri_iob;
Verilog:
module tri_iob (clk, sel, di, do);
input clk, sel; input [7:0] di; output [7:0] do;
reg [7:0] tmp1, inp_ffs; reg tmp2;
//synthesis attribute IOB tmp2 "true"
always @(posedge clk) begin inp_ffs <= di; tmp1 <= inp_ffs; end