ec said:
Hi all
I am not sure when to define inputs and outputs in the
entity as STD_LOGIC and when as STD_ULOGIC
If you have (or could have) multiple drivers of a signal you must use
std_logic. If there is only one driver for a signal you can use either
std_logic or std_ulogic. More on this at the end.
The same question applies about siganls
declared in the architecture .
Same as above.
what is the "rule" for this ?
When a signal has only one driver, there is no 'rule' just a few guidlines.
- First off, in general, most signals have only one driver, they are not
tri-statable so they have no reason to be of type std_logic.
- If you use std_ulogic types and you inadvertantly have two statements or
processes driving the same signal then this error will get caught
immediately when you compile the file for simulation. The compiler will
also generally point you to the lines of code that are driving the same
signal and you have immediate and accurate feedback of where you have a
problem.
- If you use std_logic types and you inadvertantly have two statements or
processes driving the same signal then this error won't be caught until
you....
- Debug down to the cause using a simulator
- Run the tool through synthesis where the fitter will complain about
multiple drivers for a signal.
For the reasons mentioned above it is generally desirable to use std_ulogic
as your first choice and std_logic for signals that really are tri-statable
and potentially driven by multiple sources (like a bi-directional data bus
for instance).
One of the downsides to this though is, when interfacing to other people's
code, the standard practice is to use std_logic type (at least for the
outermost exposed entity) whether it needs it or not. If you connect up
your std_ulogic_vector types to their std_logic_vector you will have to
perform a type conversion (i.e. Their_slv_signal <=
std_logic_vector(My_sulv_signal). Note: This is only for vectors, not for
the basic std_ulogic/std_logic discrete signals.
The pragmatic approach is to make your 'top level' entity have only
std_logic types, and from there on down use std_ulogic where appropriate.
This will force you to put any required type conversions inside the
architecture of your own code so that you're not burdening the user of your
code with this operation.
This brings up the question of what is the 'top level'? If you think of a
design as consisting of a bunch of nested entities one could say that each
lower level entity is a 'top level' of something and by that reasoning the
interface to those should follow the standard practice of using std_logic.
If you do that then, you'll never end up using std_ulogic so you'll never
gain the benefit of having the compiler catch those inadvertant multiple
drivers so you'll spend time debugging down to each one over the entire
course of your career that you write code. If that's how you choose to
spend your time that's up to you.
In order to gain the benefit of the compiler catching things and still write
code per industry practice you simply make the pragmatic decision about what
really is the 'top level' in your design and if someone wants to use your
lower level entities (the ones where you use std_ulogic) than it's up to
them to interface to your std_ulogic interface.
Again, the only time type conversions come into play that create any sort of
nuisance, is when you have a vector (std_logic_vector/std_ulogic_vector);
the base types themselves cause no interfacing issues at all.
Hope this helps.
KJ
KJ