- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
your statement: datan <= datan + 1 is combinatorial feedback and leads to oscilation. insert that in first process kaz- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Thank you very much!
why does these statement place to the first process? Could you tell me the reason?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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...- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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? :(
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page