1-- Debugger for interpreter 2-- Copyright (C) 2014 Tristan Gingold 3-- 4-- This program is free software: you can redistribute it and/or modify 5-- it under the terms of the GNU General Public License as published by 6-- the Free Software Foundation, either version 2 of the License, or 7-- (at your option) any later version. 8-- 9-- This program is distributed in the hope that it will be useful, 10-- but WITHOUT ANY WARRANTY; without even the implied warranty of 11-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12-- GNU General Public License for more details. 13-- 14-- You should have received a copy of the GNU General Public License 15-- along with this program. If not, see <gnu.org/licenses>. 16 17with System; 18with Tables; 19with Types; use Types; 20with Name_Table; 21with Str_Table; 22with Files_Map; 23with Vhdl.Parse; 24with Vhdl.Scanner; 25with Vhdl.Tokens; 26with Vhdl.Sem_Expr; 27with Vhdl.Sem_Scopes; 28with Vhdl.Canon; 29with Std_Names; 30with Libraries; 31with Vhdl.Std_Package; 32with Vhdl.Annotations; use Vhdl.Annotations; 33with Simul.Elaboration; use Simul.Elaboration; 34with Simul.Execution; use Simul.Execution; 35with Vhdl.Utils; use Vhdl.Utils; 36with Errorout; use Errorout; 37with Vhdl.Errors; use Vhdl.Errors; 38with Vhdl.Prints; 39with Vhdl.Nodes_Walk; use Vhdl.Nodes_Walk; 40with Areapools; use Areapools; 41with Grt.Types; use Grt.Types; 42with Grt.Disp; 43with Grt.Readline; 44with Grt.Errors; 45with Grt.Disp_Signals; 46with Grt.Signals; use Grt.Signals; 47with Grt.Processes; 48with Grt.Options; 49with Grt.Stdio; use Grt.Stdio; 50with Grt.Astdio; use Grt.Astdio; 51with Grt.Astdio.Vhdl; use Grt.Astdio.Vhdl; 52 53package body Simul.Debugger is 54 -- This exception can be raised by a debugger command to directly return 55 -- to the prompt. 56 Command_Error : exception; 57 58 type Menu_Procedure is access procedure (Line : String); 59 60 -- If set (by commands), call this procedure on empty line to repeat 61 -- last command. 62 Cmd_Repeat : Menu_Procedure; 63 64 -- For the list command: current file and current line. 65 List_Current_File : Source_File_Entry := No_Source_File_Entry; 66 List_Current_Line : Natural := 0; 67 List_Current_Line_Pos : Source_Ptr := 0; 68 69 -- Set List_Current_* from a location. To be called after program break 70 -- to indicate current location. 71 procedure Set_List_Current (Loc : Location_Type) 72 is 73 Offset : Natural; 74 begin 75 Files_Map.Location_To_Coord 76 (Loc, List_Current_File, List_Current_Line_Pos, 77 List_Current_Line, Offset); 78 end Set_List_Current; 79 80 Dbg_Top_Frame : Block_Instance_Acc; 81 Dbg_Cur_Frame : Block_Instance_Acc; 82 83 procedure Set_Cur_Frame (Frame : Block_Instance_Acc) is 84 begin 85 Dbg_Cur_Frame := Frame; 86 end Set_Cur_Frame; 87 88 procedure Set_Top_Frame (Frame : Block_Instance_Acc) is 89 begin 90 Dbg_Top_Frame := Frame; 91 Set_Cur_Frame (Frame); 92 end Set_Top_Frame; 93 94 type Breakpoint_Entry is record 95 Stmt : Iir; 96 end record; 97 98 package Breakpoints is new Tables 99 (Table_Index_Type => Natural, 100 Table_Component_Type => Breakpoint_Entry, 101 Table_Low_Bound => 1, 102 Table_Initial => 16); 103 104 -- Current execution state, or reason to stop execution (set by the 105 -- last debugger command). 106 type Exec_State_Type is 107 (-- Execution should continue until a breakpoint is reached or assertion 108 -- failure. 109 Exec_Run, 110 111 -- Execution will stop at the next statement. 112 Exec_Single_Step, 113 114 -- Execution will stop at the next simple statement in the same frame. 115 Exec_Next, 116 117 -- Execution will stop at the next statement in the same frame. In 118 -- case of compound statement, stop after the compound statement. 119 Exec_Next_Stmt); 120 121 Exec_State : Exec_State_Type := Exec_Run; 122 123 -- Current frame for next. 124 Exec_Instance : Block_Instance_Acc; 125 126 -- Current statement for next_stmt. 127 Exec_Statement : Iir; 128 129 procedure Disp_Iir_Location (N : Iir) is 130 begin 131 if N = Null_Iir then 132 Put (stderr, "??:??:??"); 133 else 134 Put (stderr, Disp_Location (N)); 135 end if; 136 Put (stderr, ": "); 137 end Disp_Iir_Location; 138 139 -- Disp a message during execution. 140 procedure Error_Msg_Exec (Msg: String; Loc: in Iir) is 141 begin 142 Disp_Iir_Location (Loc); 143 Put_Line (stderr, Msg); 144 Grt.Errors.Fatal_Error; 145 end Error_Msg_Exec; 146 147 procedure Warning_Msg_Exec (Msg: String; Loc: Iir) is 148 begin 149 Disp_Iir_Location (Loc); 150 Put (stderr, "warning: "); 151 Put_Line (stderr, Msg); 152 end Warning_Msg_Exec; 153 154 -- Disp a message for a constraint error. 155 procedure Error_Msg_Constraint (Expr: in Iir) is 156 begin 157 if Expr /= Null_Iir then 158 Disp_Iir_Location (Expr); 159 end if; 160 Put (stderr, "constraint violation"); 161 if Expr /= Null_Iir then 162 case Get_Kind (Expr) is 163 when Iir_Kind_Addition_Operator => 164 Put_Line (stderr, " in the ""+"" operation"); 165 when Iir_Kind_Substraction_Operator => 166 Put_Line (stderr, " in the ""-"" operation"); 167 when Iir_Kind_Integer_Literal => 168 Put_Line (stderr, ", literal out of range"); 169 when Iir_Kind_Interface_Signal_Declaration 170 | Iir_Kind_Signal_Declaration => 171 Put_Line (stderr, " for " & Disp_Node (Expr)); 172 when others => 173 New_Line (stderr); 174 end case; 175 end if; 176 Grt.Errors.Fatal_Error; 177 end Error_Msg_Constraint; 178 179 function Get_Instance_Local_Name (Instance : Block_Instance_Acc; 180 Short : Boolean := False) 181 return String 182 is 183 Name : constant Iir := Instance.Label; 184 begin 185 if Name = Null_Iir then 186 return "<anon>"; 187 end if; 188 189 case Get_Kind (Name) is 190 when Iir_Kind_Block_Statement 191 | Iir_Kind_If_Generate_Statement 192 | Iir_Kind_For_Generate_Statement 193 | Iir_Kind_Component_Instantiation_Statement 194 | Iir_Kind_Procedure_Declaration 195 | Iir_Kinds_Process_Statement 196 | Iir_Kind_Package_Declaration 197 | Iir_Kind_Configuration_Declaration => 198 return Image_Identifier (Name); 199 when Iir_Kind_Generate_Statement_Body => 200 return Image_Identifier (Get_Parent (Name)) 201 & '(' & Image_Identifier (Name) & ')'; 202 when Iir_Kind_Iterator_Declaration => 203 return Image_Identifier (Get_Parent (Name)) & '(' 204 & Execute_Image_Attribute 205 (Instance.Objects (Get_Info (Name).Slot), Get_Type (Name)) 206 & ')'; 207 when Iir_Kind_Architecture_Body => 208 if Short then 209 return Image_Identifier (Get_Entity (Name)); 210 else 211 return Image_Identifier (Get_Entity (Name)) 212 & '(' & Image_Identifier (Name) & ')'; 213 end if; 214 when others => 215 Error_Kind ("disp_instance_local_name", Name); 216 end case; 217 end Get_Instance_Local_Name; 218 219 -- Disp the name of an instance, without newline. 220 procedure Disp_Instance_Name (Instance: Block_Instance_Acc; 221 Short : Boolean := False) is 222 begin 223 if Instance.Parent /= null then 224 Disp_Instance_Name (Instance.Parent); 225 Put ('.'); 226 end if; 227 Put (Get_Instance_Local_Name (Instance, Short)); 228 end Disp_Instance_Name; 229 230 function Get_Instance_Name (Instance: Block_Instance_Acc) return String 231 is 232 function Parent_Name return String is 233 begin 234 if Instance.Parent /= null then 235 return Get_Instance_Name (Instance.Parent) & '.'; 236 else 237 return ""; 238 end if; 239 end Parent_Name; 240 begin 241 return Parent_Name & Get_Instance_Local_Name (Instance); 242 end Get_Instance_Name; 243 244 procedure Disp_Instances_Tree_Name (Inst : Block_Instance_Acc) is 245 begin 246 if Inst = null then 247 Put ("*null*"); 248 New_Line; 249 return; 250 end if; 251 Put (Get_Instance_Local_Name (Inst)); 252 253 Put (" "); 254 case Get_Kind (Inst.Label) is 255 when Iir_Kind_Block_Statement => 256 Put ("[block]"); 257 when Iir_Kind_If_Generate_Statement 258 | Iir_Kind_For_Generate_Statement 259 | Iir_Kind_Generate_Statement_Body => 260 Put ("[generate]"); 261 when Iir_Kind_Iterator_Declaration => 262 Put ("[iterator]"); 263 when Iir_Kind_Component_Instantiation_Statement => 264 Put ("[component]"); 265 when Iir_Kinds_Process_Statement => 266 Put ("[process]"); 267 when Iir_Kind_Architecture_Body => 268 Put ("[entity]"); 269 when Iir_Kind_Package_Declaration => 270 Put ("[package]"); 271 when Iir_Kind_Configuration_Declaration => 272 Put ("[configuration]"); 273 when others => 274 Error_Kind ("disp_instances_tree_name", Inst.Label); 275 end case; 276 New_Line; 277 end Disp_Instances_Tree_Name; 278 279 procedure Disp_Instances_Tree1 (Inst : Block_Instance_Acc; Pfx : String) 280 is 281 Child : Block_Instance_Acc; 282 begin 283 Child := Inst.Children; 284 if Child = null then 285 return; 286 end if; 287 288 loop 289 if Child.Brother /= null then 290 Put (Pfx & "+-"); 291 Disp_Instances_Tree_Name (Child); 292 293 Disp_Instances_Tree1 (Child, Pfx & "| "); 294 Child := Child.Brother; 295 else 296 Put (Pfx & "`-"); 297 Disp_Instances_Tree_Name (Child); 298 299 Disp_Instances_Tree1 (Child, Pfx & " "); 300 exit; 301 end if; 302 end loop; 303 end Disp_Instances_Tree1; 304 305 procedure Disp_Instances_Tree is 306 begin 307 for I in Global_Instances.Objects'Range loop 308 if Global_Instances.Objects (I) /= null then 309 Disp_Instances_Tree_Name (Global_Instances.Objects (I).Instance); 310 end if; 311 end loop; 312 Disp_Instances_Tree_Name (Top_Instance); 313 Disp_Instances_Tree1 (Top_Instance, ""); 314 end Disp_Instances_Tree; 315 316 -- Disp a block instance, in a human readable way. 317 -- Used to debug. 318 procedure Disp_Block_Instance (Instance: Block_Instance_Acc) is 319 begin 320 Put_Line ("Objects:"); 321 for I in Instance.Objects'Range loop 322 Put (Object_Slot_Type'Image (I) & ": "); 323 Disp_Value_Tab (Instance.Objects (I), 3); 324 New_Line; 325 end loop; 326 end Disp_Block_Instance; 327 328 procedure Disp_Signal (Value : Iir_Value_Literal_Acc; A_Type : Iir); 329 330 procedure Disp_Signal_Array (Value : Iir_Value_Literal_Acc; 331 A_Type : Iir; 332 Dim : Natural) 333 is 334 begin 335 if Dim = Get_Nbr_Elements (Get_Index_Subtype_List (A_Type)) then 336 Put ("("); 337 for I in Value.Val_Array.V'Range loop 338 if I /= 1 then 339 Put (", "); 340 end if; 341 Disp_Signal (Value.Val_Array.V (I), Get_Element_Subtype (A_Type)); 342 end loop; 343 Put (")"); 344 else 345 Put ("("); 346 Disp_Signal_Array (Value, A_Type, Dim + 1); 347 Put (")"); 348 end if; 349 end Disp_Signal_Array; 350 351 procedure Disp_Signal_Record (Value : Iir_Value_Literal_Acc; A_Type : Iir) 352 is 353 List : constant Iir_Flist := 354 Get_Elements_Declaration_List (Get_Base_Type (A_Type)); 355 El : Iir_Element_Declaration; 356 begin 357 Put ("("); 358 for I in Value.Val_Record.V'Range loop 359 El := Get_Nth_Element (List, Natural (I - 1)); 360 if I /= 1 then 361 Put (", "); 362 end if; 363 Put (Name_Table.Image (Get_Identifier (El))); 364 Put (" => "); 365 Disp_Signal (Value.Val_Record.V (I), Get_Type (El)); 366 end loop; 367 Put (")"); 368 end Disp_Signal_Record; 369 370 procedure Disp_Signal_Value 371 (Val : Value_Union; Mode : Mode_Type; Sig_Type : Iir) is 372 begin 373 case Mode is 374 when Mode_I64 => 375 Put (Ghdl_I64'Image (Val.I64)); 376 when Mode_I32 => 377 Put (Ghdl_I32'Image (Val.I32)); 378 when Mode_F64 => 379 Put (Ghdl_F64'Image (Val.F64)); 380 when Mode_E32 => 381 Disp_Iir_Value_Enum (Ghdl_E32'Pos (Val.E32), Sig_Type); 382 when Mode_E8 => 383 Disp_Iir_Value_Enum (Ghdl_E8'Pos (Val.E8), Sig_Type); 384 when Mode_B1 => 385 Disp_Iir_Value_Enum (Ghdl_B1'Pos (Val.B1), Sig_Type); 386 end case; 387 end Disp_Signal_Value; 388 389 procedure Disp_Transaction 390 (Head : Transaction_Acc; Mode : Mode_Type; Sig_Type : Iir) 391 is 392 Trans : Transaction_Acc; 393 begin 394 Trans := Head; 395 loop 396 case Trans.Kind is 397 when Trans_Value => 398 Disp_Signal_Value (Trans.Val, Mode, Sig_Type); 399 when Trans_Direct => 400 Disp_Signal_Value (Trans.Val_Ptr.all, Mode, Sig_Type); 401 when Trans_Null => 402 Put ("NULL"); 403 when Trans_Error => 404 Put ("ERROR"); 405 end case; 406 if Trans.Kind = Trans_Direct then 407 Put ("[DIRECT]"); 408 else 409 Put ("@"); 410 Put_Time (stdout, Trans.Time); 411 end if; 412 Trans := Trans.Next; 413 exit when Trans = null; 414 Put (", "); 415 end loop; 416 end Disp_Transaction; 417 418 procedure Disp_Signal (Value : Iir_Value_Literal_Acc; A_Type : Iir) is 419 begin 420 if Value = null then 421 Put ("!NULL!"); 422 return; 423 end if; 424 case Value.Kind is 425 when Iir_Value_Scalars 426 | Iir_Value_Access => 427 Disp_Iir_Value (Value, A_Type); 428 when Iir_Value_Array => 429 Disp_Signal_Array (Value, A_Type, 1); 430 when Iir_Value_Record => 431 Disp_Signal_Record (Value, A_Type); 432 when Iir_Value_Range => 433 -- FIXME. 434 raise Internal_Error; 435 when Iir_Value_Signal => 436 declare 437 Sig : constant Ghdl_Signal_Ptr := Value.Sig; 438 begin 439 Disp_Signal_Value (Sig.Value_Ptr.all, Sig.Mode, A_Type); 440 Grt.Disp_Signals.Disp_Single_Signal_Attributes (Value.Sig); 441 New_Line; 442 if Sig.S.Mode_Sig in Mode_Signal_User then 443 for I in 1 .. Sig.S.Nbr_Drivers loop 444 Put (" "); 445 Disp_Transaction (Sig.S.Drivers (I - 1).First_Trans, 446 Sig.Mode, A_Type); 447 New_Line; 448 end loop; 449 end if; 450 end; 451 when Iir_Value_File 452 | Iir_Value_Protected 453 | Iir_Value_Quantity 454 | Iir_Value_Terminal 455 | Iir_Value_Instance => 456 raise Internal_Error; 457 end case; 458 end Disp_Signal; 459 460 procedure Disp_Instance_Signal (Instance: Block_Instance_Acc; Decl : Iir) 461 is 462 Info : constant Sim_Info_Acc := Get_Info (Decl); 463 begin 464 Put (" "); 465 Put (Name_Table.Image (Get_Identifier (Decl))); 466 Put (" = "); 467 Disp_Signal (Instance.Objects (Info.Slot), Get_Type (Decl)); 468 end Disp_Instance_Signal; 469 470 procedure Disp_Instance_Signals_Of_Chain (Instance: Block_Instance_Acc; 471 Chain : Iir) 472 is 473 El : Iir; 474 begin 475 El := Chain; 476 while El /= Null_Iir loop 477 case Get_Kind (El) is 478 when Iir_Kind_Signal_Declaration 479 | Iir_Kind_Interface_Signal_Declaration => 480 Disp_Instance_Signal (Instance, El); 481 when others => 482 null; 483 end case; 484 El := Get_Chain (El); 485 end loop; 486 end Disp_Instance_Signals_Of_Chain; 487 488 procedure Disp_Instance_Signals (Instance: Block_Instance_Acc) 489 is 490 Blk : constant Iir := Instance.Label; 491 Child: Block_Instance_Acc; 492 begin 493 case Get_Kind (Blk) is 494 when Iir_Kind_Architecture_Body => 495 declare 496 Ent : constant Iir := Get_Entity (Blk); 497 begin 498 Disp_Instance_Name (Instance); 499 Put_Line (" [architecture]:"); 500 501 Disp_Instance_Signals_Of_Chain 502 (Instance, Get_Port_Chain (Ent)); 503 Disp_Instance_Signals_Of_Chain 504 (Instance, Get_Declaration_Chain (Ent)); 505 Disp_Instance_Signals_Of_Chain 506 (Instance, Get_Declaration_Chain (Blk)); 507 end; 508 when Iir_Kind_Block_Statement => 509 Disp_Instance_Name (Instance); 510 Put_Line (" [block]:"); 511 512 declare 513 Header : constant Iir := Get_Block_Header (Blk); 514 begin 515 if Header /= Null_Iir then 516 Disp_Instance_Signals_Of_Chain 517 (Instance, Get_Port_Chain (Header)); 518 end if; 519 end; 520 Disp_Instance_Signals_Of_Chain 521 (Instance, Get_Declaration_Chain (Blk)); 522 523 when Iir_Kind_If_Generate_Statement 524 | Iir_Kind_For_Generate_Statement => 525 Disp_Instance_Name (Instance); 526 Put_Line (" [generate]:"); 527 528 when Iir_Kind_Generate_Statement_Body => 529 Disp_Instance_Signals_Of_Chain 530 (Instance, Get_Declaration_Chain (Blk)); 531 when Iir_Kind_Component_Instantiation_Statement => 532 Disp_Instance_Name (Instance); 533 Put_Line (" [component]:"); 534 Disp_Instance_Signals_Of_Chain 535 (Instance, Get_Port_Chain (Instance.Stmt)); 536 when Iir_Kinds_Process_Statement => 537 null; 538 when Iir_Kind_Iterator_Declaration => 539 null; 540 when others => 541 Error_Kind ("disp_instance_signals", Instance.Label); 542 end case; 543 544 Child := Instance.Children; 545 while Child /= null loop 546 Disp_Instance_Signals (Child); 547 Child := Child.Brother; 548 end loop; 549 end Disp_Instance_Signals; 550 551 -- Disp all signals name and values. 552 procedure Disp_Signals_Value is 553 begin 554 if Disp_Time_Before_Values then 555 Grt.Disp.Disp_Now; 556 end if; 557 Disp_Instance_Signals (Top_Instance); 558 end Disp_Signals_Value; 559 560 procedure Disp_Label (Process : Iir) 561 is 562 Label : Name_Id; 563 begin 564 Label := Get_Label (Process); 565 if Label = Null_Identifier then 566 Put ("<unlabeled>"); 567 else 568 Put (Name_Table.Image (Label)); 569 end if; 570 end Disp_Label; 571 572 procedure Disp_Declaration_Object 573 (Instance : Block_Instance_Acc; Decl : Iir) is 574 begin 575 case Get_Kind (Decl) is 576 when Iir_Kind_Constant_Declaration 577 | Iir_Kind_Variable_Declaration 578 | Iir_Kind_Interface_Variable_Declaration 579 | Iir_Kind_Interface_Constant_Declaration 580 | Iir_Kind_Interface_File_Declaration 581 | Iir_Kind_Object_Alias_Declaration => 582 Put (Disp_Node (Decl)); 583 Put (" = "); 584 Disp_Value_Tab (Instance.Objects (Get_Info (Decl).Slot), 3); 585 when Iir_Kind_Interface_Signal_Declaration 586 | Iir_Kind_Signal_Declaration => 587 declare 588 Sig : Iir_Value_Literal_Acc; 589 begin 590 Sig := Instance.Objects (Get_Info (Decl).Slot); 591 Put (Disp_Node (Decl)); 592 Put (" = "); 593 Disp_Signal (Sig, Get_Type (Decl)); 594 New_Line; 595 end; 596 when Iir_Kinds_Signal_Attribute => 597 -- FIXME: todo ? 598 null; 599 when Iir_Kind_Type_Declaration 600 | Iir_Kind_Anonymous_Type_Declaration 601 | Iir_Kind_Subtype_Declaration => 602 -- FIXME: disp ranges 603 null; 604 when others => 605 Error_Kind ("disp_declaration_object", Decl); 606 end case; 607 end Disp_Declaration_Object; 608 609 procedure Disp_Declaration_Objects 610 (Instance : Block_Instance_Acc; Decl_Chain : Iir) 611 is 612 El : Iir; 613 begin 614 El := Decl_Chain; 615 while El /= Null_Iir loop 616 Disp_Declaration_Object (Instance, El); 617 El := Get_Chain (El); 618 end loop; 619 end Disp_Declaration_Objects; 620 621 procedure Disp_Objects (Instance : Block_Instance_Acc) 622 is 623 Decl : constant Iir := Instance.Label; 624 begin 625 Disp_Instance_Name (Instance); 626 New_Line; 627 case Get_Kind (Decl) is 628 when Iir_Kind_Procedure_Declaration 629 | Iir_Kind_Function_Declaration => 630 Disp_Declaration_Objects 631 (Instance, Get_Interface_Declaration_Chain (Decl)); 632 Disp_Declaration_Objects 633 (Instance, 634 Get_Declaration_Chain (Get_Subprogram_Body (Decl))); 635 when Iir_Kind_Architecture_Body => 636 declare 637 Entity : constant Iir_Entity_Declaration := Get_Entity (Decl); 638 begin 639 Disp_Declaration_Objects 640 (Instance, Get_Generic_Chain (Entity)); 641 Disp_Declaration_Objects 642 (Instance, Get_Port_Chain (Entity)); 643 Disp_Declaration_Objects 644 (Instance, Get_Declaration_Chain (Entity)); 645 Disp_Declaration_Objects 646 (Instance, Get_Declaration_Chain (Decl)); 647 -- FIXME: processes. 648 end; 649 when Iir_Kind_Component_Instantiation_Statement => 650 null; 651 when others => 652 Error_Kind ("disp_objects", Decl); 653 end case; 654 end Disp_Objects; 655 pragma Unreferenced (Disp_Objects); 656 657 procedure Disp_Process_Stats 658 is 659 Proc : Iir; 660 Stmt : Iir; 661 Nbr_User_Sensitized_Processes : Natural := 0; 662 Nbr_User_If_Sensitized_Processes : Natural := 0; 663 Nbr_Conc_Sensitized_Processes : Natural := 0; 664 Nbr_User_Non_Sensitized_Processes : Natural := 0; 665 Nbr_Conc_Non_Sensitized_Processes : Natural := 0; 666 begin 667 for I in Processes_Table.First .. Processes_Table.Last loop 668 Proc := Processes_Table.Table (I).Label; 669 case Get_Kind (Proc) is 670 when Iir_Kind_Sensitized_Process_Statement => 671 if Get_Process_Origin (Proc) = Null_Iir then 672 Stmt := Get_Sequential_Statement_Chain (Proc); 673 if Stmt /= Null_Iir 674 and then Get_Kind (Stmt) = Iir_Kind_If_Statement 675 and then Get_Chain (Stmt) = Null_Iir 676 then 677 Nbr_User_If_Sensitized_Processes := 678 Nbr_User_If_Sensitized_Processes + 1; 679 else 680 Nbr_User_Sensitized_Processes := 681 Nbr_User_Sensitized_Processes + 1; 682 end if; 683 else 684 Nbr_Conc_Sensitized_Processes := 685 Nbr_Conc_Sensitized_Processes + 1; 686 end if; 687 when Iir_Kind_Process_Statement => 688 if Get_Process_Origin (Proc) = Null_Iir then 689 Nbr_User_Non_Sensitized_Processes := 690 Nbr_User_Non_Sensitized_Processes + 1; 691 else 692 Nbr_Conc_Non_Sensitized_Processes := 693 Nbr_Conc_Non_Sensitized_Processes + 1; 694 end if; 695 when others => 696 raise Internal_Error; 697 end case; 698 end loop; 699 700 Put (Natural'Image (Nbr_User_If_Sensitized_Processes)); 701 Put_Line (" user sensitized processes with only a if stmt"); 702 Put (Natural'Image (Nbr_User_Sensitized_Processes)); 703 Put_Line (" user sensitized processes (others)"); 704 Put (Natural'Image (Nbr_User_Non_Sensitized_Processes)); 705 Put_Line (" user non sensitized processes"); 706 Put (Natural'Image (Nbr_Conc_Sensitized_Processes)); 707 Put_Line (" sensitized concurrent statements"); 708 Put (Natural'Image (Nbr_Conc_Non_Sensitized_Processes)); 709 Put_Line (" non sensitized concurrent statements"); 710 Put (Process_Index_Type'Image (Processes_Table.Last)); 711 Put_Line (" processes (total)"); 712 end Disp_Process_Stats; 713 714 procedure Disp_Signals_Stats 715 is 716 type Counters_Type is array (Mode_Signal_Type) of Natural; 717 Counters : Counters_Type := (others => 0); 718 Nbr_User_Signals : Natural := 0; 719 Nbr_Signal_Elements : Natural := 0; 720 begin 721 for I in Signals_Table.First .. Signals_Table.Last loop 722 declare 723 Ent : Signal_Entry renames Signals_Table.Table (I); 724 begin 725 if Ent.Kind in Mode_Signal_User then 726 Nbr_User_Signals := Nbr_User_Signals + 1; 727 Nbr_Signal_Elements := Nbr_Signal_Elements + 728 Get_Nbr_Of_Scalars (Signals_Table.Table (I).Sig); 729 end if; 730 Counters (Ent.Kind) := Counters (Ent.Kind) + 1; 731 end; 732 end loop; 733 Put (Integer'Image (Nbr_User_Signals)); 734 Put_Line (" declared user signals or ports"); 735 Put (Integer'Image (Nbr_Signal_Elements)); 736 Put_Line (" user signals sub-elements"); 737 Put (Integer'Image (Counters (Mode_Quiet))); 738 Put_Line (" 'quiet implicit signals"); 739 Put (Integer'Image (Counters (Mode_Stable))); 740 Put_Line (" 'stable implicit signals"); 741 Put (Integer'Image (Counters (Mode_Delayed))); 742 Put_Line (" 'delayed implicit signals"); 743 Put (Integer'Image (Counters (Mode_Transaction))); 744 Put_Line (" 'transaction implicit signals"); 745 Put (Integer'Image (Counters (Mode_Guard))); 746 Put_Line (" guard signals"); 747 end Disp_Signals_Stats; 748 749 procedure Disp_Design_Stats is 750 begin 751 Disp_Process_Stats; 752 753 New_Line; 754 755 Disp_Signals_Stats; 756 757 New_Line; 758 759 Put (Integer'Image (Connect_Table.Last)); 760 Put_Line (" connections"); 761 end Disp_Design_Stats; 762 763 procedure Disp_Design_Non_Sensitized 764 is 765 Instance : Block_Instance_Acc; 766 Proc : Iir; 767 begin 768 for I in Processes_Table.First .. Processes_Table.Last loop 769 Instance := Processes_Table.Table (I); 770 Proc := Processes_Table.Table (I).Label; 771 if Get_Kind (Proc) = Iir_Kind_Process_Statement then 772 Disp_Instance_Name (Instance); 773 New_Line; 774 Put_Line (" at " & Disp_Location (Proc)); 775 end if; 776 end loop; 777 end Disp_Design_Non_Sensitized; 778 779 procedure Disp_Design_Connections is 780 begin 781 for I in Connect_Table.First .. Connect_Table.Last loop 782 declare 783 Conn : Connect_Entry renames Connect_Table.Table (I); 784 begin 785 Disp_Iir_Location (Conn.Assoc); 786 New_Line; 787 end; 788 end loop; 789 end Disp_Design_Connections; 790 791 function Walk_Files (Cb : Walk_Cb) return Walk_Status 792 is 793 Lib : Iir_Library_Declaration := Libraries.Get_Libraries_Chain; 794 File : Iir_Design_File; 795 begin 796 while Lib /= Null_Iir loop 797 File := Get_Design_File_Chain (Lib); 798 while File /= Null_Iir loop 799 case Cb.all (File) is 800 when Walk_Continue => 801 null; 802 when Walk_Up => 803 exit; 804 when Walk_Abort => 805 return Walk_Abort; 806 end case; 807 File := Get_Chain (File); 808 end loop; 809 Lib := Get_Chain (Lib); 810 end loop; 811 return Walk_Continue; 812 end Walk_Files; 813 814 Walk_Units_Cb : Walk_Cb; 815 816 function Cb_Walk_Units (Design_File : Iir) return Walk_Status 817 is 818 Unit : Iir_Design_Unit; 819 begin 820 Unit := Get_First_Design_Unit (Design_File); 821 while Unit /= Null_Iir loop 822 case Walk_Units_Cb.all (Get_Library_Unit (Unit)) is 823 when Walk_Continue => 824 null; 825 when Walk_Abort => 826 return Walk_Abort; 827 when Walk_Up => 828 exit; 829 end case; 830 Unit := Get_Chain (Unit); 831 end loop; 832 return Walk_Continue; 833 end Cb_Walk_Units; 834 835 function Walk_Units (Cb : Walk_Cb) return Walk_Status is 836 begin 837 Walk_Units_Cb := Cb; 838 return Walk_Files (Cb_Walk_Units'Access); 839 end Walk_Units; 840 841 Walk_Declarations_Cb : Walk_Cb; 842 843 function Cb_Walk_Declarations (Unit : Iir) return Walk_Status 844 is 845 function Walk_Decl_Chain (Chain : Iir) return Walk_Status 846 is 847 Decl : Iir; 848 begin 849 Decl := Chain; 850 while Decl /= Null_Iir loop 851 case Walk_Declarations_Cb.all (Decl) is 852 when Walk_Abort => 853 return Walk_Abort; 854 when Walk_Up => 855 return Walk_Continue; 856 when Walk_Continue => 857 null; 858 end case; 859 Decl := Get_Chain (Decl); 860 end loop; 861 return Walk_Continue; 862 end Walk_Decl_Chain; 863 864 function Walk_Conc_Chain (Chain : Iir) return Walk_Status; 865 866 function Walk_Generate_Statement_Body (Bod : Iir) return Walk_Status is 867 begin 868 if Walk_Decl_Chain (Get_Declaration_Chain (Bod)) = Walk_Abort then 869 return Walk_Abort; 870 end if; 871 if Walk_Conc_Chain (Get_Concurrent_Statement_Chain (Bod)) = Walk_Abort 872 then 873 return Walk_Abort; 874 end if; 875 return Walk_Continue; 876 end Walk_Generate_Statement_Body; 877 878 function Walk_Conc_Chain (Chain : Iir) return Walk_Status 879 is 880 Stmt : Iir := Chain; 881 begin 882 while Stmt /= Null_Iir loop 883 case Get_Kind (Stmt) is 884 when Iir_Kinds_Process_Statement => 885 if Walk_Decl_Chain (Get_Declaration_Chain (Stmt)) 886 = Walk_Abort 887 then 888 return Walk_Abort; 889 end if; 890 when Iir_Kind_For_Generate_Statement => 891 if Walk_Declarations_Cb.all 892 (Get_Parameter_Specification (Stmt)) = Walk_Abort 893 or else Walk_Generate_Statement_Body 894 (Get_Generate_Statement_Body (Stmt)) = Walk_Abort 895 then 896 return Walk_Abort; 897 end if; 898 when Iir_Kind_If_Generate_Statement => 899 declare 900 Stmt1 : Iir; 901 begin 902 Stmt1 := Stmt; 903 while Stmt1 /= Null_Iir loop 904 if Walk_Generate_Statement_Body 905 (Get_Generate_Statement_Body (Stmt)) = Walk_Abort 906 then 907 return Walk_Abort; 908 end if; 909 Stmt1 := Get_Generate_Else_Clause (Stmt1); 910 end loop; 911 end; 912 when Iir_Kind_Component_Instantiation_Statement => 913 null; 914 when Iir_Kind_Block_Statement => 915 -- FIXME: header 916 if (Walk_Decl_Chain 917 (Get_Declaration_Chain (Stmt)) = Walk_Abort) 918 or else 919 (Walk_Conc_Chain 920 (Get_Concurrent_Statement_Chain (Stmt)) = Walk_Abort) 921 then 922 return Walk_Abort; 923 end if; 924 when others => 925 Error_Kind ("walk_conc_chain", Stmt); 926 end case; 927 Stmt := Get_Chain (Stmt); 928 end loop; 929 return Walk_Continue; 930 end Walk_Conc_Chain; 931 begin 932 case Get_Kind (Unit) is 933 when Iir_Kind_Entity_Declaration => 934 if Walk_Decl_Chain (Get_Generic_Chain (Unit)) = Walk_Abort 935 or else Walk_Decl_Chain (Get_Port_Chain (Unit)) = Walk_Abort 936 or else (Walk_Decl_Chain 937 (Get_Declaration_Chain (Unit)) = Walk_Abort) 938 or else (Walk_Conc_Chain 939 (Get_Concurrent_Statement_Chain (Unit)) = Walk_Abort) 940 then 941 return Walk_Abort; 942 end if; 943 when Iir_Kind_Architecture_Body => 944 if (Walk_Decl_Chain 945 (Get_Declaration_Chain (Unit)) = Walk_Abort) 946 or else (Walk_Conc_Chain 947 (Get_Concurrent_Statement_Chain (Unit)) = Walk_Abort) 948 then 949 return Walk_Abort; 950 end if; 951 when Iir_Kind_Package_Declaration 952 | Iir_Kind_Package_Body => 953 if Walk_Decl_Chain (Get_Declaration_Chain (Unit)) = Walk_Abort 954 then 955 return Walk_Abort; 956 end if; 957 when Iir_Kind_Configuration_Declaration => 958 if Walk_Decl_Chain (Get_Declaration_Chain (Unit)) = Walk_Abort 959 then 960 return Walk_Abort; 961 end if; 962 -- FIXME: block configuration ? 963 when Iir_Kind_Context_Declaration => 964 null; 965 when others => 966 Error_Kind ("Cb_Walk_Declarations", Unit); 967 end case; 968 return Walk_Continue; 969 end Cb_Walk_Declarations; 970 971 function Walk_Declarations (Cb : Walk_Cb) return Walk_Status is 972 begin 973 Walk_Declarations_Cb := Cb; 974 return Walk_Units (Cb_Walk_Declarations'Access); 975 end Walk_Declarations; 976 977 function Is_Blank (C : Character) return Boolean is 978 begin 979 return C = ' ' or else C = ASCII.HT; 980 end Is_Blank; 981 982 function Skip_Blanks (S : String) return Positive 983 is 984 P : Positive := S'First; 985 begin 986 while P <= S'Last and then Is_Blank (S (P)) loop 987 P := P + 1; 988 end loop; 989 return P; 990 end Skip_Blanks; 991 992 -- Return the position of the last character of the word (the last 993 -- non-blank character). 994 function Get_Word (S : String) return Positive 995 is 996 P : Positive := S'First; 997 begin 998 while P <= S'Last and then not Is_Blank (S (P)) loop 999 P := P + 1; 1000 end loop; 1001 return P - 1; 1002 end Get_Word; 1003 1004 procedure Disp_A_Frame (Instance: Block_Instance_Acc) is 1005 begin 1006 if Instance = Global_Instances then 1007 pragma Assert (Instance.Label = Null_Iir); 1008 Put_Line ("global instances"); 1009 return; 1010 end if; 1011 1012 Put (Disp_Node (Instance.Label)); 1013 if Instance.Stmt /= Null_Iir then 1014 Put (" at "); 1015 Put (Files_Map.Image (Get_Location (Instance.Stmt))); 1016 end if; 1017 New_Line; 1018 end Disp_A_Frame; 1019 1020 procedure Debug_Bt (Instance : Block_Instance_Acc) 1021 is 1022 Inst : Block_Instance_Acc; 1023 begin 1024 Inst := Instance; 1025 while Inst /= null loop 1026 Disp_A_Frame (Inst); 1027 Inst := Inst.Parent; 1028 end loop; 1029 end Debug_Bt; 1030 pragma Unreferenced (Debug_Bt); 1031 1032 procedure Debug_Upblock (Instance : Block_Instance_Acc) 1033 is 1034 Inst : Block_Instance_Acc; 1035 begin 1036 Inst := Instance; 1037 while Inst /= null loop 1038 Disp_A_Frame (Inst); 1039 Inst := Inst.Up_Block; 1040 end loop; 1041 end Debug_Upblock; 1042 pragma Unreferenced (Debug_Upblock); 1043 1044 procedure Disp_Current_Lines 1045 is 1046 use Files_Map; 1047 -- Number of lines to display before and after the current line. 1048 Radius : constant := 5; 1049 1050 Buf : File_Buffer_Acc; 1051 1052 Pos : Source_Ptr; 1053 Line : Natural; 1054 Len : Source_Ptr; 1055 C : Character; 1056 begin 1057 if List_Current_Line > Radius then 1058 Line := List_Current_Line - Radius; 1059 else 1060 Line := 1; 1061 end if; 1062 1063 Pos := File_Line_To_Position (List_Current_File, Line); 1064 Buf := Get_File_Source (List_Current_File); 1065 1066 while Line < List_Current_Line + Radius loop 1067 -- Compute line length. 1068 Len := 0; 1069 loop 1070 C := Buf (Pos + Len); 1071 exit when C = ASCII.CR or C = ASCII.LF or C = ASCII.EOT; 1072 Len := Len + 1; 1073 end loop; 1074 1075 -- Disp line number. 1076 declare 1077 Str : constant String := Natural'Image (Line); 1078 begin 1079 if Line = List_Current_Line then 1080 Put ('*'); 1081 else 1082 Put (' '); 1083 end if; 1084 Put ((Str'Length .. 5 => ' ')); 1085 Put (Str (Str'First + 1 .. Str'Last)); 1086 Put (' '); 1087 end; 1088 1089 -- Disp line. 1090 Put_Line (String (Buf (Pos .. Pos + Len - 1))); 1091 1092 -- Skip EOL. 1093 exit when C = ASCII.EOT; 1094 Pos := Pos + Len + 1; 1095 if C = ASCII.CR then 1096 if Buf (Pos) = ASCII.LF then 1097 Pos := Pos + 1; 1098 end if; 1099 else 1100 pragma Assert (C = ASCII.LF); 1101 if Buf (Pos) = ASCII.CR then 1102 Pos := Pos + 1; 1103 end if; 1104 end if; 1105 1106 Line := Line + 1; 1107 end loop; 1108 end Disp_Current_Lines; 1109 1110 procedure Disp_Source_Line (Loc : Location_Type) 1111 is 1112 use Files_Map; 1113 1114 File : Source_File_Entry; 1115 Line_Pos : Source_Ptr; 1116 Line : Natural; 1117 Offset : Natural; 1118 Buf : File_Buffer_Acc; 1119 Next_Line_Pos : Source_Ptr; 1120 begin 1121 Location_To_Coord (Loc, File, Line_Pos, Line, Offset); 1122 Buf := Get_File_Source (File); 1123 Next_Line_Pos := File_Line_To_Position (File, Line + 1); 1124 Put (String (Buf (Line_Pos .. Next_Line_Pos - 1))); 1125 end Disp_Source_Line; 1126 1127 type Menu_Kind is (Menu_Command, Menu_Submenu); 1128 type Menu_Entry (Kind : Menu_Kind); 1129 type Menu_Entry_Acc is access all Menu_Entry; 1130 1131 type Cst_String_Acc is access constant String; 1132 1133 type Menu_Entry (Kind : Menu_Kind) is record 1134 Name : Cst_String_Acc; 1135 Next : Menu_Entry_Acc; 1136 1137 case Kind is 1138 when Menu_Command => 1139 Proc : Menu_Procedure; 1140 when Menu_Submenu => 1141 First, Last : Menu_Entry_Acc := null; 1142 end case; 1143 end record; 1144 1145 -- Check there is a current process. 1146 procedure Check_Current_Process is 1147 begin 1148 if Current_Process = null then 1149 Put_Line ("no current process"); 1150 raise Command_Error; 1151 end if; 1152 end Check_Current_Process; 1153 1154 -- The status of the debugger. This status can be modified by a command 1155 -- as a side effect to resume or quit the debugger. 1156 type Command_Status_Type is (Status_Default, Status_Quit); 1157 Command_Status : Command_Status_Type; 1158 1159 procedure Help_Proc (Line : String); 1160 1161 procedure Disp_Process_Loc (Proc : Process_State_Type) is 1162 begin 1163 Disp_Instance_Name (Proc.Top_Instance); 1164 Put (" (" & Files_Map.Image (Get_Location (Proc.Proc)) & ")"); 1165 New_Line; 1166 end Disp_Process_Loc; 1167 1168 -- Disp the list of processes (and its state) 1169 procedure Ps_Proc (Line : String) is 1170 pragma Unreferenced (Line); 1171 Process : Iir; 1172 begin 1173 if Processes_State = null then 1174 Put_Line ("no processes"); 1175 return; 1176 end if; 1177 1178 for I in Processes_State'Range loop 1179 Put (Process_Index_Type'Image (I) & ": "); 1180 Process := Processes_State (I).Proc; 1181 if Process /= Null_Iir then 1182 Disp_Process_Loc (Processes_State (I)); 1183 Disp_A_Frame (Processes_State (I).Instance); 1184 else 1185 Put_Line ("not yet elaborated"); 1186 end if; 1187 end loop; 1188 end Ps_Proc; 1189 1190 procedure List_Proc (Line : String) 1191 is 1192 pragma Unreferenced (Line); 1193 begin 1194 Disp_Current_Lines; 1195 end List_Proc; 1196 1197 procedure Up_Proc (Line : String) 1198 is 1199 pragma Unreferenced (Line); 1200 begin 1201 Check_Current_Process; 1202 if Dbg_Cur_Frame.Parent = null then 1203 Put_Line ("top of frames reached"); 1204 else 1205 Set_Cur_Frame (Dbg_Cur_Frame.Parent); 1206 end if; 1207 end Up_Proc; 1208 1209 procedure Down_Proc (Line : String) 1210 is 1211 pragma Unreferenced (Line); 1212 Inst : Block_Instance_Acc; 1213 begin 1214 Check_Current_Process; 1215 if Dbg_Cur_Frame = Dbg_Top_Frame then 1216 Put_Line ("bottom of frames reached"); 1217 else 1218 Inst := Dbg_Top_Frame; 1219 while Inst.Parent /= Dbg_Cur_Frame loop 1220 Inst := Inst.Parent; 1221 end loop; 1222 Set_Cur_Frame (Inst); 1223 end if; 1224 end Down_Proc; 1225 1226 procedure Set_Breakpoint (Stmt : Iir) is 1227 begin 1228 Put_Line ("set breakpoint at: " & Files_Map.Image (Get_Location (Stmt))); 1229 Breakpoints.Append (Breakpoint_Entry'(Stmt => Stmt)); 1230 Flag_Need_Debug := True; 1231 end Set_Breakpoint; 1232 1233 function Is_Within_Statement (Stmt : Iir; Cur : Iir) return Boolean 1234 is 1235 Parent : Iir; 1236 begin 1237 Parent := Cur; 1238 loop 1239 if Parent = Stmt then 1240 return True; 1241 end if; 1242 case Get_Kind (Parent) is 1243 when Iir_Kinds_Sequential_Statement => 1244 Parent := Get_Parent (Parent); 1245 when others => 1246 return False; 1247 end case; 1248 end loop; 1249 end Is_Within_Statement; 1250 1251 -- Next statement in the same frame, but handle compound statements as 1252 -- one statement. 1253 procedure Next_Stmt_Proc (Line : String) 1254 is 1255 pragma Unreferenced (Line); 1256 begin 1257 Exec_State := Exec_Next_Stmt; 1258 Exec_Instance := Dbg_Top_Frame; 1259 Exec_Statement := Dbg_Top_Frame.Stmt; 1260 Flag_Need_Debug := True; 1261 Command_Status := Status_Quit; 1262 end Next_Stmt_Proc; 1263 1264 -- Finish parent statement. 1265 procedure Finish_Stmt_Proc (Line : String) 1266 is 1267 pragma Unreferenced (Line); 1268 begin 1269 Exec_State := Exec_Next_Stmt; 1270 Exec_Instance := Dbg_Top_Frame; 1271 Exec_Statement := Get_Parent (Dbg_Top_Frame.Stmt); 1272 Flag_Need_Debug := True; 1273 Command_Status := Status_Quit; 1274 end Finish_Stmt_Proc; 1275 1276 procedure Next_Proc (Line : String) 1277 is 1278 pragma Unreferenced (Line); 1279 begin 1280 Exec_State := Exec_Next; 1281 Exec_Instance := Dbg_Top_Frame; 1282 Flag_Need_Debug := True; 1283 Command_Status := Status_Quit; 1284 Cmd_Repeat := Next_Proc'Access; 1285 end Next_Proc; 1286 1287 procedure Step_Proc (Line : String) 1288 is 1289 pragma Unreferenced (Line); 1290 begin 1291 Exec_State := Exec_Single_Step; 1292 Flag_Need_Debug := True; 1293 Command_Status := Status_Quit; 1294 Cmd_Repeat := Step_Proc'Access; 1295 end Step_Proc; 1296 1297 Break_Id : Name_Id; 1298 1299 function Cb_Set_Break (El : Iir) return Walk_Status is 1300 begin 1301 case Get_Kind (El) is 1302 when Iir_Kind_Function_Declaration 1303 | Iir_Kind_Procedure_Declaration => 1304 if Get_Identifier (El) = Break_Id 1305 and then 1306 Get_Implicit_Definition (El) not in Iir_Predefined_Implicit 1307 then 1308 Set_Breakpoint 1309 (Get_Sequential_Statement_Chain (Get_Subprogram_Body (El))); 1310 end if; 1311 when others => 1312 null; 1313 end case; 1314 return Walk_Continue; 1315 end Cb_Set_Break; 1316 1317 procedure Break_Proc (Line : String) 1318 is 1319 Status : Walk_Status; 1320 P : Natural; 1321 begin 1322 P := Skip_Blanks (Line); 1323 if Line (P) = '"' then 1324 -- An operator name. 1325 declare 1326 use Str_Table; 1327 Str : String8_Id; 1328 Len : Nat32; 1329 begin 1330 Str := Create_String8; 1331 Len := 0; 1332 P := P + 1; 1333 while Line (P) /= '"' loop 1334 Append_String8_Char (Line (P)); 1335 Len := Len + 1; 1336 P := P + 1; 1337 end loop; 1338 Break_Id := Vhdl.Parse.Str_To_Operator_Name 1339 (Str, Len, No_Location); 1340 -- FIXME: free string. 1341 -- FIXME: catch error. 1342 end; 1343 else 1344 Break_Id := Name_Table.Get_Identifier (Line (P .. Line'Last)); 1345 end if; 1346 Status := Walk_Declarations (Cb_Set_Break'Access); 1347 pragma Assert (Status = Walk_Continue); 1348 end Break_Proc; 1349 1350 procedure Where_Proc (Line : String) is 1351 pragma Unreferenced (Line); 1352 Frame : Block_Instance_Acc; 1353 begin 1354 Check_Current_Process; 1355 Frame := Dbg_Top_Frame; 1356 while Frame /= null loop 1357 if Frame = Dbg_Cur_Frame then 1358 Put ("* "); 1359 else 1360 Put (" "); 1361 end if; 1362 Disp_A_Frame (Frame); 1363 Frame := Frame.Parent; 1364 end loop; 1365 end Where_Proc; 1366 1367 procedure Info_Tree_Proc (Line : String) 1368 is 1369 pragma Unreferenced (Line); 1370 begin 1371 if Top_Instance = null then 1372 Put_Line ("design not yet fully elaborated"); 1373 else 1374 Disp_Instances_Tree; 1375 end if; 1376 end Info_Tree_Proc; 1377 1378 procedure Info_Instances_Proc (Line : String) 1379 is 1380 pragma Unreferenced (Line); 1381 procedure Disp_Instances (Inst : Block_Instance_Acc) 1382 is 1383 Child : Block_Instance_Acc; 1384 begin 1385 case Get_Kind (Inst.Label) is 1386 when Iir_Kind_Architecture_Body => 1387 Disp_Instances_Tree_Name (Inst); 1388 when others => 1389 null; 1390 end case; 1391 1392 Child := Inst.Children; 1393 while Child /= null loop 1394 if Get_Kind (Child.Label) not in Iir_Kinds_Process_Statement then 1395 Disp_Instances (Child); 1396 end if; 1397 Child := Child.Brother; 1398 end loop; 1399 1400 end Disp_Instances; 1401 begin 1402 if Top_Instance = null then 1403 Put_Line ("design not yet fully elaborated"); 1404 return; 1405 end if; 1406 for I in Global_Instances.Objects'Range loop 1407 if Global_Instances.Objects (I) /= null then 1408 Put (Get_Instance_Local_Name 1409 (Global_Instances.Objects (I).Instance)); 1410 Put_Line (" [package]"); 1411 end if; 1412 end loop; 1413 Disp_Instances (Top_Instance); 1414 end Info_Instances_Proc; 1415 1416 procedure Info_Params_Proc (Line : String) 1417 is 1418 pragma Unreferenced (Line); 1419 Decl : Iir; 1420 Params : Iir; 1421 begin 1422 Check_Current_Process; 1423 if Dbg_Cur_Frame = null then 1424 Put_Line ("not in a subprogram"); 1425 return; 1426 end if; 1427 Decl := Dbg_Cur_Frame.Label; 1428 if Decl = Null_Iir 1429 or else Get_Kind (Decl) not in Iir_Kinds_Subprogram_Declaration 1430 then 1431 Put_Line ("current frame is not a subprogram"); 1432 return; 1433 end if; 1434 Params := Get_Interface_Declaration_Chain (Decl); 1435 Disp_Declaration_Objects (Dbg_Cur_Frame, Params); 1436 end Info_Params_Proc; 1437 1438 procedure Info_Proc_Proc (Line : String) is 1439 pragma Unreferenced (Line); 1440 begin 1441 Check_Current_Process; 1442 Disp_Process_Loc (Current_Process.all); 1443 end Info_Proc_Proc; 1444 1445 function Cb_Disp_Subprograms (El : Iir) return Walk_Status is 1446 begin 1447 case Get_Kind (El) is 1448 when Iir_Kind_Function_Declaration 1449 | Iir_Kind_Procedure_Declaration => 1450 Put_Line (Name_Table.Image (Get_Identifier (El))); 1451 when others => 1452 null; 1453 end case; 1454 return Walk_Continue; 1455 end Cb_Disp_Subprograms; 1456 1457 procedure Info_Subprograms_Proc (Line : String) is 1458 pragma Unreferenced (Line); 1459 Status : Walk_Status; 1460 begin 1461 Status := Walk_Declarations (Cb_Disp_Subprograms'Access); 1462 pragma Assert (Status = Walk_Continue); 1463 end Info_Subprograms_Proc; 1464 1465 function Cb_Disp_Units (El : Iir) return Walk_Status is 1466 begin 1467 case Get_Kind (El) is 1468 when Iir_Kind_Package_Declaration => 1469 Put ("package "); 1470 Put_Line (Name_Table.Image (Get_Identifier (El))); 1471 when Iir_Kind_Entity_Declaration => 1472 Put ("entity "); 1473 Put_Line (Name_Table.Image (Get_Identifier (El))); 1474 when Iir_Kind_Architecture_Body => 1475 Put ("architecture "); 1476 Put (Name_Table.Image (Get_Identifier (El))); 1477 Put (" of "); 1478 Put_Line (Name_Table.Image (Get_Identifier 1479 (Get_Entity_Name (El)))); 1480 when Iir_Kind_Configuration_Declaration => 1481 Put ("configuration "); 1482 Put_Line (Name_Table.Image (Get_Identifier (El))); 1483 when Iir_Kind_Package_Body => 1484 null; 1485 when others => 1486 Error_Kind ("cb_disp_units", El); 1487 end case; 1488 return Walk_Continue; 1489 end Cb_Disp_Units; 1490 1491 procedure Info_Units_Proc (Line : String) is 1492 pragma Unreferenced (Line); 1493 Status : Walk_Status; 1494 begin 1495 Status := Walk_Units (Cb_Disp_Units'Access); 1496 pragma Assert (Status = Walk_Continue); 1497 end Info_Units_Proc; 1498 1499 function Cb_Disp_File (El : Iir) return Walk_Status is 1500 begin 1501 Put_Line (Name_Table.Image (Get_Design_File_Filename (El))); 1502 return Walk_Continue; 1503 end Cb_Disp_File; 1504 1505 procedure Info_PSL_Proc (Line : String) 1506 is 1507 pragma Unreferenced (Line); 1508 begin 1509 if PSL_Table.Last < PSL_Table.First then 1510 Put_Line ("no PSL directive"); 1511 return; 1512 end if; 1513 1514 for I in PSL_Table.First .. PSL_Table.Last loop 1515 declare 1516 E : PSL_Entry renames PSL_Table.Table (I); 1517 begin 1518 Disp_Instance_Name (E.Instance); 1519 Put ('.'); 1520 Put (Name_Table.Image (Get_Identifier (E.Stmt))); 1521 New_Line; 1522 Vhdl.Prints.Disp_PSL_NFA (Get_PSL_NFA (E.Stmt)); 1523 Put (" 01234567890123456789012345678901234567890123456789"); 1524 for I in E.States'Range loop 1525 if I mod 50 = 0 then 1526 New_Line; 1527 Put (Int32'Image (I / 10)); 1528 Put (": "); 1529 end if; 1530 if E.States (I) then 1531 Put ('*'); 1532 else 1533 Put ('.'); 1534 end if; 1535 end loop; 1536 New_Line; 1537 end; 1538 end loop; 1539 end Info_PSL_Proc; 1540 1541 procedure Info_Stats_Proc (Line : String) is 1542 P : Natural := Line'First; 1543 E : Natural; 1544 begin 1545 P := Skip_Blanks (Line (P .. Line'Last)); 1546 if P > Line'Last then 1547 -- No parameters. 1548 Disp_Design_Stats; 1549 return; 1550 end if; 1551 1552 E := Get_Word (Line (P .. Line'Last)); 1553 if Line (P .. E) = "global" then 1554 Disp_Design_Stats; 1555 elsif Line (P .. E) = "non-sensitized" then 1556 Disp_Design_Non_Sensitized; 1557 null; 1558 elsif Line (P .. E) = "connections" then 1559 Disp_Design_Connections; 1560 -- TODO: nbr of conversions 1561 else 1562 Put_Line ("options are: global, non-sensitized, connections"); 1563 -- TODO: signals: nbr of scalars, nbr of non-user... 1564 end if; 1565 end Info_Stats_Proc; 1566 1567 procedure Info_Files_Proc (Line : String) 1568 is 1569 pragma Unreferenced (Line); 1570 Status : Walk_Status; 1571 begin 1572 Status := Walk_Files (Cb_Disp_File'Access); 1573 pragma Assert (Status = Walk_Continue); 1574 end Info_Files_Proc; 1575 1576 procedure Info_Libraries_Proc (Line : String) is 1577 pragma Unreferenced (Line); 1578 Lib : Iir_Library_Declaration := Libraries.Get_Libraries_Chain; 1579 begin 1580 while Lib /= Null_Iir loop 1581 Put_Line (Name_Table.Image (Get_Identifier (Lib))); 1582 Lib := Get_Chain (Lib); 1583 end loop; 1584 end Info_Libraries_Proc; 1585 1586 procedure Disp_Declared_Signals_Chain 1587 (Chain : Iir; Instance : Block_Instance_Acc) 1588 is 1589 pragma Unreferenced (Instance); 1590 Decl : Iir; 1591 begin 1592 Decl := Chain; 1593 while Decl /= Null_Iir loop 1594 case Get_Kind (Decl) is 1595 when Iir_Kind_Interface_Signal_Declaration 1596 | Iir_Kind_Signal_Declaration => 1597 Put_Line (" " & Name_Table.Image (Get_Identifier (Decl))); 1598 when others => 1599 null; 1600 end case; 1601 Decl := Get_Chain (Decl); 1602 end loop; 1603 end Disp_Declared_Signals_Chain; 1604 1605 procedure Disp_Declared_Signals (Decl : Iir; Instance : Block_Instance_Acc) 1606 is 1607 begin 1608 case Get_Kind (Decl) is 1609 when Iir_Kind_Sensitized_Process_Statement 1610 | Iir_Kind_Process_Statement => 1611 Disp_Declared_Signals (Get_Parent (Decl), Instance); 1612 when Iir_Kind_Architecture_Body => 1613 Disp_Declared_Signals (Get_Entity (Decl), Instance); 1614 when Iir_Kind_Entity_Declaration => 1615 null; 1616 when others => 1617 Error_Kind ("disp_declared_signals", Decl); 1618 end case; 1619 1620 case Get_Kind (Decl) is 1621 when Iir_Kind_Sensitized_Process_Statement 1622 | Iir_Kind_Process_Statement => 1623 -- No signal declaration in a process (FIXME: implicit signals) 1624 null; 1625 when Iir_Kind_Architecture_Body => 1626 Put_Line ("Signals of architecture " 1627 & Name_Table.Image (Get_Identifier (Decl)) & ':'); 1628 Disp_Declared_Signals_Chain 1629 (Get_Declaration_Chain (Decl), Instance); 1630 when Iir_Kind_Entity_Declaration => 1631 Put_Line ("Ports of entity " 1632 & Name_Table.Image (Get_Identifier (Decl)) & ':'); 1633 Disp_Declared_Signals_Chain 1634 (Get_Port_Chain (Decl), Instance); 1635 when others => 1636 Error_Kind ("disp_declared_signals (2)", Decl); 1637 end case; 1638 end Disp_Declared_Signals; 1639 1640 procedure Info_Signals_Proc (Line : String) 1641 is 1642 Verbose : Boolean; 1643 P : Natural; 1644 E : Natural; 1645 begin 1646 Verbose := False; 1647 1648 P := Skip_Blanks (Line); 1649 loop 1650 E := Get_Word (Line (P .. Line'Last)); 1651 exit when P > Line'Last; 1652 if Line (P .. E) = "-v" then 1653 Verbose := True; 1654 elsif Line (P .. E) = "-l" then 1655 -- Local signals 1656 Check_Current_Process; 1657 Disp_Declared_Signals 1658 (Current_Process.Proc, Current_Process.Top_Instance); 1659 return; 1660 elsif Line (P .. E) = "-t" then 1661 Disp_Signals_Value; 1662 return; 1663 elsif Line (P .. E) = "-T" then 1664 Grt.Disp_Signals.Disp_Signals_Table; 1665 return; 1666 else 1667 Put_Line ("options: -v(erbose) -l(ocal) -t(ree) -T(able)"); 1668 return; 1669 end if; 1670 P := E + 1; 1671 end loop; 1672 1673 for I in Signals_Table.First .. Signals_Table.Last loop 1674 declare 1675 S : Signal_Entry renames Signals_Table.Table (I); 1676 begin 1677 Disp_Instance_Name (S.Instance, False); 1678 Put ('.'); 1679 if S.Kind in Grt.Types.Mode_Signal_User then 1680 Put (Name_Table.Image (Get_Identifier (S.Decl))); 1681 New_Line; 1682 Put (" sig: "); 1683 Disp_Value (S.Sig); 1684 Put (" val: "); 1685 Disp_Value (S.Val); 1686 if Verbose then 1687 -- Dummy to keep compiler happy. 1688 Verbose := False; 1689 end if; 1690 else 1691 Disp_Declaration_Object (S.Instance, S.Decl); 1692 end if; 1693 end; 1694 end loop; 1695 end Info_Signals_Proc; 1696 1697 type Handle_Scope_Type is access procedure (N : Iir); 1698 1699 procedure Foreach_Scopes (N : Iir; Handler : Handle_Scope_Type) is 1700 begin 1701 case Get_Kind (N) is 1702 when Iir_Kind_Process_Statement 1703 | Iir_Kind_Sensitized_Process_Statement => 1704 Foreach_Scopes (Get_Parent (N), Handler); 1705 Handler.all (N); 1706 when Iir_Kind_Architecture_Body => 1707 Foreach_Scopes (Get_Entity (N), Handler); 1708 Handler.all (N); 1709 1710 when Iir_Kind_Entity_Declaration => 1711 -- Top of scopes. 1712 Handler.all (N); 1713 1714 when Iir_Kind_Function_Body 1715 | Iir_Kind_Procedure_Body => 1716 Foreach_Scopes (Get_Parent (N), Handler); 1717 Handler.all (N); 1718 when Iir_Kind_Package_Body => 1719 Handler.all (N); 1720 1721 when Iir_Kind_Variable_Assignment_Statement 1722 | Iir_Kind_Simple_Signal_Assignment_Statement 1723 | Iir_Kind_Null_Statement 1724 | Iir_Kind_Assertion_Statement 1725 | Iir_Kind_Report_Statement 1726 | Iir_Kind_Wait_Statement 1727 | Iir_Kind_Return_Statement 1728 | Iir_Kind_Next_Statement 1729 | Iir_Kind_Exit_Statement 1730 | Iir_Kind_Procedure_Call_Statement 1731 | Iir_Kind_If_Statement 1732 | Iir_Kind_While_Loop_Statement 1733 | Iir_Kind_Case_Statement => 1734 Foreach_Scopes (Get_Parent (N), Handler); 1735 1736 when Iir_Kind_For_Loop_Statement 1737 | Iir_Kind_Block_Statement 1738 | Iir_Kind_If_Generate_Statement 1739 | Iir_Kind_For_Generate_Statement 1740 | Iir_Kind_Generate_Statement_Body => 1741 Foreach_Scopes (Get_Parent (N), Handler); 1742 Handler.all (N); 1743 1744 when others => 1745 Error_Kind ("foreach_scopes", N); 1746 end case; 1747 end Foreach_Scopes; 1748 1749 procedure Add_Decls_For (N : Iir) 1750 is 1751 use Vhdl.Sem_Scopes; 1752 begin 1753 case Get_Kind (N) is 1754 when Iir_Kind_Entity_Declaration => 1755 declare 1756 Unit : constant Iir := Get_Design_Unit (N); 1757 begin 1758 Add_Context_Clauses (Unit); 1759 -- Add_Name (Unit, Get_Identifier (N), False); 1760 Add_Entity_Declarations (N); 1761 end; 1762 when Iir_Kind_Architecture_Body => 1763 Open_Declarative_Region; 1764 Add_Context_Clauses (Get_Design_Unit (N)); 1765 Add_Declarations (Get_Declaration_Chain (N), False); 1766 Add_Declarations_Of_Concurrent_Statement (N); 1767 when Iir_Kind_Package_Body => 1768 declare 1769 Package_Decl : constant Iir := Get_Package (N); 1770 Package_Unit : constant Iir := Get_Design_Unit (Package_Decl); 1771 begin 1772 Add_Name (Package_Unit); 1773 Add_Context_Clauses (Package_Unit); 1774 Open_Declarative_Region; 1775 Add_Declarations (Get_Declaration_Chain (Package_Decl), False); 1776 Add_Declarations (Get_Declaration_Chain (N), False); 1777 end; 1778 when Iir_Kind_Procedure_Body 1779 | Iir_Kind_Function_Body => 1780 declare 1781 Spec : constant Iir := Get_Subprogram_Specification (N); 1782 begin 1783 Open_Declarative_Region; 1784 Add_Declarations 1785 (Get_Interface_Declaration_Chain (Spec), False); 1786 Add_Declarations 1787 (Get_Declaration_Chain (N), False); 1788 end; 1789 when Iir_Kind_Process_Statement 1790 | Iir_Kind_Sensitized_Process_Statement => 1791 Open_Declarative_Region; 1792 Add_Declarations (Get_Declaration_Chain (N), False); 1793 when Iir_Kind_For_Loop_Statement 1794 | Iir_Kind_For_Generate_Statement => 1795 Open_Declarative_Region; 1796 Add_Name (Get_Parameter_Specification (N)); 1797 when Iir_Kind_Block_Statement => 1798 declare 1799 Header : constant Iir := Get_Block_Header (N); 1800 begin 1801 Open_Declarative_Region; 1802 if Header /= Null_Iir then 1803 Add_Declarations (Get_Generic_Chain (Header), False); 1804 Add_Declarations (Get_Port_Chain (Header), False); 1805 end if; 1806 Add_Declarations (Get_Declaration_Chain (N), False); 1807 Add_Declarations_Of_Concurrent_Statement (N); 1808 end; 1809 when Iir_Kind_Generate_Statement_Body => 1810 Open_Declarative_Region; 1811 Add_Declarations (Get_Declaration_Chain (N), False); 1812 Add_Declarations_Of_Concurrent_Statement (N); 1813 when others => 1814 Error_Kind ("enter_scope(2)", N); 1815 end case; 1816 end Add_Decls_For; 1817 1818 procedure Enter_Scope (Node : Iir) 1819 is 1820 use Vhdl.Sem_Scopes; 1821 begin 1822 Push_Interpretations; 1823 Open_Declarative_Region; 1824 1825 -- Add STD 1826 Add_Name (Libraries.Std_Library, Std_Names.Name_Std, False); 1827 Use_All_Names (Vhdl.Std_Package.Standard_Package); 1828 1829 Foreach_Scopes (Node, Add_Decls_For'Access); 1830 end Enter_Scope; 1831 1832 procedure Del_Decls_For (N : Iir) 1833 is 1834 use Vhdl.Sem_Scopes; 1835 begin 1836 case Get_Kind (N) is 1837 when Iir_Kind_Entity_Declaration => 1838 null; 1839 when Iir_Kind_Architecture_Body => 1840 Close_Declarative_Region; 1841 when Iir_Kind_Process_Statement 1842 | Iir_Kind_Sensitized_Process_Statement 1843 | Iir_Kind_Package_Body 1844 | Iir_Kind_Procedure_Body 1845 | Iir_Kind_Function_Body 1846 | Iir_Kind_For_Loop_Statement 1847 | Iir_Kind_Block_Statement 1848 | Iir_Kind_If_Generate_Statement 1849 | Iir_Kind_For_Generate_Statement 1850 | Iir_Kind_Generate_Statement_Body => 1851 Close_Declarative_Region; 1852 when others => 1853 Error_Kind ("Decl_Decls_For", N); 1854 end case; 1855 end Del_Decls_For; 1856 1857 procedure Leave_Scope (Node : Iir) 1858 is 1859 use Vhdl.Sem_Scopes; 1860 begin 1861 Foreach_Scopes (Node, Del_Decls_For'Access); 1862 1863 Close_Declarative_Region; 1864 Pop_Interpretations; 1865 end Leave_Scope; 1866 1867 Buffer_Index : Natural := 1; 1868 1869 procedure Print_Proc (Line : String) 1870 is 1871 use Vhdl.Tokens; 1872 Index_Str : String := Natural'Image (Buffer_Index); 1873 File : Source_File_Entry; 1874 Expr : Iir; 1875 Res : Iir_Value_Literal_Acc; 1876 P : Natural; 1877 Opt_Value : Boolean := False; 1878 Opt_Name : Boolean := False; 1879 Marker : Mark_Type; 1880 begin 1881 -- Decode options: /v 1882 P := Line'First; 1883 loop 1884 P := Skip_Blanks (Line (P .. Line'Last)); 1885 if P + 2 < Line'Last and then Line (P .. P + 1) = "/v" then 1886 Opt_Value := True; 1887 P := P + 2; 1888 elsif P + 2 < Line'Last and then Line (P .. P + 1) = "/n" then 1889 Opt_Name := True; 1890 P := P + 2; 1891 else 1892 exit; 1893 end if; 1894 end loop; 1895 1896 Buffer_Index := Buffer_Index + 1; 1897 Index_Str (Index_Str'First) := '*'; 1898 File := Files_Map.Create_Source_File_From_String 1899 (Name_Table.Get_Identifier ("*debug" & Index_Str & '*'), 1900 Line (P .. Line'Last)); 1901 Vhdl.Scanner.Set_File (File); 1902 Vhdl.Scanner.Scan; 1903 Expr := Vhdl.Parse.Parse_Expression; 1904 if Vhdl.Scanner.Current_Token /= Tok_Eof then 1905 Put_Line ("garbage at end of expression ignored"); 1906 end if; 1907 Vhdl.Scanner.Close_File; 1908 if Nbr_Errors /= 0 then 1909 Put_Line ("error while parsing expression, evaluation aborted"); 1910 Nbr_Errors := 0; 1911 return; 1912 end if; 1913 1914 Enter_Scope (Dbg_Cur_Frame.Stmt); 1915 Expr := Vhdl.Sem_Expr.Sem_Expression_Universal (Expr); 1916 Leave_Scope (Dbg_Cur_Frame.Stmt); 1917 1918 if Expr = Null_Iir 1919 or else Nbr_Errors /= 0 1920 then 1921 Put_Line ("error while analyzing expression, evaluation aborted"); 1922 Nbr_Errors := 0; 1923 return; 1924 end if; 1925 1926 Vhdl.Prints.Disp_Expression (Expr); 1927 New_Line; 1928 1929 Annotate_Expand_Table; 1930 Vhdl.Canon.Canon_Expression (Expr); 1931 1932 Mark (Marker, Expr_Pool); 1933 1934 if Opt_Name then 1935 case Get_Kind (Expr) is 1936 when Iir_Kind_Simple_Name => 1937 null; 1938 when others => 1939 Put_Line ("expression is not a name"); 1940 Opt_Name := False; 1941 end case; 1942 end if; 1943 if Opt_Name then 1944 Res := Execute_Name (Dbg_Cur_Frame, Expr, True); 1945 else 1946 Res := Execute_Expression (Dbg_Cur_Frame, Expr); 1947 end if; 1948 if Opt_Value then 1949 Disp_Value (Res); 1950 else 1951 Disp_Iir_Value (Res, Get_Type (Expr)); 1952 end if; 1953 New_Line; 1954 1955 -- Free value 1956 Release (Marker, Expr_Pool); 1957 end Print_Proc; 1958 1959 procedure Quit_Proc (Line : String) is 1960 pragma Unreferenced (Line); 1961 begin 1962 Command_Status := Status_Quit; 1963 raise Debugger_Quit; 1964 end Quit_Proc; 1965 1966 procedure Prepare_Continue is 1967 begin 1968 Command_Status := Status_Quit; 1969 1970 -- Set Flag_Need_Debug only if there is at least one enabled breakpoint. 1971 Flag_Need_Debug := False; 1972 for I in Breakpoints.First .. Breakpoints.Last loop 1973 Flag_Need_Debug := True; 1974 exit; 1975 end loop; 1976 end Prepare_Continue; 1977 1978 procedure Run_Proc (Line : String) 1979 is 1980 Delta_Time : Std_Time; 1981 P : Positive; 1982 begin 1983 P := Skip_Blanks (Line); 1984 if P <= Line'Last then 1985 Delta_Time := Grt.Options.Parse_Time (Line (P .. Line'Last)); 1986 if Delta_Time = -1 then 1987 return; 1988 end if; 1989 Break_Time := Grt.Processes.Next_Time + Delta_Time; 1990 end if; 1991 1992 Prepare_Continue; 1993 end Run_Proc; 1994 1995 procedure Cont_Proc (Line : String) is 1996 pragma Unreferenced (Line); 1997 begin 1998 Prepare_Continue; 1999 end Cont_Proc; 2000 2001 Menu_Info_Instances : aliased Menu_Entry := 2002 (Kind => Menu_Command, 2003 Name => new String'("instances"), 2004 Next => null, 2005 Proc => Info_Instances_Proc'Access); 2006 2007 Menu_Info_Psl : aliased Menu_Entry := 2008 (Kind => Menu_Command, 2009 Name => new String'("psl"), 2010 Next => Menu_Info_Instances'Access, 2011 Proc => Info_PSL_Proc'Access); 2012 2013 Menu_Info_Stats : aliased Menu_Entry := 2014 (Kind => Menu_Command, 2015 Name => new String'("stats"), 2016 Next => Menu_Info_Psl'Access, 2017 Proc => Info_Stats_Proc'Access); 2018 2019 Menu_Info_Tree : aliased Menu_Entry := 2020 (Kind => Menu_Command, 2021 Name => new String'("tree"), 2022 Next => Menu_Info_Stats'Access, 2023 Proc => Info_Tree_Proc'Access); 2024 2025 Menu_Info_Params : aliased Menu_Entry := 2026 (Kind => Menu_Command, 2027 Name => new String'("param*eters"), 2028 Next => Menu_Info_Tree'Access, 2029 Proc => Info_Params_Proc'Access); 2030 2031 Menu_Info_Subprograms : aliased Menu_Entry := 2032 (Kind => Menu_Command, 2033 Name => new String'("subp*rograms"), 2034 Next => Menu_Info_Params'Access, 2035 Proc => Info_Subprograms_Proc'Access); 2036 2037 Menu_Info_Units : aliased Menu_Entry := 2038 (Kind => Menu_Command, 2039 Name => new String'("units"), 2040 Next => Menu_Info_Subprograms'Access, 2041 Proc => Info_Units_Proc'Access); 2042 2043 Menu_Info_Files : aliased Menu_Entry := 2044 (Kind => Menu_Command, 2045 Name => new String'("files"), 2046 Next => Menu_Info_Units'Access, 2047 Proc => Info_Files_Proc'Access); 2048 2049 Menu_Info_Libraries : aliased Menu_Entry := 2050 (Kind => Menu_Command, 2051 Name => new String'("lib*raries"), 2052 Next => Menu_Info_Files'Access, 2053 Proc => Info_Libraries_Proc'Access); 2054 2055 Menu_Info_Signals : aliased Menu_Entry := 2056 (Kind => Menu_Command, 2057 Name => new String'("sig*nals"), 2058 Next => Menu_Info_Libraries'Access, 2059 Proc => Info_Signals_Proc'Access); 2060 2061 Menu_Info_Proc : aliased Menu_Entry := 2062 (Kind => Menu_Command, 2063 Name => new String'("proc*esses"), 2064 Next => Menu_Info_Signals'Access, 2065 Proc => Info_Proc_Proc'Access); 2066 2067 Menu_List : aliased Menu_Entry := 2068 (Kind => Menu_Command, 2069 Name => new String'("l*list"), 2070 Next => null, 2071 Proc => List_Proc'Access); 2072 2073 Menu_Down : aliased Menu_Entry := 2074 (Kind => Menu_Command, 2075 Name => new String'("down"), 2076 Next => Menu_List'Access, 2077 Proc => Down_Proc'Access); 2078 2079 Menu_Up : aliased Menu_Entry := 2080 (Kind => Menu_Command, 2081 Name => new String'("up"), 2082 Next => Menu_Down'Access, 2083 Proc => Up_Proc'Access); 2084 2085 Menu_Nstmt : aliased Menu_Entry := 2086 (Kind => Menu_Command, 2087 Name => new String'("ns*tmt"), 2088 Next => Menu_Up'Access, 2089 Proc => Next_Stmt_Proc'Access); 2090 2091 Menu_Fstmt : aliased Menu_Entry := 2092 (Kind => Menu_Command, 2093 Name => new String'("fs*tmt"), 2094 Next => Menu_Nstmt'Access, 2095 Proc => Finish_Stmt_Proc'Access); 2096 2097 Menu_Next : aliased Menu_Entry := 2098 (Kind => Menu_Command, 2099 Name => new String'("n*ext"), 2100 Next => Menu_Fstmt'Access, 2101 Proc => Next_Proc'Access); 2102 2103 Menu_Step : aliased Menu_Entry := 2104 (Kind => Menu_Command, 2105 Name => new String'("s*tep"), 2106 Next => Menu_Next'Access, 2107 Proc => Step_Proc'Access); 2108 2109 Menu_Break : aliased Menu_Entry := 2110 (Kind => Menu_Command, 2111 Name => new String'("b*reak"), 2112 Next => Menu_Step'Access, 2113 Proc => Break_Proc'Access); 2114 2115 Menu_Where : aliased Menu_Entry := 2116 (Kind => Menu_Command, 2117 Name => new String'("where"), 2118 Next => Menu_Break'Access, 2119 Proc => Where_Proc'Access); 2120 2121 Menu_Ps : aliased Menu_Entry := 2122 (Kind => Menu_Command, 2123 Name => new String'("ps"), 2124 Next => Menu_Where'Access, 2125 Proc => Ps_Proc'Access); 2126 2127 Menu_Info : aliased Menu_Entry := 2128 (Kind => Menu_Submenu, 2129 Name => new String'("i*nfo"), 2130 Next => Menu_Ps'Access, 2131 First | Last => Menu_Info_Proc'Access); 2132 2133 Menu_Print : aliased Menu_Entry := 2134 (Kind => Menu_Command, 2135 Name => new String'("pr*int"), 2136 Next => Menu_Info'Access, 2137 Proc => Print_Proc'Access); 2138 2139 Menu_Cont : aliased Menu_Entry := 2140 (Kind => Menu_Command, 2141 Name => new String'("c*ont"), 2142 Next => Menu_Print'Access, 2143 Proc => Cont_Proc'Access); 2144 2145 Menu_Run : aliased Menu_Entry := 2146 (Kind => Menu_Command, 2147 Name => new String'("r*un"), 2148 Next => Menu_Cont'Access, 2149 Proc => Run_Proc'Access); 2150 2151 Menu_Quit : aliased Menu_Entry := 2152 (Kind => Menu_Command, 2153 Name => new String'("q*uit"), 2154 Next => Menu_Run'Access, 2155 Proc => Quit_Proc'Access); 2156 2157 Menu_Help1 : aliased Menu_Entry := 2158 (Kind => Menu_Command, 2159 Name => new String'("help"), 2160 Next => Menu_Quit'Access, 2161 Proc => Help_Proc'Access); 2162 2163 Menu_Help2 : aliased Menu_Entry := 2164 (Kind => Menu_Command, 2165 Name => new String'("?"), 2166 Next => Menu_Help1'Access, 2167 Proc => Help_Proc'Access); 2168 2169 Menu_Top : aliased Menu_Entry := 2170 (Kind => Menu_Submenu, 2171 Name => null, 2172 Next => null, 2173 First | Last => Menu_Help2'Access); 2174 2175 function Find_Menu (Menu : Menu_Entry_Acc; Cmd : String) 2176 return Menu_Entry_Acc 2177 is 2178 function Is_Cmd (Cmd_Name : String; Str : String) return Boolean 2179 is 2180 -- Number of characters that were compared. 2181 P : Natural; 2182 begin 2183 P := 0; 2184 -- Prefix (before the '*'). 2185 loop 2186 if P = Cmd_Name'Length then 2187 -- Full match. 2188 return P = Str'Length; 2189 end if; 2190 exit when Cmd_Name (Cmd_Name'First + P) = '*'; 2191 if P = Str'Length then 2192 -- Command is too short 2193 return False; 2194 end if; 2195 if Cmd_Name (Cmd_Name'First + P) /= Str (Str'First + P) then 2196 return False; 2197 end if; 2198 P := P + 1; 2199 end loop; 2200 -- Suffix (after the '*') 2201 loop 2202 if P = Str'Length then 2203 return True; 2204 end if; 2205 if P + 1 = Cmd_Name'Length then 2206 -- String is too long 2207 return False; 2208 end if; 2209 if Cmd_Name (Cmd_Name'First + P + 1) /= Str (Str'First + P) then 2210 return False; 2211 end if; 2212 P := P + 1; 2213 end loop; 2214 end Is_Cmd; 2215 Ent : Menu_Entry_Acc; 2216 begin 2217 Ent := Menu.First; 2218 while Ent /= null loop 2219 if Is_Cmd (Ent.Name.all, Cmd) then 2220 return Ent; 2221 end if; 2222 Ent := Ent.Next; 2223 end loop; 2224 return null; 2225 end Find_Menu; 2226 2227 procedure Parse_Command (Line : String; 2228 P : in out Natural; 2229 Menu : out Menu_Entry_Acc) 2230 is 2231 E : Natural; 2232 begin 2233 P := Skip_Blanks (Line (P .. Line'Last)); 2234 if P > Line'Last then 2235 return; 2236 end if; 2237 E := Get_Word (Line (P .. Line'Last)); 2238 Menu := Find_Menu (Menu, Line (P .. E)); 2239 if Menu = null then 2240 Put_Line ("command '" & Line (P .. E) & "' not found"); 2241 end if; 2242 P := E + 1; 2243 end Parse_Command; 2244 2245 procedure Help_Proc (Line : String) 2246 is 2247 P : Natural; 2248 Root : Menu_Entry_Acc := Menu_Top'access; 2249 begin 2250 Put_Line ("This is the help command"); 2251 P := Line'First; 2252 while P < Line'Last loop 2253 Parse_Command (Line, P, Root); 2254 if Root = null then 2255 return; 2256 elsif Root.Kind /= Menu_Submenu then 2257 Put_Line ("Menu entry " & Root.Name.all & " is not a submenu"); 2258 return; 2259 end if; 2260 end loop; 2261 2262 Root := Root.First; 2263 while Root /= null loop 2264 Put (Root.Name.all); 2265 if Root.Kind = Menu_Submenu then 2266 Put (" (menu)"); 2267 end if; 2268 New_Line; 2269 Root := Root.Next; 2270 end loop; 2271 end Help_Proc; 2272 2273 function Breakpoint_Hit return Natural 2274 is 2275 Stmt : constant Iir := Current_Process.Instance.Stmt; 2276 begin 2277 for I in Breakpoints.First .. Breakpoints.Last loop 2278 if Stmt = Breakpoints.Table (I).Stmt then 2279 return I; 2280 end if; 2281 end loop; 2282 return 0; 2283 end Breakpoint_Hit; 2284 2285 Prompt_Debug : constant String := "debug> " & ASCII.NUL; 2286 Prompt_Error : constant String := "error> " & ASCII.NUL; 2287 Prompt_Init : constant String := "init> " & ASCII.NUL; 2288 Prompt_Elab : constant String := "elab> " & ASCII.NUL; 2289 2290 procedure Debug (Reason: Debug_Reason) 2291 is 2292 use Grt.Readline; 2293 Raw_Line : Char_Ptr; 2294 Prompt : System.Address; 2295 begin 2296 -- Unless interractive, do not use the debugger. 2297 case Reason is 2298 when Reason_Internal_Debug => 2299 null; 2300 when Reason_Assert 2301 | Reason_Error => 2302 if not Flag_Debugger then 2303 return; 2304 end if; 2305 when Reason_Start 2306 | Reason_Elab => 2307 if not Flag_Interractive then 2308 return; 2309 end if; 2310 when Reason_Break 2311 | Reason_Time => 2312 null; 2313 end case; 2314 2315 Prompt := Prompt_Debug'Address; 2316 2317 case Reason is 2318 when Reason_Start => 2319 Set_Top_Frame (null); 2320 Prompt := Prompt_Init'Address; 2321 when Reason_Elab => 2322 Set_Top_Frame (null); 2323 Prompt := Prompt_Elab'Address; 2324 when Reason_Internal_Debug => 2325 if Current_Process = null then 2326 Set_Top_Frame (null); 2327 else 2328 Set_Top_Frame (Current_Process.Instance); 2329 end if; 2330 when Reason_Time => 2331 Break_Time := Grt.Types.Std_Time'Last; 2332 Exec_State := Exec_Run; 2333 when Reason_Break => 2334 case Exec_State is 2335 when Exec_Run => 2336 if Breakpoint_Hit /= 0 then 2337 Put_Line ("breakpoint hit"); 2338 else 2339 return; 2340 end if; 2341 when Exec_Single_Step => 2342 null; 2343 when Exec_Next => 2344 if Current_Process.Instance /= Exec_Instance then 2345 return; 2346 end if; 2347 when Exec_Next_Stmt => 2348 if Current_Process.Instance /= Exec_Instance 2349 or else Is_Within_Statement (Exec_Statement, 2350 Current_Process.Instance.Stmt) 2351 then 2352 return; 2353 end if; 2354 end case; 2355 -- Default state. 2356 Exec_State := Exec_Run; 2357 Set_Top_Frame (Current_Process.Instance); 2358 declare 2359 Stmt : constant Iir := Dbg_Cur_Frame.Stmt; 2360 begin 2361 Put ("stopped at: "); 2362 Disp_Iir_Location (Stmt); 2363 New_Line; 2364 Disp_Source_Line (Get_Location (Stmt)); 2365 end; 2366 when Reason_Assert => 2367 Set_Top_Frame (Current_Process.Instance); 2368 Prompt := Prompt_Error'Address; 2369 Put_Line ("assertion failure, enterring in debugger"); 2370 when Reason_Error => 2371 Set_Top_Frame (Current_Process.Instance); 2372 Prompt := Prompt_Error'Address; 2373 Put_Line ("error occurred, enterring in debugger"); 2374 end case; 2375 2376 if Dbg_Cur_Frame /= null then 2377 Set_List_Current (Get_Location (Dbg_Cur_Frame.Stmt)); 2378 end if; 2379 2380 Command_Status := Status_Default; 2381 2382 loop 2383 loop 2384 Raw_Line := Readline (Prompt); 2385 -- Skip empty lines 2386 if Raw_Line = null or else Raw_Line (1) = ASCII.NUL then 2387 if Cmd_Repeat /= null then 2388 Cmd_Repeat.all (""); 2389 case Command_Status is 2390 when Status_Default => 2391 null; 2392 when Status_Quit => 2393 return; 2394 end case; 2395 end if; 2396 else 2397 Cmd_Repeat := null; 2398 exit; 2399 end if; 2400 end loop; 2401 declare 2402 Line_Last : constant Natural := Strlen (Raw_Line); 2403 Line : String renames Raw_Line (1 .. Line_Last); 2404 P, E : Positive; 2405 Cmd : Menu_Entry_Acc := Menu_Top'Access; 2406 begin 2407 -- Find command 2408 P := 1; 2409 loop 2410 E := P; 2411 Parse_Command (Line, E, Cmd); 2412 exit when Cmd = null; 2413 case Cmd.Kind is 2414 when Menu_Submenu => 2415 if E > Line_Last then 2416 Put_Line ("missing command for submenu " 2417 & Line (P .. E - 1)); 2418 Cmd := null; 2419 exit; 2420 end if; 2421 P := E; 2422 when Menu_Command => 2423 exit; 2424 end case; 2425 end loop; 2426 2427 if Cmd /= null then 2428 Cmd.Proc.all (Line (E .. Line_Last)); 2429 2430 case Command_Status is 2431 when Status_Default => 2432 null; 2433 when Status_Quit => 2434 exit; 2435 end case; 2436 end if; 2437 exception 2438 when Command_Error => 2439 null; 2440 end; 2441 end loop; 2442 -- Put ("resuming"); 2443 end Debug; 2444 2445 procedure Debug_Error is 2446 begin 2447 Debug (Reason_Error); 2448 end Debug_Error; 2449end Simul.Debugger; 2450