0

So...i need an output pin to stay high for a second and switch back to low. It is triggered manually by a user pressing a button, changing state in a FSM with a much higher speeded clock.

entity red_green is

    port(
        clk      : in   std_logic;
        reset : in std_logic;
        in_red, in_green : in std_logic;
        out_green, out_red : out std_logic

    );

end entity;

architecture r_g of red_green is
signal i_clk, trigger : std_logic;
signal i_reset : std_logic;

begin

process(in_red, in_green, clk )
begin

    if in_red = '1' then
        out_red <= '1';
    elsif rising_edge(i_clk) then
        out_red <= '0';
    end if;

    if in_green = '1' then
        out_green <= '1';
    elsif rising_edge(i_clk) then
        out_green <= '0';
    end if;

end process;


clock : entity work.clock_gen port map( clk => clk, reset => reset, speed => '0', clk_out => i_clk );

end r_g;

The clock_gen component just divides a 50 MHz clock downto 1 Hz by a counter process. The code sort of Works, but the "lenght" of the high on the outputs alters from time to time. I guess depending on the counter value in the clock_gen component.

How do i ensure that i get the same "high time" on my output every time? Using Altera DE2

2 Answers2

1

You generate a 1 Hz clock to reset the outputs without relation to the starting time. Of course the amount of time will vary wildly depending on when exactly the button is pressed.

You will need a counter used as a timer that will start whenever the button is pressed.

Andreas Bombe
  • 2,450
  • 13
  • 20
1

If the 1Hz signal from clock_gen core is not used anywhere else, you can generate a reset signal to precisely measure a 1s interval.

I would also suggests not to use the buttons directly in the sensitivity list of the process. The buttons should be gated by a clock signal in a way like:

process button_hit (clk_in) is
signal btn_old;
begin
    if clk_in'Event and clk_in = '1' then   --use 50MHz clock on DE2 to sample buttons
         btn_old <= btn;
         if btn_old = '1' and btn = '0' then   --this marks the button press 
             reset_sig <= '1';   -- one edge reset signal only to the clock_gen core
         else
             reset_sig <= '0';
         end if;
    end if;
end process;

This will mark precisely your one second interval when pressing the button. If both buttons could be pressed simultaneously you will have to had a timing counter (or instance of clock_gen core) for each of them.

petr
  • 21
  • 2