Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

Pretty new at this Trying to make a stopwatch

Here is the code I have

 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity Stopwatch is
port (clk1 : in std_logic;
  run  : in std_logic;
  res  : in std_logic;
      tenths : out std_logic_vector(3 downto 0);
      seconds : out std_logic_vector(3 downto 0);
      tens : out std_logic_vector(3 downto 0);
  LED1 : out std_logic_vector(6 downto 0);
  LED2 : out std_logic_vector(6 downto 0);
  LED3 : out std_logic_vector(6 downto 0)
  
     );
end Stopwatch;
architecture Behavioral of Stopwatch is
signal tnt,sec,ten : integer range 0 to 9 :=0;
signal count : integer :=1;
signal clk : std_logic :='0';
signal runs : std_logic :='0';
begin
tenths <= conv_std_logic_vector(tnt,4);
seconds <= conv_std_logic_vector(sec,4);
tens <= conv_std_logic_vector(ten,4);
 --clk generation.For 100 MHz clock this generates 1 Hz clock.
process(clk1)
begin
if(clk1'event and clk1='1') then
count <=count+1;
if(count = 3) then
clk <= not clk;
count <=1;
end if;
end if;
end process;
 
 
 
process(clk)   --period of clk is 1 second.
begin
if (res = '1') then
tnt<= 0;
sec<= 0;
ten<= 0;
end if;
if (run='1' and runs='0') then
runs <='1';
ELSIF (run='1' and runs='1') then
runs <='0';
end if;
if(clk'event and clk='1') then
if (runs='1')then
tnt <= tnt+ 1; 
end if;
if(tnt = 9) then
tnt<=0;
sec <= sec + 1;
if(sec = 9) then
ten <= ten + 1;
sec <= 0;
if(ten = 9) then
ten <= 0;
end if;
end if;
end if;
end if;
If (tnt = 0) Then
LED1 <= "0000001" ;
ELSIF (tnt = 1) Then
LED1 <= "1001111";
ELSIF (tnt = 2) Then
LED1 <= "0010110";
ELSIF (tnt = 3) Then
LED1 <= "0000110";
ELSIF (tnt = 4) Then
LED1 <= "1001100";
ELSIF (tnt = 5) Then
LED1 <= "0100100";
ELSIF (tnt = 6) Then
LED1 <= "0100000";
ELSIF (tnt = 7) Then
LED1 <= "0001111";
ELSIF (tnt = 8) Then
LED1 <= "0000000";
ELSIF (tnt = 9) Then
LED1 <= "0001100";
end if ;
If (sec = 0) Then
LED2 <= "0000001" ;
ELSIF (sec = 1) Then
LED2 <= "1001111";
ELSIF (sec = 2) Then
LED2 <= "0010110";
ELSIF (sec = 3) Then
LED2 <= "0000110";
ELSIF (sec = 4) Then
LED2 <= "1001100";
ELSIF (sec = 5) Then
LED2 <= "0100100";
ELSIF (sec = 6) Then
LED2 <= "0100000";
ELSIF (sec = 7) Then
LED2 <= "0001111";
ELSIF (sec = 8) Then
LED2 <= "0000000";
ELSIF (sec = 9) Then
LED2 <= "0001100";
end if ;
If (ten = 0) Then
LED3 <= "0000001" ;
ELSIF (ten = 1) Then
LED3 <= "1001111";
ELSIF (ten = 2) Then
LED3 <= "0010110";
ELSIF (ten = 3) Then
LED3 <= "0000110";
ELSIF (ten = 4) Then
LED3 <= "1001100";
ELSIF (ten = 5) Then
LED3 <= "0100100";
ELSIF (ten = 6) Then
LED3 <= "0100000";
ELSIF (ten = 7) Then
LED3 <= "0001111";
ELSIF (ten = 8) Then
LED3 <= "0000000";
ELSIF (ten = 9) Then
LED3 <= "0001100";
end if ;
 
 
end process ;
 
 
end Behavioral;

And I keep getting the error saying

cannot infer register for tnt because it does not hold value outside of clock edge.

The problems go away when i remove the code for res and runs but I want res to be a button that resets everything to 0 when pressed and I want run to be the button that starts and stops the timer.

What am I doing wrong here?

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The synthesizer could be confused by the construction you used for the clocked process. A clocked process should always be constructed like this:

    process(clk,reset)
      if (reset = '1') then
        signals reset
      elsif rising_edge(clk) -- or (clk'event and clk='1')
        instructions
      end if;
    end process;

    You shouldn't do anything outside the clocked area except reset. In you code you have multiple conditions where you modify signals outside a clock edge or reset condition. And worse, some outputs of the process aren't defined on some of the paths, so you will create latches. Stick to the model above and it will avoid lots of problems.

    Also in FPGAs it isn't recommended to generate a clock the way you do, it can lead to timing problems and strange behaviour due to glitches. It is better to do a clock enable, i.e. to clock your process with the 100MHz clock, and only perform the stopwatch actions when the count signal reaches its limit.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Okay, so thats how I should set up the reset but how is the start stop button implemented? It seems like it will just keep running on its own with the way the second if is set up

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    you can sample the start and stop buttons in the clocked part of the process. You can have for example an 'on' signal that you set to 1 when you detect the start button has been pressed and back to 0 when you detect the stop button has been pressed. Then only update your counter when the 'on' signal is 1.