Cant figure this out. Edge triggered signals..need help VHDL

Status
Not open for further replies.

BlackHelicopter

Full Member level 2
Joined
Jun 3, 2010
Messages
137
Helped
13
Reputation
26
Reaction score
16
Trophy points
1,298
Activity points
2,207
Hi, I'm trying to generate this signal in VHDL(signal out). I have a signal coming in (signal in) that I want to trigger off of on the rising edge, then start a counter with a 20MHz clock (I want some sort of delay that I can control) and then bring it low after the counter/delay is finished.

It's hard for me to figure this out because there are two rising edges I need to trigger off of (clk and signal in, which aren't synced up) and VHDL doesn't agree with anything I've tried. How would you implement this?

I'm having a lot of trouble coding and understanding VHDL and get stuck on problems like this often, anyone have any good advise?
 

Re: Cant figure this out. Edge triggered signals..need help

I would like to help you....
but i want to know more about the problem first...
1.what are we supposed to do if signal in goes low before your delay counter has finished the programmed delay..?
2.Do you want to get signal_out high as soon as you get the input high or one clock delay is permissible ..?
 

Re: Cant figure this out. Edge triggered signals..need help


Hi kvingle,

1. Good question. I would program the delay counter to be less the time signal in is high, so signal out would always go low before signal in does.

I hadn't thought about this, but if signal in did happen to go low, I would still want signal out to have the same delay as I had programmed.

2. I would like to have signal out high as soon as signal in goes high.


Thanks for your help.
 

Re: Cant figure this out. Edge triggered signals..need help

I have tailored this code for you...

Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity sio is
port (
reset : in std_logic;
clk   : in std_logic;
signal_in : in std_logic;
signal_out : out std_logic
);
end entity;

architecture sio_arch of sio is
  constant delay_so : integer := 5;
  signal latch : std_logic;
  signal signal_in_delayed : std_logic;
  signal reset_delay_cntr : std_logic;
  signal delay_cntr : std_logic_vector(31 downto 0);
  signal signal_in_pulse : std_logic;
  signal signal_in_pulse2 : std_logic;
  
begin

signal_out <= signal_in_pulse or signal_in_pulse2 or latch;

signal_in_pulse <= signal_in and not(signal_in_delayed);


process(reset, clk)
begin
  if (reset = '1') then
    delay_cntr <= (others => '0');
    latch <= '0';
    reset_delay_cntr <= '0';
    signal_in_pulse2 <= '0';
    signal_in_delayed <= '0';
  elsif rising_edge(clk) then
    if signal_in = '1' then 
      latch <= '1';
    end if;  
    if reset_delay_cntr = '1' then
      delay_cntr <= (others => '0');
      latch <= '0'; 
    elsif latch = '1' then
      delay_cntr <= delay_cntr + '1';
    end if;
    signal_in_delayed <= signal_in;
    signal_in_pulse2 <= signal_in_pulse; 
    
if (delay_cntr = delay_so) then
    reset_delay_cntr  <= '1';
  elsif signal_in_pulse = '1' then
    reset_delay_cntr  <= '0';     
  end if;

 end if;
  end process;

end sio_arch;


Hope this helps..

Added after 4 minutes:

you can modify 'delay_so' for adjustable delay...
 
Re: Cant figure this out. Edge triggered signals..need help

Sorry for the late reply. Thanks very much for the help and your time! This worked great!

 

Re: Cant figure this out. Edge triggered signals..need help

BlackHelicopter said:
1. Good question. I would program the delay counter to be less the time signal in is high, so signal out would always go low before signal in does.
2. I would like to have signal out high as soon as signal in goes high.

If you want maximum precision on your pulse timing, you should arrange things so that time can be measured using either rising or falling clock edges. I would expect that this could most easily be dealt with if you could use !signal_in as an asynchronous reset, which would mean that if signal_in went low before the timer expired the timing event would be canceled.

If you're not using a logic family which allows double-edge flip flops, , I would suggest having a couple of flip flops which are asynchronously reset by !signal_in, fed a continuously-high data signal, and triggered by rising edge and the other by falling edge. The outputs of these should drive active-low R and S inputs of an RS flip flop (initially, when signal_in is high, both R and S should be active; one will be inactivated, then the other). The input clock should be XOR'ed with the output of this flip flop, and the output of that XOR should be ANDed with the outputs of the two initial latches, and that used to drive the counter.

Thus, if signal_in rises when clock is high, the sequence of events would be:

Initially both flip flops are clear, the RS output is don't-care, and the clock to the counter would be low.
Next the clock would fall, the falling-edge flip flop would be set, the RS output would be clear, and the counter clock would be low (because of the AND gate).
Next the clock would rise, both flip flops would be set, the RS output would still be clear, the XOR output would rise, and the counter clock would rise (since both flip flops and the XOR output would be set).
From thence forth, every clock edge would generate a clock edge to the counter.

If signal_in falls rises clock is low, the sequence of events would be:

Initially both flip flops are clear, the RS output is don't-care, and the clock to the counter would be low.
Next the clock would rise, the rising-edge flip flop would be set, the RS output would be set, and the counter clock would be low (because of the AND gate).
Next the clock would fall, both flip flops would be set, the RS output would still be set, the XOR output would rise, and the counter clock would rise (since both flip flops and the XOR output would be set).
From thence forth, every clock edge would generate a clock edge to the counter.

The clock fed to the counter would be completely clean; the only potential race condition or setup/hold violation would be the rising edge of signal_in relative to a clock edge. In that scenario, one of the flip flops might go into a metastable state. Since the clock output can't start until both a rising and a falling clock edge have been seen, there would be no problem provided the metastable state resolves itself before the next clock edge. If the metastable flip flop resolves high, the counter would start cleanly half a cycle sooner than if it resolves low.

One thing to watch out for is to ensure that the RS inputs are chosen correctly, so that the output of the XOR has its rising edge when the second clock edge arrives. If the output of the XOR has its falling edge then, a runt clock pulse could be generated since one input to the AND would be rising while the other was falling.
 

Re: Cant figure this out. Edge triggered signals..need help


Well! That is why I asked first question, to which BlackHelicopter has already cleared that signal_in is assumed that it wont go low before delay counter is exhausted.
 

Re: Cant figure this out. Edge triggered signals..need help

kvingle said:
Well! That is why I asked first question, to which BlackHelicopter has already cleared that signal_in is assumed that it wont go low before delay counter is exhausted.

I recognize that. It sounded like the original poster didn't expect it to particularly matter what the circuit would do in a circumstance he was expecting would never arise; I wasn't sure whether his suggestion that the cycle continue without regard for the input was predicated upon particular desire to have the system behave that way, or whether the decision was arbitrary. I often find it helpful, when making nearly-arbitrary decisions, to evaluate whether either approach be easier to implement, so I can decide "would it be worth X amount of extra logic to have the system work in fashion P rather than fashion Q?"

If the system can use the enable input as a master-async-reset, then it is relatively practical to use a circuit such as the one I described to allow the clock to run off either the rising or the falling clock edge. In a CPLD, it would use four macrocells(*); I don't know how many resources would be required in various FPGA topologies. If one can't use asynchronous reset, effective clock switching is still possible, but harder.

(*) Clock-phase generation could be done in three macrocells, but a three-cell version would either have a race condition if a latch switches faster than expected, or could generate goofy clock pulses if the first flop-flop that gets hit goes metastable even for a moment. I would thus regard the four-cell version as more robust.
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…