Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20705 Discussions

errors in quartus when simulation

Altera_Forum
Honored Contributor II
1,191 Views

I have some code about LEDs cycle. I wrote two process, one is a time divider, the other is LED turn on according with divider. the project was complied, but quartus has some errors when staring simulation.  

the error message is Error: Zero-time oscillation in node "|led_glimpse|lpm_mux:Mux4|mux_hfc:auto_generated|_~7" at time 5243903.5 ns. Check the design or vector source file for combinational loop. 

 

I don't know where is wrong in the code to bring this error? Thanks!  

the code is displayed as below: 

process(Reset,clk) 

begin 

if Reset='0' then 

counter<=(others=>'0'); 

elsif clk'event and clk='1' then 

counter<=counter+1; 

end if;  

end process; 

 

process(Reset,counter(10),datan) 

begin 

if Reset='0' then 

ledn<=(others=>'0'); 

datan<=(others=>'0'); 

elsif counter(10)='1' then 

datan<=datan+1; 

case datan is 

when "000" => ledn<="10000000"; 

when "001" => ledn<="00000001"; 

when "010" => ledn<="00000010"; 

when "011" => ledn<="00000100"; 

when "100" => ledn<="00001000"; 

when "101" => ledn<="00010000"; 

when "110" => ledn<="00100000"; 

when "111" => ledn<="01000000"; 

end case; 

end if; 

end process;
0 Kudos
12 Replies
Altera_Forum
Honored Contributor II
460 Views

Hi, 

 

your statement: 

 

datan <= datan + 1 is combinatorial feedback and leads to oscilation. 

 

insert that in first process 

 

kaz
0 Kudos
Altera_Forum
Honored Contributor II
460 Views

Hi, Thank you very much! 

why does these statement place to the first process? 

Could you tell me the reason?
0 Kudos
Altera_Forum
Honored Contributor II
460 Views

 

--- Quote Start ---  

Hi, Thank you very much! 

why does these statement place to the first process? 

Could you tell me the reason? 

--- Quote End ---  

 

 

When you put the statement in the first process, the update is controlled by the clock and you got registers instead of combinatorial logic for your data_an.
0 Kudos
Altera_Forum
Honored Contributor II
460 Views

Hi, 

 

As explained to you by Pletz. If you only depend on combinatorial delay to update then you will incrementing many times during one clock period and thats not what you want. Combinatorial feedback is not suitable for fpgas but is used in the ASICs e.g.for SR latch where two nand gates feedback to each other after controlled delay. 

 

Note also you may insert all assignments of second process in the first clocked process since you are inferring latches(if count(10) = '0' is not defined). You should avoid latches as well...
0 Kudos
Altera_Forum
Honored Contributor II
460 Views

Hi,  

You are very nice teachers.  

I think that the second process always runs when counter(10) is '1', because the counter(10) is puted to the sensitivity list. I have corrected the code. 

 

the another hands, I'm reading the book about VHDL at afternoon. It said that combinatorial feedback is not admitted when designing ATPG(auto test pattern generation), so I must avoid to write this code such as q<=q+1 in my architecture? Could you give me some hint? 

You told me ASIC is usually used this method, but ASIC also needs testing in the manufacture. How does ASIC tesing without ATPG?
0 Kudos
Altera_Forum
Honored Contributor II
460 Views

Hi, 

 

I don't quite follow you about ASIC, I wouldn't bother about that if I am doing FPGAs. If you are just testing leds with datan values then you get the test pattern(you only need clock and reset inputs) 

 

Your code can be like this if you want safe design: 

 

process(reset,clk) 

begin 

if (reset='0') then 

ledn <= (others => '0'); 

datan <= (others => '0'); 

counter<=(others=>'0'); 

 

elsif (clk'event and clk='1') then 

 

count <=count + 1; -- assuming modulo 2, no maximum defined 

 

if(count(10) = '1')then -- divider 

datan <= datan + 1; 

end if; 

 

case datan is 

when "000" => ledn<="10000000"; 

when "001" => ledn<="00000001"; 

when "010" => ledn<="00000010"; 

when "011" => ledn<="00000100"; 

when "100" => ledn<="00001000"; 

when "101" => ledn<="00010000"; 

when "110" => ledn<="00100000"; 

when "111" => ledn<="01000000"; 

end case; 

 

end if;  

end process; 

 

Notice that leds wouldn't show to the eye when fast changes occur. So you should be kind to the eye limitations. There will also be one clock latency in simulation between datan value and ledn value 

0 Kudos
Altera_Forum
Honored Contributor II
460 Views

Hi I have a similar problem, but i don't put my signal in process sensitive list, so i think it shouldn't make a combinational loop but again i have the same error for oscillating!!! 

an interesting point is that the error may disappear in some testcases!!! usually when test case doesn't go in if( inc = '1')!!! 

i will be glad if any one can help me!!! 

process( reset, shift, add, inc, swap, comp, datain) 

begin 

if (reset = '1') then  

accumulator <= "0000000000000000"; 

else 

if (shift = '1') then 

accumulator <= '0' & accumulator(15 downto 1); 

else 

if (add = '1') then  

accumulator <= accumulator + datain; 

else 

if (inc = '1' ) then 

accumulator <= accumulator + 1; 

else 

if( swap = '1') then 

accumulator <= accumulator ( 6 downto 0) & accumulator( 15 downto 7); 

else 

accumulator <= accumulator; 

end if; 

end if; 

end if; 

end if; 

end if; 

end process;
0 Kudos
Altera_Forum
Honored Contributor II
460 Views

This should work in simulation, but this will not work on hardware, because of the feedback loops created. When inc = '1' then accumulator will just keep adding until inc goes back to '0', so its trying to loop through an infinite number of times. 

 

The simulator is trying to warn you of bad things on hardware. Id recommend making the entire design syncronous rather than asyncronous.
0 Kudos
Altera_Forum
Honored Contributor II
460 Views

It isn't clear for me yet, i don't understand what is the differnce between to 'in' type either it is clk or inc, inc signal is high for just one clk cycle , and a process runs just when some changes accures in its sensitive list and in my code on just pos edge, exactly what we want to do when we use clk . 

i think it should make a D flip-flop for that part that just works on pos edge on inc ( we can consider it as a clk). 

p.s: but i added a clk signal to my sensitive list to see am i right or not, and put the whole process in a if clause to run just when the clk has changes to high(red part) 

this is the whole code.. 

library ieee; 

use ieee.std_logic_1164.all; 

use ieee.std_logic_arith.all; 

use ieee.math_real; 

use ieee.std_logic_unsigned.all; 

entity dataPath is  

port(clk, reset, shift, add, inc, swap, comp:in std_logic; 

datain:in std_logic_vector(15 downto 0);  

dataout: out std_logic_vector(15 downto 0)); 

end dataPath; 

architecture computer of dataPath is 

signal accumulator:std_logic_vector(15 downto 0):= "0000000000000000";  

begin 

dataout <= accumulator; 

process(clk, reset, shift, add, inc, swap, comp) 

begin 

if ( clk = '1') then 

if (reset = '1') then  

accumulator <= "0000000000000000"; 

else 

if (shift = '1') then 

accumulator <= '0' & accumulator(15 downto 1); 

else 

if (add = '1') then  

accumulator <= accumulator + datain; 

else 

if (inc = '1' ) then 

accumulator <= accumulator + 1; 

else 

if( swap = '1') then 

accumulator <= accumulator ( 7 downto 0) & accumulator( 15 downto 8); 

else 

accumulator <= accumulator; 

end if; 

end if; 

end if; 

end if; 

end if; 

end if; 

end process; 

end computer; 

--------------------------------------- 

library ieee; 

use ieee.std_logic_1164.all; 

entity controller is  

port(serialin, clk:in std_logic;  

reset, shift, add, inc, swap, comp: out std_logic); 

end controller; 

architecture ctr_states of controller is 

TYPE state is ( dummy, dummy1, dummy2, ready, ready1,ready2, ready3, ready4, ready5 , resetS, shiftS, addS, incS, swapS, compS); 

signal dummy_state, ready_state:std_logic;  

signal present_state:state:= dummy;signal next_state : state; 

begin 

--shayad bayad hazf she 

-- shift <= '0'; 

-- add <= '0'; 

-- inc <= '0'; 

-- swap <= '0'; 

-- comp <= '0'; 

PROCESS(clk) 

BEGIN 

if ((clk'EVENT) AND (clk = '1')) then  

present_state <= next_state; 

end if; 

END PROCESS; 

process( present_state, serialin ) 

begin 

case present_state is  

when dummy => 

reset <= '0'; 

shift <= '0'; 

add <= '0'; 

inc <= '0'; 

swap <= '0'; 

comp <= '0'; 

if (serialin = '1') then 

next_state <= dummy1; 

else 

next_state <= dummy; 

end if;  

when dummy1 => 

reset <= '0'; 

shift <= '0'; 

add <= '0'; 

inc <= '0'; 

swap <= '0'; 

comp <= '0'; 

if (serialin = '1') then 

next_state <= dummy2; 

else 

next_state <= dummy; 

end if;  

when dummy2 => 

reset <= '0'; 

shift <= '0'; 

add <= '0'; 

inc <= '0'; 

swap <= '0'; 

comp <= '0'; 

if (serialin = '1') then 

next_state <= ready; 

else 

next_state <= dummy; 

end if; 

when ready => 

reset <= '0'; 

shift <= '0'; 

add <= '0'; 

inc <= '0'; 

swap <= '0'; 

comp <= '0'; 

if (serialin = '1') then 

next_state <= ready3; 

else 

next_state <= ready1; 

end if;  

when ready1 => 

reset <= '0'; 

shift <= '0'; 

add <= '0'; 

inc <= '0'; 

swap <= '0'; 

comp <= '0'; 

if (serialin = '1') then 

next_state <= ready4; 

else 

next_state <= ready2; 

end if;  

when ready2 => 

reset <= '0'; 

shift <= '0'; 

add <= '0'; 

inc <= '0'; 

swap <= '0'; 

comp <= '0'; 

if (serialin = '1') then 

next_state <= shiftS; 

else 

next_state <= resetS; 

end if;  

when ready3 => 

reset <= '0'; 

shift <= '0'; 

add <= '0'; 

inc <= '0'; 

swap <= '0'; 

comp <= '0'; 

if (serialin = '1') then 

next_state <= ready; 

else 

next_state <= ready5; 

end if;  

when ready4 => 

reset <= '0'; 

shift <= '0'; 

add <= '0'; 

inc <= '0'; 

swap <= '0'; 

comp <= '0'; 

if (serialin = '1') then 

next_state <= incS; 

else 

next_state <= addS; 

end if;  

when ready5 => 

reset <= '0'; 

shift <= '0'; 

add <= '0'; 

inc <= '0'; 

swap <= '0'; 

comp <= '0'; 

if (serialin = '1') then 

next_state <= compS; 

else 

next_state <= swapS; 

end if;  

when resetS => 

reset <= '1'; 

shift <= '0'; 

add <= '0'; 

inc <= '0'; 

swap <= '0'; 

comp <= '0'; 

if (serialin = '1') then 

next_state <= dummy1; 

else 

next_state <= dummy; 

end if;  

when shiftS => 

reset <= '0'; 

shift <= '1'; 

add <= '0'; 

inc <= '0'; 

swap <= '0'; 

comp <= '0'; 

if (serialin = '1') then 

next_state <= dummy1; 

else 

next_state <= dummy; 

end if;  

when addS => 

reset <= '0'; 

shift <= '0'; 

add <= '1'; 

inc <= '0'; 

swap <= '0'; 

comp <= '0'; 

if (serialin = '1') then 

next_state <= dummy1; 

else 

next_state <= dummy; 

end if;  

when incS => 

reset <= '0'; 

shift <= '0'; 

add <= '0'; 

inc <= '1'; 

swap <= '0'; 

comp <= '0'; 

if (serialin = '1') then 

next_state <= dummy1; 

else 

next_state <= dummy; 

end if;  

when swapS => 

reset <= '0'; 

shift <= '0'; 

add <= '0'; 

inc <= '0'; 

swap <= '1'; 

comp <= '0'; 

if (serialin = '1') then 

next_state <= dummy1; 

else 

next_state <= dummy; 

end if;  

when compS => 

reset <= '0'; 

shift <= '0'; 

add <= '0'; 

inc <= '0'; 

swap <= '0'; 

comp <= '1'; 

if (serialin = '1') then 

next_state <= dummy1; 

else 

next_state <= dummy; 

end if;  

-- when others => 

-- reset <= '0'; 

-- shift <= '0'; 

-- add <= '0'; 

-- inc <= '0'; 

-- swap <= '0'; 

-- comp <= '0'; 

-- next_state <= dummy; 

end case; 

end process; 

end ctr_states;
0 Kudos
Altera_Forum
Honored Contributor II
460 Views

 

--- Quote Start ---  

This should work in simulation, but this will not work on hardware, because of the feedback loops created. When inc = '1' then accumulator will just keep adding until inc goes back to '0', so its trying to loop through an infinite number of times. 

 

The simulator is trying to warn you of bad things on hardware. Id recommend making the entire design syncronous rather than asyncronous. 

--- Quote End ---  

 

 

 

you mean that we cann't synthesis asyncronous design? :(
0 Kudos
Altera_Forum
Honored Contributor II
460 Views

you can, but you're liable to have timing failures and have race conditions all over and all sorts of problems. 

 

What you need to do in your first process is wrap it up as a D-type flip flop process - just put  

 

if rising_edge(clk) then  

(or you can use: 

if clk'event and clk = '1' then 

 

at the top, then you wont have a problem. You can remove all signals other than the clock from the sensitivity list. What you have done by putting "if clk = '1' then" at the top is use the clock as a logic signal, not a clock, which is bad, and wont solve any problems.
0 Kudos
Altera_Forum
Honored Contributor II
460 Views

 

--- Quote Start ---  

you can, but you're liable to have timing failures and have race conditions all over and all sorts of problems. 

 

What you need to do in your first process is wrap it up as a D-type flip flop process - just put  

 

if rising_edge(clk) then  

(or you can use: 

if clk'event and clk = '1' then 

 

at the top, then you wont have a problem. You can remove all signals other than the clock from the sensitivity list. What you have done by putting "if clk = '1' then" at the top is use the clock as a logic signal, not a clock, which is bad, and wont solve any problems. 

--- Quote End ---  

 

 

tnx a lot.
0 Kudos
Reply