Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17241 Discussions

Problems with bidirectional signals in VHDL Testbench for ModelSim

Altera_Forum
Honored Contributor II
6,994 Views

Hi all, 

 

I was just wondering if there is a simple way of implimenting bidirectional signals in a VHDL testbench I'm using ModelSim - Altera Starter Edition 6.5e and am very new to Quartus II, VHDL and FPGAs but feel I am making some progress slowly. 

 

I have some bidirectional signals in my design, and in my testbench want to be able to put some inputs/stimuli into these, but also be able to see the outputs in the generated "wave" signal plot, as at the moment the values seem fine when acting as inputs but just give an X when they should be outputs as they are being assigned by both the test bench and my design but in different directions. 

 

Any help is much appreciated even if its just a link to a clear explanation or example... I'm trying to look into it now, but so far haven't found anything that clear or a nice example... 

 

Cheers
0 Kudos
18 Replies
Altera_Forum
Honored Contributor II
5,089 Views

Usually designers use bidirectional signals on pins and not internally. 

 

input state: Your testbench should drive these pins when they are inputs to your DUT. Here your DUT can read them but should apply tristate(Z) i.e.cutoff logic. 

 

output state: 

Your DUT should drive them when they are outputs. testbench can read them. 

 

The io blocks have tristate buffer that is switched off if Z applied. Internally no such buffer exists but can be emulated in logic but as mentioned, there is no need to use them internally.
0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

Hi, 

Are you sure about your "bidirectional" design ? Have you wrote the 'z' for the case where your bidir is in inuput mode ? 

'x' means forcing unkown : it is 0 or 1 but it often means that there is conflict. Your bidir is in ouput mode and your stimuli force this signal at the same time. (not verified myself, i may be wrong) 

 

in quartus, you have templates available in menu when you edit vhdl. 

In literature section on altera website, you will find example. 

 

You have to check both your design and your testbench. 

Keep in mind that VHDL is just a description langage (not a program). 

 

Could you post your design and testbench ?
0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

TO_BE_DONE

0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

you need to drive "ZZZZZZZZ" onto AD and AC when you expect signals to come out of the DUT. 

 

Bidirectional signals are otherwise best avoided.
0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

 

--- Quote Start ---  

you need to drive "ZZZZZZZZ" onto AD and AC when you expect signals to come out of the DUT. 

 

Bidirectional signals are otherwise best avoided. 

--- Quote End ---  

 

 

Ah I knew I had to do something like this but was just trying to drive AD to 'Z' rather than "ZZZZZZZZ"... 

 

Cheers, I'll give this a try...
0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

Hmm... Still having a few problems with this... as I said I am very new to VHDL. 

 

I can't avoid using the bidirectional signals/pins, as this is for the 245 Communication Interface between the Cyclone II and the FTDI FT2232H USB Bridge chip on the board. I am only trying to establish simple communications over USB and for now just echo back recieved characters.  

 

This means to test my design I want my test bench to be able to input data into the AD[0..7] pins, then processed this data (in my design I am just trying to invert each bit of the byte for now) and then when its clear to transmit change AD[0..7] to outputs to output the data back to the FTDI chip (which puts the data into a transmit FIFO buffer to be send over USB.) 

 

The output enable shown below "N_OE" is the output enable for the FTDI chip and so is used when reading from the FTDI chip, i.e. using AD[0..7] as inputs. 

 

At the moment my values of AD[0..7] are now just appearing as either Z or X but not with any values on... The ammended code for my test bench is included... 

 

Cheers 

 

-- *************************************************************************** -- This file contains a Vhdl test bench template that is freely editable to -- suit user's needs .Comments are provided in each section to help the user -- fill out necessary details. -- *************************************************************************** -- Generated on "10/13/2010 16:36:17" -- Vhdl Test Bench template for design : Morph_USB_LOOPBACK -- -- Simulation tool : ModelSim-Altera (VHDL) -- LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY Morph_USB_LOOPBACK_vhd_tst IS END Morph_USB_LOOPBACK_vhd_tst; ARCHITECTURE Morph_USB_LOOPBACK_arch OF Morph_USB_LOOPBACK_vhd_tst IS -- constants -- signals SIGNAL testdata : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL AC : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL AD : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL clkout : STD_LOGIC; SIGNAL N_OE : STD_LOGIC; SIGNAL rst : STD_LOGIC; SIGNAL siwua : STD_LOGIC; COMPONENT Morph_USB_LOOPBACK PORT ( AC : INOUT STD_LOGIC_VECTOR(3 DOWNTO 0); AD : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0); clkout : IN STD_LOGIC; N_OE : OUT STD_LOGIC; rst : IN STD_LOGIC; siwua : OUT STD_LOGIC ); END COMPONENT; BEGIN i1 : Morph_USB_LOOPBACK PORT MAP ( -- list connections between master ports and signals AC => AC, AD => AD, clkout => clkout, N_OE => N_OE, rst => rst, siwua => siwua ); init : PROCESS -- variable declarations BEGIN if (N_OE = '0') then AD <= testdata; else AD <= "ZZZZZZZZ"; end if; testdata <= "00000000", "10101010" after 166.6 NS, "11110000" after 499.8 NS; AC(0) <= '1', '0' after 183.2 NS,'1' after 266.2 NS, '0' after 582.8 NS, '1' after 665.8 NS; AC(1) <= '0', '0' after 333.2 NS, '1' after 499.8 NS, '1' after 582.8 NS; rst <= '0'; WAIT; END PROCESS init; always : PROCESS -- optional sensitivity list -- ( ) -- variable declarations BEGIN -- code executes for every event on sensitivity list WAIT; END PROCESS always; END Morph_USB_LOOPBACK_arch;
0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

you process only runs once and then does nothing, so it is not changing during simulation. to fix it you need to do the following: 

1. make the process sensive to "N_OE".  

2. Delete the wait at the end of the process (you dont want any waits inside the process) 

3. put the testdata assignment outside of the process. 

 

This should make it work.
0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

Brilliant...thanks very much. 

 

There are still problems with the actual design, but at least now I can see the simulation and should be able to attempt to work out what they are and tackle them... 

 

Once again, Cheers! :)
0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

Just as a side note to tidy up the code: you could replace that process with: 

 

AD <= testdata when N_OE = '0' else (others => 'Z');
0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

Hello and Hi..Ia m Engineering student and working on VHDL for my Final Year Project..i have a problem in bidirectional data transfering...kindly help me to sort out the problem.... 

the problem is that i instantiate components in a top module and port map them in one direction.if want to port map them in second direction in same top module.....
0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

Why not post the code and the errors.

0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

this is the overview of my program.....the problem is in port maping .if i maped port in clockwise direction then what can i do for counter clock wise portmaping.?

0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

THis would be a single entity, you wouldnt need any port mapping. 

Post the code and the errors and we can help.
0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

if (sel= 0) then 

ch0: noc 

PORT MAP( 

clk => clk,  

reset => reset, 

data_in => mDch_buffer0, 

parity_in =>mPch_buffer0,  

bflag_in => mch0_busy,  

--bflag_out : out std_logic; 

parity_out => mP_buffer1, ---line 950  

data_out =>mD_buffer1 ); 

elsif (sel= 1) then---- line 952 

PORT MAP( 

clk => clk,  

reset => reset, 

data_in => mDch_buffer1, 

parity_in =>mPch_buffer1,  

bflag_in => mch0_busy,  

--bflag_out : out std_logic; 

parity_out => mP_buffer0,  

data_out =>mD_buffer0 ); 

end if; 

** Error: C:/Modeltech_5.7g/examples/nov5.vhd(950): near ";": expecting: ')' 

** Error: C:/Modeltech_5.7g/examples/nov5.vhd(952): near "then": expecting: <= :=
0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

you cannot put an instantiation inside a process.

0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

 

--- Quote Start ---  

if (sel= 0) then 

ch0: noc 

PORT MAP( 

clk => clk,  

reset => reset, 

data_in => mDch_buffer0, 

parity_in =>mPch_buffer0,  

bflag_in => mch0_busy,  

--bflag_out : out std_logic; 

parity_out => mP_buffer1, ---line 950  

data_out =>mD_buffer1 ); 

elsif (sel= 1) then---- line 952 

PORT MAP( 

clk => clk,  

reset => reset, 

data_in => mDch_buffer1, 

parity_in =>mPch_buffer1,  

bflag_in => mch0_busy,  

--bflag_out : out std_logic; 

parity_out => mP_buffer0,  

data_out =>mD_buffer0 ); 

end if; 

** Error: C:/Modeltech_5.7g/examples/nov5.vhd(950): near ";": expecting: ')' 

** Error: C:/Modeltech_5.7g/examples/nov5.vhd(952): near "then": expecting: <= := 

--- Quote End ---  

 

 

what you need in this case is one port map but then connect signals in the logic. e.g 

 

port map ... data_in => data_in, data_out => data_out, ... then in your logic: if sel = '0' then data_in <= mDch_buffer0; mD_buffer1 <= data_out; else data_in <= mDch_buffer1; mD_buffer0 <= data_out; end if;
0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

i started t resolve my solution from base . 

this is the simple counter program of my project . 

 

library ieee ; 

use ieee.std_logic_1164.all; 

use ieee.std_logic_unsigned.all; 

 

entity counter is  

port( clk: in std_logic; 

reset: in std_logic; 

load: in std_logic; 

data: in std_logic_vector(3 downto 0); 

busy : out std_logic; 

dcount: out std_logic_vector(3 downto 0); 

count: out std_logic_vector(3 downto 0) 

); 

end counter; 

 

architecture behav of counter is  

signal pre_count: std_logic_vector(3 downto 0); 

signal dec: std_logic_vector(3 downto 0); 

begin 

process(clk,reset) 

begin 

if reset = '1' then 

pre_count <= "0000"; 

busy<='0';  

elsif (clk='1' and clk'event) then 

if load = '1' then 

dec<=data; 

busy<='1'; 

 

elsif dec >0 then  

dec<=dec-'1'; 

pre_count <= pre_count + "1"; 

elsif dec= 0 then 

busy<='0'; 

 

end if; 

end if; 

end process; 

dcount <=dec;  

count <= pre_count; 

end behav; 

 

library ieee ; 

use ieee.std_logic_1164.all; 

use ieee.std_logic_unsigned.all; 

use ieee.std_logic_textio.all; 

use std.textio.all;  

 

entity counter_tb is 

end; 

 

architecture counter_tb of counter_tb is 

 

COMPONENT counter 

PORT ( clk: in std_logic; 

reset: in std_logic; 

load: in std_logic; 

data: in std_logic_vector(3 downto 0); 

busy : out std_logic; 

dcount: out std_logic_vector(3 downto 0); 

count: out std_logic_vector(3 downto 0) ); 

END COMPONENT ; 

 

SIGNAL clk : std_logic := '0'; 

SIGNAL reset : std_logic := '0'; 

SIGNAL load,cheko : std_logic := '0'; 

Signal data: std_logic_vector(3 downto 0):="1010" ; 

SIGNAL busy : std_logic; 

SIGNAL count : std_logic_vector(3 downto 0); 

signal dcount: std_logic_vector(3 downto 0); 

 

begin 

 

dut : counter  

PORT MAP ( 

count => count, 

clk => clk, 

load=> load, 

busy=> busy, 

data=> data, 

dcount =>dcount, 

reset => reset ); 

 

chekoo : PROCESS 

begin 

if ( busy ='1') then 

cheko <='1'; 

elsif ( busy ='0') then  

cheko <='0'; 

else 

cheko <='0'; 

end if; 

end process chekoo;  

 

clock : PROCESS 

begin 

wait for 1 ns; clk <= not clk; 

end PROCESS clock; 

 

stimulus : PROCESS 

begin 

load <= '0'; 

wait for 5 ns; reset <= '1'; 

wait for 4 ns; reset <= '0'; 

wait for 4 ns; load <= '1'; 

wait for 2 ns; load <= '0'; 

wait; 

end PROCESS stimulus; 

 

end counter_tb; 

 

WARNING[2]: C:/Modeltech_5.7g/examples/nov5.vhd(93): Possible infinite loop: process has no wait statement.
0 Kudos
Altera_Forum
Honored Contributor II
5,089 Views

All processes must have either a wait statement or a sensitivity list, otherwise they will loop forever in 0 time. You chekkoo process probably needs a sensitivity list with bust in it.

0 Kudos
Reply