summaryrefslogtreecommitdiff
path: root/src/grt/grt-processes.ads
diff options
context:
space:
mode:
Diffstat (limited to 'src/grt/grt-processes.ads')
-rw-r--r--src/grt/grt-processes.ads260
1 files changed, 260 insertions, 0 deletions
diff --git a/src/grt/grt-processes.ads b/src/grt/grt-processes.ads
new file mode 100644
index 0000000..22326eb
--- /dev/null
+++ b/src/grt/grt-processes.ads
@@ -0,0 +1,260 @@
+-- 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);
+
+ -- 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;