-- GHDL Run Time (GRT) - processes. -- Copyright (C) 2002 - 2014 Tristan Gingold -- -- GHDL is free software; you can redistribute it and/or modify it under -- the terms of the GNU General Public License as published by the Free -- Software Foundation; either version 2, or (at your option) any later -- version. -- -- GHDL is distributed in the hope that it will be useful, but WITHOUT ANY -- WARRANTY; without even the implied warranty of MERCHANTABILITY or -- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- for more details. -- -- You should have received a copy of the GNU General Public License -- along with GCC; see the file COPYING. If not, write to the Free -- Software Foundation, 59 Temple Place - Suite 330, Boston, MA -- 02111-1307, USA. -- -- As a special exception, if other files instantiate generics from this -- unit, or you link this unit with other files to produce an executable, -- this unit does not by itself cause the resulting executable to be -- covered by the GNU General Public License. This exception does not -- however invalidate any other reasons why the executable file might be -- covered by the GNU Public License. with System; with Grt.Stack2; use Grt.Stack2; with Grt.Types; use Grt.Types; with Grt.Signals; use Grt.Signals; with Grt.Stacks; use Grt.Stacks; with Grt.Rtis; use Grt.Rtis; with Grt.Rtis_Addr; with Grt.Stdio; package Grt.Processes is pragma Suppress (All_Checks); -- Internal initialisations. procedure Init; -- Do the VHDL simulation. -- Return 0 in case of success (end of time reached). function Simulation return Integer; -- Number of delta cycles. Nbr_Delta_Cycles : Integer; -- Number of non-delta cycles. Nbr_Cycles : Integer; -- If true, the simulation should be stopped. Break_Simulation : Boolean; -- If true, there is one stack for all processes. Non-sensitized -- processes must save their state. One_Stack : Boolean := False; type Process_Type is private; -- type Process_Acc is access all Process_Type; -- Return the identifier of the current process. -- During the elaboration, this is the identifier of the last process -- being elaborated. So, this function can be used to create signal -- drivers. -- Return the total number of processes and number of sensitized processes. -- Used for statistics. function Get_Nbr_Processes return Natural; function Get_Nbr_Sensitized_Processes return Natural; -- Total number of resumed processes. function Get_Nbr_Resumed_Processes return Natural; -- Disp the name of process PROC. procedure Disp_Process_Name (Stream : Grt.Stdio.FILEs; Proc : Process_Acc); -- Register a process during elaboration. -- This procedure is called by vhdl elaboration code. procedure Ghdl_Process_Register (Instance : Instance_Acc; Proc : Proc_Acc; Ctxt : Ghdl_Rti_Access; Addr : System.Address); procedure Ghdl_Sensitized_Process_Register (Instance : Instance_Acc; Proc : Proc_Acc; Ctxt : Ghdl_Rti_Access; Addr : System.Address); procedure Ghdl_Postponed_Process_Register (Instance : Instance_Acc; Proc : Proc_Acc; Ctxt : Ghdl_Rti_Access; Addr : System.Address); procedure Ghdl_Postponed_Sensitized_Process_Register (Instance : Instance_Acc; Proc : Proc_Acc; Ctxt : Ghdl_Rti_Access; Addr : System.Address); -- For verilog processes. procedure Ghdl_Finalize_Register (Instance : Instance_Acc; Proc : Proc_Acc); procedure Ghdl_Initial_Register (Instance : Instance_Acc; Proc : Proc_Acc); procedure Ghdl_Always_Register (Instance : Instance_Acc; Proc : Proc_Acc); -- Add a simple signal in the sensitivity of the last registered -- (sensitized) process. procedure Ghdl_Process_Add_Sensitivity (Sig : Ghdl_Signal_Ptr); -- Resume a process. procedure Resume_Process (Proc : Process_Acc); -- Incomplete wait statement: -- Wait without timeout or sensitivity: wait; procedure Ghdl_Process_Wait_Exit; -- Wait for a timeout (without sensitivity): wait for X; procedure Ghdl_Process_Wait_Timeout (Time : Std_Time); -- Full wait statement: -- 1. Call Ghdl_Process_Wait_Set_Timeout (if there is a timeout) -- 2. Call Ghdl_Process_Wait_Add_Sensitivity (for each signal) -- 3. Call Ghdl_Process_Wait_Suspend, go to 4 if it returns true (timeout) -- Evaluate the condition and go to 4 if true -- Else, restart 3 -- 4. Call Ghdl_Process_Wait_Close -- Add a timeout for a wait. procedure Ghdl_Process_Wait_Set_Timeout (Time : Std_Time); -- Add a sensitivity for a wait. procedure Ghdl_Process_Wait_Add_Sensitivity (Sig : Ghdl_Signal_Ptr); -- Wait until timeout or sensitivity. -- Return TRUE in case of timeout. function Ghdl_Process_Wait_Suspend return Boolean; -- Finish a wait statement. procedure Ghdl_Process_Wait_Close; -- For one stack setups, wait_suspend is decomposed into the suspension -- procedure and the function to get resume status. procedure Ghdl_Process_Wait_Wait; function Ghdl_Process_Wait_Has_Timeout return Boolean; -- Verilog. procedure Ghdl_Process_Delay (Del : Ghdl_U32); -- Secondary stack. function Ghdl_Stack2_Allocate (Size : Ghdl_Index_Type) return System.Address; function Ghdl_Stack2_Mark return Mark_Id; procedure Ghdl_Stack2_Release (Mark : Mark_Id); -- Protected variables. procedure Ghdl_Protected_Enter (Obj : System.Address); procedure Ghdl_Protected_Leave (Obj : System.Address); procedure Ghdl_Protected_Init (Obj : System.Address); procedure Ghdl_Protected_Fini (Obj : System.Address); type Run_Handler is access function return Integer; -- Run HAND through a wrapper that catch some errors (in particular on -- windows). Returns < 0 in case of error. function Run_Through_Longjump (Hand : Run_Handler) return Integer; pragma Import (Ada, Run_Through_Longjump, "__ghdl_run_through_longjump"); private -- State of a process. type Process_State is ( -- Sensitized process. Its state cannot change. State_Sensitized, -- Non-sensitized process, ready to run. State_Ready, -- Verilog process, being suspended. State_Delayed, -- Non-sensitized process being suspended. State_Wait, -- Non-sensitized process being awaked by a wait timeout. This state -- is transcient. -- This is necessary so that the process will exit immediately from the -- wait statements without checking if the wait condition is true. State_Timeout, -- Non-sensitized process waiting until end. State_Dead); type Process_Type is record -- Stack for the process. -- This must be the first field of the record (and this is the only -- part visible). -- Must be NULL_STACK for sensitized processes. Stack : Stacks.Stack_Type; -- Subprogram containing process code. Subprg : Proc_Acc; -- Instance (THIS parameter) for the subprogram. This : Instance_Acc; -- Name of the process. Rti : Rtis_Addr.Rti_Context; -- True if the process is resumed and will be run at next cycle. Resumed : Boolean; -- True if the process is postponed. Postponed : Boolean; State : Process_State; -- Timeout value for wait. Timeout : Std_Time; -- Sensitivity list while the (non-sensitized) process is waiting. Sensitivity : Action_List_Acc; Timeout_Chain_Next : Process_Acc; Timeout_Chain_Prev : Process_Acc; end record; pragma Export (C, Ghdl_Process_Register, "__ghdl_process_register"); pragma Export (C, Ghdl_Sensitized_Process_Register, "__ghdl_sensitized_process_register"); pragma Export (C, Ghdl_Postponed_Process_Register, "__ghdl_postponed_process_register"); pragma Export (C, Ghdl_Postponed_Sensitized_Process_Register, "__ghdl_postponed_sensitized_process_register"); pragma Export (C, Ghdl_Finalize_Register, "__ghdl_finalize_register"); pragma Export (C, Ghdl_Always_Register, "__ghdl_always_register"); pragma Export (C, Ghdl_Initial_Register, "__ghdl_initial_register"); pragma Export (C, Ghdl_Process_Add_Sensitivity, "__ghdl_process_add_sensitivity"); pragma Export (C, Ghdl_Process_Wait_Exit, "__ghdl_process_wait_exit"); pragma Export (C, Ghdl_Process_Wait_Timeout, "__ghdl_process_wait_timeout"); pragma Export (C, Ghdl_Process_Wait_Add_Sensitivity, "__ghdl_process_wait_add_sensitivity"); pragma Export (C, Ghdl_Process_Wait_Set_Timeout, "__ghdl_process_wait_set_timeout"); pragma Export (Ada, Ghdl_Process_Wait_Suspend, "__ghdl_process_wait_suspend"); pragma Export (C, Ghdl_Process_Wait_Close, "__ghdl_process_wait_close"); pragma Export (C, Ghdl_Process_Delay, "__ghdl_process_delay"); pragma Export (C, Ghdl_Stack2_Allocate, "__ghdl_stack2_allocate"); pragma Export (C, Ghdl_Stack2_Mark, "__ghdl_stack2_mark"); pragma Export (C, Ghdl_Stack2_Release, "__ghdl_stack2_release"); pragma Export (C, Ghdl_Protected_Enter, "__ghdl_protected_enter"); pragma Export (C, Ghdl_Protected_Leave, "__ghdl_protected_leave"); pragma Export (C, Ghdl_Protected_Init, "__ghdl_protected_init"); pragma Export (C, Ghdl_Protected_Fini, "__ghdl_protected_fini"); end Grt.Processes;