Bit vs. std_logic for description of internal structures

M

Maciej Sobczak

Guest
Hi,

I have found a coding guideline that recommends to use std_logic everywhere in preference to bit, on the basis that it can represent more states (X, Z, etc.).
What I found surprising is the implicit assumption that more states is an added value. I understand that on the module boundary the additional states can be useful, as they can model (or even enable) wider interfacing options.. But for modeling (and ultimately synthesis) of internal logic, I see no particular benefit - on the contrary, I can imagine that it might be beneficial to restrict the number of possible states as much as possible and in fact, elsewhere designers are encouraged to always use (or define) the narrowest type that covers the given context. Additional and unused states are also problematic with language constructs like the case statement, which expect complete coverage and code fragments like this:

case my_std_logic_value is
when '0' => ...
when '1' => ...
when others =>
assert false;
end case;

obviously miss the point.

So I find such guidelines contradicting each other. What is your opinion on this? Are there other aspects worth discussing? Do you feel bad using bit(_vector) for modeling internal logic?

--
Maciej Sobczak * http://www.inspirel.com
 
On Monday, October 7, 2019 at 3:07:18 AM UTC-4, Maciej Sobczak wrote:
Hi,

I have found a coding guideline that recommends to use std_logic everywhere in preference to bit, on the basis that it can represent more states (X, Z, etc.).
What I found surprising is the implicit assumption that more states is an added value. I understand that on the module boundary the additional states can be useful, as they can model (or even enable) wider interfacing options. But for modeling (and ultimately synthesis) of internal logic, I see no particular benefit - on the contrary, I can imagine that it might be beneficial to restrict the number of possible states as much as possible and in fact, elsewhere designers are encouraged to always use (or define) the narrowest type that covers the given context. Additional and unused states are also problematic with language constructs like the case statement, which expect complete coverage and code fragments like this:

case my_std_logic_value is
when '0' => ...
when '1' => ...
when others =
assert false;
end case;

obviously miss the point.

So I find such guidelines contradicting each other. What is your opinion on this? Are there other aspects worth discussing? Do you feel bad using bit(_vector) for modeling internal logic?

--
Maciej Sobczak * http://www.inspirel.com

I suppose this is not unlike the use of Boolean for certain signals. The various values that std_logic can take on allows for indications of problems in simulation. When signals are uninitialized std_logic makes that known easily. When signals have driver conflicts std_logic makes that known easily.

That said, I'm sure in many cases the need for this sort of debugging help is minimal. Still, rather than trying to figure out when it is better to use bit vs. std_logic, why not just use std_logic everywhere?

I gave up using Boolean a long time ago. I don't think I ever really used BIT.

--

Rick C.

- Get 2,000 miles of free Supercharging
- Tesla referral code - https://ts.la/richard11209
 
On 07/10/2019 08:07, Maciej Sobczak wrote:
Hi,

I have found a coding guideline that recommends to use std_logic everywhere in preference to bit, on the basis that it can represent more states (X, Z, etc.).
What I found surprising is the implicit assumption that more states is an added value. I understand that on the module boundary the additional states can be useful, as they can model (or even enable) wider interfacing options. But for modeling (and ultimately synthesis) of internal logic, I see no particular benefit - on the contrary, I can imagine that it might be beneficial to restrict the number of possible states as much as possible and in fact, elsewhere designers are encouraged to always use (or define) the narrowest type that covers the given context. Additional and unused states are also problematic with language constructs like the case statement, which expect complete coverage and code fragments like this:

case my_std_logic_value is
when '0' => ...
when '1' => ...
when others =
assert false;
end case;

obviously miss the point.

So I find such guidelines contradicting each other. What is your opinion on this? Are there other aspects worth discussing? Do you feel bad using bit(_vector) for modeling internal logic?

I can think of 3 reasons why you might want to use std_logic(_vector)
types, the first is that it allows you to use 'X' (carefully as dontcare
could have nasty side effects) which could help synthesis (but
unfortunately not always).

As Rick already mentioned, the second reason is that it is great for
showing issues, if you feed an 'X' into a bit(_vector) circuit your
conversion function will mask the fact you are reading invalid values.

The third reason is that most hard-ip/coregens/megawizards/examples etc
all use std_logic types so you would need a lot of conversion functions
which becomes a real pain.

I always use std_logic types on the I/O and boolean/unsigned/integer etc
internally.

For Code Coverage it not really an issue as you will know if the "when
others" clause should be hit or not, if the case statement is fully
decoded you can use a coverage exclude pragma or some global flag like
Modelsim's -coverexcludedefault.

Now if you have 'X's propagating through your design then Code Coverage
becomes more complex as 'X's might give you a false positive.

Hans
www.ht-lab.com
 
Am Montag, 7. Oktober 2019 09:07:18 UTC+2 schrieb Maciej Sobczak:
> What I found surprising is the implicit assumption that more states is an added value.

Std_logic vs bit costs simulation performance but provides an universal and known good debug tool that bit will never provide.

First keep in mind that real world VHDL code needs to be portable as much as possible from design to design (reuse). This will always mean that the code needs to be portable from tool to tool as good as possible (Every designer knows the limits when technology dependency is needed for performance reasons) as some might request you to incorporate 10 year old fpga code in a mixed signal ASIC as IP.

In large projects it is quite common to detect problems with unitialised registers which might not even be detectable in an Xilinx-FPGA on equipment level as this FF is initialised to low after power up, when moving same design to ASIC you learn that there is no guarantee that FF is low after Power-Up.

std_(u)logic helps detecting this in first simulations. Same for correct behavior of (intended or undesired) tristate.

And what benefit is gained, when you need to convert anywhere between bit internal and std_(u)logic as your internal signal might be tomorrow external input or output.

Therefore it is far easier to encurage to use std_logic anywhere instead of wasting time for checking on every signal what type is more benefitial.

Same for integer. It is easier to use always (un)signed instead of integer/natural instead of double checking if integer is really useable or not.


regards Thomas
 
On Tuesday, October 8, 2019 at 4:32:07 AM UTC-4, Thomas Stanka wrote:
Am Montag, 7. Oktober 2019 09:07:18 UTC+2 schrieb Maciej Sobczak:
What I found surprising is the implicit assumption that more states is an added value.

Std_logic vs bit costs simulation performance but provides an universal and known good debug tool that bit will never provide.

First keep in mind that real world VHDL code needs to be portable as much as possible from design to design (reuse). This will always mean that the code needs to be portable from tool to tool as good as possible (Every designer knows the limits when technology dependency is needed for performance reasons) as some might request you to incorporate 10 year old fpga code in a mixed signal ASIC as IP.

In large projects it is quite common to detect problems with unitialised registers which might not even be detectable in an Xilinx-FPGA on equipment level as this FF is initialised to low after power up, when moving same design to ASIC you learn that there is no guarantee that FF is low after Power-Up.

std_(u)logic helps detecting this in first simulations. Same for correct behavior of (intended or undesired) tristate.

And what benefit is gained, when you need to convert anywhere between bit internal and std_(u)logic as your internal signal might be tomorrow external input or output.

Therefore it is far easier to encurage to use std_logic anywhere instead of wasting time for checking on every signal what type is more benefitial.

Same for integer. It is easier to use always (un)signed instead of integer/natural instead of double checking if integer is really useable or not.

I would also point out the inconvenience of needing to think about the type conversions required when using other than std_logic. Unless all your non-vector data types are BIT, it gets messy to combine them with logical operators. Maybe VHDL-2008 made that easier with some of the defaults. I wouldn't know since I don't use BIT type.

I don't want to turn this into a general "what type is better" discussion, but I find the range limiting of integer can be useful over signed or unsigned. If I want a counter that ranges from 0 to 9 or 0 to 16,384 times 2048, integer gives me that without hassle, helps sanity check my code and I don't need to count how many bits it will require.

I don't mind mixing data types if it gives me some advantage or ease of use..

For simple signals I can't see the performance advantages being very significant unless there are an awful lot of them.

--

Rick C.

- Get 2,000 miles of free Supercharging
- Tesla referral code - https://ts.la/richard11209
 
Thank you all for your answers, they were very instructive. The general theme is that std_logic prevents hiding some of the issues that otherwise might get lost when narrower bit is used.

I also understand that the mere presence of 'Z' in the std_logic type does not necessarily lead the synthesis tool to choose more expensive elements for what is intended to be a basic logic (2-state) circuit. Or that in practice what the designer thinks to be a basic logic ends up in LUTs and whatever else is available, so that the "savings" presumed by the use of bit are not going to lead to actually smaller footprint. If that's the case, then this clears my concerns.

Reagrds,

--
Maciej Sobczak * http://www.inspirel.com
 
On Wednesday, October 9, 2019 at 3:16:44 AM UTC-4, Maciej Sobczak wrote:
Thank you all for your answers, they were very instructive. The general theme is that std_logic prevents hiding some of the issues that otherwise might get lost when narrower bit is used.

Another good take away is that std_ulogic can be generally better than std_logic since it allows the compiler to catch when you have multiple signal drivers on something that should only have one driver. However, whether or not you find it useful can depend on your design flow. If you tend to simulate first to get to a somewhat 'working' state then run through synthesis then you will find the value in using std_ulogic since the compiler will immediately flag multiple drivers. The savings is that you don't have to debug to find that type of error. On the other hand if you tend to simulate and synthesize in parallel then the synthesis tool will find and flag multiple drivers of any type.

There is no conversion required between std_logic and std_ulogic but you do have to convert between std_logic_vector and std_ulogic_vector due to a quirk in the way the two are defined.

Kevin Jennings
 
On Monday, October 7, 2019 at 3:07:18 AM UTC-4, Maciej Sobczak wrote:
Hi,

I have found a coding guideline that recommends to use std_logic everywhere in preference to bit, on the basis that it can represent more states (X, Z, etc.).
What I found surprising is the implicit assumption that more states is an added value. I understand that on the module boundary the additional states can be useful, as they can model (or even enable) wider interfacing options. But for modeling (and ultimately synthesis) of internal logic, I see no particular benefit - on the contrary, I can imagine that it might be beneficial to restrict the number of possible states as much as possible and in fact, elsewhere designers are encouraged to always use (or define) the narrowest type that covers the given context. Additional and unused states are also problematic with language constructs like the case statement, which expect complete coverage and code fragments like this:

case my_std_logic_value is
when '0' => ...
when '1' => ...
when others =
assert false;
end case;

obviously miss the point.

So I find such guidelines contradicting each other. What is your opinion on this? Are there other aspects worth discussing? Do you feel bad using bit(_vector) for modeling internal logic?

--
Maciej Sobczak * http://www.inspirel.com
 
On Monday, October 7, 2019 at 3:07:18 AM UTC-4, Maciej Sobczak wrote:
Hi,

I have found a coding guideline that recommends to use std_logic everywhere in preference to bit, on the basis that it can represent more states (X, Z, etc.).
What I found surprising is the implicit assumption that more states is an added value. I understand that on the module boundary the additional states can be useful, as they can model (or even enable) wider interfacing options. But for modeling (and ultimately synthesis) of internal logic, I see no particular benefit - on the contrary, I can imagine that it might be beneficial to restrict the number of possible states as much as possible and in fact, elsewhere designers are encouraged to always use (or define) the narrowest type that covers the given context. Additional and unused states are also problematic with language constructs like the case statement, which expect complete coverage and code fragments like this:

case my_std_logic_value is
when '0' => ...
when '1' => ...
when others =
assert false;
end case;

obviously miss the point.

So I find such guidelines contradicting each other. What is your opinion on this? Are there other aspects worth discussing? Do you feel bad using bit(_vector) for modeling internal logic?

--
Maciej Sobczak * http://www.inspirel.com
 
On Monday, October 7, 2019 at 3:07:18 AM UTC-4, Maciej Sobczak wrote:
Hi,

I have found a coding guideline that recommends to use std_logic everywhere in preference to bit, on the basis that it can represent more states (X, Z, etc.).
What I found surprising is the implicit assumption that more states is an added value. I understand that on the module boundary the additional states can be useful, as they can model (or even enable) wider interfacing options. But for modeling (and ultimately synthesis) of internal logic, I see no particular benefit - on the contrary, I can imagine that it might be beneficial to restrict the number of possible states as much as possible and in fact, elsewhere designers are encouraged to always use (or define) the narrowest type that covers the given context. Additional and unused states are also problematic with language constructs like the case statement, which expect complete coverage and code fragments like this:

case my_std_logic_value is
when '0' => ...
when '1' => ...
when others =
assert false;
end case;

obviously miss the point.

So I find such guidelines contradicting each other. What is your opinion on this? Are there other aspects worth discussing? Do you feel bad using bit(_vector) for modeling internal logic?

--
Maciej Sobczak * http://www.inspirel.com

The Z state is needed to implement a bidirectional bus. Such a bus is needed, for example, to work with on-board read-write memory; direction into memory for write, out of memory for read. I have used this in practice.
 

Welcome to EDABoard.com

Sponsor

Back
Top