1
\$\begingroup\$

I'd like a process to listen to changes in a signal, but not before 20 ns. How can I achieve that?
It doesn't seem possible to use wait statements in such a process, which makes sense since is has a sensitivity list.
What I'm really trying to achieve is a test bench that changes one signal indefinitely and another for like 5 ns after signal ready = '1'. But I don't know precisely when that will happen. I only know that before 20 ns the system is still resetting and hence I should not listen to changes in ready before 20 ns because then I'd get errors.
Alternatives to the approach in the question are welcome.

| improve this question | | | | |
\$\endgroup\$
  • \$\begingroup\$ if ready = '1' and reset = '1' is probably a good alternative to dictate what should be done in the first 20 ns \$\endgroup\$ – Yuri Borges Jun 18 '15 at 9:08
  • \$\begingroup\$ Run a fast clock. Start incrementing a counter on ready. Ignore changes to the other signal until the counter is high enough. \$\endgroup\$ – David Jun 18 '15 at 9:09
  • 2
    \$\begingroup\$ Perhaps you could do a little research on processes and wait statements. A sensitivity list is the equivalent of placing a `wait on sensitivity_list; as the last statement in the process. If a process sensitivity list and wait statements are mutually exclusive and the process with a sensitivity has an implied wait statement, why not make that explicit? \$\endgroup\$ – user8352 Jun 18 '15 at 9:45
  • \$\begingroup\$ I interpreted the question as referring to wait for 20ns which obviously won't work in real hardware. \$\endgroup\$ – David Jun 18 '15 at 11:40
2
\$\begingroup\$

For much testbench code, we do not use looping processes and process sensitivity lists to search for things. Instead, we use wait to find events.

TestProc : process 
begin
  Out1 <= '1' ; -- Steady 1 after this point.

  -- Find Reset as it deactivates
  -- a better alternative than waiting for an ad-hoc amount of time
  if Reset /= ACTIVE then
    wait until Reset = ACTIVE ; 
  end if; 
  wait until Reset /= ACTIVE ; 

  -- find ready at a level 1
  if ready /= '1' then 
    wait until ready = '1' ; 
  end if ; 
  Out2 <= '1' after 5 ns ; 

  -- find a rising edge of Clock
  -- Assumes that clock always transitions from 0 to 1 
  wait until Clk = '1' ; 
  Out2 <= '0' after 5 ns ; 
  ...

  -- Also find a rising edge of Clock
  -- rising_edge is extra work for the simulator and probably not necessary here
  wait until rising_edge(Clk) ; 
  Out2 <= '1' after 5 ns ; 
  ...

  std.env.stop ; -- stop the testbench
end process TestProc ; 

If you are looking for a behavioral model that drives Out1 to a static value, but inverts Out2 5 ns after each time Ready rises to a 1, then you can do the following:

signal Out2 : std_logic := '0' ; 
. . . 
FollowReady : process  
begin 
  -- initialization 
  Out1 <= '1' ; 
  wait for 20 ns ; 

  -- looping process like behavior
  loop 
    -- Ready is a design signal.  Only detect a 0 to 1 change
    wait until rising_edge(Ready) ;
    Out2 <= not Out2 after 5 ns ; 
  end loop ; 
end process ; 
| improve this answer | | | | |
\$\endgroup\$
1
\$\begingroup\$

To avoid a process with a sensitivity list and a wait statement, you can simply something like that :

Method 1:

Process 1 (No sensitivity list) containing the following:

Out1 <= '1';
wait for 20 ns;
Out1 <= '0';
wait;

Process 2 (The one with a sensitivity list) containing this:

if Ready = '1' then
  -- track signal changes
else
  -- stay idle
end if;

Method 2:

If your VHDL code is to be synthesized, I would try something different, also using two different processes.

It assumes that the changes on the signal you are tracking are not faster than your clock.

Process 1 detects changes on the signal:

edge_detector : process (Clk, Reset_n) 
    begin

    if Reset_n = '0' then  
        edge_detected <='0';
        old_s_signal <='0';  
    elsif rising_edge(Clk) then   
            if old_s_signal='1' and s_signal='0' then
                edge_detected<='1';
            else
                edge_detected<='0';
            end if; 
            old_s_signal<=s_signal;   
    end if;  
end process;

Process 2 waits for 20 ns and then takes actions when a change is seen on the signal:

tracker : process (Clk, Reset_n)   

variable cpt_wait : integer;  

begin

if Reset_n = '0' then 
    cpt_wait := '0';  
    -- initialize all other variables and signals assigned in this process here
elsif rising_edge(Clk) then   
        if cpt_wait = NB_OF_TCLK_TO_MAKE_20_NS then  
            if edge_detected = '1' then
                -- track changes    
            end if;
        else 
           cpt_wait := cpt_wait + 1;   
        end if;
 end if;   

end process;
| improve this answer | | | | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.