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

Timing Problem(Clock Edge)

Altera_Forum
Honored Contributor II
1,559 Views

Dear all, 

 

I'm new to VHDL and need all u guys out there, 

 

I'm currently designning a VHDL code for traffic light (two processes) coding style and i bump to this error regarding clock timing: 

 

Error (10818): Can't infer register for "state.s0" at traffic.vhd(44) because it does not hold its value outside the clock edge 

 

Error (10818): Can't infer register for "state.s1" at traffic.vhd(44) because it does not hold its value outside the clock edge 

 

and so on...... 

 

 

All ur help will be deeply appreciate by me.. enlight me... thx
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
481 Views

here is de code: 

 

library IEEE; 

use IEEE.std_logic_1164.all; 

use IEEE.std_logic_arith.all; 

use IEEE.std_logic_unsigned.all; 

entity traffic is 

port ( 

 

CLK : in std_logic; 

RST : in std_logic; 

car : in std_logic; 

pedestrian : in std_logic; 

Digit1_o : out unsigned (3 downto 0); 

Digit10_o : out unsigned (3 downto 0); 

lights : out std_logic_vector (6 downto 0) 

 

); 

 

end traffic; 

architecture traffic_arch of traffic is 

type state_type is (s0,s1,s2,s3,s4,s5,s6,s7); 

signal state : state_type; 

signal Digit1 : unsigned (3 downto 0); 

signal Digit10 : unsigned (3 downto 0); 

 

begin 

main:process(CLK,RST,car,pedestrian) 

begin 

if pedestrian = '1' then 

state <= s4; 

 

if RST = '1' then 

state <= s0; 

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

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

 

if CLK'event and CLK = '1' then 

 

case state is 

 

when s0 => 

 

if Digit1 < 9 then 

state <= s0; 

Digit1 <= Digit1 + 1; 

if 

Digit10 < 5 then 

state <= s0; 

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

Digit10 <= Digit10 + 1; 

 

else  

state <= s1;  

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

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

end if; 

end if; 

 

 

 

when s1 => 

 

if (car = '1') then 

state <= s2; 

 

else  

if Digit1 < 9 then 

state <= s1; 

Digit1 <= Digit1 + 1; 

if 

Digit10 < 2 then 

state <= s1; 

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

Digit10 <= Digit10 + 1; 

 

else  

state <= s2;  

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

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

end if; 

end if; 

end if; 

 

when s2 => 

 

if Digit1 < 9 then 

state <= s2; 

Digit1 <= Digit1 + 1; 

if 

Digit10 < 0 then 

state <= s2; 

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

Digit10 <= Digit10 + 1; 

 

else  

state <= s3;  

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

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

end if; 

end if; 

 

 

when s3 => 

 

if Digit1 < 2 then 

state <= s3; 

Digit1 <= Digit1 + 1; 

if 

Digit10 < 0 then 

state <= s3; 

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

Digit10 <= Digit10 + 1; 

 

else  

state <= s4;  

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

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

end if; 

end if; 

 

 

when s4 => 

 

if Digit1 < 9 then 

state <= s4; 

Digit1 <= Digit1 + 1; 

if 

Digit10 < 2 then 

state <= s4; 

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

Digit10 <= Digit10 + 1; 

 

else  

state <= s5;  

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

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

end if; 

end if; 

 

 

when s5 => 

 

if (car = '1') then 

if Digit1 < 9 then 

state <= s5; 

Digit1 <= Digit1 + 1; 

if 

Digit10 < 2 then 

state <= s5; 

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

Digit10 <= Digit10 + 1; 

 

else  

state <= s6;  

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

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

 

if (car = '0') then 

state <= s6; 

 

end if; 

end if; 

end if; 

end if; 

 

when s6 => 

 

if Digit1 < 9 then 

state <= s6; 

Digit1 <= Digit1 + 1; 

if 

Digit10 < 0 then 

state <= s6; 

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

Digit10 <= Digit10 + 1; 

 

else  

state <= s7;  

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

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

end if; 

end if; 

 

when s7 => 

 

if Digit1 < 2 then 

state <= s7; 

Digit1 <= Digit1 + 1; 

if 

Digit10 < 0 then 

state <= s7; 

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

Digit10 <= Digit10 + 1; 

 

else  

state <= s0;  

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

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

end if; 

end if; 

 

 

when others => 

 

state <= s0; 

end case; 

 

end if; 

end if; 

end if; 

end process main; 

Digit1_o <= Digit1; 

Digit10_o <= Digit10; 

 

sub:process(state) 

begin 

case state is 

when s0 => 

lights <= "1011011"; 

 

when s1 => 

lights <= "1011011"; 

 

when s2 => 

lights <= "1010111"; 

 

when s3 => 

lights <= "1001111"; 

 

when s4 => 

lights <= "1101101"; 

 

when s5 => 

lights <= "1101101"; 

 

when s6 => 

lights <= "1101110"; 

 

when s7 => 

lights <= "1001111"; 

 

when others => 

lights <= "1011011"; 

 

end case; 

end process sub; 

 

end traffic_arch;
0 Kudos
Altera_Forum
Honored Contributor II
481 Views

You are missing some elses in the main process... You should start with replacing the two ifs (on RST and CLK'event) with elsifs and see what happens

0 Kudos
Altera_Forum
Honored Contributor II
481 Views

thanks for ur comment.. i will try it out.. and certainly.. appreciate de help from u guys..

0 Kudos
Altera_Forum
Honored Contributor II
481 Views

Also I would look at the structure of your process. You have to be very strict with your coding style for synthesis: 

process (clk, reset_n, async_load) begin if reset_n = '0' then -- ansynchonous clear assignments elsif async_load = '1' then -- asynchronous load assignments elsif rising_edge(clk) then -- put your register assignments (i.e. your state machine) in here end if; end process 

 

Of course you don't have to have the asynchronous reset or load in there: 

process (clk) begin if rising_edge(clk) then -- put your register assignments (i.e. your state machine) in here end if; end process 

 

Don't be tempted to add anything else into the rising_edge(clk) line as this will give you a gated clock. 

 

Altera have some guidelines on coding for synthesis (which are pretty much the same as other FPGA manufacturers): 

 

http://www.altera.com/literature/hb/...din g%20style (http://www.altera.com/literature/hb/qts/qts_qii51007.pdf?gsa_pos=1&wt.oss_r=1&wt.oss=coding%20style

 

By the way the "clk'event and clk = '1'" notation that you've used is fine and basically the same as "rising_edge(clk)" - the only real difference is that the latter works with transitions like 'L' to 'H' in simulation - for synthesis it won't make a difference. 

 

I would start by tweaking your code to comply with this sort of standard and I'm sure you will get rid of the errors, a whole load more warnings that you haven't noticed yet and a whole load of nasties still waiting in the wings. 

 

Probably something like this: 

 

process (CLK,RST) begin if RST = '1' then state <= s0; Digit1 <= (others=>'0'); Digit10 <= (others=>'0'); elsif CLK'event and CLK = '1' then if pedestrian = '1' then state <= s4; else case state is when s0 => -- etc etc end if; end if; end process 

 

Your pedestrian signal is now effectively a synchronous reset but note that the reset and clk conditions are as above. 

 

Hope this helps - the coding style document is really worth a read.
0 Kudos
Altera_Forum
Honored Contributor II
481 Views

thanks for all ur comments. i hav finished modifying de traffic code and now it is really works.. sorry if i bother u all too much..  

 

another question.. de prob that i facing now is that i want to generated a 1 Hz clock using clock divider method from the original crystal frequency of 33.333 MHz.. The FPGA board that I'm using is Apex20k EFC200-484 from Altera 

 

 

de code is as below : 

 

begin 

cloc:process(clk) 

variable cnt : integer range 0 to 16500000; 

begin 

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

if(cnt=16500000)then 

cnt:=0; 

clkout<='1'; 

else 

cnt := cnt+1; 

clkout<='0'; 

end if; 

end if; 

end process cloc; 

 

 

I had compiled the code above.. and when i simulate for 2 seconds .. it took me overnite to finish .. anyone hav better idea than this method? thanks
0 Kudos
Altera_Forum
Honored Contributor II
481 Views

 

--- Quote Start ---  

sorry if i bother u all too much..  

--- Quote End ---  

 

 

No worries - the forum exists for us all to help each other. 

 

As for your clock divider - the code looks fine - the real question is the headache of the simulation job. I'm sure that you'll get a few different bits of advice on this. Personally I would break down the task into a few different objectives. 

 

You've done your big simulation to show that your clock divider works with the correct frequencies - i.e. for a 33 MHz clock and a division of 16500000 you get a 1 Hz output. 

 

Now you want to check that this interacts with everything else in the design which will be the case regardless of the frequencies involved, so change your division to something much quicker - everything based on the 1Hz clock will obviously happen much faster than in real life but you know that when you change your divider constant for synthesis, you will get the right result. 

 

What I sometimes do is use the "--translate synthesis_off" and "--translate synthesis_on" comments to mask off bits from synthesis so that no code changes are required between simulation and synthesis. 

 

constant division : integer := 16500000; constant division_sim : integer := 165; phttp://www.alteraforum.com/images/smilies/tongue.gifrocess(clk) variable cnt : integer range 0 to 16500000; begin if(clk'event and clk='1') then if(cnt=0)then cnt:=division; -- translate synthesis_off cnt := division_sim; -- translate synthesis_on clkout<='1'; else cnt := cnt-1; clkout<='0'; end if; end if; end process cloc; 

 

Basically what happens here is your counter gets loaded with the large value and then decrements to zero. At zero, your output goes high and the counter is reloaded. Now for simulation, you load cnt with division (16500000), then straight way before this value has any effect, you load cnt again but with division_sim (165). For synthesis, the translate pragmas mask off the second assignment and so cnt only gets loaded with division. 

 

This way you can use the same code for (speeded up) simulation and (real time) synthesis. 

 

Hope you find this useful.
0 Kudos
Reply