Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20638 Discussions

Can I safely ignore warning that output pin cannot be tristated?

Altera_Forum
Honored Contributor II
2,632 Views

Dear all, 

I have the following code for driving the output and input of my design: 

 

Fout_DATA <= DATA; Fout_BE <= BE; Fout_RXF <= RXF; Fout_TXE <= TXE; WR <= Fin_WR; DATA(31 downto 16) <= int_DATA(31 downto 16) when (BE_out_en = '0') else "ZZZZZZZZZZZZZZZZ" when (BE_out_en = '1') else (others => '0'); DATA(15 downto 8) <= int_DATA(15 downto 8) when (DATA_out_en = '0') else "ZZZZZZZZ" when (DATA_out_en = '1') else (others => '0'); DATA(7 downto 0) <= int_DATA(7 downto 0) when (BE_out_en = '0') else "ZZZZZZZZ" when (BE_out_en = '1') else (others => '0');  

 

DATA is INOUT with STD_LOGIC_VECTOR(31 downto 0) going to an external 32 bit interface. Fout_DATA collects what is on the DATA bus from the outside and puts it to FPGA internal digital design. However I seem to get the following warnings for all DATA 

[*]: 

 

Warning (14632): Output pin "pre_syn.bp.io_control_inst1_Fout_DATA_0_" driven by bidirectional pin "DATA" cannot be tri-stated Warning (14632): Output pin "pre_syn.bp.io_control_inst1_Fout_DATA_1_" driven by bidirectional pin "DATA" cannot be tri-stated Warning (14632): Output pin "pre_syn.bp.io_control_inst1_Fout_DATA_2_" driven by bidirectional pin "DATA" cannot be tri-stated Warning (14632): Output pin "pre_syn.bp.io_control_inst1_Fout_DATA_3_" driven by bidirectional pin "DATA" cannot be tri-stated and so on...  

 

And in my desing when there is an idle time on the bus the external chip should drive the DATA[31:16] and DATA[7:0] to zero, but Signal Tap says that DATA[31:16] and DATA[7:0] are FFFFFF... 

Can you give me a hint what is the problem in the design? FPGA is Cyclone V using Terasic Cyclone V GX starter board. 

 

Thank you.
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
992 Views

Its probably because you have fout_data and data being the same signal. 

INOUTs should only connect directly the to top level, you appear to have it connected to part of your design and the pin? 

 

Another point - you have DATA connected to (others => '0') when BE_out_en is not '0' or '1'. If this is a trap for simulation faults, it is much safer if you connect it to (others => 'X').
0 Kudos
Altera_Forum
Honored Contributor II
992 Views

Hi, 

 

The issue here is that you are driving a tri-stated signal to a normal IO pin. When the Bidir/Tri signal DATA is tristated ('Z'), the Fout_Data (normal IO) driver can't drive that onto the pin since it is not declared as Tri/Bidir. This kind of logic should ideally not be done in tri/bidir designs as you will loose the Tristate/Bidir functionality of the signal being driven.
0 Kudos
Altera_Forum
Honored Contributor II
992 Views

Dear Tricky and eapenabrm, 

thank you for your answers.  

Above mentioned code is not in the top module but in an underlying module IO_control. The module IO_control is getting the signals directly from the top module. 

The top module entity is this: 

 

entity mainboard_top is port ( RESET_F : IN STD_LOGIC; RESET_H : IN STD_LOGIC; CLOCK_50_B5B : IN STD_LOGIC; CLOCK_50_B6A : IN STD_LOGIC; GPIO : INOUT STD_LOGIC_VECTOR(36 downto 0); SW : IN STD_LOGIC_VECTOR(9 downto 0); LEDG : OUT STD_LOGIC_VECTOR(7 downto 0); LEDR : OUT STD_LOGIC_VECTOR(9 downto 0); KEY : IN STD_LOGIC_VECTOR(4 downto 0); -- Master interface CLK : IN STD_LOGIC; DATA : INOUT STD_LOGIC_VECTOR(31 downto 0); BE : INOUT STD_LOGIC_VECTOR(3 downto 0); RXF_N : IN STD_LOGIC; TXE_N : IN STD_LOGIC; WR_N : OUT STD_LOGIC; SIWU_N : OUT STD_LOGIC; RD_N : OUT STD_LOGIC; OE_N : OUT STD_LOGIC); end entity mainboard_top;  

 

The IO_control module directly connects to the DATA INOUT (the red one) of the top module (and also for the byte_enabled port, the green one): 

I do not have additional signals between IO_control outputs and in/outputs of top module but I rather attached the pins directly. Is this critical? 

 

architecture behaviour of mainboard_top is ... begin ... io_control_inst1 : io_control port map ( CLK => CLK, RESET => RESET_F, DATA => DATA, BE => BE, ...  

 

 

and the IO_control code is: 

 

LIBRARY IEEE; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity io_control is port ( CLK : IN STD_LOGIC; RESET : IN STD_LOGIC; DATA : INOUT STD_LOGIC_VECTOR(31 downto 0); BE : INOUT STD_LOGIC_VECTOR(3 downto 0); TXE : INOUT STD_LOGIC; RXF : INOUT STD_LOGIC; WR : OUT STD_LOGIC; Fin_DATA_ram : IN STD_LOGIC_VECTOR(31 downto 0); Fin_DATA_ep : IN STD_LOGIC_VECTOR(3 downto 0); Fin_BE : IN STD_LOGIC_VECTOR(3 downto 0); DATA_out_en : in STD_LOGIC; BE_out_en : in STD_LOGIC; send_command : in STD_LOGIC; Fin_WR : in STD_LOGIC; Fout_DATA : out STD_LOGIC_VECTOR(31 downto 0); Fout_BE : out STD_LOGIC_VECTOR(3 downto 0); Fout_RXF : out STD_LOGIC; Fout_TXE : out STD_LOGIC); end entity io_control; architecture behaviour of io_control is SIGNAL int_DATA : STD_LOGIC_VECTOR(31 downto 0); SIGNAL command : STD_LOGIC_VECTOR(31 downto 0); begin Fout_DATA <= DATA; Fout_BE <= BE; Fout_RXF <= RXF; Fout_TXE <= TXE; WR <= Fin_WR; DATA(31 downto 16) <= int_DATA(31 downto 16) when (BE_out_en = '0') else "ZZZZZZZZZZZZZZZZ" when (BE_out_en = '1') else (others => 'X'); DATA(15 downto 8) <= int_DATA(15 downto 8) when (DATA_out_en = '0') else "ZZZZZZZZ" when (DATA_out_en = '1') else (others => 'X'); DATA(7 downto 0) <= int_DATA(7 downto 0) when (BE_out_en = '0') else "ZZZZZZZZ" when (BE_out_en = '1') else (others => 'X'); BE <= Fin_BE when (BE_out_en = '0') else "ZZZZ" when (BE_out_en = '1') else (others => 'X'); command <= ("000000000000000000000000" & "0000" & Fin_DATA_ep); data_mux : process(CLK, RESET) begin if (RESET = '0') then int_DATA <= (others => '1'); elsif (rising_edge(CLK)) then if (send_command = '1') then int_DATA <= command; elsif (send_command = '0') then int_DATA <= Fin_DATA_ram; end if; end if; end process data_mux; end architecture behaviour; 

 

You see that I changed the (others => '0') to (others => 'X'). Fout_DATA is an output of the IO_Control, how should Fout_DATA drive the DATA bus of IO_control? I see no reason since it is clearly an output?! I do not see another possibility to read the signals from the DATA bus. Or should I rather put all this in a process and make a complex IF-query? 

Should I rather implement this in the top module? I do not understand why this is critical. VHDL Modules are for user friendliness and in my understanding do not determine where fitter is placing the IOCELLS, BUFS, MUXes etc etc.? 

Again thank you for your help!
0 Kudos
Altera_Forum
Honored Contributor II
992 Views

As long as the tri-state is the only thing that ultimately connects to the IO pin, it doesnt matter where in the hierarchy it is.  

And for fout_Data, you have done the right thing. You should be able to read it when be_out_en is '0'.
0 Kudos
Altera_Forum
Honored Contributor II
992 Views

 

--- Quote Start ---  

As long as the tri-state is the only thing that ultimately connects to the IO pin, it doesnt matter where in the hierarchy it is.  

And for fout_Data, you have done the right thing. You should be able to read it when be_out_en is '0'. 

--- Quote End ---  

 

 

Yes, it is working now. Thank you. 

Kind regards.
0 Kudos
Reply