INOUT std_logic problem in ModelSim

G

GDan

Hi,

I've run through some tutorials on VHDL. Just playing with ModelSim
and decided to start using INOUT for some bi-directional logic. All of
the examples so far use either IN or OUT. The trouble I'm having is
that even when I assign a value to the signal in a test bench, all I
get on the waveform is 'U' state.

So something like...

test : INOUT std_logic

testasclk: PROCESS
BEGIN
CLOCK_LOOP : LOOP
test <= '0';
WAIT FOR 100 ns;
test <= '1';
WAIT FOR 100 ns;
END LOOP CLOCK_LOOP;
END PROCESS;

In this case I know I only using it as an output but it's one example
that generates the trouble I'm having.

Thanks

GD
 
G

GDan

Mike,

Thanks. However I don't understand why ModelSim displays 'U' even when
I single step the program and can see the assign statements get
executed?

GD
 
R

Ralf Hildebrandt

GDan wrote:

I've run through some tutorials on VHDL. Just playing with ModelSim
and decided to start using INOUT for some bi-directional logic. All of
the examples so far use either IN or OUT.

The do it for a good reason ;-) as Mike has already told you Its
uncommon to have bidirectional wires inside circuits.

The trouble I'm having is
that even when I assign a value to the signal in a test bench, all I
get on the waveform is 'U' state. ....
In this case I know I only using it as an output but it's one example
that generates the trouble I'm having.

Thats a simulation problem: Inside your component you drive some value
to your bidirectional signal but I guess you don't have any value (not
even 'Z') driven outside the component to this wire. (You say, that you
use it just as an output.) Therefore this wire has outside its initial
state, which is 'U'. And because 'U' is stronger than '1' or '0' this
'U' from outside propagates into your component.

Note that you should drive this wire in every component in which it is
located (including the testbench).

Ralf
 
R

radarman

Mike said:
For internal fpga logic description, IN and OUT
is all you will ever need.

An INOUT port is only needed to describe tri-state
device pins. Here is an example testbench.

http://home.comcast.net/~mike_treseler/oe_demo.vhd

-- Mike Treseler

Not always true. Older FPGA families did allow for true internal
tri-state busses, and that could be used to collapse a lot of logic.

The Xilinx 4010e design I just re-engineered was a good example. That
part couldn't have supported VME readback had it not been for the
internal tri-state busses. Since it did support it, I went ahead and
used all of the internal tri-state nets to collapse other things as
well. You can save some serious area by replacing a mux with a set of
tri-state buffers.

I just checked, and the Flex10k parts supported an emulated tri-state
bus as well. Later Altera & Xilinx families did away with any semblance
of internal tri-state nets, and use muxes in logic instead.

BTW - you can still define them for modern parts that don't natively
support internal tri-state nets, but the tools will automatically
convert them into muxes. Usually, this is not as optimal as it could
be, so I don't write tri-state code for internal logic on FPGA families
that don't natively support it.

-Seth
 
G

GDan

Ralf said:
GDan wrote:



The do it for a good reason ;-) as Mike has already told you Its
uncommon to have bidirectional wires inside circuits.



Thats a simulation problem: Inside your component you drive some value
to your bidirectional signal but I guess you don't have any value (not
even 'Z') driven outside the component to this wire. (You say, that you
use it just as an output.) Therefore this wire has outside its initial
state, which is 'U'. And because 'U' is stronger than '1' or '0' this
'U' from outside propagates into your component.

As 'U' is the left most state and if it really is the strongest - how
can I ever set the wire to anything else?
Note that you should drive this wire in every component in which it is
located (including the testbench).

I see sort of what you mean. I've justed googled and maybe it's my
understanding of how the INOUT type should function with assign
statements. I'm reading about concurrent signal assignment at present
and think this is the issue.

Speaking from a micro controller point of view as a programmer I would
have to set a port bit to input and then have another driver actually
driving the input to say get a low or high sample.

So do I have to model this in VHDL where one process sets the line to
say a High Impedance 'Z' from it's default left most state of 'U' and
then another process say changing it's state from '0' and '1' if it
were a bidirectional data line and the data was say a simply clock for
arguments sake.

process
begin
test <= 'Z';
end process;

-- process which is now driving?
process
begin
test <= '1';
end process;

I've built a simple switch out of 74hc573's and want to design this in
a CPLD. I thought I'd start by creating a 1bit version of the switch
and expand up. When googling I found mention of a Resolve(...)
function for a simlar purpose but it's not completely clear why.

GD
 
M

Mike Treseler

radarman said:
Not always true. Older FPGA families did allow for true internal
tri-state busses, and that could be used to collapse a lot of logic.

Yes, but true enough for new designs by a new designer.

-- Mike Treseler
 
R

Ralf Hildebrandt

radarman wrote:

Not always true. Older FPGA families did allow for true internal
tri-state busses, and that could be used to collapse a lot of logic.

The Xilinx 4010e design I just re-engineered was a good example. That
part couldn't have supported VME readback had it not been for the
internal tri-state busses. Since it did support it, I went ahead and
used all of the internal tri-state nets to collapse other things as
well. You can save some serious area by replacing a mux with a set of
tri-state buffers.

Well ... it heavily depends on the target which type of mux will be
better: a tri-state-mux or an OR-gate-mux (resp. AND-gate).


In a in-house 0,5um standard cell library, that I have used for
comparisons the tri-state mux can be the fastest (but is only a little
bit faster) but is always bigger and consumes a lot more energy than the
OR-/AND-mux.

To clarify: An OR- or AND-mux is a multiplexer, that collects several
signals of several components. Every component drives '0' for its
signals for the OR-mux resp. '1' for the AND-mux, if this component was
not selected.

Let me add: Even a classic global mux, that just selects one out several
signals was better in terms of area and power consumption than the
tri-state mux for this target library.


For another library (Xfab xc06, 0.6um) the results are simular for area
and speed. (I don't have simulation results for energy.)



Tri-state muxes seems to be nice to just connect another component to a
big bus without modification at another component. So it seems, that a
tri-state mux is scalable. But this is _not_ true. As bigger the bus
becomes the higher the capacitive load will be. Then synthesis tools
will insert stronger tri-state drivers. But usually one does not have
"infinitely" strong tri-state drivers. (Its is usual to have a normal
and a stronger cell - nothing more.) Therefore the tri-state bus may
become too big for the drivers and a synthesis tool will not find a
solution. For classic muxes it is easy to just insert a buffer which
costs some area and speed, but makes the mux mux more scalable than the
tri-state mux.


So be careful: Tri-state muxes seem to be elegant, but this might be a
pitfall, because it does not hold for all target libraries.

Ralf
 
R

Ralf Hildebrandt

GDan wrote:

As 'U' is the left most state and if it really is the strongest - how
can I ever set the wire to anything else?

Just rive 'Z' from your testbench to that wire.

Speaking from a micro controller point of view as a programmer I would
have to set a port bit to input and then have another driver actually
driving the input to say get a low or high sample.

What you do with this action is switching a bidirectional in/out pad
from one direction to another. How does this work? Setting output
direction just means activating a driver, that drives the value from
inside to outside while input direction means setting this driver to
tri-state. Ok, that was for the output signal - the input signal is even
simpler: you just read the value at the pad.

inp_______
|
|\ |
outp__| \_|__pad
| /
|/o
|
dir_____|

As you can see: internally there are two signals: inp and outp (plus a
direction selector). Only the signal pad is a true bidirectional INOUT
signal.

So do I have to model this in VHDL where one process sets the line to
say a High Impedance 'Z' from it's default left most state of 'U' and
then another process say changing it's state from '0' and '1' if it
were a bidirectional data line and the data was say a simply clock for
arguments sake.

process
begin
test <= 'Z';
end process;

You can just write:
test <= 'Z'; -- not inside a process - its the same

-- process which is now driving?
process
begin
test <= '1';
end process;

Both processes "drive". The value '1' wins, because it is stronger.

I've built a simple switch out of 74hc573's and want to design this in
a CPLD. I thought I'd start by creating a 1bit version of the switch
and expand up.

Does your CPLD have pads like I have "pictured"? If yes, use them!

When googling I found mention of a Resolve(...)
function for a simlar purpose but it's not completely clear why.

If more than one driver drives a signal to a wire, the VHDL simulator
has to determine the resulting value. If you use std_logic(_vector) for
signals with more than one driver this determination is done by it's
resolve-function. How does it work? The resolution function builds a
vector with the width being equal to the number of drivers to a wire.
Every driver "gets a bit" inside this vector. If one of these drivers
changes, the function is checking the value of all drivers (a for-loop
over the vector) and computes the resulting value.

You don't have to care, how the resolution function works. It just
determines the resulting value of a wire, that is driven by more than
one driver. Every process or concurrent signal assignment is one driver.




Let me add: It is always helpful to use std_Ulogic(_vector) for signals
with only one driver, because this signal type does not have a
resolution function and therefore multiple drivers are an error. It is a
nice check, if one did a mistake and you save simulation computing time.

Ralf
 
R

radarman

Mike said:
Yes, but true enough for new designs by a new designer.

-- Mike Treseler

Not to harp, but this is only true for a new designer doing *new*
designs. If that new designer happens to work for a defense contractor,
the odds are heavily tilted away from that scenario.

Unfortunately, we get the same attitude from the tool vendors as well.
We complain about bugs in the tools, and their response is "You're
using a what?"

I've been with my current employer for 5 years, and I have worked on
designs using XC4010E's, Virtex (no suffix), Flex 10K, Apex 20k, a
rad-hard Lattice part (don't remember the part number) and PAL 22V10's
- all on production designs that are STILL SHIPPING. I can do one
better. We have new programs, that haven't shipped, yet using Altera
20k200's and 20k300's right now. (admittedly, these don't support true
internal tri-states, but they are getting old)

The only design I have done on a "modern" part is a little IR&D job,
where we are using a Virtex 4.

So, while it may generally hold true that you don't need to understand
some of this cruft, sometimes it can be helpful. You might never know
when you will have to support an existing design that has one of those
old devices on it.
 
Joined
Jun 29, 2006
Messages
1
Reaction score
0
got the same problem

I'm kind of new to VHDL. I'm trying to resolve the simulation problem with the bidirectional data bus (IP_Data). I wrote the code below but got wrong simulation results including "U" with ModelSim! Can you notice anything wrong below? Hope to get it resolved quickly! Violet

ENTITY IP_Data_Module IS
PORT(
Read_IP_Data : IN IP_Data_Type; -- 16 bits data read from FPGA
nWrite_Data : IN std_logic;
nFPGA_Reset : IN std_logic;
Write_IP_Data : OUT IP_Data_Type; -- 16 bits data written into FPGA
IP_Data : INOUT IP_Data_Type -- 16 bits data bus betw. FPGA & IP bus
);
END IP_Data_Module ;

ARCHITECTURE arch OF IP_Data_Module IS

BEGIN

Write_Read_Process: PROCESS (nWrite_Data) IS

BEGIN

IF nFPGA_Reset = '0' THEN -- nFPGA_Reset is active low

Write_IP_Data <= (others => 'Z'); -- all outputs are reset to 'Z'
IP_Data <= (others => 'Z');

ELSIF nFPGA_Reset = '1' THEN

IF nWrite_Data = '1' THEN -- nWrite_Data high means Read
IP_Data <= Read_IP_Data; -- IP_Data is to be read from FPGA
ELSIF nWrite_Data = '0' THEN -- nWrite_Data low means Write
Write_IP_Data <= IP_Data; -- Write_IP_Data is to be written into FPGA
END IF;

END IF;

END PROCESS Write_Read_Process;
END ARCHITECTURE arch;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top