aboutsummaryrefslogtreecommitdiffstats
path: root/src/simul/simul-vhdl_debug.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/simul/simul-vhdl_debug.adb')
-rw-r--r--src/simul/simul-vhdl_debug.adb728
1 files changed, 728 insertions, 0 deletions
diff --git a/src/simul/simul-vhdl_debug.adb b/src/simul/simul-vhdl_debug.adb
new file mode 100644
index 000000000..651302f57
--- /dev/null
+++ b/src/simul/simul-vhdl_debug.adb
@@ -0,0 +1,728 @@
+-- Debugger for VHDL simulation
+-- Copyright (C) 2022 Tristan Gingold
+--
+-- This file is part of GHDL.
+--
+-- This program 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 of the License, or
+-- (at your option) any later version.
+--
+-- This program 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 this program. If not, see <gnu.org/licenses>.
+
+with System;
+with Ada.Unchecked_Conversion;
+
+with GNAT.OS_Lib;
+
+with Types; use Types;
+with Name_Table; use Name_Table;
+with Simple_IO; use Simple_IO;
+with Utils_IO; use Utils_IO;
+
+with Vhdl.Nodes; use Vhdl.Nodes;
+with Vhdl.Utils; use Vhdl.Utils;
+with Vhdl.Errors;
+
+with Elab.Memtype;
+with Elab.Vhdl_Objtypes; use Elab.Vhdl_Objtypes;
+with Elab.Debugger; use Elab.Debugger;
+with Elab.Vhdl_Debug; use Elab.Vhdl_Debug;
+with Elab.Vhdl_Values; use Elab.Vhdl_Values;
+with Elab.Vhdl_Values.Debug; use Elab.Vhdl_Values.Debug;
+with Simul.Vhdl_Elab; use Simul.Vhdl_Elab;
+with Simul.Vhdl_Simul;
+
+with Grt.Types; use Grt.Types;
+with Grt.Vhdl_Types; use Grt.Vhdl_Types;
+with Grt.Options;
+with Grt.Processes;
+with Grt.Signals; use Grt.Signals;
+with Grt.Disp_Signals;
+with Grt.Rtis_Addr;
+
+package body Simul.Vhdl_Debug is
+
+ procedure Put_Time (Time : Std_Time)
+ is
+ use Grt.Options;
+ Unit : Natural_Time_Scale;
+ T : Std_Time;
+ begin
+ if Time = Std_Time'First then
+ Put ("-Inf");
+ else
+ -- Do not bother with sec, min, and hr.
+ Unit := Time_Resolution_Scale;
+ T := Time;
+ while Unit > 1 and then (T mod 1_000) = 0 loop
+ T := T / 1000;
+ Unit := Unit - 1;
+ end loop;
+ Put_Int64 (Int64 (T));
+ case Unit is
+ when 0 =>
+ Put ("sec");
+ when 1 =>
+ Put ("ms");
+ when 2 =>
+ Put ("us");
+ when 3 =>
+ Put ("ns");
+ when 4 =>
+ Put ("ps");
+ when 5 =>
+ Put ("fs");
+ end case;
+ end if;
+ end Put_Time;
+
+ procedure Disp_Driver_Entry (D : Driver_Entry) is
+ begin
+ Put (" [");
+ Put_Uns32 (Uns32 (D.Proc));
+ Put ("] ");
+ Disp_Instance_Path (Processes_Table.Table (D.Proc).Inst);
+ New_Line;
+ Put (" noff: ");
+ Put_Uns32 (D.Off.Net_Off);
+ Put (", moff: ");
+ Put_Uns32 (Uns32 (D.Off.Mem_Off));
+ Put (", len: ");
+ Put_Uns32 (D.Typ.W);
+ Put (", typ: ");
+ Debug_Type_Short (D.Typ);
+ New_Line;
+ end Disp_Driver_Entry;
+
+ function Read_Value (Value_Ptr : Ghdl_Value_Ptr; Mode : Mode_Type)
+ return Int64 is
+ begin
+ case Mode is
+ when Mode_B1 =>
+ return Ghdl_B1'Pos (Value_Ptr.B1);
+ when Mode_E8 =>
+ return Int64 (Value_Ptr.E8);
+ when Mode_E32 =>
+ return Int64 (Value_Ptr.E32);
+ when Mode_I32 =>
+ return Int64 (Value_Ptr.I32);
+ when Mode_I64 =>
+ return Int64 (Value_Ptr.I64);
+ when Mode_F64 =>
+ raise Internal_Error;
+ end case;
+ end Read_Value;
+
+ function Read_Value (Value : Value_Union; Mode : Mode_Type)
+ return Int64 is
+ begin
+ case Mode is
+ when Mode_B1 =>
+ return Ghdl_B1'Pos (Value.B1);
+ when Mode_E8 =>
+ return Int64 (Value.E8);
+ when Mode_E32 =>
+ return Int64 (Value.E32);
+ when Mode_I32 =>
+ return Int64 (Value.I32);
+ when Mode_I64 =>
+ return Int64 (Value.I64);
+ when Mode_F64 =>
+ raise Internal_Error;
+ end case;
+ end Read_Value;
+
+ procedure Disp_Transaction (Trans : Transaction_Acc;
+ Sig_Type : Node;
+ Mode : Mode_Type)
+ is
+ T : Transaction_Acc;
+ begin
+ T := Trans;
+ loop
+ case T.Kind is
+ when Trans_Value =>
+ Disp_Discrete_Value (Read_Value (T.Val, Mode), Sig_Type);
+ when Trans_Direct =>
+ Disp_Discrete_Value (Read_Value (T.Val_Ptr, Mode), Sig_Type);
+ when Trans_Null =>
+ Put ("NULL");
+ when Trans_Error =>
+ Put ("ERROR");
+ end case;
+ if T.Kind = Trans_Direct then
+ -- The Time field is not updated for direct transaction.
+ Put ("[DIRECT]");
+ else
+ Put ("@");
+ Put_Time (T.Time);
+ end if;
+ T := T.Next;
+ exit when T = null;
+ Put (", ");
+ end loop;
+ end Disp_Transaction;
+
+ procedure Info_Scalar_Signal_Driver (S : Memtyp; Stype : Node)
+ is
+ function To_Address is new Ada.Unchecked_Conversion
+ (Source => Resolved_Signal_Acc, Target => System.Address);
+ Sig : Ghdl_Signal_Ptr;
+ begin
+ Sig := Simul.Vhdl_Simul.Read_Sig (S.Mem);
+ Put_Addr (Sig.all'Address);
+ Put (' ');
+ Grt.Disp_Signals.Disp_Single_Signal_Attributes (Sig);
+ Put (" val=");
+ Disp_Discrete_Value (Read_Value (Sig.Value_Ptr, Sig.Mode), Stype);
+ Put ("; drv=");
+ Disp_Discrete_Value (Read_Value (Sig.Driving_Value, Sig.Mode), Stype);
+ if Sig.Nbr_Ports > 0 then
+ Put (';');
+ Put_Int32 (Int32 (Sig.Nbr_Ports));
+ Put (" ports");
+ end if;
+ case Sig.S.Mode_Sig is
+ when Mode_Signal_User =>
+ if Sig.S.Resolv /= null then
+ Put (" resolver=");
+ Put_Addr (To_Address (Sig.S.Resolv));
+ end if;
+ if Sig.S.Nbr_Drivers = 0 then
+ Put ("; no driver");
+ elsif Sig.S.Nbr_Drivers = 1 then
+ Put ("; trans=");
+ Disp_Transaction
+ (Sig.S.Drivers (0).First_Trans, Stype, Sig.Mode);
+ else
+ for I in 0 .. Sig.S.Nbr_Drivers - 1 loop
+ New_Line;
+ Put (" ");
+-- Disp_Context
+-- (Processes.Get_Rti_Context (Sig.S.Drivers (I).Proc));
+ Put (": ");
+ Disp_Transaction
+ (Sig.S.Drivers (I).First_Trans, Stype, Sig.Mode);
+ end loop;
+ end if;
+
+ when Mode_Delayed =>
+ Put ("; trans=");
+ Disp_Transaction (Sig.S.Attr_Trans, Stype, Sig.Mode);
+
+ when others =>
+ null;
+ end case;
+ New_Line;
+ end Info_Scalar_Signal_Driver;
+
+ generic
+ with procedure For_Scalar_Signal (S : Memtyp; Stype : Node);
+ procedure For_Each_Scalar_Signal (S : Memtyp; Stype : Node);
+
+ procedure For_Each_Scalar_Signal (S : Memtyp; Stype : Node) is
+ begin
+ case S.Typ.Kind is
+ when Type_Bit
+ | Type_Logic
+ | Type_Discrete =>
+ For_Scalar_Signal (S, Get_Base_Type (Stype));
+ when Type_Vector
+ | Type_Array =>
+ declare
+ use Simul.Vhdl_Simul;
+ Len : constant Uns32 := S.Typ.Abound.Len;
+ El_Type : Node;
+ Stride : Uns32;
+ begin
+ if S.Typ.Alast then
+ El_Type := Get_Element_Subtype (Stype);
+ else
+ El_Type := Stype;
+ end if;
+ Stride := S.Typ.Arr_El.W;
+
+ for I in 1 .. Len loop
+ For_Each_Scalar_Signal
+ ((S.Typ.Arr_El, Sig_Index (S.Mem, (Len - I) * Stride)),
+ El_Type);
+ end loop;
+ end;
+ when Type_Record =>
+ declare
+ use Simul.Vhdl_Simul;
+ El_List : constant Iir_Flist :=
+ Get_Elements_Declaration_List (Stype);
+ El : Node;
+ begin
+ for I in S.Typ.Rec.E'Range loop
+ El := Get_Nth_Element (El_List, Natural (I - 1));
+ Put (Image (Get_Identifier (El)));
+ Put (": ");
+ For_Each_Scalar_Signal
+ ((S.Typ.Rec.E (I).Typ,
+ Sig_Index (S.Mem, S.Typ.Rec.E (I).Offs.Net_Off)),
+ Get_Type (El));
+ end loop;
+ end;
+ when Type_Float
+ | Type_Unbounded_Vector
+ | Type_Unbounded_Record
+ | Type_Unbounded_Array
+ | Type_Slice
+ | Type_Protected
+ | Type_File
+ | Type_Access =>
+ raise Internal_Error;
+ end case;
+ end For_Each_Scalar_Signal;
+
+ procedure Info_Signal_Driver is new For_Each_Scalar_Signal
+ (Info_Scalar_Signal_Driver);
+
+ procedure Info_Scalar_Signal_Action (S : Memtyp; Stype : Node)
+ is
+ pragma Unreferenced (Stype);
+ use Grt.Rtis_Addr;
+ use Grt.Processes;
+ Sig : Ghdl_Signal_Ptr;
+ Ev : Action_List_Acc;
+ Ctxt : Rti_Context;
+ begin
+ Sig := Simul.Vhdl_Simul.Read_Sig (S.Mem);
+ Put_Addr (Sig.all'Address);
+ Put (' ');
+ Ev := Sig.Event_List;
+ while Ev /= null loop
+ Ctxt := Get_Rti_Context (Ev.Proc);
+ Put (' ');
+ Put_Addr (Ctxt.Base);
+ Ev := Ev.Next;
+ end loop;
+ New_Line;
+ end Info_Scalar_Signal_Action;
+
+ procedure Info_Signal_Action is new For_Each_Scalar_Signal
+ (Info_Scalar_Signal_Action);
+
+ type Info_Signal_Options is record
+ Value : Boolean;
+ Drivers : Boolean;
+ Actions : Boolean;
+ end record;
+
+ procedure Info_Signal_Opts (Idx : Signal_Index_Type;
+ Opts : Info_Signal_Options)
+ is
+ use Elab.Memtype;
+ S : Signal_Entry renames Signals_Table.Table (Idx);
+ Nbr_Drv : Int32;
+ Nbr_Conn_Drv : Int32;
+ Nbr_Sens : Int32;
+ Sens : Sensitivity_Index_Type;
+ Driver : Driver_Index_Type;
+ Conn : Connect_Index_Type;
+ begin
+ Put_Int32 (Int32 (Idx));
+ Put (": ");
+ if S.Decl = Null_Iir then
+ Put_Line ("??");
+ return;
+ end if;
+
+ Disp_Instance_Path (S.Inst, True);
+ Put ('/');
+ Put (Image (Get_Identifier (S.Decl)));
+
+ case Get_Kind (S.Decl) is
+ when Iir_Kind_Signal_Declaration =>
+ Put (" [sig]");
+ when Iir_Kind_Interface_Signal_Declaration =>
+ case Get_Mode (S.Decl) is
+ when Iir_In_Mode =>
+ Put (" [in]");
+ when Iir_Out_Mode =>
+ Put (" [out]");
+ when Iir_Buffer_Mode =>
+ Put (" [buf]");
+ when Iir_Linkage_Mode =>
+ Put (" [lnk]");
+ when Iir_Inout_Mode =>
+ Put (" [io]");
+ when Iir_Unknown_Mode =>
+ Put (" [??]");
+ end case;
+ when others =>
+ raise Internal_Error;
+ end case;
+ New_Line;
+
+ Put (" type: ");
+ Debug_Type_Short (S.Typ);
+ Put (", len: ");
+ Put_Uns32 (S.Typ.W);
+ New_Line;
+
+ Nbr_Conn_Drv := 0;
+ Conn := S.Connect;
+ while Conn /= No_Connect_Index loop
+ declare
+ C : Connect_Entry renames Connect_Table.Table (Conn);
+ begin
+ if C.Formal_Base = Idx then
+ if C.Drive_Formal then
+ Nbr_Conn_Drv := Nbr_Conn_Drv + 1;
+ end if;
+ Conn := C.Formal_Link;
+ else
+ pragma Assert (C.Actual_Base = Idx);
+ if C.Drive_Actual then
+ Nbr_Conn_Drv := Nbr_Conn_Drv + 1;
+ end if;
+ Conn := C.Actual_Link;
+ end if;
+ end;
+ end loop;
+
+ Nbr_Drv := 0;
+ Driver := S.Drivers;
+ while Driver /= No_Driver_Index loop
+ Nbr_Drv := Nbr_Drv + 1;
+ Driver := Drivers_Table.Table (Driver).Prev_Sig;
+ end loop;
+ Put (" nbr sources: ");
+ Put_Int32 (Nbr_Drv + Nbr_Conn_Drv);
+
+ Nbr_Sens := 0;
+ Sens := S.Sensitivity;
+ while Sens /= No_Sensitivity_Index loop
+ Nbr_Sens := Nbr_Sens + 1;
+ Sens := Sensitivity_Table.Table (Sens).Prev_Sig;
+ end loop;
+
+ Put (", nbr sensitivity: ");
+ Put_Int32 (Nbr_Sens);
+
+ Put (", collapsed_by: ");
+ Put_Uns32 (Uns32 (S.Collapsed_By));
+ New_Line;
+
+ if Opts.Value then
+ Driver := S.Drivers;
+ while Driver /= No_Driver_Index loop
+ declare
+ D : Driver_Entry renames Drivers_Table.Table (Driver);
+ begin
+ Put (" driver:");
+ Disp_Driver_Entry (D);
+
+ Driver := D.Prev_Sig;
+ end;
+ end loop;
+
+ Sens := S.Sensitivity;
+ while Sens /= No_Sensitivity_Index loop
+ declare
+ D : Driver_Entry renames Sensitivity_Table.Table (Sens);
+ begin
+ Put (" sensitivity:");
+ Disp_Driver_Entry (D);
+
+ Sens := D.Prev_Sig;
+ end;
+ end loop;
+
+ Put ("value (");
+ Put_Addr (S.Val.all'Address);
+ Put ("): ");
+ Disp_Memtyp ((S.Typ, S.Val), Get_Type (S.Decl));
+ New_Line;
+ end if;
+
+ if Opts.Drivers and then S.Sig /= null then
+ Put ("drivers (");
+ Put_Addr (S.Sig.all'Address);
+ Put ("): ");
+ New_Line;
+ Info_Signal_Driver ((S.Typ, S.Sig), Get_Type (S.Decl));
+ end if;
+
+ if Opts.Actions and then S.Sig /= null then
+ Put_Line ("actions:");
+ Info_Signal_Action ((S.Typ, S.Sig), Get_Type (S.Decl));
+ end if;
+ end Info_Signal_Opts;
+
+ procedure Info_Signal (Idx : Signal_Index_Type) is
+ begin
+ Info_Signal_Opts (Idx, (others => False));
+ end Info_Signal;
+
+ -- For gdb.
+ pragma Unreferenced (Info_Signal);
+
+ procedure Info_Signal_Proc (Line : String)
+ is
+ Opts : Info_Signal_Options;
+ F, L : Natural;
+ Idx : Uns32;
+ Valid : Boolean;
+ begin
+ Opts := (others => False);
+ Idx := 0;
+
+ F := Line'First;
+ loop
+ F := Skip_Blanks (Line, F);
+ exit when F > Line'Last;
+ L := Get_Word (Line, F);
+ if Line (F .. L) = "-h" then
+ Put_Line ("info sig [OPTS] [SIG]");
+ Put_Line (" -h disp this help");
+ Put_Line (" -v disp values");
+ Put_Line (" -d disp drivers");
+ Put_Line (" -a disp actions");
+ return;
+ elsif Line (F .. L) = "-v" then
+ Opts.Value := True;
+ elsif Line (F .. L) = "-d" then
+ Opts.Drivers := True;
+ elsif Line (F .. L) = "-a" then
+ Opts.Actions := True;
+ elsif Line (F) in '0' .. '9' then
+ To_Num (Line (F .. L), Idx, Valid);
+ if not Valid
+ or else Signal_Index_Type (Idx) > Signals_Table.Last
+ then
+ Put_Line ("invalid signal index");
+ return;
+ end if;
+ else
+ Put_Line ("unknown option");
+ return;
+ end if;
+ F := L + 1;
+ end loop;
+
+ if Idx = 0 then
+ for I in Signals_Table.First .. Signals_Table.Last loop
+ Info_Signal_Opts (I, Opts);
+ end loop;
+ else
+ Info_Signal_Opts (Signal_Index_Type (Idx), Opts);
+ end if;
+ end Info_Signal_Proc;
+
+ procedure Disp_Quantity_Prefix (Decl : Node) is
+ begin
+ case Get_Kind (Decl) is
+ when Iir_Kind_Free_Quantity_Declaration =>
+ Put (Image (Get_Identifier (Decl)));
+ when Iir_Kind_Dot_Attribute =>
+ Disp_Quantity_Prefix (Get_Prefix (Decl));
+ Put ("'dot");
+ when Iir_Kinds_Denoting_Name =>
+ Disp_Quantity_Prefix (Get_Named_Entity (Decl));
+ when others =>
+ Vhdl.Errors.Error_Kind ("disp_quantity_prefix", Decl);
+ end case;
+ end Disp_Quantity_Prefix;
+
+ procedure Info_Quantity_Proc (Line : String)
+ is
+ pragma Unreferenced (Line);
+ begin
+ for I in Quantity_Table.First .. Quantity_Table.Last loop
+ declare
+ Q : Quantity_Entry renames Quantity_Table.Table (I);
+ Idx : Scalar_Quantity_Index;
+ begin
+ Put_Int32 (Int32 (I));
+ Put (": ");
+
+ Disp_Instance_Path (Q.Inst, True);
+ Put ('/');
+ Disp_Quantity_Prefix (Q.Decl);
+ Put (" type: ");
+ Debug_Type_Short (Q.Typ);
+ Put (", len: ");
+ Put_Uns32 (Q.Typ.W);
+ Put (", Idx: ");
+ Put_Uns32 (Uns32 (Q.Idx));
+ Put (", val: ");
+ Disp_Memtyp ((Q.Typ, Q.Val), Get_Type (Q.Decl));
+ New_Line;
+ Idx := Q.Idx;
+ for I in 1 .. Q.Typ.W loop
+ declare
+ use Simul.Vhdl_Simul;
+ Sq : Scalar_Quantity_Record renames
+ Scalar_Quantities_Table.Table (Idx);
+ begin
+ Put (" scal #");
+ Put_Uns32 (Uns32 (Idx));
+ Put (" idx: ");
+ Put_Uns32 (Uns32 (Sq.Idx));
+ Put (", deriv: ");
+ Put_Uns32 (Uns32 (Sq.Deriv));
+ Put (", integ: ");
+ Put_Uns32 (Uns32 (Sq.Integ));
+ New_Line;
+ end;
+ Idx := Idx + 1;
+ end loop;
+ end;
+ end loop;
+ end Info_Quantity_Proc;
+
+ procedure Info_Equations_Proc (Line : String)
+ is
+ pragma Unreferenced (Line);
+ begin
+ for I in Simultaneous_Table.First .. Simultaneous_Table.Last loop
+ declare
+ S : Simultaneous_Record renames Simultaneous_Table.Table (I);
+ begin
+ Put_Int32 (Int32 (I));
+ Put (": ");
+
+ Disp_Instance_Path (S.Inst, True);
+ New_Line;
+ end;
+ end loop;
+ end Info_Equations_Proc;
+
+ procedure Info_Time (Line : String)
+ is
+ pragma Unreferenced (Line);
+ begin
+ Put ("now: ");
+ Put_Time (Current_Time);
+ if Grt.Processes.Flag_AMS then
+ Put (" ");
+ Put_Fp64 (Fp64 (Current_Time_AMS));
+ end if;
+ New_Line;
+ Put ("next time: ");
+ Put_Time (Grt.Processes.Next_Time);
+ New_Line;
+ end Info_Time;
+
+ procedure Run_Proc (Line : String)
+ is
+ Delta_Time : Std_Time;
+ P : Positive;
+ begin
+ P := Skip_Blanks (Line);
+ if P <= Line'Last then
+ Delta_Time := Grt.Options.Parse_Time (Line (P .. Line'Last));
+ if Delta_Time = -1 then
+ return;
+ end if;
+ Simul.Vhdl_Simul.Break_Time := Current_Time + Delta_Time;
+ Grt.Processes.Next_Time := Current_Time + Delta_Time;
+ end if;
+
+ Elab.Debugger.Prepare_Continue;
+ end Run_Proc;
+
+ procedure Ps_Proc (Line : String)
+ is
+ pragma Unreferenced (Line);
+ begin
+ for I in Processes_Table.First .. Processes_Table.Last loop
+ Put_Uns32 (Uns32 (I));
+ Put (": ");
+ Disp_Instance_Path (Processes_Table.Table (I).Inst);
+ Put (" (");
+ Put (Vhdl.Errors.Disp_Location (Processes_Table.Table (I).Proc));
+ Put_Line (")");
+ end loop;
+ end Ps_Proc;
+
+ procedure Trace_Proc (Line : String)
+ is
+ Fn, Ln : Natural;
+ Fv, Lv : Natural;
+ State : Boolean;
+ begin
+ Fn := Skip_Blanks (Line, Line'First);
+ if Fn > Line'Last then
+ Put ("missing trace name");
+ return;
+ end if;
+ Ln := Get_Word (Line, Fn);
+
+ Fv := Skip_Blanks (Line, Ln + 1);
+ if Fv > Line'Last then
+ Put ("missing on/off/0/1");
+ return;
+ end if;
+ Lv := Get_Word (Line, Fv);
+ if Line (Fv .. Lv) = "on" or Line (Fv .. Lv) = "1" then
+ State := True;
+ elsif Line (Fv .. Lv) = "off" or Line (Fv .. Lv) = "0" then
+ State := False;
+ else
+ Put ("expect on/off/0/1");
+ return;
+ end if;
+
+ if Line (Fn .. Ln) = "residues" then
+ Simul.Vhdl_Simul.Trace_Residues := State;
+ else
+ Put_Line ("usage: trace residues on|off|0|1");
+ end if;
+ end Trace_Proc;
+
+ procedure Quit_Proc (Line : String)
+ is
+ pragma Unreferenced (Line);
+ begin
+ GNAT.OS_Lib.OS_Exit (0);
+ end Quit_Proc;
+
+ procedure Init is
+ begin
+ Elab.Vhdl_Debug.Append_Commands;
+ Append_Info_Command
+ (new String'("sig*nal"),
+ new String'("display info about a signal"),
+ Info_Signal_Proc'Access);
+ Append_Info_Command
+ (new String'("quan*tity"),
+ new String'("display info about quantities"),
+ Info_Quantity_Proc'Access);
+ Append_Info_Command
+ (new String'("equ*ations"),
+ new String'("display info about equations"),
+ Info_Equations_Proc'Access);
+ Append_Info_Command
+ (new String'("t*ime"),
+ new String'("display current time"),
+ Info_Time'Access);
+ Append_Menu_Command
+ (new String'("r*un"),
+ new String'("resume execution for an amount of time"),
+ Run_Proc'Access);
+ Append_Menu_Command
+ (new String'("ps"),
+ new String'("print all processes"),
+ Ps_Proc'Access);
+ Append_Menu_Command
+ (new String'("trace"),
+ new String'("enable/disable a trace"),
+ Trace_Proc'Access);
+ Append_Menu_Command
+ (new String'("q*uit"),
+ new String'("exit simulation"),
+ Quit_Proc'Access);
+ end Init;
+end Simul.Vhdl_Debug;