Author Topic: externally triggered time counter in verilog  (Read 4041 times)

0 Members and 1 Guest are viewing this topic.

Offline fabioacostaTopic starter

  • Newbie
  • Posts: 1
externally triggered time counter in verilog
« on: November 03, 2014, 04:15:14 am »
Hi I'm new to the fpga world, just got a Xilinx Spartan 3E and started playing around with it in verilog with ISE design tools.

My frustration came when I try to use 2 external triggers to activate counters. My goal is to make a program that when given 3 posedges of a push button in a range of 5 seconds turns on a led. If the 5 seconds go and there haven't been 3 events from the push, resets and restart the process.

I tried to code this and the concept was something like this

Always@(posedge push)
**if first push then flag=1**

Always @(posedge clock)
** if flag==1 then start counter
       **check function for pushes and time reset



This had the issue that I had to change registers on both blocks so I've been told to put both processes in one block. The problem with it is that I don't see a way to make the push posedge work since the clock is always faster.

Is there a way for me to activate a clock counter after another posedge event and make it synthesizable. I know for a fact this is a possible implementation  using a counter that controls another one via reset or enable and I would just make it through schematic if it wasn't for the absurdly large counter that is needed with a 50Mhz clock.

Please help me with this and I'll be eternally grateful.
 

Offline jahonen

  • Super Contributor
  • ***
  • Posts: 1054
  • Country: fi
Re: externally triggered time counter in verilog
« Reply #1 on: November 03, 2014, 11:04:40 am »
You'll need to synchronize the push signal to your clock so that they have guaranteed (or almost, excluding metastability probability :) ) timing relationship. Then generate "edge flag" for the push signal. I suck at verilog so in VHDL something like

Code: [Select]

signal push : std_logic;
signal push_rise : std_logic;

...

push_sync: process(clk, reset)
  variable sreg : std_logic_vector(2 downto 0); -- adjust length for desired metastability protection
begin
  if reset = '1' then
    sreg := (others => '0');
    push <= '0';
  elsif rising_edge(clk) then
    push <= sreg(sreg'left);
    sreg := sreg(sreg'left-1 downto 0) & push_in; -- push_in is the unsynchronized signal
  end if;
end process;

push_edgedet: process(clk, reset)
  variable prev : std_logic;
  if reset = '1' then
    prev := '0';
    push_rise <= '0';
  elsif rising_edge(clk) then
    push_rise <= '0';
    if prev /= push and push = '1' then
      push_rise <= '1';
    end if;
    prev := push;
  end if;
end process;


Now the push_rise is the signal which goes to '1' for one clock period whenever a rising edge is detected, so you can read it safely in your synchronized counter. I guess that it comes from some push-button so it is left an exercise to the reader to implement a debounce for that signal.

Regards,
Janne
« Last Edit: November 03, 2014, 11:09:31 am by jahonen »
 

Online langwadt

  • Super Contributor
  • ***
  • Posts: 4427
  • Country: dk
Re: externally triggered time counter in verilog
« Reply #2 on: November 06, 2014, 12:09:41 am »
Hi I'm new to the fpga world, just got a Xilinx Spartan 3E and started playing around with it in verilog with ISE design tools.

My frustration came when I try to use 2 external triggers to activate counters. My goal is to make a program that when given 3 posedges of a push button in a range of 5 seconds turns on a led. If the 5 seconds go and there haven't been 3 events from the push, resets and restart the process.

I tried to code this and the concept was something like this

Always@(posedge push)
**if first push then flag=1**

Always @(posedge clock)
** if flag==1 then start counter
       **check function for pushes and time reset



This had the issue that I had to change registers on both blocks so I've been told to put both processes in one block. The problem with it is that I don't see a way to make the push posedge work since the clock is always faster.

Is there a way for me to activate a clock counter after another posedge event and make it synthesizable. I know for a fact this is a possible implementation  using a counter that controls another one via reset or enable and I would just make it through schematic if it wasn't for the absurdly large counter that is needed with a 50Mhz clock.

Please help me with this and I'll be eternally grateful.

unless you have very specific needs or want to make life difficult run everything synchronous on a
single clock

i.e. sample the button input on the clock edges, detect the change from low to high use that
to control state machine that counts down from 5 seconds, once it sees the first "pushed"

 
 
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: externally triggered time counter in verilog
« Reply #3 on: November 06, 2014, 08:46:14 pm »
Depending on exactly what you want there is many different ways to skin the cat. Here's how I would do it (in a gibberish pseudo code)

Code: [Select]

on the posedge of the external clock
   
   // Detect when you need to respond to the button press
   if btn_debounced_last = '0' and btn_debounced = '1' and led = '0' then
       if counter = 0 then
           // Start the counter for five seconds
           counter = clock_freq * 5 - 2; 
       elsif press2 = 0 then
           // Flag that we have seen a second press
           press2 = '1';
       else
           // We've seen the third press!
           // Turn on the LED and set up a five second timeout
           led = '1';
           counter = clock_freq * 5 - 1; 
       end if;
   else
        if counter != 0 then
          counter = counter -1;
        else
           // Reset state
           press2 = '0';
           led = '0';
        end if;
   end if;
   btn_debounced_last = btn_debounced;

It's not perfect, and doesn't show how to debounce the button input, but logic looks OK to me at first glance.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf