4

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

giroy
  • 2,203
  • 6
  • 27
  • 38
  • Hmm, this doesn't really sound like the right thing to do. What do you really want to achieve? How do the two clocks relate to each other? How do you want to use 'bit'? Can you draw a waveform in ASCII art? – danielpoe Aug 20 '09 at 08:20
  • the signal aren't actually clocks. its two control signals and the third signal has to respond on the falling edge of one and rising edge of the other. these two signals mark the start and end. I realize this is not the best way of doing it, but that is outside my control and i'm stuck working with it. – giroy Aug 20 '09 at 13:26

1 Answers1

4

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.

Marty
  • 6,494
  • 3
  • 37
  • 40
  • Cool. As I mentioned, be careful with it though - I'm not 100% sure that it's synthesisable. – Marty Aug 20 '09 at 19:28
  • 1
    Also add metastability hardening if the input signals are async to the clock. – Brian Carlton Aug 20 '09 at 19:31
  • Oops - looks like I got sig1 and sig2 switched around if comparing against your code. – Marty Aug 20 '09 at 19:49
  • 1
    As you have asked for comments, the processes output_ctrl and delay_regs should have 'rst' in the sensitivity list and for describing a register you normally want it to have a async reset, therefore I would write (please remove \n with a new line):\n if rst = '1' then\n bito = '0';\n elsif rising_edge(clk) then\n if sig_rise ...\n endif; – danielpoe Aug 21 '09 at 14:19