A
Analog_Guy
Guest
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;
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;