Search code examples
vhdlxilinxvirtex

Flip-Flop triggered on the edge of two signals


I need a flip flop that reacts on the edges of two different signals. Something like this:

if(rising_edge(sig1)) then
    bit <= '0';
elsif(rising_edge(sig2)) then
    bit <= '1';
end if;

Does such a flip flop exist or is there some other technique i could use? I need this to be synthesizable on a Xilinx Virtex-5 FPGA. Thanks


Solution

  • What I'd usually do in this case is to keep a delayed version of both the control signals and generate a pulse one clock wide at the rising edge of each signal. I'd then use these pulses to drive a tiny FSM to generate the 'bit' signal. Here's some VHDL below.

    --                                         -*-vhdl-*-
    --  Finding edges of control signals and using the
    -- edges to control the state of an output variable
    --
    
    library ieee;
    use ieee.std_logic_1164.all;
    
    entity stackoverflow_edges is
      port ( clk  : in std_ulogic;
         rst  : in std_ulogic;
         sig1 : in std_ulogic;
         sig2 : in std_ulogic;
         bito : out std_ulogic );
    
    end entity stackoverflow_edges;
    
    architecture rtl of stackoverflow_edges is
    
      signal sig1_d1  , sig2_d1   : std_ulogic;
      signal sig1_rise, sig2_rise : std_ulogic;
    
    begin 
    
      -- Flops to store a delayed version of the control signals
      -- If the contorl signals are not synchronous with clk,
      -- consider using a bank of 2 delays and using those outputs
      -- to generate the edge flags
      delay_regs: process ( clk ) is 
      begin 
        if rising_edge(clk) then
          if rst = '1' then 
            sig1_d1 <= '0';
            sig2_d1 <= '0';
          else
            sig1_d1 <= sig1;
            sig2_d1 <= sig2;
          end if;
        end if;
      end process delay_regs;
    
    
      -- Edge flags
      edge_flags: process (sig1, sig1_d1, sig2, sig2_d1) is
      begin
        sig1_rise <= sig1 and not sig1_d1;
        sig2_rise <= sig2 and not sig2_d1;
      end process edge_flags;
    
      -- Output control bit
      output_ctrl: process (clk) is
      begin 
        if rst = '1' then
          bito <= '0';
        elsif sig1_rise = '1' then
          bito <= '1';
        elsif sig2_rise = '1' then
          bito <= '0';
        end if;
      end process output_ctrl;
    
    end rtl;
    

    I'm a lot more comfortable in verilog, so double check this VHDL (any comments appreciated).

    waveforms http://img33.imageshack.us/img33/893/stackoverflowvhdlq.png

    This code assumes that the clock is fast enough to capture all the control signal pulses. If the control signals are not synchronous with the clock, I'd keep a further delayed version of the delayed control signal (eg sig_d2) then make the flags from sig_d1 and sig_d2.