Search code examples
vhdlfpga

Breaking out of a procedure in VHDL


I am trying to figure out a way to break out of a procedure if some external event occurs. Let's say I have a procedure like this:

procedure p_RECEIVE_DATA (
o_data : out std_logic) is
begin

  wait until rising_edge(i2c_clock);
  o_data := i2c_data;
  wait until falling_edge(i2c_clock);

end procedure P_RECEIVE_DATA;

Now what I want is if an external signal, let's call it r_STOP gets asserted at any time, I want this procedure to exit immediately. Is there a nice way to do this? I was thinking that if this Verilog I could use fork/join_any to accomplish this, but there is no equivalent to fork and join in VHDL. Does anyone have any suggestions?


Solution

  • First of all, the code you have here might be just fine for a test or simulation. If this is what it's for, then great. However, keep in mind that code written as you have above is not synthesizable. You can compile and run it in a simulation setup, but you almost certainly won't be able to turn this into a hardware design for an FPGA, ASIC, or any other type of physical device. (In general, procedures can be used in synthesis only when they are called in a process and have no wait statements (or, less commonly, and only in some tools, when all of the wait statements are exactly the same).)

    So to answer exactly what you've asked, the way to break out of a procedure is to call return when the condition you are interested in is met. For example if you wanted a global "r_stop" signal as you suggested make this procedure exit early no matter what whenever it changed to a '1', then you'd look for that explicitly:

    procedure p_RECEIVE_DATA (
    o_data : out std_logic) is
    begin
    
      wait until rising_edge(i2c_clock) or r_stop = '1';
      if r_stop = '1' then return; end if;
      o_data := i2c_data;
      wait until falling_edge(i2c_clock) or r_stop = '1';
      if r_stop = '1' then return; end if;
    
    end procedure P_RECEIVE_DATA;
    

    Again, if this is not testbench code, but is meant to be synthesizable, you need to take a different approach and model your logic as an explicit finite state machine.