Forum Discussion
Altera_Forum
Honored Contributor
14 years agoVHDL integer causing RTL and Gate level simulation difference
I have a general question regarding the use of integers in VHDL.
If I have a lot of Array defined, we have to use integer as its index when accessing the arrays. However, when the index is converted from std_logic_vectors, it masked away the 'X' values, which masked my signal initiailization problem. Can anybody please let me know how to avoid this problem? When running simulation, I have the following warning: # ** Warning: NUMERIC_STD.TO_INTEGER: metavalue deteced, returning 0 The code example is below: SIGNAL a : ARRAY (INTEGER 0 TO 15) of STD_LOGIC_VECTOR(5 DOWNTO 0); SIGNAL b : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL c : STD_LOGIC_VECTOR(5 DOWNTO 0); c <= a(TO_INTEGER(UNSIGNED(b));15 Replies
- Altera_Forum
Honored Contributor
The problem is brought up with uninialized std_logic and derived types, that have a default value of 'U' in functional simulation and '0' in real hardware. Add '0' initializers to the definition of register signals or add an explicite reset initialization to achieve consistent simulation.
- Altera_Forum
Honored Contributor
--- Quote Start --- I have a general question regarding the use of integers in VHDL. If I have a lot of Array defined, we have to use integer as its index when accessing the arrays. However, when the index is converted from std_logic_vectors, it masked away the 'X' values, which masked my signal initiailization problem. Can anybody please let me know how to avoid this problem? When running simulation, I have the following warning: # ** Warning: NUMERIC_STD.TO_INTEGER: metavalue deteced, returning 0 --- Quote End --- Actually, the simulator didn't mask the problem, you ignored the reporting. As you can see from the message that you posted you ignored what was reported presumably since it was 'just' a warning. You can set the simulator to stop on warnings as well as errors. Having said that though, making use of the message that was reported can be problematic since at t=0 you can likely have a ton of such messages reporting similar warnings, so usually the better solution will be more task specific as mentioned below... --- Quote Start --- The code example is below: SIGNAL a : ARRAY (INTEGER 0 TO 15) of STD_LOGIC_VECTOR(5 DOWNTO 0); SIGNAL b : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL c : STD_LOGIC_VECTOR(5 DOWNTO 0); c <= a(TO_INTEGER(UNSIGNED(b)); --- Quote End --- To be able to flag the problem you're seeing with this example you can create your own assertion. Let's say that you want to ignore problems at t=0 but otherwise report when 'b' has unknown values in them. The following assertion will do the trick: assert (t=0 ns) or (b = to_unsigned(to_integer(unsigned(b)), b'length)) report "OOPS! Unknown value detected on 'b'" severity ERROR; This will create an error rather than a warning but it won't bother with things when t=0. One caveat though is that if the bits in b get set to an unknown value at t=0, and b never changes after that then the above assertion won't catch it either because it only does the check when there is a change on 'b'. Lastly, a way to work around it is to give b an initial value like this SIGNAL b : STD_LOGIC_VECTOR(3 DOWNTO 0) := (others => '0'); The problem with this approach is that it might not reflect what the real hardware is doing for initializations in which case you've simply punted the problem downstream. Instead of being able to catch the problem in simulation, you now will think everything is good, but when you build the real hardware it is working differently. Kevin Jennings - Altera_Forum
Honored Contributor
Thanks very much for the reply.
My problem is exactly 'B' gets an unknown value in the design. In RTL simulation, the good 'C' values corresponding to address 0 gets used; while in Gate level simulation, the unknown 'C' gets used. When there is tons of such logic in your design and we don't do reset our flops as a general principle, it is very hard to catch which one causes the problem in gate level simulation if it is not duplicate-able in RTL simulation. In general, we don't want to give an initial value to a variable since it is ignored by the synthesize tools. What we want is to have an exact RTL simulation to avoid debugging problem using gate level simulation. - Altera_Forum
Honored Contributor
--- Quote Start --- In general, we don't want to give an initial value to a variable since it is ignored by the synthesize tools. --- Quote End --- What makes you say that? FPGAs configure from bit-streams, and those bitstreams define the register states at power-on. Most devices power-up with registers set to 0, but if you initialize a signal to 1, the synthesis tool will use 'not gate pushback' to invert the input and output to the register, so as far as your logic is concerned, the register powers up to your initialized value of 1. Cheers, Dave - Altera_Forum
Honored Contributor
--- Quote Start --- Thanks very much for the reply. My problem is exactly 'B' gets an unknown value in the design. In RTL simulation, the good 'C' values corresponding to address 0 gets used; while in Gate level simulation, the unknown 'C' gets used. When there is tons of such logic in your design and we don't do reset our flops as a general principle, it is very hard to catch which one causes the problem in gate level simulation if it is not duplicate-able in RTL simulation. In general, we don't want to give an initial value to a variable since it is ignored by the synthesize tools. What we want is to have an exact RTL simulation to avoid debugging problem using gate level simulation. --- Quote End --- What this points to then is that you may need to be writing a better testbench. The signal 'c' eventually has some effect on the overall design and it being stuck at the value contained in a(0) should have caused some output to not be correct at some point...but it can only be determined to be incorrect if you take the time to write a testbench that generates stimulus sufficient to exercise the signals and that actually checks the outputs to verify that they are correct. The time it takes to write testbenches will pay off dividends over the entire lifecycle of the code as it changes over time. However, even when you do take that time things will get missed because it can take roughly as much time to write a testbench as it does to do the design. But it can also take just a small bit of time to get a testbench that covers a lot without much effort. The value judgment comes in as to where to draw the line about where you think you've tested this enough because there will never be an end to tests that you could've written. As you've already noticed running gate level simulations are painfully slow. Many experienced designers do not run them as a simple matter of course since there time is more effectively spent elsewhere. As I mentioned in the first post, one can sometimes also write self-checking right into the design itself. It's more limited then testbench testing but has the advantage of being usable in any testbench. Kevin Jennings - Altera_Forum
Honored Contributor
OK. Here is what we observed in our lab.
Our turbo decoder design can pass the RTL simulations, but not the gate level. We have to deposit '0's to all the flops before we can pass gate level simulation. When the chip comes back in our lab, we see some tests passes, but not others. Some chips passes all tests consistently, but others not. If we run some tests first, then other tests starts to pass as well. All of these observations made us think there is initialization issues in our design. Since we decided not to do reset to all of our flops unless required. There is lots of flops not having known reset value at power on. My task is to figure our what needs to be reset in this design. Since there is lots of integers used in the design, such as index to arrays and integers get value '0' at power on in RTL simulation, while it gets unknown value in real chip. This, I think, made RTL simulation hides lot of potential bugs in our design. This is why I want to get rid of all INTEGERs so that I can have a consistently simulation between RTL and GATE. I can capture all my bugs in RTL simulation only. - Altera_Forum
Honored Contributor
--- Quote Start --- integers get value '0' at power on in RTL simulation, while it gets unknown value in real chip. --- Quote End --- Uninitialized integers get assigned the value -2^(N-1), where N is the number of bits in the integer. (At least under VHDL). --- Quote Start --- This is why I want to get rid of all INTEGERs so that I can have a consistently simulation between RTL and GATE. I can capture all my bugs in RTL simulation only. --- Quote End --- I could have sworn one of the first things you're supposed to learn when writing HDL, is to never use integers. That is why there are signed and unsigned types ... of course, that kind of advice does not help when you inherit code ... Cheers, Dave - Altera_Forum
Honored Contributor
There is nothing wrong with integers when properly constrained. I'm with KJ - dodgy code and/or testbench.
- Altera_Forum
Honored Contributor
--- Quote Start --- Our turbo decoder design can pass the RTL simulations, but not the gate level. We have to deposit '0's to all the flops before we can pass gate level simulation. When the chip comes back in our lab, we see some tests passes, but not others. Some chips passes all tests consistently, but others not. If we run some tests first, then other tests starts to pass as well. --- Quote End --- Are you talking about FPGA or ASICs?. As previously explained, FPGA registers have a defined POR state which determines the behaviour in gate level simulation. It should be noticed however that the problems brought up by asynchronous reset can also affect power-on reset if the design clock is already present during reset. In this case, explicite reset logic and a reset synchronizer are required. --- Quote Start --- Uninitialized integers get assigned the value -2^(N-1), where N is the number of bits in the integer. (At least under VHDL). --- Quote End --- This is only true in functional simulation and for unconstrained or signed integers. Integers are synthesized either as signed or unsigned in gate level logic, depending on the range and initialized to all zero by default. --- Quote Start --- This is why I want to get rid of all INTEGERs so that I can have a consistently simulation between RTL and GATE. I can capture all my bugs in RTL simulation only. --- Quote End --- The described problems in gate level behaviour have unlikely to do with integer usage. - Altera_Forum
Honored Contributor
We are doing ASIC designs.