HOLD warning? Please comment on my code!

A

Analog_Guy

DEVICE:
Lattice ispMACH4256V CPLD

TOOLS:
ModelSim, Lattice ispLEVER

PROBLEM:
ModelSim asserts a HOLD violation WARNING on my structural (post fit)
simulation, on a node internal to my design.

Lattice ispLEVER static timing analyzer specifies an Fmax (86 MHz)
which far exceeds my operating frequency (60 MHz). How can I get a
hold violation on an internal node?

This code has been working fine until recently, when more logic was
added to the device.

DESIGN:
Basically, there are two processes.

In one process, I have a simple down counter, which is pre-loaded, then
counts down to zero and stops. In the second process, I decode when
certain counts are reached, and assert outputs appropriately.

The HOLD violation occurs on the output signal (OUT_C) that is asserted
as a result of the counter reaching a count of zero.

Could you please look at my code, and see if any flags are raised
concerning the coding style that would lead to my problem.

Mainly:
1. Does this appear to be a "design" problem, or a simulator problem
(i.e. delta cycles, etc.)?

2. Is the style of checking for a zero count in the counter process,
and then performing a signal assignment to zero a cause for concern?

3. Is there a problem of using integers to define my counter pre-load
and trip points, or should everything be expressed in std_logic_vector?
It just seemed more intuitive to use integers.

4. In the second process, does the IF ... ELSIF ... ELSIF provide a
source for concern? The different counter settings are mutually
exclusive, so is it better to use independent IF ... THEN ... END IF
for each of the 3 conditions?

5. In the second process, is there a problem in making a comparison of
the std_logic_vector counter to an integer value (i.e. ELSIF (counter =
0) )?


It's very frustrating, because the code in itself is very simple, and I
was just trying to make it more "readable" (to myself !?!). Any
comments would be appreciated.




CONSTANT counter_bits : INTEGER := 7;
CONSTANT cnt_rst_2_load : INTEGER := 100;

CONSTANT trip_1 : INTEGER := 82;
CONSTANT trip_2 : INTEGER := 76;

SIGNAL cnt_rst_2 : STD_LOGIC_VECTOR(counter_bits - 1 DOWNTO 0);


PROCESS (reset, clk)
BEGIN
IF (reset = '0') THEN
counter <= CONV_STD_LOGIC_VECTOR(counter_load, counter_bits);
ELSIF (clk = '1' AND clk'EVENT) THEN
IF (strobe = '1') THEN
IF (counter = 0) THEN
counter <= (OTHERS => '0');
ELSE
counter <= counter - '1';
END IF;
END IF;
END IF;
END PROCESS;


PROCESS (reset, clk)
BEGIN
IF (reset = '0') THEN
OUT_A <= '0';
OUT_B <= '0';
OUT_C <= '1';
ELSIF (clk = '1' AND clk'EVENT) THEN
IF (counter = trip_1) THEN
OUT_A <= '1';
ELSIF (counter = trip_2) THEN
OUT_B <= '1';
ELSIF (counter = 0) THEN
OUT_C <= '0';
END IF;
END IF;
END PROCESS;
 
M

Mike Treseler

Analog_Guy said:
ModelSim asserts a HOLD violation WARNING on my structural (post fit)
simulation, on a node internal to my design.

Lattice ispLEVER static timing analyzer specifies an Fmax (86 MHz)
which far exceeds my operating frequency (60 MHz). How can I get a
hold violation on an internal node?

The most common way is by not using a low-skew
network for the system clock. Check how "clk"
is distributed. Since your design is synchronous,
the static timing analysis result makes the testbench
timing result suspect. The design is working, right?

1. Does this appear to be a "design" problem, or a simulator problem
(i.e. delta cycles, etc.)?

I expect you have a backannotation or testbench error.
Does the same testbench work ok for the functional test?
Why are you using a timing simulation in the first place?
2. Is the style of checking for a zero count in the counter process,
and then performing a signal assignment to zero a cause for concern?

It's just poor style, since the assignment has no effect.
3. Is there a problem of using integers to define my counter pre-load
and trip points, or should everything be expressed in std_logic_vector?
It just seemed more intuitive to use integers.

That's fine.
4. In the second process, does the IF ... ELSIF ... ELSIF provide a
source for concern? The different counter settings are mutually
exclusive, so is it better to use independent IF ... THEN ... END IF
for each of the 3 conditions?

Wouldn't make any difference if the logic were the same.
A CASE might look cleaner.
5. In the second process, is there a problem in making a comparison of
the std_logic_vector counter to an integer value (i.e. ELSIF (counter =
0) )?

No, but the description might be easier to follow
if you combined the two processes into one.

-- Mike Treseler
 
A

Analog Guy

Thanks for the reply.

The design is working, right?

Yes, the design is working, but I am still worried about eliminating this
hold problem.
Does the same testbench work ok for the functional test?

Yes. I have no problems with functional simulation, and up until the device
has filled up, I had no problems
with the structural simulation. One thing to note is that the d-inputs of
the counter do tend to glitch
occasionally (i..e. when passing through the zero condition), but shouldn't
have any effect on the q outputs.
Why are you using a timing simulation in the first place?

As far as I was aware, that is the only way to verify the "physical" device
in the simulator, and to achieve a good
degree of confidence before going to the lab. By using the SDF delays, you
get a worst-case representation of the
timing. I realize the sims take orders of magnitude longer to run, but you
get a dynamic representation of your device
performance. Are you suggesting to use only the static timing analysis?
It's just poor style, since the assignment has no effect.

How would I correct the poor style? I would like to make the code as
logical and readable as possible. Are you
suggesting one of the following would be better:

1. IF (counter = 0) THEN
counter <= NULL;
ELSE
counter <= counter - '1';
END IF;


2. IF (counter /= 0) THEN
counter <= counter - '1';
END IF;


Or is there a better way to define this counter? I use a similar style when
coding a free-running
counter, only I pre-load on the zero condition instead of assigning to zero.
I thought this assignment
to zero was just an extension of the free-running condition?
 
K

Kim Enkovaara

Analog said:
Yes, the design is working, but I am still worried about eliminating this
hold problem.

Easiest way to debug the problem is to get all the signals around the cells
that give the warning. And then you should just manually from the wave try
to understand why the warning happened.

One possible reason could be timing resolution. Are you using accurate enough
timing for the models (can be set in modelsim.ini or vith "-t 1ps" style
command line switch).

Also some glitches can have affect in the simulation models. Usually the
vendor gives some notes if pulse rejection must be used (in modelsim
+pulse* switches).

As far as I was aware, that is the only way to verify the "physical" device
in the simulator, and to achieve a good
degree of confidence before going to the lab. By using the SDF delays, you
get a worst-case representation of the
timing. I realize the sims take orders of magnitude longer to run, but you
get a dynamic representation of your device
performance. Are you suggesting to use only the static timing analysis?

Usually STA is enough. SDF simulations of the design are made to make sure
that the STA setups in big chips are correct, and to test the asynchronous
interfaces a little. If there are only few clock domains it's easier just to
review the STA setup.

Also synthesis errors can be debugged with post simulations,
but RTL->gate formal verification is easier tool for that (and exhaustive).
Also in the ASIC world post simulations are usually needed to check
that all the test logic is connected correctly (can be done mostly also
with formal checks).

--Kim
 
M

Mike Treseler

Analog said:
Thanks for the reply.

You are welcome.
One thing to note is that the d-inputs of
the counter do tend to glitch
occasionally

That's fine.
As far as I was aware, that is the only way to verify the "physical" device
in the simulator, and to achieve a good
degree of confidence before going to the lab.

That is debatable, and the debate has occurred here many times.
By using the SDF delays, you
get a worst-case representation of the
timing. I realize the sims take orders of magnitude longer to run, but you
get a dynamic representation of your device
performance. Are you suggesting to use only the static timing analysis?

Functional simulation *and* synchronous design *and* STA.

That is up to you.

I use timing sims only to test tools,
not to test FPGAs or synthesis code.

Note that STA assumes that
all inputs are synchronized to the fpga clock,
and that no asynchronous logic is used in the design.
How would I correct the poor style?
2. IF (counter /= 0) THEN
counter <= counter - '1';
END IF;

That looks much cleaner to me.



-- Mike Treseler
 
D

Duane Clark

Analog_Guy said:
DEVICE:
Lattice ispMACH4256V CPLD

I tried to download the datasheet, but Lattice wants me to register to
do that. So forget it.
Mainly:
1. Does this appear to be a "design" problem, or a simulator problem
(i.e. delta cycles, etc.)?

It is possible that in certain configurations in a CPLD, there is a hold
time requirement. I certainly ran into this in some small Actel devices.
Does the datasheet show any hold time requirements for the internal
registers or whatever is in the ispMACH?
...
PROCESS (reset, clk)
BEGIN
IF (reset = '0') THEN
OUT_A <= '0';
OUT_B <= '0';
OUT_C <= '1';
ELSIF (clk = '1' AND clk'EVENT) THEN
IF (counter = trip_1) THEN
OUT_A <= '1';
ELSIF (counter = trip_2) THEN
OUT_B <= '1';
ELSIF (counter = 0) THEN
OUT_C <= '0';
END IF;
END IF;
END PROCESS;

Hmm.. it appears that the only way for OUT_A/B/C to get set back to
their original values is via an asynchronous reset. Where does this
reset come from? That may be the source of your problem.
 
A

Andy Peters

Analog_Guy said:
DEVICE:
Lattice ispMACH4256V CPLD

TOOLS:
ModelSim, Lattice ispLEVER

PROBLEM:
ModelSim asserts a HOLD violation WARNING on my structural (post fit)
simulation, on a node internal to my design.

Lattice ispLEVER static timing analyzer specifies an Fmax (86 MHz)
which far exceeds my operating frequency (60 MHz). How can I get a
hold violation on an internal node?

This code has been working fine until recently, when more logic was
added to the device.

DESIGN:
Basically, there are two processes.

In one process, I have a simple down counter, which is pre-loaded, then
counts down to zero and stops. In the second process, I decode when
certain counts are reached, and assert outputs appropriately.

The HOLD violation occurs on the output signal (OUT_C) that is asserted
as a result of the counter reaching a count of zero.

Could you please look at my code, and see if any flags are raised
concerning the coding style that would lead to my problem.

CONSTANT counter_bits : INTEGER := 7;
CONSTANT cnt_rst_2_load : INTEGER := 100;

CONSTANT trip_1 : INTEGER := 82;
CONSTANT trip_2 : INTEGER := 76;

SIGNAL cnt_rst_2 : STD_LOGIC_VECTOR(counter_bits - 1 DOWNTO 0);

PROCESS (reset, clk)
BEGIN
IF (reset = '0') THEN
counter <= CONV_STD_LOGIC_VECTOR(counter_load, counter_bits);

You haven't told us whether counter_load is a constant or whether it is
a signal in your module. I'd guess that if it wasn't a constant, the
logic created might be uglier than one might like.

-a
 

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

Similar Threads


Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top