Immunizing Design/Simulation From Unknowns

M

M. Norton

Guest
Alright, well in the interests of bettering my design process etc, I've been trying to do a lot more low level simulations, full chip simulations, fiddling with post-fit models, etc. I've got a little CPLD whose main purpose in life is to condition the reset signals a microprocessor gets and runs the configuration signals that are active while the processor is held in reset. Nothing particularly magic, nothing exotic.

My trouble is that even with good design, the simulation of this falls apart because unknowns are propagated when they really shouldn't be. I may be missing a trick with the simulator but thus far I haven't found how to control this.

So for example, my RTL code for this little reset pulse stretch runs like this:

-- All the resets that enter the CPLD are asynchronous with the clock. To
-- alleviate metastability concerns and make setup times for the counter
-- used to pulse stretch, the resets here are synchronized into the clock
-- domain.
RESET_SYNC : process (i_clk_66mhz)
begin
if rising_edge(i_clk_66mhz) then
board_por_n_meta <= i_board_por_n;
board_por_n <= board_por_n_meta;

cop_hreset_n_meta <= i_cop_hreset_n;
cop_hreset_n <= cop_hreset_n_meta;

cop_sreset_n_meta <= i_cop_sreset_n;
cop_sreset_n <= cop_sreset_n_meta;

fpga_sreset_n_meta <= i_fpga_sreset_out_n;
fpga_sreset_n <= fpga_sreset_n_meta;
end if;
end process RESET_SYNC;

-- proc_hreset_n is used throughout for the configuration and here is
-- assigned to an output port.
o_proc_hreset_n <= proc_hreset_n;
o_proc_sreset_n <= proc_sreset_n;

-- Reset control needs to conform to the reset initialization timing listed
-- in the hardware specification (Section 2.4). In short, HRESET must be
-- asserted a minimum of 25 us. SRESET must be asserted a minimum of 3
-- SYSCLK cycles (30 ns). Additionally, the input setup time for POR
-- configuration with respect to HRESET deassertion is 4 SYSCLK cycles.
-- Thus any time HRESET is asserted, it must stay in that state for at least
-- 4 clocks before it may be deasserted.
HRESET_CTRL : process (i_clk_66mhz)
begin
if rising_edge(i_clk_66mhz) then
if (board_por_n = '0' or cop_hreset_n = '0') then
-- Assertion may happen immediately, start a count to control
-- assertion minimum time. 25 us is 1667 15 ns counts.
proc_hreset_n <= '0';
else
-- Deassertion must only happen after the minimum delay was reached.
if (proc_hreset_n = '0' and hreset_count = 0) then
proc_hreset_n <= '1';
end if;
end if;
end if;
end process HRESET_CTRL;

HRESET_STRETCH_COUNTER : process (i_clk_66mhz)
begin
if rising_edge(i_clk_66mhz) then
if (proc_hreset_n = '0') then
if (hreset_count /= 0) then
hreset_count <= hreset_count - 1;
end if;
else
hreset_count <= to_unsigned(1750,12);
end if;
end if;
end process HRESET_STRETCH_COUNTER;

Of course what I'm actually simulating is the post-fit primitives, but this is the essential behavior. So, if the initial reset meets the setup conditions for its first register, the whole thing works beautifully. However I cannot be guaranteed that, so I run a simulation where the reset does NOT meet the setup conditions for the first register. Now, this is exactly why I have metastability registers emplaced on the input. The leading edge through the register will resolve high/low but be unknown, but the second clock cycle will resolve low and we're off to the races.

The problem is that this unknown propagates through the rest of the design and basically fouls up figuring anything out. So Modelsim naturally says "I don't know what this input is during this clock cycle. The counter might start counting down -- or the counter might stay put and start counting down the next cycle. The result is a big mess of red.

From one point of view, this is exactly what it ought to show, but I don't know what that means from a verification standpoint. I can demonstrate that if the input signal meets the setup time and the design works properly post-fit with backannotated timing. If the input signal does not meet the setup time, I can demonstrate from the device final schematic that there are two registers with enough delay to account for the metastability settling time and no interior registers are exposed to this unknown state. That is more of an analytical proof and it'd be nice to show a more direct proof that the design will indeed perform correctly.

So am I resigned to just having to prove the design through metastability analysis and leave simulation to the "well-behaved" cases? Or is there some trick of design or Modelsim wizardry where I can put in a badly behaved case in Modelsim and see that my design works properly regardless?

Thanks for any insight.

Best regards,
Mark Norton
 
On Fri, 01 Mar 2013 13:59:17 -0800, M. Norton wrote:

Alright, well in the interests of bettering my design process etc, I've
been trying to do a lot more low level simulations, full chip
simulations, fiddling with post-fit models, etc.
....

So am I resigned to just having to prove the design through
metastability analysis and leave simulation to the "well-behaved" cases?
Or is there some trick of design or Modelsim wizardry where I can put
in a badly behaved case in Modelsim and see that my design works
properly regardless?
There is an attribute ASYNC_REG taking values TRUE and FALSE. This can be
applied to Xilinx Unisim and Simprim flipflops : the same may or may not
be true of other CPLD technologies. It suppresses X generation on that FF
ONLY if setup and hold times are not met.

Use at your peril : i.e. apply to your first clock-crossing FF and
nowhere else.

How to instantiate it in the gate level model? I had to read the gate
level VHDL netlist and apply it by hand the one time I needed this,
several years ago.

Today it MAY be possible to attach it to a signal pre-synth and have it
propagate through the tools : in the spirit of not trusting the tools I
would recommend inspecting the gate level netlist to make sure. If you
try, please report success/failure here.

I hope this helps,
- Brian
 
On 01/03/2013 21:59, M. Norton wrote:
...snip

The problem is that this unknown propagates through the rest of the design and basically fouls up figuring anything out. So Modelsim naturally says "I don't know what this input is during this clock cycle. The counter might start counting down -- or the counter might stay put and start counting down the next cycle. The result is a big mess of red.

From one point of view, this is exactly what it ought to show, but I don't know what that means from a verification standpoint. I can demonstrate that if the input signal meets the setup time and the design works properly post-fit with backannotated timing. If the input signal does not meet the setup time, I can demonstrate from the device final schematic that there are two registers with enough delay to account for the metastability settling time and no interior registers are exposed to this unknown state. That is more of an analytical proof and it'd be nice to show a more direct proof that the design will indeed perform correctly.

So am I resigned to just having to prove the design through metastability analysis and leave simulation to the "well-behaved" cases? Or is there some trick of design or Modelsim wizardry where I can put in a badly behaved case in Modelsim and see that my design works properly regardless?
If you are running Modelsim SE or Questa search the reference manual for
tcheck_set and tcheck_status, these commands can be used to
control/modify X generation per instance.

Hans
www.ht-lab.com

Thanks for any insight.

Best regards,
Mark Norton
 
On Monday, March 4, 2013 3:16:50 AM UTC-6, HT-Lab wrote:
On 01/03/2013 21:59, M. Norton wrote:

..snip



The problem is that this unknown propagates through the rest of the design and basically fouls up figuring anything out. So Modelsim naturally says "I don't know what this input is during this clock cycle. The counter might start counting down -- or the counter might stay put and start counting down the next cycle. The result is a big mess of red.



From one point of view, this is exactly what it ought to show, but I don't know what that means from a verification standpoint. I can demonstrate that if the input signal meets the setup time and the design works properly post-fit with backannotated timing. If the input signal does not meet the setup time, I can demonstrate from the device final schematic that there are two registers with enough delay to account for the metastability settling time and no interior registers are exposed to this unknown state. That is more of an analytical proof and it'd be nice to show a more direct proof that the design will indeed perform correctly.



So am I resigned to just having to prove the design through metastability analysis and leave simulation to the "well-behaved" cases? Or is there some trick of design or Modelsim wizardry where I can put in a badly behaved case in Modelsim and see that my design works properly regardless?



If you are running Modelsim SE or Questa search the reference manual for

tcheck_set and tcheck_status, these commands can be used to

control/modify X generation per instance.
Thanks to you and Brian for these tips. It occurred to me that really what I needed to do was have two additional simulations where the metastability resolves high, and another where the metastability resolves low and then simulation can prove that the design is well behaved at these cases. I'll look into the tcheck items and the asynchronous register attribute and see if I can't create these verification cases. And agreed, the goal would be to only place it on a single point of entry and verify the rest of the design reacts appropriately.

Best regards,
Mark Norton
 
M. Norton wrote:
On Monday, March 4, 2013 3:16:50 AM UTC-6, HT-Lab wrote:
On 01/03/2013 21:59, M. Norton wrote:

..snip



The problem is that this unknown propagates through the rest of the design and basically fouls up figuring anything out. So Modelsim naturally says "I don't know what this input is during this clock cycle. The counter might start counting down -- or the counter might stay put and start counting down the next cycle. The result is a big mess of red.
From one point of view, this is exactly what it ought to show, but I don't know what that means from a verification standpoint. I can demonstrate that if the input signal meets the setup time and the design works properly post-fit with backannotated timing. If the input signal does not meet the setup time, I can demonstrate from the device final schematic that there are two registers with enough delay to account for the metastability settling time and no interior registers are exposed to this unknown state. That is more of an analytical proof and it'd be nice to show a more direct proof that the design will indeed perform correctly.
So am I resigned to just having to prove the design through metastability analysis and leave simulation to the "well-behaved" cases? Or is there some trick of design or Modelsim wizardry where I can put in a badly behaved case in Modelsim and see that my design works properly regardless?


If you are running Modelsim SE or Questa search the reference manual for

tcheck_set and tcheck_status, these commands can be used to

control/modify X generation per instance.

Thanks to you and Brian for these tips. It occurred to me that really what I needed to do was have two additional simulations where the metastability resolves high, and another where the metastability resolves low and then simulation can prove that the design is well behaved at these cases. I'll look into the tcheck items and the asynchronous register attribute and see if I can't create these verification cases. And agreed, the goal would be to only place it on a single point of entry and verify the rest of the design reacts appropriately.

Best regards,
Mark Norton
Probably a better method is a simulation where "metastability," which in
your case really means failure to meet setup/hold, resolves to a random
1 or 0. This covers more cases than the all 1's or all 0's method.

-- Gabor
 

Welcome to EDABoard.com

Sponsor

Back
Top