Forum Discussion
Altera_Forum
Honored Contributor
17 years agoTiming Problem(Clock Edge)
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... thx6 Replies
- Altera_Forum
Honored Contributor
--- 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.
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.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; - Altera_Forum
Honored Contributor
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 - Altera_Forum
Honored Contributor
Also I would look at the structure of your process. You have to be very strict with your coding style for synthesis:
Of course you don't have to have the asynchronous reset or load in there: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
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) begin if rising_edge(clk) then -- put your register assignments (i.e. your state machine) in here 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.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 - Altera_Forum
Honored Contributor
thanks for ur comment.. i will try it out.. and certainly.. appreciate de help from u guys..
- Altera_Forum
Honored Contributor
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
- Altera_Forum
Honored Contributor
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;