grt-processes.adb

来自「vhdl集成电路设计软件.需要用gcc-4.0.2版本编译.」· ADB 代码 · 共 797 行 · 第 1/2 页

ADB
797
字号
   begin      if Lock.Process /= Get_Current_Process_Id then         Internal_Error ("protected_leave(1)");      end if;      if Lock.Count <= 0 then         Internal_Error ("protected_leave(2)");      end if;      Lock.Count := Lock.Count - 1;      if Lock.Count = 0 then         Lock.Process := Nul_Process_Id;      end if;   end Ghdl_Protected_Leave;   procedure Ghdl_Protected_Init (Obj : System.Address)   is      Lock : Object_Lock_Acc_Acc := To_Lock_Acc_Acc (Obj);   begin      Lock.all := new Object_Lock'(Process => Nul_Process_Id,                                   Count => 0);   end Ghdl_Protected_Init;   procedure Ghdl_Protected_Fini (Obj : System.Address)   is      procedure Deallocate is new Ada.Unchecked_Deallocation        (Object => Object_Lock, Name => Object_Lock_Acc);      Lock : Object_Lock_Acc_Acc := To_Lock_Acc_Acc (Obj);   begin      if Lock.all.Count /= 0 or Lock.all.Process /= Nul_Process_Id then         Internal_Error ("protected_fini");      end if;      Deallocate (Lock.all);   end Ghdl_Protected_Fini;   function Compute_Next_Time return Std_Time   is      Res : Std_Time;   begin      --  f) The time of the next simulation cycle, Tn, is determined by      --     setting it to the earliest of      --     1) TIME'HIGH      Res := Std_Time'Last;      --     2) The next time at which a driver becomes active, or      Res := Std_Time'Min (Res, Grt.Signals.Find_Next_Time);      if Res = Current_Time then         return Res;      end if;      --     3) The next time at which a process resumes.      for I in Process_Table.First .. Process_Table.Last loop         declare            Proc : Process_Type renames Process_Table.Table (I);         begin            if Proc.State = State_Wait              and then Proc.Timeout < Res              and then Proc.Timeout >= 0            then               --  No signals to be updated.               Grt.Signals.Flush_Active_List;               if Proc.Timeout = Current_Time then                  --  Can't be better.                  return Current_Time;               else                  Res := Proc.Timeout;               end if;            end if;         end;      end loop;      return Res;   end Compute_Next_Time;   procedure Disp_Process_Name (Stream : Grt.Stdio.FILEs; Proc : Process_Id)   is   begin      Grt.Rtis_Utils.Put (Stream, Process_Table.Table (Proc).Rti);   end Disp_Process_Name;   type Run_Handler is access function return Integer;   --  pragma Convention (C, Run_Handler);   function Run_Through_Longjump (Hand : Run_Handler) return Integer;   pragma Import (C, Run_Through_Longjump, "__ghdl_run_through_longjump");   --  Run resumed processes.   --  If POSTPONED is true, resume postponed processes, else resume   --  non-posponed processes.   --  Returns one of these values:   --  No process has been run.   Run_None : constant Integer := 1;   --  At least one process was run.   Run_Resumed : constant Integer := 2;   --  Simulation is finished.   Run_Finished : constant Integer := 3;   --  Failure, simulation should stop.   Run_Failure : constant Integer := -1;   function Run_Processes (Postponed : Boolean) return Integer   is      Status : Integer;   begin      Status := Run_None;      if Options.Flag_Stats then         Stats.Start_Processes;      end if;      for I in Process_Table.First .. Process_Table.Last loop         if Process_Table.Table (I).Postponed = Postponed           and Process_Table.Table (I).Resumed         then            if Grt.Options.Trace_Processes then               Grt.Astdio.Put ("run process ");               Disp_Process_Name (Stdio.stdout, I);               Grt.Astdio.Put (" [");               Grt.Astdio.Put (Stdio.stdout, Process_Table.Table (I).This);               Grt.Astdio.Put ("]");               Grt.Astdio.New_Line;            end if;            Process_Table.Table (I).Resumed := False;            Status := Run_Resumed;            Cur_Proc_Id := I;            Cur_Proc := To_Acc (Process_Table.Table (I)'Address);            if Cur_Proc.State = State_Sensitized then               Cur_Proc.Subprg.all (Cur_Proc.This);            else               Stack_Switch (Cur_Proc.Stack, Main_Stack);            end if;            if Grt.Options.Checks then               Ghdl_Signal_Internal_Checks;               Grt.Stack2.Check_Empty (Stack2);            end if;         end if;      end loop;      if Options.Flag_Stats then         Stats.End_Processes;      end if;      return Status;   end Run_Processes;   function Initialization_Phase return Integer   is      Status : Integer;   begin      --  LRM93 12.6.4      --  At the beginning of initialization, the current time, Tc, is assumed      --  to be 0 ns.      Current_Time := 0;      --  The initialization phase consists of the following steps:      --  - The driving value and the effective value of each explicitly      --    declared signal are computed, and the current value of the signal      --    is set to the effective value.  This value is assumed to have been      --    the value of the signal for an infinite length of time prior to      --    the start of the simulation.      Init_Signals;      --  - The value of each implicit signal of the form S'Stable(T) or      --    S'Quiet(T) is set to true.  The value of each implicit signal of      --    the form S'Delayed is set to the initial value of its prefix, S.      --  GHDL: already done when the signals are created.      null;      --  - The value of each implicit GUARD signal is set to the result of      --    evaluating the corresponding guard expression.      null;      --  - Each nonpostponed process in the model is executed until it      --    suspends.      Status := Run_Processes (Postponed => False);      if Status = Run_Failure then         return Run_Failure;      end if;      --  - Each postponed process in the model is executed until it suspends.      Status := Run_Processes (Postponed => True);      if Status = Run_Failure then         return Run_Failure;      end if;      --  - The time of the next simulation cycle (which in this case is the      --    first simulation cycle), Tn, is calculated according to the rules      --    of step f of the simulation cycle, below.      Current_Time := Compute_Next_Time;      return Run_Resumed;   end Initialization_Phase;   --  Launch a simulation cycle.   --  Set FINISHED to true if this is the last cycle.   function Simulation_Cycle return Integer   is      Tn : Std_Time;      Status : Integer;   begin      --  LRM93 12.6.4      --  A simulation cycle consists of the following steps:      --      --  a) The current time, Tc is set equal to Tn.  Simulation is complete      --     when Tn = TIME'HIGH and there are no active drivers or process      --     resumptions at Tn.      --  GHDL: this is done at the last step of the cycle.      null;      --  b) Each active explicit signal in the model is updated.  (Events      --     may occur on signals as a result).      --  c) Each implicit signal in the model is updated.  (Events may occur      --     on signals as a result.)      if Options.Flag_Stats then         Stats.Start_Update;      end if;      Update_Signals;      if Options.Flag_Stats then         Stats.End_Update;      end if;      --  d) For each process P, if P is currently sensitive to a signal S and      --     if an event has occured on S in this simulation cycle, then P      --     resumes.      for I in Process_Table.First .. Process_Table.Last loop         declare            Proc : Process_Type renames Process_Table.Table (I);            El : Sensitivity_Acc;         begin            case Proc.State is               when State_Sensitized =>                  null;               when State_Delayed =>                  if Proc.Timeout = Current_Time then                     Proc.Timeout := Bad_Time;                     Proc.Resumed := True;                     Proc.State := State_Sensitized;                  end if;               when State_Wait =>                  if Proc.Timeout = Current_Time then                     Proc.Timeout := Bad_Time;                     Proc.Resumed := True;                     Proc.State := State_Timeout;                  else                     El := Proc.Sensitivity;                     while El /= null loop                        if El.Sig.Event then                           Proc.Resumed := True;                           exit;                        else                           El := El.Next;                        end if;                     end loop;                  end if;               when State_Timeout =>                  Internal_Error ("process in timeout");               when State_Dead =>                  null;            end case;         end;      end loop;      --  e) Each nonpostponed that has resumed in the current simulation cycle      --     is executed until it suspends.      Status := Run_Processes (Postponed => False);      if Status = Run_Failure then         return Run_Failure;      end if;      --  f) The time of the next simulation cycle, Tn, is determined by      --     setting it to the earliest of      --     1) TIME'HIGH      --     2) The next time at which a driver becomes active, or      --     3) The next time at which a process resumes.      --     If Tn = Tc, then the next simulation cycle (if any) will be a      --     delta cycle.      if Options.Flag_Stats then         Stats.Start_Next_Time;      end if;      Tn := Compute_Next_Time;      if Options.Flag_Stats then         Stats.End_Next_Time;      end if;      --  g) If the next simulation cycle will be a delta cycle, the remainder      --     of the step is skipped.      --     Otherwise, each postponed process that has resumed but has not      --     been executed since its last resumption is executed until it      --     suspends.  Then Tn is recalculated according to the rules of      --     step f.  It is an error if the execution of any postponed      --     process causes a delta cycle to occur immediatly after the      --     current simulation cycle.      if Tn = Current_Time then         if Current_Time = Last_Time and then Status = Run_None then            return Run_Finished;         else            Current_Delta := Current_Delta + 1;            return Run_Resumed;         end if;      else         Current_Delta := 0;         Status := Run_Processes (Postponed => True);         if Status = Run_Resumed then            Flush_Active_List;            if Options.Flag_Stats then               Stats.Start_Next_Time;            end if;            Tn := Compute_Next_Time;            if Options.Flag_Stats then               Stats.End_Next_Time;            end if;            if Tn = Current_Time then               Error ("postponed process causes a delta cycle");            end if;         elsif Status = Run_Failure then            return Run_Failure;         end if;         Current_Time := Tn;         return Run_Resumed;      end if;   end Simulation_Cycle;   function Simulation return Integer   is      use Options;      Status : Integer;   begin      --Put_Line ("grt.processes:" & Process_Id'Image (Process_Table.Last)      --          & " process(es)");--       if Disp_Sig_Types then--          Grt.Disp.Disp_Signals_Type;--       end if;      Grt.Hooks.Call_Start_Hooks;      Status := Run_Through_Longjump (Initialization_Phase'Access);      if Status /= Run_Resumed then         return -1;      end if;      Current_Delta := 0;      Nbr_Delta_Cycles := 0;      Nbr_Cycles := 0;      if Trace_Signals then         Grt.Disp_Signals.Disp_All_Signals;      end if;      if Current_Time /= 0 then         --  This is the end of a cycle.         Cycle_Time := 0;         Grt.Hooks.Call_Cycle_Hooks;      end if;      loop         Cycle_Time := Current_Time;         if Disp_Time then            Grt.Disp.Disp_Now;         end if;         Status := Run_Through_Longjump (Simulation_Cycle'Access);         exit when Status = Run_Failure;         if Trace_Signals then            Grt.Disp_Signals.Disp_All_Signals;         end if;         --  Statistics.         if Current_Delta = 0 then            Nbr_Cycles := Nbr_Cycles + 1;         else            Nbr_Delta_Cycles := Nbr_Delta_Cycles + 1;         end if;         exit when Status = Run_Finished;         if Current_Delta = 0 then            Grt.Hooks.Call_Cycle_Hooks;         end if;         if Current_Delta >= Stop_Delta then            Error ("simulation stopped by --stop-delta");            exit;         end if;         if Current_Time > Stop_Time then            Info ("simulation stopped by --stop-time");            exit;         end if;      end loop;      Grt.Hooks.Call_Finish_Hooks;      if Status = Run_Failure then         return -1;      else         return 0;      end if;   end Simulation;end Grt.Processes;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?