1-- Interpreted simulation 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 Ada.Unchecked_Conversion; 19with Simple_IO; use Simple_IO; 20with Types; use Types; 21with Grt.Types; use Grt.Types; 22with Flags; use Flags; 23with Vhdl.Errors; use Vhdl.Errors; 24with Vhdl.Std_Package; 25with Vhdl.Evaluation; 26with Vhdl.Utils; use Vhdl.Utils; 27with Name_Table; 28with Simul.File_Operation; 29with Simul.Debugger; use Simul.Debugger; 30with Std_Names; 31with Str_Table; 32with Files_Map; 33with Vhdl.Nodes_Utils; use Vhdl.Nodes_Utils; 34with Simul.Simulation; use Simul.Simulation; 35with Grt.Astdio.Vhdl; 36with Grt.Stdio; 37with Grt.Options; 38with Grt.Vstrings; 39with Grt.To_Strings; 40with Simul.Grt_Interface; 41with Grt.Values; 42with Grt.Errors; 43with Grt.Std_Logic_1164; 44with Grt.Lib; 45with Grt.Strings; 46with Vhdl.Sem_Inst; 47 48package body Simul.Execution is 49 50 function Execute_Function_Call 51 (Block: Block_Instance_Acc; Expr: Iir; Imp : Iir) 52 return Iir_Value_Literal_Acc; 53 54 procedure Finish_Sequential_Statements 55 (Proc : Process_State_Acc; Complex_Stmt : Iir); 56 procedure Init_Sequential_Statements 57 (Proc : Process_State_Acc; Complex_Stmt : Iir); 58 procedure Update_Next_Statement (Proc : Process_State_Acc); 59 60 -- Display a message when an assertion has failed. 61 procedure Execute_Failed_Assertion (Msg : String; 62 Report : String; 63 Severity : Natural; 64 Stmt: Iir); 65 66 function Get_Instance_By_Scope 67 (Instance: Block_Instance_Acc; Scope: Sim_Info_Acc) 68 return Block_Instance_Acc is 69 begin 70 case Scope.Kind is 71 when Kind_Block 72 | Kind_Frame 73 | Kind_Process => 74 declare 75 Current : Block_Instance_Acc; 76 begin 77 Current := Instance; 78 while Current /= null loop 79 if Current.Block_Scope = Scope then 80 return Current; 81 end if; 82 Current := Current.Up_Block; 83 end loop; 84 raise Internal_Error; 85 end; 86 when Kind_Protected => 87 declare 88 Current : Block_Instance_Acc; 89 begin 90 Current := Instance; 91 while Current /= null loop 92 if Current.Block_Scope = Scope 93 or Current.Uninst_Scope = Scope 94 then 95 return Current; 96 end if; 97 Current := Current.Up_Block; 98 end loop; 99 raise Internal_Error; 100 end; 101 when Kind_Package => 102 if Scope.Pkg_Parent = null then 103 -- This is a scope for an uninstantiated package. 104 declare 105 Current : Block_Instance_Acc; 106 begin 107 Current := Instance; 108 while Current /= null loop 109 if Current.Uninst_Scope = Scope then 110 return Current; 111 end if; 112 Current := Current.Up_Block; 113 end loop; 114 raise Internal_Error; 115 end; 116 else 117 -- Instantiated package. 118 declare 119 Parent : Block_Instance_Acc; 120 begin 121 Parent := Get_Instance_By_Scope (Instance, Scope.Pkg_Parent); 122 return Parent.Objects (Scope.Pkg_Slot).Instance; 123 end; 124 end if; 125 when others => 126 raise Internal_Error; 127 end case; 128 end Get_Instance_By_Scope; 129 130 function Get_Instance_Object (Instance: Block_Instance_Acc; Obj : Iir) 131 return Iir_Value_Literal_Acc 132 is 133 Info : constant Sim_Info_Acc := Get_Info (Obj); 134 Obj_Inst : Block_Instance_Acc; 135 begin 136 Obj_Inst := Get_Instance_By_Scope (Instance, Info.Obj_Scope); 137 return Obj_Inst.Objects (Info.Slot); 138 end Get_Instance_Object; 139 140 function Get_Info_For_Scope (Scope : Iir) return Sim_Info_Acc is 141 begin 142 -- The info for an architecture is in fact the entity. 143 if Get_Kind (Scope) = Iir_Kind_Architecture_Body then 144 return Get_Info (Get_Entity (Scope)); 145 else 146 return Get_Info (Scope); 147 end if; 148 end Get_Info_For_Scope; 149 150 procedure Create_Right_Bound_From_Length 151 (Bounds : Iir_Value_Literal_Acc; Len : Iir_Index32) is 152 begin 153 pragma Assert (Bounds.Right = null); 154 155 case Bounds.Left.Kind is 156 when Iir_Value_E32 => 157 declare 158 R : Ghdl_E32; 159 begin 160 case Bounds.Dir is 161 when Dir_To => 162 R := Bounds.Left.E32 + Ghdl_E32 (Len - 1); 163 when Dir_Downto => 164 R := Bounds.Left.E32 - Ghdl_E32 (Len - 1); 165 end case; 166 Bounds.Right := Create_E32_Value (R); 167 end; 168 when Iir_Value_I64 => 169 declare 170 R : Ghdl_I64; 171 begin 172 case Bounds.Dir is 173 when Dir_To => 174 R := Bounds.Left.I64 + Ghdl_I64 (Len - 1); 175 when Dir_Downto => 176 R := Bounds.Left.I64 - Ghdl_I64 (Len - 1); 177 end case; 178 Bounds.Right := Create_I64_Value (R); 179 end; 180 when others => 181 raise Internal_Error; 182 end case; 183 end Create_Right_Bound_From_Length; 184 185 function Create_Bounds_From_Length (Block : Block_Instance_Acc; 186 Atype : Iir; 187 Len : Iir_Index32) 188 return Iir_Value_Literal_Acc 189 is 190 Res : Iir_Value_Literal_Acc; 191 Index_Bounds : Iir_Value_Literal_Acc; 192 begin 193 Index_Bounds := Execute_Bounds (Block, Atype); 194 195 Res := Create_Range_Value (Left => Index_Bounds.Left, 196 Right => null, 197 Dir => Index_Bounds.Dir, 198 Length => Len); 199 200 if Len = 0 then 201 -- Special case. 202 Res.Right := Res.Left; 203 case Res.Left.Kind is 204 when Iir_Value_I64 => 205 case Index_Bounds.Dir is 206 when Dir_To => 207 Res.Left := Create_I64_Value (Res.Right.I64 + 1); 208 when Dir_Downto => 209 Res.Left := Create_I64_Value (Res.Right.I64 - 1); 210 end case; 211 when others => 212 raise Internal_Error; 213 end case; 214 else 215 Create_Right_Bound_From_Length (Res, Len); 216 end if; 217 return Res; 218 end Create_Bounds_From_Length; 219 220 function Execute_High_Limit (Bounds : Iir_Value_Literal_Acc) 221 return Iir_Value_Literal_Acc is 222 begin 223 if Bounds.Dir = Dir_To then 224 return Bounds.Right; 225 else 226 return Bounds.Left; 227 end if; 228 end Execute_High_Limit; 229 230 function Execute_Low_Limit (Bounds : Iir_Value_Literal_Acc) 231 return Iir_Value_Literal_Acc is 232 begin 233 if Bounds.Dir = Dir_To then 234 return Bounds.Left; 235 else 236 return Bounds.Right; 237 end if; 238 end Execute_Low_Limit; 239 240 function Execute_Left_Limit (Bounds : Iir_Value_Literal_Acc) 241 return Iir_Value_Literal_Acc is 242 begin 243 return Bounds.Left; 244 end Execute_Left_Limit; 245 246 function Execute_Right_Limit (Bounds : Iir_Value_Literal_Acc) 247 return Iir_Value_Literal_Acc is 248 begin 249 return Bounds.Right; 250 end Execute_Right_Limit; 251 252 function Execute_Length (Bounds : Iir_Value_Literal_Acc) 253 return Iir_Value_Literal_Acc is 254 begin 255 return Create_I64_Value (Ghdl_I64 (Bounds.Length)); 256 end Execute_Length; 257 258 function Create_Enum_Value (Pos : Natural; Etype : Iir) 259 return Iir_Value_Literal_Acc 260 is 261 Base_Type : constant Iir := Get_Base_Type (Etype); 262 Kind : constant Kind_Enum_Types := Get_Info (Base_Type).Kind; 263 begin 264 case Kind is 265 when Kind_E8_Type 266 | Kind_Log_Type => 267 return Create_E8_Value (Ghdl_E8 (Pos)); 268 when Kind_E32_Type => 269 return Create_E32_Value (Ghdl_E32 (Pos)); 270 when Kind_Bit_Type => 271 return Create_B1_Value (Ghdl_B1'Val (Pos)); 272 end case; 273 end Create_Enum_Value; 274 275 function String_To_Iir_Value (Str : String) return Iir_Value_Literal_Acc 276 is 277 Res : Iir_Value_Literal_Acc; 278 begin 279 Res := Create_Array_Value (Str'Length, 1); 280 Res.Bounds.D (1) := Create_Range_Value 281 (Create_I64_Value (1), 282 Create_I64_Value (Str'Length), 283 Dir_To); 284 for I in Str'Range loop 285 Res.Val_Array.V (1 + Iir_Index32 (I - Str'First)) := 286 Create_E8_Value (Character'Pos (Str (I))); 287 end loop; 288 return Res; 289 end String_To_Iir_Value; 290 291 function Execute_Image_Attribute (Val : Iir_Value_Literal_Acc; 292 Expr_Type : Iir) 293 return String 294 is 295 begin 296 case Get_Kind (Expr_Type) is 297 when Iir_Kind_Floating_Type_Definition 298 | Iir_Kind_Floating_Subtype_Definition => 299 declare 300 Str : String (1 .. 24); 301 Last : Natural; 302 begin 303 Grt.To_Strings.To_String (Str, Last, Val.F64); 304 return Str (Str'First .. Last); 305 end; 306 when Iir_Kind_Integer_Type_Definition 307 | Iir_Kind_Integer_Subtype_Definition => 308 declare 309 Str : String (1 .. 21); 310 First : Natural; 311 begin 312 Grt.To_Strings.To_String (Str, First, Val.I64); 313 return Str (First .. Str'Last); 314 end; 315 when Iir_Kind_Enumeration_Type_Definition 316 | Iir_Kind_Enumeration_Subtype_Definition => 317 declare 318 Lits : constant Iir_Flist := 319 Get_Enumeration_Literal_List (Get_Base_Type (Expr_Type)); 320 Pos : Natural; 321 begin 322 case Iir_Value_Enums (Val.Kind) is 323 when Iir_Value_B1 => 324 Pos := Ghdl_B1'Pos (Val.B1); 325 when Iir_Value_E8 => 326 Pos := Ghdl_E8'Pos (Val.E8); 327 when Iir_Value_E32 => 328 Pos := Ghdl_E32'Pos (Val.E32); 329 end case; 330 return Name_Table.Image 331 (Get_Identifier (Get_Nth_Element (Lits, Pos))); 332 end; 333 when Iir_Kind_Physical_Type_Definition 334 | Iir_Kind_Physical_Subtype_Definition => 335 declare 336 Str : String (1 .. 21); 337 First : Natural; 338 Id : constant Name_Id := 339 Get_Identifier (Get_Primary_Unit (Get_Base_Type (Expr_Type))); 340 begin 341 Grt.To_Strings.To_String (Str, First, Val.I64); 342 return Str (First .. Str'Last) & ' ' & Name_Table.Image (Id); 343 end; 344 when others => 345 Error_Kind ("execute_image_attribute", Expr_Type); 346 end case; 347 end Execute_Image_Attribute; 348 349 function Execute_Image_Attribute (Block: Block_Instance_Acc; Expr: Iir) 350 return Iir_Value_Literal_Acc 351 is 352 Val : Iir_Value_Literal_Acc; 353 Attr_Type : constant Iir := Get_Type (Get_Prefix (Expr)); 354 begin 355 Val := Execute_Expression (Block, Get_Parameter (Expr)); 356 return String_To_Iir_Value 357 (Execute_Image_Attribute (Val, Attr_Type)); 358 end Execute_Image_Attribute; 359 360 function Execute_Path_Instance_Name_Attribute 361 (Block : Block_Instance_Acc; Attr : Iir) return Iir_Value_Literal_Acc 362 is 363 use Vhdl.Evaluation; 364 use Grt.Vstrings; 365 use Name_Table; 366 367 Name : constant Path_Instance_Name_Type := 368 Get_Path_Instance_Name_Suffix (Attr); 369 Instance : Block_Instance_Acc; 370 Rstr : Rstring; 371 Is_Instance : constant Boolean := 372 Get_Kind (Attr) = Iir_Kind_Instance_Name_Attribute; 373 begin 374 if Name.Path_Instance = Null_Iir then 375 return String_To_Iir_Value (Name.Suffix); 376 end if; 377 378 Instance := Get_Instance_By_Scope 379 (Block, Get_Info_For_Scope (Name.Path_Instance)); 380 381 loop 382 case Get_Kind (Instance.Label) is 383 when Iir_Kind_Entity_Declaration => 384 if Instance.Parent = null then 385 Prepend (Rstr, Image (Get_Identifier (Instance.Label))); 386 exit; 387 end if; 388 when Iir_Kind_Architecture_Body => 389 if Is_Instance then 390 Prepend (Rstr, ')'); 391 Prepend (Rstr, Image (Get_Identifier (Instance.Label))); 392 Prepend (Rstr, '('); 393 end if; 394 395 if Is_Instance or else Instance.Parent = null then 396 Prepend 397 (Rstr, 398 Image (Get_Identifier (Get_Entity (Instance.Label)))); 399 end if; 400 if Instance.Parent = null then 401 Prepend (Rstr, ':'); 402 exit; 403 else 404 Instance := Instance.Parent; 405 end if; 406 when Iir_Kind_Block_Statement => 407 Prepend (Rstr, Image (Get_Label (Instance.Label))); 408 Prepend (Rstr, ':'); 409 Instance := Instance.Parent; 410 when Iir_Kind_Iterator_Declaration => 411 declare 412 Val : Iir_Value_Literal_Acc; 413 begin 414 Val := Execute_Name (Instance, Instance.Label); 415 Prepend (Rstr, ')'); 416 Prepend (Rstr, Execute_Image_Attribute 417 (Val, Get_Type (Instance.Label))); 418 Prepend (Rstr, '('); 419 end; 420 Instance := Instance.Parent; 421 when Iir_Kind_Generate_Statement_Body => 422 Prepend (Rstr, Image (Get_Label (Get_Parent (Instance.Label)))); 423 Prepend (Rstr, ':'); 424 Instance := Instance.Parent; 425 when Iir_Kind_Component_Instantiation_Statement => 426 if Is_Instance then 427 Prepend (Rstr, '@'); 428 end if; 429 Prepend (Rstr, Image (Get_Label (Instance.Label))); 430 Prepend (Rstr, ':'); 431 Instance := Instance.Parent; 432 when others => 433 Error_Kind ("Execute_Path_Instance_Name_Attribute", 434 Instance.Label); 435 end case; 436 end loop; 437 declare 438 Str1 : String (1 .. Length (Rstr)); 439 Len1 : Natural; 440 begin 441 Copy (Rstr, Str1, Len1); 442 Free (Rstr); 443 return String_To_Iir_Value (Str1 & ':' & Name.Suffix); 444 end; 445 end Execute_Path_Instance_Name_Attribute; 446 447 function Execute_Shift_Operator (Left : Iir_Value_Literal_Acc; 448 Count : Ghdl_I64; 449 Expr : Iir) 450 return Iir_Value_Literal_Acc 451 is 452 Func : constant Iir_Predefined_Shift_Functions := 453 Get_Implicit_Definition (Get_Implementation (Expr)); 454 Cnt : Iir_Index32; 455 Len : constant Iir_Index32 := Left.Bounds.D (1).Length; 456 Dir_Left : Boolean; 457 P : Iir_Index32; 458 Res : Iir_Value_Literal_Acc; 459 E : Iir_Value_Literal_Acc; 460 begin 461 -- LRM93 7.2.3 462 -- That is, if R is 0 or if L is a null array, the return value is L. 463 if Count = 0 or else Len = 0 then 464 return Left; 465 end if; 466 467 case Func is 468 when Iir_Predefined_Array_Sll 469 | Iir_Predefined_Array_Sla 470 | Iir_Predefined_Array_Rol => 471 Dir_Left := True; 472 when Iir_Predefined_Array_Srl 473 | Iir_Predefined_Array_Sra 474 | Iir_Predefined_Array_Ror => 475 Dir_Left := False; 476 end case; 477 if Count < 0 then 478 Cnt := Iir_Index32 (-Count); 479 Dir_Left := not Dir_Left; 480 else 481 Cnt := Iir_Index32 (Count); 482 end if; 483 484 case Func is 485 when Iir_Predefined_Array_Sll 486 | Iir_Predefined_Array_Srl => 487 E := Create_Enum_Value 488 (0, Get_Element_Subtype (Get_Base_Type (Get_Type (Expr)))); 489 when Iir_Predefined_Array_Sla 490 | Iir_Predefined_Array_Sra => 491 if Dir_Left then 492 E := Left.Val_Array.V (Len); 493 else 494 E := Left.Val_Array.V (1); 495 end if; 496 when Iir_Predefined_Array_Rol 497 | Iir_Predefined_Array_Ror => 498 Cnt := Cnt mod Len; 499 if not Dir_Left then 500 Cnt := (Len - Cnt) mod Len; 501 end if; 502 end case; 503 504 Res := Create_Array_Value (1); 505 Res.Bounds.D (1) := Left.Bounds.D (1); 506 Create_Array_Data (Res, Len); 507 P := 1; 508 509 case Func is 510 when Iir_Predefined_Array_Sll 511 | Iir_Predefined_Array_Srl 512 | Iir_Predefined_Array_Sla 513 | Iir_Predefined_Array_Sra => 514 if Dir_Left then 515 if Cnt < Len then 516 for I in Cnt .. Len - 1 loop 517 Res.Val_Array.V (P) := Left.Val_Array.V (I + 1); 518 P := P + 1; 519 end loop; 520 else 521 Cnt := Len; 522 end if; 523 for I in 0 .. Cnt - 1 loop 524 Res.Val_Array.V (P) := E; 525 P := P + 1; 526 end loop; 527 else 528 if Cnt > Len then 529 Cnt := Len; 530 end if; 531 for I in 0 .. Cnt - 1 loop 532 Res.Val_Array.V (P) := E; 533 P := P + 1; 534 end loop; 535 for I in Cnt .. Len - 1 loop 536 Res.Val_Array.V (P) := Left.Val_Array.V (I - Cnt + 1); 537 P := P + 1; 538 end loop; 539 end if; 540 when Iir_Predefined_Array_Rol 541 | Iir_Predefined_Array_Ror => 542 for I in 1 .. Len loop 543 Res.Val_Array.V (P) := Left.Val_Array.V (Cnt + 1); 544 P := P + 1; 545 Cnt := Cnt + 1; 546 if Cnt = Len then 547 Cnt := 0; 548 end if; 549 end loop; 550 end case; 551 return Res; 552 end Execute_Shift_Operator; 553 554 Hex_Chars : constant array (Natural range 0 .. 15) of Character := 555 "0123456789ABCDEF"; 556 557 function Execute_Bit_Vector_To_String (Val : Iir_Value_Literal_Acc; 558 Log_Base : Natural) 559 return Iir_Value_Literal_Acc 560 is 561 Base : constant Natural := 2 ** Log_Base; 562 Blen : constant Natural := Natural (Val.Bounds.D (1).Length); 563 Str : String (1 .. (Blen + Log_Base - 1) / Log_Base); 564 Pos : Natural; 565 V : Natural; 566 N : Natural; 567 begin 568 V := 0; 569 N := 1; 570 Pos := Str'Last; 571 for I in reverse Val.Val_Array.V'Range loop 572 V := V + Ghdl_B1'Pos (Val.Val_Array.V (I).B1) * N; 573 N := N * 2; 574 if N = Base or else I = Val.Val_Array.V'First then 575 Str (Pos) := Hex_Chars (V); 576 Pos := Pos - 1; 577 N := 1; 578 V := 0; 579 end if; 580 end loop; 581 return String_To_Iir_Value (Str); 582 end Execute_Bit_Vector_To_String; 583 584 procedure Assert_Std_Ulogic_Dc (Loc : Iir) 585 is 586 begin 587 Execute_Failed_Assertion 588 ("assertion", 589 "STD_LOGIC_1164: '-' operand for matching ordering operator", 590 1, Loc); 591 end Assert_Std_Ulogic_Dc; 592 593 procedure Check_Std_Ulogic_Dc (Loc : Iir; V : Grt.Std_Logic_1164.Std_Ulogic) 594 is 595 use Grt.Std_Logic_1164; 596 begin 597 if V = '-' then 598 Assert_Std_Ulogic_Dc (Loc); 599 end if; 600 end Check_Std_Ulogic_Dc; 601 602 -- EXPR is the expression whose implementation is an implicit function. 603 function Execute_Implicit_Function (Block : Block_Instance_Acc; 604 Expr: Iir; 605 Left_Param : Iir; 606 Right_Param : Iir; 607 Res_Type : Iir) 608 return Iir_Value_Literal_Acc 609 is 610 pragma Unsuppress (Overflow_Check); 611 612 Imp : constant Iir := Strip_Denoting_Name (Get_Implementation (Expr)); 613 Func : constant Iir_Predefined_Functions := 614 Get_Implicit_Definition (Imp); 615 616 -- Rename definition for monadic operations. 617 Left, Right: Iir_Value_Literal_Acc; 618 Operand : Iir_Value_Literal_Acc renames Left; 619 Result: Iir_Value_Literal_Acc; 620 621 procedure Eval_Right is 622 begin 623 Right := Execute_Expression (Block, Right_Param); 624 end Eval_Right; 625 626 -- Eval right argument, check left and right have same length, 627 -- Create RESULT from left. 628 procedure Eval_Array is 629 begin 630 Eval_Right; 631 if Left.Bounds.D (1).Length /= Right.Bounds.D (1).Length then 632 Error_Msg_Constraint (Expr); 633 end if; 634 -- Need to copy as the result is modified. 635 Result := Unshare (Left, Expr_Pool'Access); 636 end Eval_Array; 637 begin 638 -- Eval left operand. 639 case Func is 640 when Iir_Predefined_Now_Function => 641 Left := null; 642 when Iir_Predefined_Bit_Rising_Edge 643 | Iir_Predefined_Boolean_Rising_Edge 644 | Iir_Predefined_Bit_Falling_Edge 645 | Iir_Predefined_Boolean_Falling_Edge=> 646 Operand := Execute_Name (Block, Left_Param, True); 647 when others => 648 Left := Execute_Expression (Block, Left_Param); 649 end case; 650 Right := null; 651 652 case Func is 653 when Iir_Predefined_Error => 654 raise Internal_Error; 655 656 when Iir_Predefined_Array_Array_Concat 657 | Iir_Predefined_Element_Array_Concat 658 | Iir_Predefined_Array_Element_Concat 659 | Iir_Predefined_Element_Element_Concat => 660 Eval_Right; 661 662 declare 663 -- Type of the index. 664 Idx_Type : constant Iir := 665 Get_Nth_Element (Get_Index_Subtype_List (Res_Type), 0); 666 667 -- Array length of the result. 668 Len: Iir_Index32; 669 670 -- Index into the result. 671 Pos: Iir_Index32; 672 begin 673 -- Compute the length of the result. 674 case Func is 675 when Iir_Predefined_Array_Array_Concat => 676 Len := Left.Val_Array.Len + Right.Val_Array.Len; 677 when Iir_Predefined_Element_Array_Concat => 678 Len := 1 + Right.Val_Array.Len; 679 when Iir_Predefined_Array_Element_Concat => 680 Len := Left.Val_Array.Len + 1; 681 when Iir_Predefined_Element_Element_Concat => 682 Len := 1 + 1; 683 when others => 684 raise Program_Error; 685 end case; 686 687 if Func = Iir_Predefined_Array_Array_Concat 688 and then Left.Val_Array.Len = 0 689 then 690 if Flags.Vhdl_Std = Vhdl_87 then 691 -- LRM87 7.2.3 692 -- [...], unless the left operand is a null array, in 693 -- which case the result of the concatenation is the 694 -- right operand. 695 return Right; 696 else 697 -- LRM93 7.2.4 698 -- If both operands are null arrays, then the result of 699 -- the concatenation is the right operand. 700 if Right.Val_Array.Len = 0 then 701 return Right; 702 end if; 703 end if; 704 end if; 705 706 if Flags.Vhdl_Std = Vhdl_87 707 and then (Func = Iir_Predefined_Array_Array_Concat 708 or Func = Iir_Predefined_Array_Element_Concat) 709 then 710 -- LRM87 7.2.3 Adding Operators 711 -- The left bound if this result is the left bound of the 712 -- left operand, [...]. The direction of the result is the 713 -- direction of the left operand, unless the left operand 714 -- is a null array, in which case the direction of the 715 -- result is that of the right operand. 716 Result := Create_Array_Value (Len, 1); 717 Result.Bounds.D (1) := Create_Range_Value 718 (Left.Bounds.D (1).Left, null, Left.Bounds.D (1).Dir, Len); 719 Create_Right_Bound_From_Length (Result.Bounds.D (1), Len); 720 else 721 -- Create the array result. 722 Result := Create_Array_Value (Len, 1); 723 Result.Bounds.D (1) := Create_Bounds_From_Length 724 (Block, Idx_Type, Len); 725 end if; 726 Check_Range_Constraints 727 (Block, Result.Bounds.D (1), Idx_Type, Expr); 728 729 -- Fill the result: left. 730 case Func is 731 when Iir_Predefined_Array_Array_Concat 732 | Iir_Predefined_Array_Element_Concat => 733 for I in Left.Val_Array.V'Range loop 734 Result.Val_Array.V (I) := Left.Val_Array.V (I); 735 end loop; 736 Pos := Left.Val_Array.Len; 737 when Iir_Predefined_Element_Array_Concat 738 | Iir_Predefined_Element_Element_Concat => 739 Result.Val_Array.V (1) := Left; 740 Pos := 1; 741 when others => 742 raise Program_Error; 743 end case; 744 745 -- Note: here POS is equal to the position of the last element 746 -- filled, or 0 if no elements were filled. 747 748 -- Fill the result: right. 749 case Func is 750 when Iir_Predefined_Array_Array_Concat 751 | Iir_Predefined_Element_Array_Concat => 752 for I in Right.Val_Array.V'Range loop 753 Result.Val_Array.V (Pos + I) := Right.Val_Array.V (I); 754 end loop; 755 when Iir_Predefined_Array_Element_Concat 756 | Iir_Predefined_Element_Element_Concat => 757 Result.Val_Array.V (Pos + 1) := Right; 758 when others => 759 raise Program_Error; 760 end case; 761 end; 762 763 when Iir_Predefined_Bit_And 764 | Iir_Predefined_Boolean_And => 765 if Left.B1 = Lit_Enum_0.B1 then 766 -- Short circuit operator. 767 Result := Lit_Enum_0; 768 else 769 Eval_Right; 770 Result := Boolean_To_Lit (Right.B1 = Lit_Enum_1.B1); 771 end if; 772 when Iir_Predefined_Bit_Nand 773 | Iir_Predefined_Boolean_Nand => 774 if Left.B1 = Lit_Enum_0.B1 then 775 -- Short circuit operator. 776 Result := Lit_Enum_1; 777 else 778 Eval_Right; 779 Result := Boolean_To_Lit (Right.B1 = Lit_Enum_0.B1); 780 end if; 781 when Iir_Predefined_Bit_Or 782 | Iir_Predefined_Boolean_Or => 783 if Left.B1 = Lit_Enum_1.B1 then 784 -- Short circuit operator. 785 Result := Lit_Enum_1; 786 else 787 Eval_Right; 788 Result := Boolean_To_Lit (Right.B1 = Lit_Enum_1.B1); 789 end if; 790 when Iir_Predefined_Bit_Nor 791 | Iir_Predefined_Boolean_Nor => 792 if Left.B1 = Lit_Enum_1.B1 then 793 -- Short circuit operator. 794 Result := Lit_Enum_0; 795 else 796 Eval_Right; 797 Result := Boolean_To_Lit (Right.B1 = Lit_Enum_0.B1); 798 end if; 799 when Iir_Predefined_Bit_Xor 800 | Iir_Predefined_Boolean_Xor => 801 Eval_Right; 802 Result := Boolean_To_Lit (Left.B1 /= Right.B1); 803 when Iir_Predefined_Bit_Xnor 804 | Iir_Predefined_Boolean_Xnor => 805 Eval_Right; 806 Result := Boolean_To_Lit (Left.B1 = Right.B1); 807 when Iir_Predefined_Bit_Not 808 | Iir_Predefined_Boolean_Not => 809 Result := Boolean_To_Lit (Operand.B1 = Lit_Enum_0.B1); 810 811 when Iir_Predefined_Bit_Condition => 812 Result := Boolean_To_Lit (Operand.B1 = Lit_Enum_1.B1); 813 814 when Iir_Predefined_Array_Sll 815 | Iir_Predefined_Array_Srl 816 | Iir_Predefined_Array_Sla 817 | Iir_Predefined_Array_Sra 818 | Iir_Predefined_Array_Rol 819 | Iir_Predefined_Array_Ror => 820 Eval_Right; 821 Result := Execute_Shift_Operator (Left, Right.I64, Expr); 822 823 when Iir_Predefined_Enum_Equality 824 | Iir_Predefined_Integer_Equality 825 | Iir_Predefined_Array_Equality 826 | Iir_Predefined_Access_Equality 827 | Iir_Predefined_Physical_Equality 828 | Iir_Predefined_Floating_Equality 829 | Iir_Predefined_Record_Equality 830 | Iir_Predefined_Bit_Match_Equality 831 | Iir_Predefined_Bit_Array_Match_Equality => 832 Eval_Right; 833 Result := Boolean_To_Lit (Is_Equal (Left, Right)); 834 when Iir_Predefined_Enum_Inequality 835 | Iir_Predefined_Integer_Inequality 836 | Iir_Predefined_Array_Inequality 837 | Iir_Predefined_Access_Inequality 838 | Iir_Predefined_Physical_Inequality 839 | Iir_Predefined_Floating_Inequality 840 | Iir_Predefined_Record_Inequality 841 | Iir_Predefined_Bit_Match_Inequality 842 | Iir_Predefined_Bit_Array_Match_Inequality => 843 Eval_Right; 844 Result := Boolean_To_Lit (not Is_Equal (Left, Right)); 845 when Iir_Predefined_Integer_Less 846 | Iir_Predefined_Physical_Less 847 | Iir_Predefined_Enum_Less => 848 Eval_Right; 849 Result := Boolean_To_Lit (Compare_Value (Left, Right) < Equal); 850 when Iir_Predefined_Integer_Greater 851 | Iir_Predefined_Physical_Greater 852 | Iir_Predefined_Enum_Greater => 853 Eval_Right; 854 Result := Boolean_To_Lit (Compare_Value (Left, Right) > Equal); 855 when Iir_Predefined_Integer_Less_Equal 856 | Iir_Predefined_Physical_Less_Equal 857 | Iir_Predefined_Enum_Less_Equal => 858 Eval_Right; 859 Result := Boolean_To_Lit (Compare_Value (Left, Right) <= Equal); 860 when Iir_Predefined_Integer_Greater_Equal 861 | Iir_Predefined_Physical_Greater_Equal 862 | Iir_Predefined_Enum_Greater_Equal => 863 Eval_Right; 864 Result := Boolean_To_Lit (Compare_Value (Left, Right) >= Equal); 865 866 when Iir_Predefined_Enum_Minimum 867 | Iir_Predefined_Physical_Minimum => 868 Eval_Right; 869 if Compare_Value (Left, Right) = Less then 870 Result := Left; 871 else 872 Result := Right; 873 end if; 874 when Iir_Predefined_Enum_Maximum 875 | Iir_Predefined_Physical_Maximum => 876 Eval_Right; 877 if Compare_Value (Left, Right) = Less then 878 Result := Right; 879 else 880 Result := Left; 881 end if; 882 883 when Iir_Predefined_Integer_Plus 884 | Iir_Predefined_Physical_Plus => 885 Eval_Right; 886 case Left.Kind is 887 when Iir_Value_I64 => 888 Result := Create_I64_Value (Left.I64 + Right.I64); 889 when others => 890 raise Internal_Error; 891 end case; 892 when Iir_Predefined_Integer_Minus 893 | Iir_Predefined_Physical_Minus => 894 Eval_Right; 895 case Left.Kind is 896 when Iir_Value_I64 => 897 Result := Create_I64_Value (Left.I64 - Right.I64); 898 when others => 899 raise Internal_Error; 900 end case; 901 when Iir_Predefined_Integer_Mul => 902 Eval_Right; 903 case Left.Kind is 904 when Iir_Value_I64 => 905 Result := Create_I64_Value (Left.I64 * Right.I64); 906 when others => 907 raise Internal_Error; 908 end case; 909 when Iir_Predefined_Integer_Mod => 910 Eval_Right; 911 case Left.Kind is 912 when Iir_Value_I64 => 913 if Right.I64 = 0 then 914 Error_Msg_Constraint (Expr); 915 end if; 916 Result := Create_I64_Value (Left.I64 mod Right.I64); 917 when others => 918 raise Internal_Error; 919 end case; 920 when Iir_Predefined_Integer_Rem => 921 Eval_Right; 922 case Left.Kind is 923 when Iir_Value_I64 => 924 if Right.I64 = 0 then 925 Error_Msg_Constraint (Expr); 926 end if; 927 Result := Create_I64_Value (Left.I64 rem Right.I64); 928 when others => 929 raise Internal_Error; 930 end case; 931 when Iir_Predefined_Integer_Div => 932 Eval_Right; 933 case Left.Kind is 934 when Iir_Value_I64 => 935 if Right.I64 = 0 then 936 Error_Msg_Constraint (Expr); 937 end if; 938 Result := Create_I64_Value (Left.I64 / Right.I64); 939 when others => 940 raise Internal_Error; 941 end case; 942 943 when Iir_Predefined_Integer_Absolute 944 | Iir_Predefined_Physical_Absolute => 945 case Operand.Kind is 946 when Iir_Value_I64 => 947 Result := Create_I64_Value (abs Operand.I64); 948 when others => 949 raise Internal_Error; 950 end case; 951 952 when Iir_Predefined_Integer_Negation 953 | Iir_Predefined_Physical_Negation => 954 case Operand.Kind is 955 when Iir_Value_I64 => 956 Result := Create_I64_Value (-Operand.I64); 957 when others => 958 raise Internal_Error; 959 end case; 960 961 when Iir_Predefined_Integer_Identity 962 | Iir_Predefined_Physical_Identity => 963 case Operand.Kind is 964 when Iir_Value_I64 => 965 Result := Create_I64_Value (Operand.I64); 966 when others => 967 raise Internal_Error; 968 end case; 969 970 when Iir_Predefined_Integer_Exp => 971 Eval_Right; 972 case Left.Kind is 973 when Iir_Value_I64 => 974 if Right.I64 < 0 then 975 Error_Msg_Constraint (Expr); 976 end if; 977 Result := Create_I64_Value (Left.I64 ** Natural (Right.I64)); 978 when others => 979 raise Internal_Error; 980 end case; 981 982 when Iir_Predefined_Integer_Minimum => 983 Eval_Right; 984 Result := Create_I64_Value (Ghdl_I64'Min (Left.I64, Right.I64)); 985 when Iir_Predefined_Integer_Maximum => 986 Eval_Right; 987 Result := Create_I64_Value (Ghdl_I64'Max (Left.I64, Right.I64)); 988 989 when Iir_Predefined_Floating_Mul => 990 Eval_Right; 991 Result := Create_F64_Value (Left.F64 * Right.F64); 992 when Iir_Predefined_Floating_Div => 993 Eval_Right; 994 Result := Create_F64_Value (Left.F64 / Right.F64); 995 when Iir_Predefined_Floating_Minus => 996 Eval_Right; 997 Result := Create_F64_Value (Left.F64 - Right.F64); 998 when Iir_Predefined_Floating_Plus => 999 Eval_Right; 1000 Result := Create_F64_Value (Left.F64 + Right.F64); 1001 when Iir_Predefined_Floating_Exp => 1002 Eval_Right; 1003 Result := Create_F64_Value (Left.F64 ** Integer (Right.I64)); 1004 when Iir_Predefined_Floating_Identity => 1005 Result := Create_F64_Value (Operand.F64); 1006 when Iir_Predefined_Floating_Negation => 1007 Result := Create_F64_Value (-Operand.F64); 1008 when Iir_Predefined_Floating_Absolute => 1009 Result := Create_F64_Value (abs (Operand.F64)); 1010 when Iir_Predefined_Floating_Less => 1011 Eval_Right; 1012 Result := Boolean_To_Lit (Left.F64 < Right.F64); 1013 when Iir_Predefined_Floating_Less_Equal => 1014 Eval_Right; 1015 Result := Boolean_To_Lit (Left.F64 <= Right.F64); 1016 when Iir_Predefined_Floating_Greater => 1017 Eval_Right; 1018 Result := Boolean_To_Lit (Left.F64 > Right.F64); 1019 when Iir_Predefined_Floating_Greater_Equal => 1020 Eval_Right; 1021 Result := Boolean_To_Lit (Left.F64 >= Right.F64); 1022 1023 when Iir_Predefined_Floating_Minimum => 1024 Eval_Right; 1025 Result := Create_F64_Value (Ghdl_F64'Min (Left.F64, Right.F64)); 1026 when Iir_Predefined_Floating_Maximum => 1027 Eval_Right; 1028 Result := Create_F64_Value (Ghdl_F64'Max (Left.F64, Right.F64)); 1029 1030 when Iir_Predefined_Integer_Physical_Mul => 1031 Eval_Right; 1032 Result := Create_I64_Value (Left.I64 * Right.I64); 1033 when Iir_Predefined_Physical_Integer_Mul => 1034 Eval_Right; 1035 Result := Create_I64_Value (Left.I64 * Right.I64); 1036 when Iir_Predefined_Physical_Physical_Div => 1037 Eval_Right; 1038 Result := Create_I64_Value (Left.I64 / Right.I64); 1039 when Iir_Predefined_Physical_Integer_Div => 1040 Eval_Right; 1041 Result := Create_I64_Value (Left.I64 / Right.I64); 1042 when Iir_Predefined_Real_Physical_Mul => 1043 Eval_Right; 1044 Result := Create_I64_Value 1045 (Ghdl_I64 (Left.F64 * Ghdl_F64 (Right.I64))); 1046 when Iir_Predefined_Physical_Real_Mul => 1047 Eval_Right; 1048 Result := Create_I64_Value 1049 (Ghdl_I64 (Ghdl_F64 (Left.I64) * Right.F64)); 1050 when Iir_Predefined_Physical_Real_Div => 1051 Eval_Right; 1052 Result := Create_I64_Value 1053 (Ghdl_I64 (Ghdl_F64 (Left.I64) / Right.F64)); 1054 1055 when Iir_Predefined_Universal_I_R_Mul => 1056 Eval_Right; 1057 Result := Create_F64_Value (Ghdl_F64 (Left.I64) * Right.F64); 1058 when Iir_Predefined_Universal_R_I_Mul => 1059 Eval_Right; 1060 Result := Create_F64_Value (Left.F64 * Ghdl_F64 (Right.I64)); 1061 1062 when Iir_Predefined_TF_Array_And => 1063 Eval_Array; 1064 for I in Result.Val_Array.V'Range loop 1065 Result.Val_Array.V (I).B1 := 1066 Result.Val_Array.V (I).B1 and Right.Val_Array.V (I).B1; 1067 end loop; 1068 when Iir_Predefined_TF_Array_Nand => 1069 Eval_Array; 1070 for I in Result.Val_Array.V'Range loop 1071 Result.Val_Array.V (I).B1 := 1072 not (Result.Val_Array.V (I).B1 and Right.Val_Array.V (I).B1); 1073 end loop; 1074 when Iir_Predefined_TF_Array_Or => 1075 Eval_Array; 1076 for I in Result.Val_Array.V'Range loop 1077 Result.Val_Array.V (I).B1 := 1078 Result.Val_Array.V (I).B1 or Right.Val_Array.V (I).B1; 1079 end loop; 1080 when Iir_Predefined_TF_Array_Nor => 1081 Eval_Array; 1082 for I in Result.Val_Array.V'Range loop 1083 Result.Val_Array.V (I).B1 := 1084 not (Result.Val_Array.V (I).B1 or Right.Val_Array.V (I).B1); 1085 end loop; 1086 when Iir_Predefined_TF_Array_Xor => 1087 Eval_Array; 1088 for I in Result.Val_Array.V'Range loop 1089 Result.Val_Array.V (I).B1 := 1090 Result.Val_Array.V (I).B1 xor Right.Val_Array.V (I).B1; 1091 end loop; 1092 when Iir_Predefined_TF_Array_Xnor => 1093 Eval_Array; 1094 for I in Result.Val_Array.V'Range loop 1095 Result.Val_Array.V (I).B1 := 1096 not (Result.Val_Array.V (I).B1 xor Right.Val_Array.V (I).B1); 1097 end loop; 1098 1099 when Iir_Predefined_TF_Array_Element_And => 1100 Eval_Right; 1101 Result := Unshare (Left, Expr_Pool'Access); 1102 for I in Result.Val_Array.V'Range loop 1103 Result.Val_Array.V (I).B1 := 1104 Result.Val_Array.V (I).B1 and Right.B1; 1105 end loop; 1106 when Iir_Predefined_TF_Element_Array_And => 1107 Eval_Right; 1108 Result := Unshare (Right, Expr_Pool'Access); 1109 for I in Result.Val_Array.V'Range loop 1110 Result.Val_Array.V (I).B1 := 1111 Result.Val_Array.V (I).B1 and Left.B1; 1112 end loop; 1113 1114 when Iir_Predefined_TF_Array_Element_Or => 1115 Eval_Right; 1116 Result := Unshare (Left, Expr_Pool'Access); 1117 for I in Result.Val_Array.V'Range loop 1118 Result.Val_Array.V (I).B1 := 1119 Result.Val_Array.V (I).B1 or Right.B1; 1120 end loop; 1121 when Iir_Predefined_TF_Element_Array_Or => 1122 Eval_Right; 1123 Result := Unshare (Right, Expr_Pool'Access); 1124 for I in Result.Val_Array.V'Range loop 1125 Result.Val_Array.V (I).B1 := 1126 Result.Val_Array.V (I).B1 or Left.B1; 1127 end loop; 1128 1129 when Iir_Predefined_TF_Array_Element_Xor => 1130 Eval_Right; 1131 Result := Unshare (Left, Expr_Pool'Access); 1132 for I in Result.Val_Array.V'Range loop 1133 Result.Val_Array.V (I).B1 := 1134 Result.Val_Array.V (I).B1 xor Right.B1; 1135 end loop; 1136 when Iir_Predefined_TF_Element_Array_Xor => 1137 Eval_Right; 1138 Result := Unshare (Right, Expr_Pool'Access); 1139 for I in Result.Val_Array.V'Range loop 1140 Result.Val_Array.V (I).B1 := 1141 Result.Val_Array.V (I).B1 xor Left.B1; 1142 end loop; 1143 1144 when Iir_Predefined_TF_Array_Element_Nand => 1145 Eval_Right; 1146 Result := Unshare (Left, Expr_Pool'Access); 1147 for I in Result.Val_Array.V'Range loop 1148 Result.Val_Array.V (I).B1 := 1149 not (Result.Val_Array.V (I).B1 and Right.B1); 1150 end loop; 1151 when Iir_Predefined_TF_Element_Array_Nand => 1152 Eval_Right; 1153 Result := Unshare (Right, Expr_Pool'Access); 1154 for I in Result.Val_Array.V'Range loop 1155 Result.Val_Array.V (I).B1 := 1156 not (Result.Val_Array.V (I).B1 and Left.B1); 1157 end loop; 1158 1159 when Iir_Predefined_TF_Array_Element_Nor => 1160 Eval_Right; 1161 Result := Unshare (Left, Expr_Pool'Access); 1162 for I in Result.Val_Array.V'Range loop 1163 Result.Val_Array.V (I).B1 := 1164 not (Result.Val_Array.V (I).B1 or Right.B1); 1165 end loop; 1166 when Iir_Predefined_TF_Element_Array_Nor => 1167 Eval_Right; 1168 Result := Unshare (Right, Expr_Pool'Access); 1169 for I in Result.Val_Array.V'Range loop 1170 Result.Val_Array.V (I).B1 := 1171 not (Result.Val_Array.V (I).B1 or Left.B1); 1172 end loop; 1173 1174 when Iir_Predefined_TF_Array_Element_Xnor => 1175 Eval_Right; 1176 Result := Unshare (Left, Expr_Pool'Access); 1177 for I in Result.Val_Array.V'Range loop 1178 Result.Val_Array.V (I).B1 := 1179 not (Result.Val_Array.V (I).B1 xor Right.B1); 1180 end loop; 1181 when Iir_Predefined_TF_Element_Array_Xnor => 1182 Eval_Right; 1183 Result := Unshare (Right, Expr_Pool'Access); 1184 for I in Result.Val_Array.V'Range loop 1185 Result.Val_Array.V (I).B1 := 1186 not (Result.Val_Array.V (I).B1 xor Left.B1); 1187 end loop; 1188 1189 when Iir_Predefined_TF_Array_Not => 1190 -- Need to copy as the result is modified. 1191 Result := Unshare (Operand, Expr_Pool'Access); 1192 for I in Result.Val_Array.V'Range loop 1193 Result.Val_Array.V (I).B1 := not Result.Val_Array.V (I).B1; 1194 end loop; 1195 1196 when Iir_Predefined_TF_Reduction_And => 1197 Result := Create_B1_Value (True); 1198 for I in Operand.Val_Array.V'Range loop 1199 Result.B1 := Result.B1 and Operand.Val_Array.V (I).B1; 1200 end loop; 1201 when Iir_Predefined_TF_Reduction_Nand => 1202 Result := Create_B1_Value (True); 1203 for I in Operand.Val_Array.V'Range loop 1204 Result.B1 := Result.B1 and Operand.Val_Array.V (I).B1; 1205 end loop; 1206 Result.B1 := not Result.B1; 1207 when Iir_Predefined_TF_Reduction_Or => 1208 Result := Create_B1_Value (False); 1209 for I in Operand.Val_Array.V'Range loop 1210 Result.B1 := Result.B1 or Operand.Val_Array.V (I).B1; 1211 end loop; 1212 when Iir_Predefined_TF_Reduction_Nor => 1213 Result := Create_B1_Value (False); 1214 for I in Operand.Val_Array.V'Range loop 1215 Result.B1 := Result.B1 or Operand.Val_Array.V (I).B1; 1216 end loop; 1217 Result.B1 := not Result.B1; 1218 when Iir_Predefined_TF_Reduction_Xor => 1219 Result := Create_B1_Value (False); 1220 for I in Operand.Val_Array.V'Range loop 1221 Result.B1 := Result.B1 xor Operand.Val_Array.V (I).B1; 1222 end loop; 1223 when Iir_Predefined_TF_Reduction_Xnor => 1224 Result := Create_B1_Value (False); 1225 for I in Operand.Val_Array.V'Range loop 1226 Result.B1 := Result.B1 xor Operand.Val_Array.V (I).B1; 1227 end loop; 1228 Result.B1 := not Result.B1; 1229 1230 when Iir_Predefined_Bit_Rising_Edge 1231 | Iir_Predefined_Boolean_Rising_Edge => 1232 return Boolean_To_Lit 1233 (Execute_Event_Attribute (Operand) 1234 and then Execute_Signal_Value (Operand).B1 = True); 1235 when Iir_Predefined_Bit_Falling_Edge 1236 | Iir_Predefined_Boolean_Falling_Edge => 1237 return Boolean_To_Lit 1238 (Execute_Event_Attribute (Operand) 1239 and then Execute_Signal_Value (Operand).B1 = False); 1240 1241 when Iir_Predefined_Array_Greater => 1242 Eval_Right; 1243 Result := Boolean_To_Lit (Compare_Value (Left, Right) = Greater); 1244 1245 when Iir_Predefined_Array_Greater_Equal => 1246 Eval_Right; 1247 Result := Boolean_To_Lit (Compare_Value (Left, Right) >= Equal); 1248 1249 when Iir_Predefined_Array_Less => 1250 Eval_Right; 1251 Result := Boolean_To_Lit (Compare_Value (Left, Right) = Less); 1252 1253 when Iir_Predefined_Array_Less_Equal => 1254 Eval_Right; 1255 Result := Boolean_To_Lit (Compare_Value (Left, Right) <= Equal); 1256 1257 when Iir_Predefined_Array_Minimum => 1258 Eval_Right; 1259 if Compare_Value (Left, Right) = Less then 1260 Result := Left; 1261 else 1262 Result := Right; 1263 end if; 1264 when Iir_Predefined_Array_Maximum => 1265 Eval_Right; 1266 if Compare_Value (Left, Right) = Less then 1267 Result := Right; 1268 else 1269 Result := Left; 1270 end if; 1271 1272 when Iir_Predefined_Vector_Maximum => 1273 declare 1274 El_St : constant Iir := 1275 Get_Return_Type (Get_Implementation (Expr)); 1276 V : Iir_Value_Literal_Acc; 1277 begin 1278 Result := Execute_Low_Limit (Execute_Bounds (Block, El_St)); 1279 for I in Left.Val_Array.V'Range loop 1280 V := Left.Val_Array.V (I); 1281 if Compare_Value (V, Result) = Greater then 1282 Result := V; 1283 end if; 1284 end loop; 1285 end; 1286 when Iir_Predefined_Vector_Minimum => 1287 declare 1288 El_St : constant Iir := 1289 Get_Return_Type (Get_Implementation (Expr)); 1290 V : Iir_Value_Literal_Acc; 1291 begin 1292 Result := Execute_High_Limit (Execute_Bounds (Block, El_St)); 1293 for I in Left.Val_Array.V'Range loop 1294 V := Left.Val_Array.V (I); 1295 if Compare_Value (V, Result) = Less then 1296 Result := V; 1297 end if; 1298 end loop; 1299 end; 1300 1301 when Iir_Predefined_Endfile => 1302 Result := Boolean_To_Lit (File_Operation.Endfile (Left, Null_Iir)); 1303 1304 when Iir_Predefined_Now_Function => 1305 Result := Create_I64_Value (Ghdl_I64 (Grt.Types.Current_Time)); 1306 1307 when Iir_Predefined_Integer_To_String 1308 | Iir_Predefined_Floating_To_String 1309 | Iir_Predefined_Physical_To_String => 1310 Result := String_To_Iir_Value 1311 (Execute_Image_Attribute (Left, Get_Type (Left_Param))); 1312 1313 when Iir_Predefined_Enum_To_String => 1314 declare 1315 use Name_Table; 1316 Base_Type : constant Iir := 1317 Get_Base_Type (Get_Type (Left_Param)); 1318 Lits : constant Iir_Flist := 1319 Get_Enumeration_Literal_List (Base_Type); 1320 Pos : constant Natural := Get_Enum_Pos (Left); 1321 Id : Name_Id; 1322 begin 1323 if Base_Type = Vhdl.Std_Package.Character_Type_Definition then 1324 Result := String_To_Iir_Value ((1 => Character'Val (Pos))); 1325 else 1326 Id := Get_Identifier (Get_Nth_Element (Lits, Pos)); 1327 if Is_Character (Id) then 1328 Result := String_To_Iir_Value ((1 => Get_Character (Id))); 1329 else 1330 declare 1331 Img : String := Image (Id); 1332 begin 1333 if Img (Img'First) = '\' then 1334 -- Reformat extended identifiers for to_image. 1335 pragma Assert (Img (Img'Last) = '\'); 1336 declare 1337 Npos : Natural; 1338 K : Natural; 1339 C : Character; 1340 begin 1341 Npos := Img'First; 1342 K := Npos + 1; 1343 while K < Img'Last loop 1344 C := Img (K); 1345 Img (Npos) := C; 1346 Npos := Npos + 1; 1347 if C = '\' then 1348 K := K + 2; 1349 else 1350 K := K + 1; 1351 end if; 1352 end loop; 1353 Result := String_To_Iir_Value 1354 (Img (Img'First .. Npos - 1)); 1355 end; 1356 else 1357 Result := String_To_Iir_Value (Img); 1358 end if; 1359 end; 1360 end if; 1361 end if; 1362 end; 1363 1364 when Iir_Predefined_Array_Char_To_String => 1365 declare 1366 Lits : constant Iir_Flist := 1367 Get_Enumeration_Literal_List 1368 (Get_Base_Type 1369 (Get_Element_Subtype (Get_Type (Left_Param)))); 1370 Str : String (1 .. Natural (Left.Bounds.D (1).Length)); 1371 Pos : Natural; 1372 begin 1373 for I in Left.Val_Array.V'Range loop 1374 Pos := Get_Enum_Pos (Left.Val_Array.V (I)); 1375 Str (Positive (I)) := Name_Table.Get_Character 1376 (Get_Identifier (Get_Nth_Element (Lits, Pos))); 1377 end loop; 1378 Result := String_To_Iir_Value (Str); 1379 end; 1380 1381 when Iir_Predefined_Bit_Vector_To_Hstring => 1382 return Execute_Bit_Vector_To_String (Left, 4); 1383 1384 when Iir_Predefined_Bit_Vector_To_Ostring => 1385 return Execute_Bit_Vector_To_String (Left, 3); 1386 1387 when Iir_Predefined_Real_To_String_Digits => 1388 Eval_Right; 1389 declare 1390 Str : Grt.To_Strings.String_Real_Format; 1391 Last : Natural; 1392 begin 1393 Grt.To_Strings.To_String 1394 (Str, Last, Left.F64, Ghdl_I32 (Right.I64)); 1395 Result := String_To_Iir_Value (Str (1 .. Last)); 1396 end; 1397 when Iir_Predefined_Real_To_String_Format => 1398 Eval_Right; 1399 declare 1400 Format : String (1 .. Natural (Right.Val_Array.Len) + 1); 1401 Str : Grt.To_Strings.String_Real_Format; 1402 Last : Natural; 1403 begin 1404 for I in Right.Val_Array.V'Range loop 1405 Format (Positive (I)) := 1406 Character'Val (Right.Val_Array.V (I).E8); 1407 end loop; 1408 Format (Format'Last) := ASCII.NUL; 1409 Grt.To_Strings.To_String 1410 (Str, Last, Left.F64, To_Ghdl_C_String (Format'Address)); 1411 Result := String_To_Iir_Value (Str (1 .. Last)); 1412 end; 1413 when Iir_Predefined_Time_To_String_Unit => 1414 Eval_Right; 1415 declare 1416 Str : Grt.To_Strings.String_Time_Unit; 1417 First : Natural; 1418 Unit : Iir; 1419 begin 1420 Unit := Get_Unit_Chain (Vhdl.Std_Package.Time_Type_Definition); 1421 while Unit /= Null_Iir loop 1422 exit when Vhdl.Evaluation.Get_Physical_Value (Unit) 1423 = Int64 (Right.I64); 1424 Unit := Get_Chain (Unit); 1425 end loop; 1426 if Unit = Null_Iir then 1427 Error_Msg_Exec 1428 ("to_string for time called with wrong unit", Expr); 1429 end if; 1430 Grt.To_Strings.To_String (Str, First, Left.I64, Right.I64); 1431 Result := String_To_Iir_Value 1432 (Str (First .. Str'Last) & ' ' 1433 & Name_Table.Image (Get_Identifier (Unit))); 1434 end; 1435 1436 when Iir_Predefined_Std_Ulogic_Match_Equality => 1437 Eval_Right; 1438 declare 1439 use Grt.Std_Logic_1164; 1440 begin 1441 Result := Create_E8_Value 1442 (Std_Ulogic'Pos 1443 (Match_Eq_Table (Std_Ulogic'Val (Left.E8), 1444 Std_Ulogic'Val (Right.E8)))); 1445 end; 1446 when Iir_Predefined_Std_Ulogic_Match_Inequality => 1447 Eval_Right; 1448 declare 1449 use Grt.Std_Logic_1164; 1450 begin 1451 Result := Create_E8_Value 1452 (Std_Ulogic'Pos 1453 (Not_Table (Match_Eq_Table (Std_Ulogic'Val (Left.E8), 1454 Std_Ulogic'Val (Right.E8))))); 1455 end; 1456 when Iir_Predefined_Std_Ulogic_Match_Ordering_Functions => 1457 Eval_Right; 1458 declare 1459 use Grt.Std_Logic_1164; 1460 L : constant Std_Ulogic := Std_Ulogic'Val (Left.E8); 1461 R : constant Std_Ulogic := Std_Ulogic'Val (Right.E8); 1462 Res : Std_Ulogic; 1463 begin 1464 Check_Std_Ulogic_Dc (Expr, L); 1465 Check_Std_Ulogic_Dc (Expr, R); 1466 case Iir_Predefined_Std_Ulogic_Match_Ordering_Functions (Func) 1467 is 1468 when Iir_Predefined_Std_Ulogic_Match_Less => 1469 Res := Match_Lt_Table (L, R); 1470 when Iir_Predefined_Std_Ulogic_Match_Less_Equal => 1471 Res := Or_Table (Match_Lt_Table (L, R), 1472 Match_Eq_Table (L, R)); 1473 when Iir_Predefined_Std_Ulogic_Match_Greater => 1474 Res := Not_Table (Or_Table (Match_Lt_Table (L, R), 1475 Match_Eq_Table (L, R))); 1476 when Iir_Predefined_Std_Ulogic_Match_Greater_Equal => 1477 Res := Not_Table (Match_Lt_Table (L, R)); 1478 end case; 1479 Result := Create_E8_Value (Std_Ulogic'Pos (Res)); 1480 end; 1481 1482 when Iir_Predefined_Std_Ulogic_Array_Match_Equality 1483 | Iir_Predefined_Std_Ulogic_Array_Match_Inequality => 1484 Eval_Right; 1485 if Left.Bounds.D (1).Length /= Right.Bounds.D (1).Length then 1486 Error_Msg_Constraint (Expr); 1487 end if; 1488 declare 1489 use Grt.Std_Logic_1164; 1490 Res : Std_Ulogic := '1'; 1491 Le, Re : Std_Ulogic; 1492 Has_Match_Err : Boolean; 1493 begin 1494 Has_Match_Err := False; 1495 for I in Left.Val_Array.V'Range loop 1496 Le := Std_Ulogic'Val (Left.Val_Array.V (I).E8); 1497 Re := Std_Ulogic'Val (Right.Val_Array.V (I).E8); 1498 if (Le = '-' or Re = '-') and then not Has_Match_Err then 1499 Assert_Std_Ulogic_Dc (Expr); 1500 Has_Match_Err := True; 1501 end if; 1502 Res := And_Table (Res, Match_Eq_Table (Le, Re)); 1503 end loop; 1504 if Func = Iir_Predefined_Std_Ulogic_Array_Match_Inequality then 1505 Res := Not_Table (Res); 1506 end if; 1507 Result := Create_E8_Value (Std_Ulogic'Pos (Res)); 1508 end; 1509 1510 when others => 1511 Error_Msg_Elab (Expr, "execute_implicit_function: unimplemented " & 1512 Iir_Predefined_Functions'Image (Func)); 1513 raise Internal_Error; 1514 end case; 1515 return Result; 1516 exception 1517 when Constraint_Error => 1518 Error_Msg_Constraint (Expr); 1519 end Execute_Implicit_Function; 1520 1521 procedure Execute_Implicit_Procedure 1522 (Block: Block_Instance_Acc; Stmt: Iir_Procedure_Call) 1523 is 1524 Imp : constant Iir := Get_Implementation (Stmt); 1525 Assoc_Chain : constant Iir := Get_Parameter_Association_Chain (Stmt); 1526 Inter_Chain : constant Iir := Get_Interface_Declaration_Chain (Imp); 1527 Assoc: Iir; 1528 Formal : Iir; 1529 Val : Iir; 1530 Args: Iir_Value_Literal_Array (0 .. 3); 1531 Expr_Mark : Mark_Type; 1532 begin 1533 Mark (Expr_Mark, Expr_Pool); 1534 Assoc := Assoc_Chain; 1535 Formal := Inter_Chain; 1536 for I in Iir_Index32 loop 1537 exit when Assoc = Null_Iir; 1538 case Get_Kind (Assoc) is 1539 when Iir_Kind_Association_Element_By_Expression => 1540 Val := Get_Actual (Assoc); 1541 when Iir_Kind_Association_Element_Open => 1542 Val := Get_Default_Value (Formal); 1543 when others => 1544 raise Internal_Error; 1545 end case; 1546 Args (I) := Execute_Expression (Block, Val); 1547 Assoc := Get_Chain (Assoc); 1548 Formal := Get_Chain (Formal); 1549 end loop; 1550 case Get_Implicit_Definition (Imp) is 1551 when Iir_Predefined_Deallocate => 1552 if Args (0).Val_Access /= null then 1553 Free_Heap_Value (Args (0)); 1554 Args (0).Val_Access := null; 1555 end if; 1556 when Iir_Predefined_File_Open => 1557 File_Operation.File_Open 1558 (Args (0), Args (1), Args (2), Inter_Chain, Stmt); 1559 when Iir_Predefined_File_Open_Status => 1560 File_Operation.File_Open_Status 1561 (Args (0), Args (1), Args (2), Args (3), 1562 Get_Chain (Inter_Chain), Stmt); 1563 when Iir_Predefined_Write => 1564 if Get_Text_File_Flag (Get_Type (Inter_Chain)) then 1565 File_Operation.Write_Text (Args (0), Args (1)); 1566 else 1567 File_Operation.Write_Binary (Args (0), Args (1)); 1568 end if; 1569 when Iir_Predefined_Read_Length => 1570 if Get_Text_File_Flag (Get_Type (Inter_Chain)) then 1571 File_Operation.Read_Length_Text 1572 (Args (0), Args (1), Args (2)); 1573 else 1574 File_Operation.Read_Length_Binary 1575 (Args (0), Args (1), Args (2)); 1576 end if; 1577 when Iir_Predefined_Read => 1578 File_Operation.Read_Binary (Args (0), Args (1)); 1579 when Iir_Predefined_Flush => 1580 File_Operation.Flush (Args (0)); 1581 when Iir_Predefined_File_Close => 1582 if Get_Text_File_Flag (Get_Type (Inter_Chain)) then 1583 File_Operation.File_Close_Text (Args (0), Stmt); 1584 else 1585 File_Operation.File_Close_Binary (Args (0), Stmt); 1586 end if; 1587 when others => 1588 Error_Kind ("execute_implicit_procedure", 1589 Get_Implicit_Definition (Imp)); 1590 end case; 1591 Release (Expr_Mark, Expr_Pool); 1592 end Execute_Implicit_Procedure; 1593 1594 procedure Execute_Foreign_Procedure 1595 (Block: Block_Instance_Acc; Stmt: Iir_Procedure_Call) 1596 is 1597 Imp : constant Iir := Get_Implementation (Stmt); 1598 Assoc_Chain : constant Iir := Get_Parameter_Association_Chain (Stmt); 1599 Assoc: Iir; 1600 Args: Iir_Value_Literal_Array (0 .. 3) := (others => null); 1601 Expr_Mark : Mark_Type; 1602 begin 1603 Mark (Expr_Mark, Expr_Pool); 1604 Assoc := Assoc_Chain; 1605 for I in Args'Range loop 1606 exit when Assoc = Null_Iir; 1607 Args (I) := Execute_Expression (Block, Get_Actual (Assoc)); 1608 Assoc := Get_Chain (Assoc); 1609 end loop; 1610 case Get_Identifier (Imp) is 1611 when Std_Names.Name_Untruncated_Text_Read => 1612 File_Operation.Untruncated_Text_Read 1613 (Args (0), Args (1), Args (2)); 1614 when Std_Names.Name_Control_Simulation => 1615 -- FIXME: handle stop properly. 1616 -- FIXME: this is the only place where longjump is called. 1617 Grt.Lib.Ghdl_Control_Simulation 1618 (Args (0).B1, Args (1).B1, Std_Integer (Args (2).I64)); 1619 -- Do not return. 1620 when Std_Names.Name_Textio_Write_Real => 1621 File_Operation.Textio_Write_Real 1622 (Args (0), Args (1), Args (2).F64, Std_Integer (Args (3).I64)); 1623 when others => 1624 Error_Msg_Exec ("unsupported foreign procedure call", Stmt); 1625 end case; 1626 Release (Expr_Mark, Expr_Pool); 1627 end Execute_Foreign_Procedure; 1628 1629 -- Compute the offset for INDEX into a range BOUNDS. 1630 -- EXPR is only used in case of error. 1631 function Get_Index_Offset 1632 (Index: Iir_Value_Literal_Acc; 1633 Bounds: Iir_Value_Literal_Acc; 1634 Expr: Iir) 1635 return Iir_Index32 1636 is 1637 Left_Pos, Right_Pos: Iir_Value_Literal_Acc; 1638 begin 1639 Left_Pos := Bounds.Left; 1640 Right_Pos := Bounds.Right; 1641 if Index.Kind /= Left_Pos.Kind or else Index.Kind /= Right_Pos.Kind then 1642 raise Internal_Error; 1643 end if; 1644 case Iir_Value_Discrete (Index.Kind) is 1645 when Iir_Value_B1 => 1646 case Bounds.Dir is 1647 when Dir_To => 1648 if Index.B1 >= Left_Pos.B1 and then 1649 Index.B1 <= Right_Pos.B1 1650 then 1651 -- to 1652 return Ghdl_B1'Pos (Index.B1) - Ghdl_B1'Pos (Left_Pos.B1); 1653 end if; 1654 when Dir_Downto => 1655 if Index.B1 <= Left_Pos.B1 and then 1656 Index.B1 >= Right_Pos.B1 1657 then 1658 -- downto 1659 return Ghdl_B1'Pos (Left_Pos.B1) - Ghdl_B1'Pos (Index.B1); 1660 end if; 1661 end case; 1662 when Iir_Value_E8 => 1663 case Bounds.Dir is 1664 when Dir_To => 1665 if Index.E8 >= Left_Pos.E8 and then 1666 Index.E8 <= Right_Pos.E8 1667 then 1668 -- to 1669 return Iir_Index32 (Index.E8 - Left_Pos.E8); 1670 end if; 1671 when Dir_Downto => 1672 if Index.E8 <= Left_Pos.E8 and then 1673 Index.E8 >= Right_Pos.E8 1674 then 1675 -- downto 1676 return Iir_Index32 (Left_Pos.E8 - Index.E8); 1677 end if; 1678 end case; 1679 when Iir_Value_E32 => 1680 case Bounds.Dir is 1681 when Dir_To => 1682 if Index.E32 >= Left_Pos.E32 and then 1683 Index.E32 <= Right_Pos.E32 1684 then 1685 -- to 1686 return Iir_Index32 (Index.E32 - Left_Pos.E32); 1687 end if; 1688 when Dir_Downto => 1689 if Index.E32 <= Left_Pos.E32 and then 1690 Index.E32 >= Right_Pos.E32 1691 then 1692 -- downto 1693 return Iir_Index32 (Left_Pos.E32 - Index.E32); 1694 end if; 1695 end case; 1696 when Iir_Value_I64 => 1697 case Bounds.Dir is 1698 when Dir_To => 1699 if Index.I64 >= Left_Pos.I64 and then 1700 Index.I64 <= Right_Pos.I64 1701 then 1702 -- to 1703 return Iir_Index32 (Index.I64 - Left_Pos.I64); 1704 end if; 1705 when Dir_Downto => 1706 if Index.I64 <= Left_Pos.I64 and then 1707 Index.I64 >= Right_Pos.I64 1708 then 1709 -- downto 1710 return Iir_Index32 (Left_Pos.I64 - Index.I64); 1711 end if; 1712 end case; 1713 end case; 1714 Error_Msg_Constraint (Expr); 1715 return 0; 1716 end Get_Index_Offset; 1717 1718 -- Create an iir_value_literal of kind iir_value_array and of life LIFE. 1719 -- Allocate the array of bounds, and fill it from A_TYPE. 1720 -- Allocate the array of values. 1721 function Create_Array_Bounds_From_Type (Block : Block_Instance_Acc; 1722 A_Type : Iir; 1723 Create_Val_Array : Boolean) 1724 return Iir_Value_Literal_Acc 1725 is 1726 -- Only for constrained subtypes. 1727 pragma Assert (Get_Constraint_State (A_Type) = Fully_Constrained); 1728 1729 Index_List : constant Iir_Flist := Get_Index_Subtype_List (A_Type); 1730 Res : Iir_Value_Literal_Acc; 1731 Len : Iir_Index32; 1732 Bound : Iir_Value_Literal_Acc; 1733 begin 1734 Res := Create_Array_Value (Iir_Index32 (Get_Nbr_Elements (Index_List))); 1735 Len := 1; 1736 for I in 1 .. Res.Bounds.Nbr_Dims loop 1737 Bound := Execute_Bounds 1738 (Block, Get_Nth_Element (Index_List, Natural (I - 1))); 1739 Len := Len * Bound.Length; 1740 Res.Bounds.D (I) := Bound; 1741 end loop; 1742 if Create_Val_Array then 1743 Create_Array_Data (Res, Len); 1744 end if; 1745 return Res; 1746 end Create_Array_Bounds_From_Type; 1747 1748 -- Return the steps (ie, offset in the array when index DIM is increased 1749 -- by one) for array ARR and dimension DIM. 1750 function Get_Step_For_Dim (Arr: Iir_Value_Literal_Acc; Dim : Natural) 1751 return Iir_Index32 1752 is 1753 Bounds : Value_Bounds_Array_Acc renames Arr.Bounds; 1754 Res : Iir_Index32; 1755 begin 1756 Res := 1; 1757 for I in Iir_Index32 (Dim + 1) .. Bounds.Nbr_Dims loop 1758 Res := Res * Bounds.D (I).Length; 1759 end loop; 1760 return Res; 1761 end Get_Step_For_Dim; 1762 1763 -- Create a literal for a string or a bit_string 1764 function String_To_Enumeration_Array_1 (Str: Iir; El_Type : Iir) 1765 return Iir_Value_Literal_Acc 1766 is 1767 pragma Assert (Get_Kind (Str) = Iir_Kind_String_Literal8); 1768 Id : constant String8_Id := Get_String8_Id (Str); 1769 Len : constant Iir_Index32 := Iir_Index32 (Get_String_Length (Str)); 1770 1771 El_Btype : constant Iir := Get_Base_Type (El_Type); 1772 1773 Lit: Iir_Value_Literal_Acc; 1774 El : Iir_Value_Literal_Acc; 1775 1776 Pos : Nat8; 1777 begin 1778 Lit := Create_Array_Value (Len, 1); 1779 1780 for I in Lit.Val_Array.V'Range loop 1781 -- FIXME: use literal from type ?? 1782 Pos := Str_Table.Element_String8 (Id, Pos32 (I)); 1783 El := Create_Enum_Value (Natural (Pos), El_Btype); 1784 Lit.Val_Array.V (I) := El; 1785 end loop; 1786 1787 return Lit; 1788 end String_To_Enumeration_Array_1; 1789 1790 -- Create a literal for a string or a bit_string 1791 function Execute_String_Literal (Str: Iir; Block_Type : Block_Instance_Acc) 1792 return Iir_Value_Literal_Acc 1793 is 1794 Array_Type: constant Iir := Get_Type (Str); 1795 Index_Types : constant Iir_Flist := Get_Index_Subtype_List (Array_Type); 1796 Res : Iir_Value_Literal_Acc; 1797 begin 1798 -- Array must be unidimensional. 1799 pragma Assert (Get_Nbr_Elements (Index_Types) = 1); 1800 1801 Res := String_To_Enumeration_Array_1 1802 (Str, Get_Element_Subtype (Array_Type)); 1803 1804 -- When created from static evaluation, a string may still have an 1805 -- unconstrained type. 1806 if Get_Constraint_State (Array_Type) /= Fully_Constrained then 1807 Res.Bounds.D (1) := 1808 Create_Range_Value (Create_I64_Value (1), 1809 Create_I64_Value (Ghdl_I64 (Res.Val_Array.Len)), 1810 Dir_To, 1811 Res.Val_Array.Len); 1812 else 1813 Res.Bounds.D (1) := 1814 Execute_Bounds (Block_Type, Get_Nth_Element (Index_Types, 0)); 1815 end if; 1816 1817 -- The range may not be statically constant. 1818 if Res.Bounds.D (1).Length /= Res.Val_Array.Len then 1819 Error_Msg_Constraint (Str); 1820 end if; 1821 1822 return Res; 1823 end Execute_String_Literal; 1824 1825 -- Fill LENGTH elements of RES, starting at ORIG by steps of STEP. 1826 -- Use expressions from (BLOCK, AGGREGATE) to fill the elements. 1827 -- EL_TYPE is the type of the array element. 1828 procedure Fill_Array_Aggregate_1 (Block : Block_Instance_Acc; 1829 Aggregate : Iir; 1830 Res : Iir_Value_Literal_Acc; 1831 Orig : Iir_Index32; 1832 Step : Iir_Index32; 1833 Dim : Iir_Index32; 1834 Nbr_Dim : Iir_Index32; 1835 El_Type : Iir) 1836 is 1837 Value : Iir; 1838 Bound : constant Iir_Value_Literal_Acc := Res.Bounds.D (Dim); 1839 Length : constant Iir_Index32 := Bound.Length; 1840 1841 procedure Set_Elem (Pos : Iir_Index32) 1842 is 1843 Val : Iir_Value_Literal_Acc; 1844 begin 1845 if Dim = Nbr_Dim then 1846 -- VALUE is an expression (which may be an aggregate, but not 1847 -- a sub-aggregate. 1848 Val := Execute_Expression_With_Type (Block, Value, El_Type); 1849 -- LRM93 7.3.2.2 1850 -- For a multi-dimensional aggregate of dimension n, a check 1851 -- is made that all (n-1)-dimensional subaggregates have the 1852 -- same bounds. 1853 -- GHDL: I have added an implicit array conversion, however 1854 -- it may be useful to allow cases like this: 1855 -- type str_array is array (natural range <>) 1856 -- of string (10 downto 1); 1857 -- constant floats : str_array := 1858 -- ( "00000000.0", HT & "+1.5ABCDE"); 1859 -- The subtype of the first sub-aggregate (0.0) is 1860 -- determinated by the context, according to rule 9 and 4 1861 -- of LRM93 7.3.2.2 and therefore is string (10 downto 1), 1862 -- while the subtype of the second sub-aggregate (HT & ...) 1863 -- is determinated by rules 1 and 2 of LRM 7.2.4, and is 1864 -- string (1 to 10). 1865 -- Unless an implicit conversion is used, according to the 1866 -- LRM, this should fail, but it makes no sens. 1867 -- 1868 -- FIXME: Add a warning, a flag ? 1869 --Implicit_Array_Conversion (Block, Val, El_Type, Value); 1870 --Check_Constraints (Block, Val, El_Type, Value); 1871 Res.Val_Array.V (1 + Orig + Pos * Step) := Val; 1872 else 1873 case Get_Kind (Value) is 1874 when Iir_Kind_Aggregate => 1875 -- VALUE is a sub-aggregate. 1876 Fill_Array_Aggregate_1 (Block, Value, Res, 1877 Orig + Pos * Step, 1878 Step / Res.Bounds.D (Dim + 1).Length, 1879 Dim + 1, Nbr_Dim, El_Type); 1880 when Iir_Kind_String_Literal8 => 1881 pragma Assert (Dim + 1 = Nbr_Dim); 1882 Val := String_To_Enumeration_Array_1 (Value, El_Type); 1883 if Val.Val_Array.Len /= Res.Bounds.D (Nbr_Dim).Length then 1884 Error_Msg_Constraint (Value); 1885 end if; 1886 for I in Val.Val_Array.V'Range loop 1887 Res.Val_Array.V (Orig + Pos * Step + I) := 1888 Val.Val_Array.V (I); 1889 end loop; 1890 when others => 1891 Error_Kind ("fill_array_aggregate_1", Value); 1892 end case; 1893 end if; 1894 end Set_Elem; 1895 1896 procedure Set_Elem_By_Expr (Expr : Iir) 1897 is 1898 Expr_Pos: Iir_Value_Literal_Acc; 1899 begin 1900 Expr_Pos := Execute_Expression (Block, Expr); 1901 Set_Elem (Get_Index_Offset (Expr_Pos, Bound, Expr)); 1902 end Set_Elem_By_Expr; 1903 1904 procedure Set_Elem_By_Range (Expr : Iir) 1905 is 1906 A_Range : Iir_Value_Literal_Acc; 1907 High, Low : Iir_Value_Literal_Acc; 1908 begin 1909 A_Range := Execute_Bounds (Block, Expr); 1910 if Is_Null_Range (A_Range) then 1911 return; 1912 end if; 1913 if A_Range.Dir = Dir_To then 1914 High := A_Range.Right; 1915 Low := A_Range.Left; 1916 else 1917 High := A_Range.Left; 1918 Low := A_Range.Right; 1919 end if; 1920 1921 -- Locally modified (incremented) 1922 Low := Unshare (Low, Expr_Pool'Access); 1923 1924 loop 1925 Set_Elem (Get_Index_Offset (Low, Bound, Expr)); 1926 exit when Is_Equal (Low, High); 1927 Increment (Low); 1928 end loop; 1929 end Set_Elem_By_Range; 1930 1931 Assoc : Iir; 1932 Pos : Iir_Index32; 1933 begin 1934 Assoc := Get_Association_Choices_Chain (Aggregate); 1935 Pos := 0; 1936 while Assoc /= Null_Iir loop 1937 Value := Get_Associated_Expr (Assoc); 1938 loop 1939 case Get_Kind (Assoc) is 1940 when Iir_Kind_Choice_By_None => 1941 if Get_Element_Type_Flag (Assoc) then 1942 if Pos >= Length then 1943 Error_Msg_Constraint (Assoc); 1944 end if; 1945 1946 Set_Elem (Pos); 1947 Pos := Pos + 1; 1948 else 1949 declare 1950 Val : Iir_Value_Literal_Acc; 1951 begin 1952 Val := Execute_Expression (Block, Value); 1953 pragma Assert (Val.Kind = Iir_Value_Array); 1954 pragma Assert (Val.Bounds.Nbr_Dims = 1); 1955 for I in 1 .. Val.Val_Array.Len loop 1956 if Pos >= Length then 1957 Error_Msg_Constraint (Assoc); 1958 end if; 1959 Res.Val_Array.V (1 + Orig + Pos * Step) := 1960 Val.Val_Array.V (I); 1961 Pos := Pos + 1; 1962 end loop; 1963 end; 1964 end if; 1965 when Iir_Kind_Choice_By_Expression => 1966 Set_Elem_By_Expr (Get_Choice_Expression (Assoc)); 1967 when Iir_Kind_Choice_By_Range => 1968 Set_Elem_By_Range (Get_Choice_Range (Assoc)); 1969 when Iir_Kind_Choice_By_Others => 1970 for J in 1 .. Length loop 1971 if Res.Val_Array.V (Orig + J * Step) = null then 1972 Set_Elem (J - 1); 1973 end if; 1974 end loop; 1975 return; 1976 when others => 1977 raise Internal_Error; 1978 end case; 1979 Assoc := Get_Chain (Assoc); 1980 exit when Assoc = Null_Iir; 1981 exit when not Get_Same_Alternative_Flag (Assoc); 1982 end loop; 1983 end loop; 1984 1985 -- Check each elements have been set. 1986 -- FIXME: check directly with type. 1987 for J in 1 .. Length loop 1988 if Res.Val_Array.V (Orig + J * Step) = null then 1989 Error_Msg_Constraint (Aggregate); 1990 end if; 1991 end loop; 1992 end Fill_Array_Aggregate_1; 1993 1994 -- Use expressions from (BLOCK, AGGREGATE) to fill RES. 1995 procedure Fill_Array_Aggregate (Block : Block_Instance_Acc; 1996 Aggregate : Iir; 1997 Res : Iir_Value_Literal_Acc) 1998 is 1999 Aggr_Type : constant Iir := Get_Type (Aggregate); 2000 El_Type : constant Iir := Get_Element_Subtype (Aggr_Type); 2001 Index_List : constant Iir_Flist := Get_Index_Subtype_List (Aggr_Type); 2002 Nbr_Dim : constant Iir_Index32 := 2003 Iir_Index32 (Get_Nbr_Elements (Index_List)); 2004 Step : Iir_Index32; 2005 begin 2006 Step := Get_Step_For_Dim (Res, 1); 2007 Fill_Array_Aggregate_1 2008 (Block, Aggregate, Res, 0, Step, 1, Nbr_Dim, El_Type); 2009 end Fill_Array_Aggregate; 2010 2011 function Execute_Record_Aggregate (Block: Block_Instance_Acc; 2012 Aggregate: Iir; 2013 Aggregate_Type: Iir) 2014 return Iir_Value_Literal_Acc 2015 is 2016 List : constant Iir_Flist := 2017 Get_Elements_Declaration_List (Get_Base_Type (Aggregate_Type)); 2018 2019 Res: Iir_Value_Literal_Acc; 2020 Expr : Iir; 2021 2022 procedure Set_Expr (Pos : Iir_Index32) is 2023 El : constant Iir := Get_Nth_Element (List, Natural (Pos - 1)); 2024 begin 2025 Res.Val_Record.V (Pos) := 2026 Execute_Expression_With_Type (Block, Expr, Get_Type (El)); 2027 end Set_Expr; 2028 2029 Pos : Iir_Index32; 2030 Assoc: Iir; 2031 N_Expr : Iir; 2032 begin 2033 Res := Create_Record_Value (Iir_Index32 (Get_Nbr_Elements (List))); 2034 2035 Assoc := Get_Association_Choices_Chain (Aggregate); 2036 Pos := 1; 2037 loop 2038 N_Expr := Get_Associated_Expr (Assoc); 2039 if N_Expr /= Null_Iir then 2040 Expr := N_Expr; 2041 end if; 2042 case Get_Kind (Assoc) is 2043 when Iir_Kind_Choice_By_None => 2044 Set_Expr (Pos); 2045 Pos := Pos + 1; 2046 when Iir_Kind_Choice_By_Name => 2047 Set_Expr (1 + Get_Element_Position 2048 (Get_Named_Entity (Get_Choice_Name (Assoc)))); 2049 when Iir_Kind_Choice_By_Others => 2050 for I in Res.Val_Record.V'Range loop 2051 if Res.Val_Record.V (I) = null then 2052 Set_Expr (I); 2053 end if; 2054 end loop; 2055 when others => 2056 Error_Kind ("execute_record_aggregate", Assoc); 2057 end case; 2058 Assoc := Get_Chain (Assoc); 2059 exit when Assoc = Null_Iir; 2060 end loop; 2061 return Res; 2062 end Execute_Record_Aggregate; 2063 2064 function Execute_Aggregate (Block: Block_Instance_Acc; 2065 Aggregate: Iir; 2066 Block_Type : Block_Instance_Acc; 2067 Aggregate_Type: Iir) 2068 return Iir_Value_Literal_Acc is 2069 begin 2070 case Get_Kind (Aggregate_Type) is 2071 when Iir_Kind_Array_Type_Definition 2072 | Iir_Kind_Array_Subtype_Definition => 2073 declare 2074 Res : Iir_Value_Literal_Acc; 2075 begin 2076 Res := Create_Array_Bounds_From_Type 2077 (Block_Type, Aggregate_Type, True); 2078 Fill_Array_Aggregate (Block, Aggregate, Res); 2079 return Res; 2080 end; 2081 when Iir_Kind_Record_Type_Definition 2082 | Iir_Kind_Record_Subtype_Definition => 2083 return Execute_Record_Aggregate (Block, Aggregate, Aggregate_Type); 2084 when others => 2085 Error_Kind ("execute_aggregate", Aggregate_Type); 2086 end case; 2087 end Execute_Aggregate; 2088 2089 function Execute_Association_Expression 2090 (Actual_Instance : Block_Instance_Acc; 2091 Actual : Iir; 2092 Formal_Instance : Block_Instance_Acc) 2093 return Iir_Value_Literal_Acc 2094 is 2095 begin 2096 case Get_Kind (Actual) is 2097 when Iir_Kind_String_Literal8 => 2098 return Execute_String_Literal (Actual, Formal_Instance); 2099 when Iir_Kind_Aggregate => 2100 return Execute_Aggregate 2101 (Actual_Instance, Actual, Formal_Instance, Get_Type (Actual)); 2102 when others => 2103 null; 2104 end case; 2105 return Execute_Expression (Actual_Instance, Actual); 2106 end Execute_Association_Expression; 2107 2108 2109 function Execute_Simple_Aggregate (Block: Block_Instance_Acc; Aggr : Iir) 2110 return Iir_Value_Literal_Acc 2111 is 2112 Res : Iir_Value_Literal_Acc; 2113 List : constant Iir_Flist := Get_Simple_Aggregate_List (Aggr); 2114 begin 2115 Res := Create_Array_Bounds_From_Type (Block, Get_Type (Aggr), True); 2116 for I in Res.Val_Array.V'Range loop 2117 Res.Val_Array.V (I) := 2118 Execute_Expression (Block, Get_Nth_Element (List, Natural (I - 1))); 2119 end loop; 2120 return Res; 2121 end Execute_Simple_Aggregate; 2122 2123 -- Fill LENGTH elements of RES, starting at ORIG by steps of STEP. 2124 -- Use expressions from (BLOCK, AGGREGATE) to fill the elements. 2125 -- EL_TYPE is the type of the array element. 2126 procedure Execute_Name_Array_Aggregate (Block : Block_Instance_Acc; 2127 Aggregate : Iir; 2128 Res : Iir_Value_Literal_Acc; 2129 Orig : Iir_Index32; 2130 Step : Iir_Index32; 2131 Dim : Iir_Index32; 2132 Nbr_Dim : Iir_Index32; 2133 El_Type : Iir) 2134 is 2135 Value : Iir; 2136 Bound : Iir_Value_Literal_Acc; 2137 2138 procedure Set_Elem (Pos : Iir_Index32) 2139 is 2140 Val : Iir_Value_Literal_Acc; 2141 Is_Sig : Boolean; 2142 begin 2143 if Dim = Nbr_Dim then 2144 -- VALUE is an expression (which may be an aggregate, but not 2145 -- a sub-aggregate. 2146 Execute_Name_With_Base (Block, Value, null, Val, Is_Sig); 2147 Res.Val_Array.V (1 + Orig + Pos * Step) := Val; 2148 else 2149 -- VALUE is a sub-aggregate. 2150 Execute_Name_Array_Aggregate 2151 (Block, Value, Res, 2152 Orig + Pos * Step, 2153 Step / Res.Bounds.D (Dim + 1).Length, 2154 Dim + 1, Nbr_Dim, El_Type); 2155 end if; 2156 end Set_Elem; 2157 2158 Assoc : Iir; 2159 Pos : Iir_Index32; 2160 begin 2161 Assoc := Get_Association_Choices_Chain (Aggregate); 2162 Bound := Res.Bounds.D (Dim); 2163 Pos := 0; 2164 while Assoc /= Null_Iir loop 2165 Value := Get_Associated_Expr (Assoc); 2166 case Get_Kind (Assoc) is 2167 when Iir_Kind_Choice_By_None => 2168 null; 2169 when Iir_Kind_Choice_By_Expression => 2170 declare 2171 Expr_Pos: Iir_Value_Literal_Acc; 2172 Val : constant Iir := Get_Expression (Assoc); 2173 begin 2174 Expr_Pos := Execute_Expression (Block, Val); 2175 Pos := Get_Index_Offset (Expr_Pos, Bound, Val); 2176 end; 2177 when others => 2178 raise Internal_Error; 2179 end case; 2180 Set_Elem (Pos); 2181 Pos := Pos + 1; 2182 Assoc := Get_Chain (Assoc); 2183 end loop; 2184 end Execute_Name_Array_Aggregate; 2185 2186 function Execute_Record_Name_Aggregate (Block: Block_Instance_Acc; 2187 Aggregate: Iir; 2188 Aggregate_Type: Iir) 2189 return Iir_Value_Literal_Acc 2190 is 2191 List : constant Iir_Flist := 2192 Get_Elements_Declaration_List (Get_Base_Type (Aggregate_Type)); 2193 Res: Iir_Value_Literal_Acc; 2194 Expr : Iir; 2195 Pos : Iir_Index32; 2196 El_Pos : Iir_Index32; 2197 Is_Sig : Boolean; 2198 Assoc: Iir; 2199 begin 2200 Res := Create_Record_Value (Iir_Index32 (Get_Nbr_Elements (List))); 2201 Assoc := Get_Association_Choices_Chain (Aggregate); 2202 Pos := 0; 2203 loop 2204 Expr := Get_Associated_Expr (Assoc); 2205 if Expr = Null_Iir then 2206 -- List of choices is not allowed. 2207 raise Internal_Error; 2208 end if; 2209 case Get_Kind (Assoc) is 2210 when Iir_Kind_Choice_By_None => 2211 El_Pos := Pos; 2212 Pos := Pos + 1; 2213 when Iir_Kind_Choice_By_Name => 2214 El_Pos := Get_Element_Position (Get_Name (Assoc)); 2215 when Iir_Kind_Choice_By_Others => 2216 raise Internal_Error; 2217 when others => 2218 Error_Kind ("execute_record_name_aggregate", Assoc); 2219 end case; 2220 Execute_Name_With_Base 2221 (Block, Expr, null, Res.Val_Record.V (1 + El_Pos), Is_Sig); 2222 Assoc := Get_Chain (Assoc); 2223 exit when Assoc = Null_Iir; 2224 end loop; 2225 return Res; 2226 end Execute_Record_Name_Aggregate; 2227 2228 function Execute_Name_Aggregate (Block: Block_Instance_Acc; 2229 Aggregate: Iir; 2230 Aggregate_Type: Iir) 2231 return Iir_Value_Literal_Acc is 2232 begin 2233 case Get_Kind (Aggregate_Type) is 2234 when Iir_Kind_Array_Type_Definition 2235 | Iir_Kind_Array_Subtype_Definition => 2236 declare 2237 El_Type : constant Iir := Get_Element_Subtype (Aggregate_Type); 2238 Index_List : constant Iir_Flist := 2239 Get_Index_Subtype_List (Aggregate_Type); 2240 Nbr_Dim : constant Iir_Index32 := 2241 Iir_Index32 (Get_Nbr_Elements (Index_List)); 2242 Res : Iir_Value_Literal_Acc; 2243 Step : Iir_Index32; 2244 begin 2245 pragma Assert 2246 (Get_Constraint_State (Aggregate_Type) = Fully_Constrained); 2247 Res := Create_Array_Bounds_From_Type 2248 (Block, Aggregate_Type, True); 2249 Step := Get_Step_For_Dim (Res, 1); 2250 Execute_Name_Array_Aggregate 2251 (Block, Aggregate, Res, 0, Step, 1, Nbr_Dim, El_Type); 2252 return Res; 2253 end; 2254 when Iir_Kind_Record_Type_Definition 2255 | Iir_Kind_Record_Subtype_Definition => 2256 return Execute_Record_Name_Aggregate 2257 (Block, Aggregate, Aggregate_Type); 2258 when others => 2259 Error_Kind ("execute_name_aggregate", Aggregate_Type); 2260 end case; 2261 end Execute_Name_Aggregate; 2262 2263 -- Return the indexes range for prefix of ATTR. 2264 function Execute_Indexes (Block: Block_Instance_Acc; Attr : Iir) 2265 return Iir_Value_Literal_Acc 2266 is 2267 Prefix : constant Iir := Strip_Denoting_Name (Get_Prefix (Attr)); 2268 Dim : constant Natural := 2269 Vhdl.Evaluation.Eval_Attribute_Parameter_Or_1 (Attr); 2270 begin 2271 case Get_Kind (Prefix) is 2272 when Iir_Kind_Type_Declaration 2273 | Iir_Kind_Subtype_Declaration => 2274 declare 2275 Index : Iir; 2276 begin 2277 Index := Get_Nth_Element 2278 (Get_Index_Subtype_List (Get_Type (Prefix)), Dim - 1); 2279 return Execute_Bounds (Block, Index); 2280 end; 2281 when Iir_Kind_Array_Type_Definition 2282 | Iir_Kind_Array_Subtype_Definition => 2283 Error_Kind ("execute_indexes", Prefix); 2284 when others => 2285 declare 2286 Orig : Iir_Value_Literal_Acc; 2287 begin 2288 Orig := Execute_Name (Block, Prefix, True); 2289 return Orig.Bounds.D (Iir_Index32 (Dim)); 2290 end; 2291 end case; 2292 end Execute_Indexes; 2293 2294 function Execute_Bounds (Block: Block_Instance_Acc; Prefix: Iir) 2295 return Iir_Value_Literal_Acc 2296 is 2297 Bound : Iir_Value_Literal_Acc; 2298 begin 2299 case Get_Kind (Prefix) is 2300 when Iir_Kind_Range_Expression => 2301 declare 2302 Info : constant Sim_Info_Acc := Get_Info (Prefix); 2303 begin 2304 if Info = null then 2305 Bound := Create_Range_Value 2306 (Execute_Expression (Block, Get_Left_Limit (Prefix)), 2307 Execute_Expression (Block, Get_Right_Limit (Prefix)), 2308 Get_Direction (Prefix)); 2309 elsif Info.Kind = Kind_Object then 2310 Bound := Get_Instance_Object (Block, Prefix); 2311 else 2312 raise Internal_Error; 2313 end if; 2314 end; 2315 2316 when Iir_Kind_Subtype_Declaration => 2317 return Execute_Bounds (Block, Get_Type (Prefix)); 2318 2319 when Iir_Kind_Integer_Subtype_Definition 2320 | Iir_Kind_Floating_Subtype_Definition 2321 | Iir_Kind_Enumeration_Subtype_Definition 2322 | Iir_Kind_Enumeration_Type_Definition 2323 | Iir_Kind_Physical_Subtype_Definition => 2324 -- FIXME: move this block before and avoid recursion. 2325 return Execute_Bounds (Block, Get_Range_Constraint (Prefix)); 2326 2327 when Iir_Kind_Range_Array_Attribute => 2328 Bound := Execute_Indexes (Block, Prefix); 2329 when Iir_Kind_Reverse_Range_Array_Attribute => 2330 Bound := Execute_Indexes (Block, Prefix); 2331 case Bound.Dir is 2332 when Dir_To => 2333 Bound := Create_Range_Value 2334 (Bound.Right, Bound.Left, Dir_Downto, Bound.Length); 2335 when Dir_Downto => 2336 Bound := Create_Range_Value 2337 (Bound.Right, Bound.Left, Dir_To, Bound.Length); 2338 end case; 2339 2340 when Iir_Kind_Floating_Type_Definition 2341 | Iir_Kind_Integer_Type_Definition => 2342 return Execute_Bounds 2343 (Block, 2344 Get_Range_Constraint (Get_Type (Get_Type_Declarator (Prefix)))); 2345 2346 when Iir_Kinds_Denoting_Name => 2347 return Execute_Bounds (Block, Get_Named_Entity (Prefix)); 2348 2349 when Iir_Kind_Subtype_Attribute => 2350 return Execute_Bounds (Block, Get_Type (Prefix)); 2351 2352 when others => 2353 -- Error_Kind ("execute_bounds", Get_Kind (Prefix)); 2354 declare 2355 Prefix_Val: Iir_Value_Literal_Acc; 2356 begin 2357 Prefix_Val := Execute_Expression (Block, Prefix); 2358 Bound := Prefix_Val.Bounds.D (1); 2359 end; 2360 end case; 2361 if not Bound.Dir'Valid then 2362 raise Internal_Error; 2363 end if; 2364 return Bound; 2365 end Execute_Bounds; 2366 2367 -- Perform type conversion as desribed in LRM93 7.3.5 2368 function Execute_Type_Conversion (Block: Block_Instance_Acc; 2369 Val : Iir_Value_Literal_Acc; 2370 Target_Type : Iir; 2371 Loc : Iir) 2372 return Iir_Value_Literal_Acc 2373 is 2374 Res: Iir_Value_Literal_Acc; 2375 begin 2376 Res := Val; 2377 case Get_Kind (Target_Type) is 2378 when Iir_Kind_Integer_Type_Definition 2379 | Iir_Kind_Integer_Subtype_Definition => 2380 case Iir_Value_Numerics (Res.Kind) is 2381 when Iir_Value_I64 => 2382 null; 2383 when Iir_Value_F64 => 2384 if Res.F64 > Ghdl_F64 (Int64'Last) or 2385 Res.F64 < Ghdl_F64 (Int64'First) 2386 then 2387 Error_Msg_Constraint (Loc); 2388 end if; 2389 Res := Create_I64_Value (Ghdl_I64 (Res.F64)); 2390 end case; 2391 when Iir_Kind_Floating_Type_Definition 2392 | Iir_Kind_Floating_Subtype_Definition => 2393 case Iir_Value_Numerics (Res.Kind) is 2394 when Iir_Value_F64 => 2395 null; 2396 when Iir_Value_I64 => 2397 Res := Create_F64_Value (Ghdl_F64 (Res.I64)); 2398 end case; 2399 when Iir_Kind_Enumeration_Type_Definition 2400 | Iir_Kind_Enumeration_Subtype_Definition => 2401 -- Must be same type. 2402 null; 2403 when Iir_Kind_Physical_Type_Definition 2404 | Iir_Kind_Physical_Subtype_Definition => 2405 -- Same type. 2406 null; 2407 when Iir_Kind_Record_Type_Definition 2408 | Iir_Kind_Record_Subtype_Definition => 2409 -- Same type. 2410 null; 2411 when Iir_Kind_Array_Subtype_Definition 2412 | Iir_Kind_Array_Type_Definition => 2413 -- LRM93 7.3.5 2414 -- if the type mark denotes an unconstrained array type and the 2415 -- operand is not a null array, then for each index position, the 2416 -- bounds of the result are obtained by converting the bounds of 2417 -- the operand to the corresponding index type of the target type. 2418 -- 2419 -- LRM93 7.3.5 2420 -- If the type mark denotes a constrained array subtype, then the 2421 -- bounds of the result are those imposed by the type mark. 2422 if Get_Constraint_State (Target_Type) = Fully_Constrained then 2423 Implicit_Array_Conversion (Block, Res, Target_Type, Loc); 2424 else 2425 declare 2426 Idx_List : constant Iir_Flist := 2427 Get_Index_Subtype_List (Target_Type); 2428 Idx_Type : Iir; 2429 begin 2430 Res := Create_Array_Value (Val.Bounds.Nbr_Dims); 2431 Res.Val_Array := Val.Val_Array; 2432 for I in Val.Bounds.D'Range loop 2433 Idx_Type := Get_Index_Type (Idx_List, Natural (I - 1)); 2434 Res.Bounds.D (I) := Create_Range_Value 2435 (Left => Execute_Type_Conversion 2436 (Block, Val.Bounds.D (I).Left, Idx_Type, Loc), 2437 Right => Execute_Type_Conversion 2438 (Block, Val.Bounds.D (I).Right, Idx_Type, Loc), 2439 Dir => Val.Bounds.D (I).Dir, 2440 Length => Val.Bounds.D (I).Length); 2441 end loop; 2442 end; 2443 end if; 2444 when others => 2445 Error_Kind ("execute_type_conversion", Target_Type); 2446 end case; 2447 Check_Constraints (Block, Res, Target_Type, Loc); 2448 return Res; 2449 end Execute_Type_Conversion; 2450 2451 -- Decrement VAL. 2452 -- May raise a constraint error using EXPR. 2453 function Execute_Dec (Val : Iir_Value_Literal_Acc; Expr : Iir) 2454 return Iir_Value_Literal_Acc 2455 is 2456 Res : Iir_Value_Literal_Acc; 2457 begin 2458 case Iir_Value_Discrete (Val.Kind) is 2459 when Iir_Value_B1 => 2460 if Val.B1 = False then 2461 Error_Msg_Constraint (Expr); 2462 end if; 2463 Res := Create_B1_Value (False); 2464 when Iir_Value_E8 => 2465 if Val.E8 = 0 then 2466 Error_Msg_Constraint (Expr); 2467 end if; 2468 Res := Create_E8_Value (Val.E8 - 1); 2469 when Iir_Value_E32 => 2470 if Val.E32 = 0 then 2471 Error_Msg_Constraint (Expr); 2472 end if; 2473 Res := Create_E32_Value (Val.E32 - 1); 2474 when Iir_Value_I64 => 2475 if Val.I64 = Ghdl_I64'First then 2476 Error_Msg_Constraint (Expr); 2477 end if; 2478 Res := Create_I64_Value (Val.I64 - 1); 2479 end case; 2480 return Res; 2481 end Execute_Dec; 2482 2483 -- Increment VAL. 2484 -- May raise a constraint error using EXPR. 2485 function Execute_Inc (Val : Iir_Value_Literal_Acc; Expr : Iir) 2486 return Iir_Value_Literal_Acc 2487 is 2488 Res : Iir_Value_Literal_Acc; 2489 begin 2490 case Iir_Value_Discrete (Val.Kind) is 2491 when Iir_Value_B1 => 2492 if Val.B1 = True then 2493 Error_Msg_Constraint (Expr); 2494 end if; 2495 Res := Create_B1_Value (True); 2496 when Iir_Value_E32 => 2497 if Val.E32 = Ghdl_E32'Last then 2498 Error_Msg_Constraint (Expr); 2499 end if; 2500 Res := Create_E32_Value (Val.E32 + 1); 2501 when Iir_Value_E8 => 2502 if Val.E8 = Ghdl_E8'Last then 2503 Error_Msg_Constraint (Expr); 2504 end if; 2505 Res := Create_E8_Value (Val.E8 + 1); 2506 when Iir_Value_I64 => 2507 if Val.I64 = Ghdl_I64'Last then 2508 Error_Msg_Constraint (Expr); 2509 end if; 2510 Res := Create_I64_Value (Val.I64 + 1); 2511 end case; 2512 return Res; 2513 end Execute_Inc; 2514 2515 function Execute_Expression_With_Type (Block: Block_Instance_Acc; 2516 Expr: Iir; 2517 Expr_Type : Iir) 2518 return Iir_Value_Literal_Acc 2519 is 2520 Res : Iir_Value_Literal_Acc; 2521 begin 2522 if Get_Kind (Expr) = Iir_Kind_Aggregate 2523 and then not Is_Fully_Constrained_Type (Get_Type (Expr)) 2524 then 2525 return Execute_Aggregate (Block, Expr, Block, Expr_Type); 2526 else 2527 Res := Execute_Expression (Block, Expr); 2528 Implicit_Array_Conversion (Block, Res, Expr_Type, Expr); 2529 Check_Constraints (Block, Res, Expr_Type, Expr); 2530 return Res; 2531 end if; 2532 end Execute_Expression_With_Type; 2533 2534 function Execute_Signal_Name 2535 (Block : Block_Instance_Acc; Expr : Iir; Kind : Signal_Slot) 2536 return Iir_Value_Literal_Acc 2537 is 2538 Base : constant Iir := Get_Object_Prefix (Expr, False); 2539 Info : constant Sim_Info_Acc := Get_Info (Base); 2540 Bblk : Block_Instance_Acc; 2541 Slot : Object_Slot_Type; 2542 Base_Val : Iir_Value_Literal_Acc; 2543 Res : Iir_Value_Literal_Acc; 2544 Is_Sig : Boolean; 2545 begin 2546 if Get_Kind (Base) = Iir_Kind_Object_Alias_Declaration then 2547 Bblk := Get_Instance_By_Scope (Block, Info.Obj_Scope); 2548 Base_Val := Execute_Signal_Name (Bblk, Get_Name (Base), Kind); 2549 else 2550 Bblk := Get_Instance_By_Scope (Block, Info.Obj_Scope); 2551 case Kind is 2552 when Signal_Sig => 2553 Slot := Info.Slot; 2554 when Signal_Val => 2555 Slot := Info.Slot + 1; 2556 when Signal_Init => 2557 Slot := Info.Slot + 2; 2558 end case; 2559 Base_Val := Bblk.Objects (Slot); 2560 end if; 2561 Execute_Name_With_Base (Block, Expr, Base_Val, Res, Is_Sig); 2562 pragma Assert (Is_Sig); 2563 return Res; 2564 end Execute_Signal_Name; 2565 2566 -- Indexed element will be at Pfx.Val_Array.V (Pos + 1) 2567 procedure Execute_Indexed_Name (Block: Block_Instance_Acc; 2568 Expr: Iir; 2569 Pfx : Iir_Value_Literal_Acc; 2570 Pos : out Iir_Index32) 2571 is 2572 pragma Assert (Get_Kind (Expr) = Iir_Kind_Indexed_Name); 2573 Index_List : constant Iir_Flist := Get_Index_List (Expr); 2574 Nbr_Dimensions : constant Iir_Index32 := 2575 Iir_Index32 (Get_Nbr_Elements (Index_List)); 2576 Index: Iir; 2577 Value: Iir_Value_Literal_Acc; 2578 Off : Iir_Index32; 2579 begin 2580 for I in 1 .. Nbr_Dimensions loop 2581 Index := Get_Nth_Element (Index_List, Natural (I - 1)); 2582 Value := Execute_Expression (Block, Index); 2583 Off := Get_Index_Offset (Value, Pfx.Bounds.D (I), Expr); 2584 if I = 1 then 2585 Pos := Off; 2586 else 2587 Pos := Pos * Pfx.Bounds.D (I).Length + Off; 2588 end if; 2589 end loop; 2590 end Execute_Indexed_Name; 2591 2592 -- Indexed element will be at Pfx.Val_Array.V (Pos) 2593 procedure Execute_Slice_Name (Prefix_Array: Iir_Value_Literal_Acc; 2594 Srange : Iir_Value_Literal_Acc; 2595 Low : out Iir_Index32; 2596 High : out Iir_Index32; 2597 Loc : Iir) 2598 is 2599 Index_Order : Order; 2600 -- Lower and upper bounds of the slice. 2601 begin 2602 pragma Assert (Prefix_Array /= null); 2603 2604 -- LRM93 6.5 2605 -- It is an error if the direction of the discrete range is not 2606 -- the same as that of the index range of the array denoted by 2607 -- the prefix of the slice name. 2608 if Srange.Dir /= Prefix_Array.Bounds.D (1).Dir then 2609 Error_Msg_Exec ("slice direction mismatch", Loc); 2610 end if; 2611 2612 -- LRM93 6.5 2613 -- It is an error if either of the bounds of the 2614 -- discrete range does not belong to the index range of the 2615 -- prefixing array, unless the slice is a null slice. 2616 Index_Order := Compare_Value (Srange.Left, Srange.Right); 2617 if (Srange.Dir = Dir_To and Index_Order = Greater) 2618 or (Srange.Dir = Dir_Downto and Index_Order = Less) 2619 then 2620 -- Null slice. 2621 Low := 1; 2622 High := 0; 2623 else 2624 Low := Get_Index_Offset 2625 (Srange.Left, Prefix_Array.Bounds.D (1), Loc); 2626 High := Get_Index_Offset 2627 (Srange.Right, Prefix_Array.Bounds.D (1), Loc); 2628 end if; 2629 end Execute_Slice_Name; 2630 2631 procedure Execute_Name_With_Base (Block: Block_Instance_Acc; 2632 Expr: Iir; 2633 Base : Iir_Value_Literal_Acc; 2634 Res : out Iir_Value_Literal_Acc; 2635 Is_Sig : out Boolean) is 2636 begin 2637 -- Default value 2638 Is_Sig := False; 2639 2640 case Get_Kind (Expr) is 2641 when Iir_Kind_Interface_Signal_Declaration 2642 | Iir_Kind_Signal_Declaration 2643 | Iir_Kind_Guard_Signal_Declaration 2644 | Iir_Kind_Stable_Attribute 2645 | Iir_Kind_Quiet_Attribute 2646 | Iir_Kind_Delayed_Attribute 2647 | Iir_Kind_Transaction_Attribute => 2648 Is_Sig := True; 2649 if Base /= null then 2650 Res := Base; 2651 else 2652 Res := Get_Instance_Object (Block, Expr); 2653 end if; 2654 2655 when Iir_Kind_Object_Alias_Declaration => 2656 -- FIXME: add a flag ? 2657 Is_Sig := Is_Signal_Object (Expr); 2658 if Base /= null then 2659 Res := Base; 2660 else 2661 Res := Get_Instance_Object (Block, Expr); 2662 end if; 2663 2664 when Iir_Kind_Interface_Constant_Declaration 2665 | Iir_Kind_Constant_Declaration 2666 | Iir_Kind_Interface_Variable_Declaration 2667 | Iir_Kind_Variable_Declaration 2668 | Iir_Kind_Interface_File_Declaration 2669 | Iir_Kind_File_Declaration 2670 | Iir_Kind_Attribute_Value 2671 | Iir_Kind_Iterator_Declaration 2672 | Iir_Kind_Terminal_Declaration 2673 | Iir_Kinds_Quantity_Declaration 2674 | Iir_Kind_Psl_Endpoint_Declaration => 2675 if Base /= null then 2676 Res := Base; 2677 else 2678 Res := Get_Instance_Object (Block, Expr); 2679 end if; 2680 2681 when Iir_Kind_Indexed_Name => 2682 declare 2683 Pfx : Iir_Value_Literal_Acc; 2684 Pos : Iir_Index32; 2685 begin 2686 Execute_Name_With_Base 2687 (Block, Get_Prefix (Expr), Base, Pfx, Is_Sig); 2688 Execute_Indexed_Name (Block, Expr, Pfx, Pos); 2689 Res := Pfx.Val_Array.V (Pos + 1); 2690 end; 2691 2692 when Iir_Kind_Slice_Name => 2693 declare 2694 Prefix_Array: Iir_Value_Literal_Acc; 2695 Srange : Iir_Value_Literal_Acc; 2696 Low, High: Iir_Index32; 2697 begin 2698 Execute_Name_With_Base 2699 (Block, Get_Prefix (Expr), Base, Prefix_Array, Is_Sig); 2700 2701 Srange := Execute_Bounds (Block, Get_Suffix (Expr)); 2702 Execute_Slice_Name (Prefix_Array, Srange, Low, High, Expr); 2703 2704 Res := Create_Array_Value (High - Low + 1, 1); 2705 Res.Bounds.D (1) := Srange; 2706 for I in Low .. High loop 2707 Res.Val_Array.V (1 + I - Low) := 2708 Prefix_Array.Val_Array.V (1 + I); 2709 end loop; 2710 end; 2711 2712 when Iir_Kind_Selected_Element => 2713 declare 2714 Prefix: Iir_Value_Literal_Acc; 2715 Pos: Iir_Index32; 2716 begin 2717 Execute_Name_With_Base 2718 (Block, Get_Prefix (Expr), Base, Prefix, Is_Sig); 2719 Pos := Get_Element_Position (Get_Named_Entity (Expr)); 2720 Res := Prefix.Val_Record.V (Pos + 1); 2721 end; 2722 2723 when Iir_Kind_Dereference 2724 | Iir_Kind_Implicit_Dereference => 2725 declare 2726 Prefix: Iir_Value_Literal_Acc; 2727 begin 2728 Prefix := Execute_Name (Block, Get_Prefix (Expr)); 2729 Res := Prefix.Val_Access; 2730 if Res = null then 2731 Error_Msg_Exec ("deferencing null access", Expr); 2732 end if; 2733 end; 2734 2735 when Iir_Kinds_Denoting_Name 2736 | Iir_Kind_Attribute_Name => 2737 Execute_Name_With_Base 2738 (Block, Get_Named_Entity (Expr), Base, Res, Is_Sig); 2739 2740 when Iir_Kind_Function_Call => 2741 -- A prefix can be an expression 2742 if Base /= null then 2743 raise Internal_Error; 2744 end if; 2745 Res := Execute_Expression (Block, Expr); 2746 2747 when Iir_Kind_Aggregate => 2748 Res := Execute_Name_Aggregate (Block, Expr, Get_Type (Expr)); 2749 2750 when Iir_Kind_Image_Attribute => 2751 Res := Execute_Image_Attribute (Block, Expr); 2752 2753 when Iir_Kind_Path_Name_Attribute 2754 | Iir_Kind_Instance_Name_Attribute => 2755 Res := Execute_Path_Instance_Name_Attribute (Block, Expr); 2756 2757 when others => 2758 Error_Kind ("execute_name_with_base", Expr); 2759 end case; 2760 end Execute_Name_With_Base; 2761 2762 function Execute_Name (Block: Block_Instance_Acc; 2763 Expr: Iir; 2764 Ref : Boolean := False) 2765 return Iir_Value_Literal_Acc 2766 is 2767 Res: Iir_Value_Literal_Acc; 2768 Is_Sig : Boolean; 2769 begin 2770 Execute_Name_With_Base (Block, Expr, null, Res, Is_Sig); 2771 if not Is_Sig or else Ref then 2772 return Res; 2773 else 2774 return Execute_Signal_Value (Res); 2775 end if; 2776 end Execute_Name; 2777 2778 function Execute_Value_Attribute (Block: Block_Instance_Acc; 2779 Str_Val : Iir_Value_Literal_Acc; 2780 Expr: Iir) 2781 return Iir_Value_Literal_Acc 2782 is 2783 use Grt_Interface; 2784 use Name_Table; 2785 pragma Unreferenced (Block); 2786 2787 Expr_Type : constant Iir := Get_Type (Expr); 2788 Res : Iir_Value_Literal_Acc; 2789 2790 Str_Bnd : aliased Std_String_Bound := Build_Bound (Str_Val); 2791 Str_Str : aliased Std_String_Uncons (1 .. Str_Bnd.Dim_1.Length); 2792 Str : aliased Std_String := (To_Std_String_Basep (Str_Str'Address), 2793 To_Std_String_Boundp (Str_Bnd'Address)); 2794 begin 2795 Set_Std_String_From_Iir_Value (Str, Str_Val); 2796 case Get_Kind (Expr_Type) is 2797 when Iir_Kind_Integer_Type_Definition 2798 | Iir_Kind_Integer_Subtype_Definition => 2799 Res := Create_I64_Value 2800 (Grt.Values.Ghdl_Value_I64 (Str'Unrestricted_Access)); 2801 when Iir_Kind_Floating_Type_Definition 2802 | Iir_Kind_Floating_Subtype_Definition => 2803 Res := Create_F64_Value 2804 (Grt.Values.Ghdl_Value_F64 (Str'Unrestricted_Access)); 2805 when Iir_Kind_Physical_Type_Definition 2806 | Iir_Kind_Physical_Subtype_Definition => 2807 declare 2808 Is_Real : Boolean; 2809 Lit_Pos : Ghdl_Index_Type; 2810 Lit_End : Ghdl_Index_Type; 2811 Unit_Pos : Ghdl_Index_Type; 2812 Unit_Len : Ghdl_Index_Type; 2813 Mult : Ghdl_I64; 2814 Unit : Iir; 2815 Unit_Id : Name_Id; 2816 begin 2817 Grt.Values.Ghdl_Value_Physical_Split 2818 (Str'Unrestricted_Access, 2819 Is_Real, Lit_Pos, Lit_End, Unit_Pos); 2820 2821 -- Find unit. 2822 Unit_Len := 0; 2823 Unit_Pos := Unit_Pos + 1; -- From 0 based to 1 based 2824 for I in Unit_Pos .. Str_Bnd.Dim_1.Length loop 2825 exit when Grt.Strings.Is_Whitespace (Str_Str (I)); 2826 Unit_Len := Unit_Len + 1; 2827 Str_Str (I) := Grt.Strings.To_Lower (Str_Str (I)); 2828 end loop; 2829 2830 Unit := Get_Primary_Unit (Expr_Type); 2831 while Unit /= Null_Iir loop 2832 Unit_Id := Get_Identifier (Unit); 2833 exit when Get_Name_Length (Unit_Id) = Natural (Unit_Len) 2834 and then Image (Unit_Id) = 2835 String (Str_Str (Unit_Pos .. Unit_Pos + Unit_Len - 1)); 2836 Unit := Get_Chain (Unit); 2837 end loop; 2838 2839 if Unit = Null_Iir then 2840 Error_Msg_Exec ("incorrect unit name", Expr); 2841 end if; 2842 Mult := Ghdl_I64 (Get_Value (Get_Physical_Literal (Unit))); 2843 2844 Str_Bnd.Dim_1.Length := Lit_End; 2845 if Is_Real then 2846 Res := Create_I64_Value 2847 (Ghdl_I64 2848 (Grt.Values.Ghdl_Value_F64 (Str'Unrestricted_Access) 2849 * Ghdl_F64 (Mult))); 2850 else 2851 Res := Create_I64_Value 2852 (Grt.Values.Ghdl_Value_I64 (Str'Unrestricted_Access) 2853 * Mult); 2854 end if; 2855 end; 2856 when Iir_Kind_Enumeration_Type_Definition 2857 | Iir_Kind_Enumeration_Subtype_Definition => 2858 declare 2859 Enums : constant Iir_Flist := 2860 Get_Enumeration_Literal_List (Get_Base_Type (Expr_Type)); 2861 Lit_Start : Ghdl_Index_Type; 2862 Lit_End : Ghdl_Index_Type; 2863 Enum : Iir; 2864 Lit_Id : Name_Id; 2865 Enum_Id : Name_Id; 2866 begin 2867 -- Remove leading and trailing blanks 2868 for I in Str_Str'Range loop 2869 if not Grt.Strings.Is_Whitespace (Str_Str (I)) then 2870 Lit_Start := I; 2871 exit; 2872 end if; 2873 end loop; 2874 for I in reverse Lit_Start .. Str_Str'Last loop 2875 if not Grt.Strings.Is_Whitespace (Str_Str (I)) then 2876 Lit_End := I; 2877 exit; 2878 end if; 2879 end loop; 2880 2881 if Str_Str (Lit_Start) = ''' 2882 and then Str_Str (Lit_End) = ''' 2883 and then Lit_End = Lit_Start + 2 2884 then 2885 -- Enumeration literal. 2886 Lit_Id := Get_Identifier (Str_Str (Lit_Start + 1)); 2887 2888 for I in Natural loop 2889 Enum := Get_Nth_Element (Enums, I); 2890 exit when Enum = Null_Iir; 2891 exit when Get_Identifier (Enum) = Lit_Id; 2892 end loop; 2893 else 2894 -- Literal identifier. 2895 -- Convert to lower case. 2896 for I in Lit_Start .. Lit_End loop 2897 Str_Str (I) := Grt.Strings.To_Lower (Str_Str (I)); 2898 end loop; 2899 2900 for I in Natural loop 2901 Enum := Get_Nth_Element (Enums, I); 2902 exit when Enum = Null_Iir; 2903 Enum_Id := Get_Identifier (Enum); 2904 exit when (Get_Name_Length (Enum_Id) = 2905 Natural (Lit_End - Lit_Start + 1)) 2906 and then (Image (Enum_Id) = 2907 String (Str_Str (Lit_Start .. Lit_End))); 2908 end loop; 2909 end if; 2910 2911 if Enum = Null_Iir then 2912 Error_Msg_Exec 2913 ("incorrect enumeration literal for 'value", Expr); 2914 end if; 2915 2916 return Create_Enum_Value 2917 (Natural (Get_Enum_Pos (Enum)), Expr_Type); 2918 end; 2919 when others => 2920 Error_Kind ("value_attribute", Expr_Type); 2921 end case; 2922 return Res; 2923 end Execute_Value_Attribute; 2924 2925 -- For 'Last_Event and 'Last_Active: convert the absolute last time to 2926 -- a relative delay. 2927 function To_Relative_Time (T : Ghdl_I64) return Iir_Value_Literal_Acc 2928 is 2929 A : Ghdl_I64; 2930 begin 2931 if T = -Ghdl_I64'Last then 2932 A := Ghdl_I64'Last; 2933 else 2934 A := Ghdl_I64 (Grt.Types.Current_Time) - T; 2935 end if; 2936 return Create_I64_Value (A); 2937 end To_Relative_Time; 2938 2939 -- Evaluate an expression. 2940 function Execute_Expression (Block: Block_Instance_Acc; Expr: Iir) 2941 return Iir_Value_Literal_Acc 2942 is 2943 Res: Iir_Value_Literal_Acc; 2944 begin 2945 case Get_Kind (Expr) is 2946 when Iir_Kind_Interface_Signal_Declaration 2947 | Iir_Kind_Signal_Declaration 2948 | Iir_Kind_Guard_Signal_Declaration 2949 | Iir_Kind_Stable_Attribute 2950 | Iir_Kind_Quiet_Attribute 2951 | Iir_Kind_Delayed_Attribute 2952 | Iir_Kind_Transaction_Attribute 2953 | Iir_Kind_Object_Alias_Declaration => 2954 Res := Execute_Name (Block, Expr); 2955 return Res; 2956 2957 when Iir_Kind_Interface_Constant_Declaration 2958 | Iir_Kind_Constant_Declaration 2959 | Iir_Kind_Interface_Variable_Declaration 2960 | Iir_Kind_Variable_Declaration 2961 | Iir_Kind_Interface_File_Declaration 2962 | Iir_Kind_File_Declaration 2963 | Iir_Kind_Attribute_Value 2964 | Iir_Kind_Iterator_Declaration 2965 | Iir_Kind_Indexed_Name 2966 | Iir_Kind_Slice_Name 2967 | Iir_Kind_Selected_Element 2968 | Iir_Kind_Dereference 2969 | Iir_Kind_Implicit_Dereference 2970 | Iir_Kind_Psl_Endpoint_Declaration => 2971 return Execute_Name (Block, Expr); 2972 2973 when Iir_Kinds_Denoting_Name 2974 | Iir_Kind_Attribute_Name => 2975 return Execute_Expression (Block, Get_Named_Entity (Expr)); 2976 2977 when Iir_Kind_Aggregate => 2978 return Execute_Aggregate (Block, Expr, Block, Get_Type (Expr)); 2979 when Iir_Kind_Simple_Aggregate => 2980 return Execute_Simple_Aggregate (Block, Expr); 2981 2982 when Iir_Kinds_Dyadic_Operator 2983 | Iir_Kinds_Monadic_Operator => 2984 declare 2985 Imp : constant Iir := Get_Implementation (Expr); 2986 begin 2987 if Get_Implicit_Definition (Imp) in Iir_Predefined_Explicit then 2988 return Execute_Function_Call (Block, Expr, Imp); 2989 else 2990 if Get_Kind (Expr) in Iir_Kinds_Dyadic_Operator then 2991 Res := Execute_Implicit_Function 2992 (Block, Expr, Get_Left (Expr), Get_Right (Expr), 2993 Get_Type (Expr)); 2994 else 2995 Res := Execute_Implicit_Function 2996 (Block, Expr, Get_Operand (Expr), Null_Iir, 2997 Get_Type (Expr)); 2998 end if; 2999 return Res; 3000 end if; 3001 end; 3002 3003 when Iir_Kind_Function_Call => 3004 declare 3005 Imp : constant Iir := Get_Implementation (Expr); 3006 Assoc : Iir; 3007 Args : Iir_Array (0 .. 1); 3008 begin 3009 if Get_Implicit_Definition (Imp) in Iir_Predefined_Explicit then 3010 return Execute_Function_Call (Block, Expr, Imp); 3011 else 3012 Assoc := Get_Parameter_Association_Chain (Expr); 3013 if Assoc /= Null_Iir then 3014 Args (0) := Get_Actual (Assoc); 3015 Assoc := Get_Chain (Assoc); 3016 else 3017 Args (0) := Null_Iir; 3018 end if; 3019 if Assoc /= Null_Iir then 3020 Args (1) := Get_Actual (Assoc); 3021 else 3022 Args (1) := Null_Iir; 3023 end if; 3024 return Execute_Implicit_Function 3025 (Block, Expr, Args (0), Args (1), Get_Type (Expr)); 3026 end if; 3027 end; 3028 3029 when Iir_Kind_Integer_Literal => 3030 declare 3031 Lit_Type : constant Iir := Get_Base_Type (Get_Type (Expr)); 3032 Lit : constant Int64 := Get_Value (Expr); 3033 begin 3034 case Get_Info (Lit_Type).Kind is 3035 when Kind_I64_Type => 3036 return Create_I64_Value (Ghdl_I64 (Lit)); 3037 when others => 3038 raise Internal_Error; 3039 end case; 3040 end; 3041 3042 when Iir_Kind_Floating_Point_Literal => 3043 return Create_F64_Value (Ghdl_F64 (Get_Fp_Value (Expr))); 3044 3045 when Iir_Kind_Enumeration_Literal => 3046 return Create_Enum_Value (Natural (Get_Enum_Pos (Expr)), 3047 Get_Type (Expr)); 3048 3049 when Iir_Kind_Physical_Int_Literal 3050 | Iir_Kind_Physical_Fp_Literal 3051 | Iir_Kind_Unit_Declaration => 3052 return Create_I64_Value 3053 (Ghdl_I64 (Vhdl.Evaluation.Get_Physical_Value (Expr))); 3054 3055 when Iir_Kind_String_Literal8 => 3056 return Execute_String_Literal (Expr, Block); 3057 3058 when Iir_Kind_Null_Literal => 3059 return Null_Lit; 3060 3061 when Iir_Kind_Overflow_Literal => 3062 Error_Msg_Constraint (Expr); 3063 return null; 3064 3065 when Iir_Kind_Parenthesis_Expression => 3066 return Execute_Expression (Block, Get_Expression (Expr)); 3067 3068 when Iir_Kind_Type_Conversion => 3069 return Execute_Type_Conversion 3070 (Block, Execute_Expression (Block, Get_Expression (Expr)), 3071 Get_Type (Expr), Expr); 3072 3073 when Iir_Kind_Qualified_Expression => 3074 Res := Execute_Expression_With_Type 3075 (Block, Get_Expression (Expr), Get_Type (Get_Type_Mark (Expr))); 3076 return Res; 3077 3078 when Iir_Kind_Allocator_By_Expression => 3079 Res := Execute_Expression (Block, Get_Expression (Expr)); 3080 Res := Unshare_Heap (Res); 3081 return Create_Access_Value (Res); 3082 3083 when Iir_Kind_Allocator_By_Subtype => 3084 Res := Create_Value_For_Type 3085 (Block, 3086 Get_Type_Of_Subtype_Indication (Get_Subtype_Indication (Expr)), 3087 Init_Value_Default); 3088 Res := Unshare_Heap (Res); 3089 return Create_Access_Value (Res); 3090 3091 when Iir_Kind_Left_Type_Attribute => 3092 Res := Execute_Bounds (Block, Get_Prefix (Expr)); 3093 return Execute_Left_Limit (Res); 3094 3095 when Iir_Kind_Right_Type_Attribute => 3096 Res := Execute_Bounds (Block, Get_Prefix (Expr)); 3097 return Execute_Right_Limit (Res); 3098 3099 when Iir_Kind_High_Type_Attribute => 3100 Res := Execute_Bounds (Block, Get_Prefix (Expr)); 3101 return Execute_High_Limit (Res); 3102 3103 when Iir_Kind_Low_Type_Attribute => 3104 Res := Execute_Bounds (Block, Get_Prefix (Expr)); 3105 return Execute_Low_Limit (Res); 3106 3107 when Iir_Kind_High_Array_Attribute => 3108 Res := Execute_Indexes (Block, Expr); 3109 return Execute_High_Limit (Res); 3110 3111 when Iir_Kind_Low_Array_Attribute => 3112 Res := Execute_Indexes (Block, Expr); 3113 return Execute_Low_Limit (Res); 3114 3115 when Iir_Kind_Left_Array_Attribute => 3116 Res := Execute_Indexes (Block, Expr); 3117 return Execute_Left_Limit (Res); 3118 3119 when Iir_Kind_Right_Array_Attribute => 3120 Res := Execute_Indexes (Block, Expr); 3121 return Execute_Right_Limit (Res); 3122 3123 when Iir_Kind_Length_Array_Attribute => 3124 Res := Execute_Indexes (Block, Expr); 3125 return Execute_Length (Res); 3126 3127 when Iir_Kind_Ascending_Array_Attribute => 3128 Res := Execute_Indexes (Block, Expr); 3129 return Boolean_To_Lit (Res.Dir = Dir_To); 3130 3131 when Iir_Kind_Event_Attribute => 3132 Res := Execute_Name (Block, Get_Prefix (Expr), True); 3133 return Boolean_To_Lit (Execute_Event_Attribute (Res)); 3134 3135 when Iir_Kind_Active_Attribute => 3136 Res := Execute_Name (Block, Get_Prefix (Expr), True); 3137 return Boolean_To_Lit (Execute_Active_Attribute (Res)); 3138 3139 when Iir_Kind_Driving_Attribute => 3140 Res := Execute_Name (Block, Get_Prefix (Expr), True); 3141 return Boolean_To_Lit (Execute_Driving_Attribute (Res)); 3142 3143 when Iir_Kind_Last_Value_Attribute => 3144 Res := Execute_Name (Block, Get_Prefix (Expr), True); 3145 return Execute_Last_Value_Attribute (Res); 3146 3147 when Iir_Kind_Driving_Value_Attribute => 3148 Res := Execute_Name (Block, Get_Prefix (Expr), True); 3149 return Execute_Driving_Value_Attribute (Res); 3150 3151 when Iir_Kind_Last_Event_Attribute => 3152 Res := Execute_Name (Block, Get_Prefix (Expr), True); 3153 return To_Relative_Time (Execute_Last_Event_Attribute (Res)); 3154 3155 when Iir_Kind_Last_Active_Attribute => 3156 Res := Execute_Name (Block, Get_Prefix (Expr), True); 3157 return To_Relative_Time (Execute_Last_Active_Attribute (Res)); 3158 3159 when Iir_Kind_Val_Attribute => 3160 declare 3161 Prefix_Type: constant Iir := Get_Type (Get_Prefix (Expr)); 3162 Base_Type : constant Iir := Get_Base_Type (Prefix_Type); 3163 Kind : constant Kind_Discrete_Types := 3164 Get_Info (Base_Type).Kind; 3165 begin 3166 Res := Execute_Expression (Block, Get_Parameter (Expr)); 3167 case Kind is 3168 when Kind_I64_Type => 3169 null; 3170 when Kind_E8_Type 3171 | Kind_Log_Type => 3172 Res := Create_E8_Value (Ghdl_E8 (Res.I64)); 3173 when Kind_E32_Type => 3174 Res := Create_E32_Value (Ghdl_E32 (Res.I64)); 3175 when Kind_Bit_Type => 3176 Res := Create_B1_Value (Ghdl_B1'Val (Res.I64)); 3177 end case; 3178 Check_Constraints (Block, Res, Prefix_Type, Expr); 3179 return Res; 3180 end; 3181 3182 when Iir_Kind_Pos_Attribute => 3183 declare 3184 N_Res: Iir_Value_Literal_Acc; 3185 Prefix_Type: constant Iir := Get_Type (Get_Prefix (Expr)); 3186 Base_Type : constant Iir := Get_Base_Type (Prefix_Type); 3187 Mode : constant Kind_Discrete_Types := 3188 Get_Info (Base_Type).Kind; 3189 begin 3190 Res := Execute_Expression (Block, Get_Parameter (Expr)); 3191 case Mode is 3192 when Kind_I64_Type => 3193 null; 3194 when Kind_Bit_Type => 3195 N_Res := Create_I64_Value (Ghdl_B1'Pos (Res.B1)); 3196 Res := N_Res; 3197 when Kind_E8_Type 3198 | Kind_Log_Type => 3199 N_Res := Create_I64_Value (Ghdl_I64 (Res.E8)); 3200 Res := N_Res; 3201 when Kind_E32_Type => 3202 N_Res := Create_I64_Value (Ghdl_I64 (Res.E32)); 3203 Res := N_Res; 3204 end case; 3205 Check_Constraints (Block, Res, Get_Type (Expr), Expr); 3206 return Res; 3207 end; 3208 3209 when Iir_Kind_Succ_Attribute => 3210 Res := Execute_Expression (Block, Get_Parameter (Expr)); 3211 Res := Execute_Inc (Res, Expr); 3212 Check_Constraints (Block, Res, Get_Type (Expr), Expr); 3213 return Res; 3214 3215 when Iir_Kind_Pred_Attribute => 3216 Res := Execute_Expression (Block, Get_Parameter (Expr)); 3217 Res := Execute_Dec (Res, Expr); 3218 Check_Constraints (Block, Res, Get_Type (Expr), Expr); 3219 return Res; 3220 3221 when Iir_Kind_Leftof_Attribute => 3222 declare 3223 Bound : Iir_Value_Literal_Acc; 3224 begin 3225 Res := Execute_Expression (Block, Get_Parameter (Expr)); 3226 Bound := Execute_Bounds 3227 (Block, Get_Type (Get_Prefix (Expr))); 3228 case Bound.Dir is 3229 when Dir_To => 3230 Res := Execute_Dec (Res, Expr); 3231 when Dir_Downto => 3232 Res := Execute_Inc (Res, Expr); 3233 end case; 3234 Check_Constraints (Block, Res, Get_Type (Expr), Expr); 3235 return Res; 3236 end; 3237 3238 when Iir_Kind_Rightof_Attribute => 3239 declare 3240 Bound : Iir_Value_Literal_Acc; 3241 begin 3242 Res := Execute_Expression (Block, Get_Parameter (Expr)); 3243 Bound := Execute_Bounds 3244 (Block, Get_Type (Get_Prefix (Expr))); 3245 case Bound.Dir is 3246 when Dir_Downto => 3247 Res := Execute_Dec (Res, Expr); 3248 when Dir_To => 3249 Res := Execute_Inc (Res, Expr); 3250 end case; 3251 Check_Constraints (Block, Res, Get_Type (Expr), Expr); 3252 return Res; 3253 end; 3254 3255 when Iir_Kind_Image_Attribute => 3256 return Execute_Image_Attribute (Block, Expr); 3257 3258 when Iir_Kind_Value_Attribute => 3259 Res := Execute_Expression (Block, Get_Parameter (Expr)); 3260 return Execute_Value_Attribute (Block, Res, Expr); 3261 3262 when Iir_Kind_Path_Name_Attribute 3263 | Iir_Kind_Instance_Name_Attribute => 3264 return Execute_Path_Instance_Name_Attribute (Block, Expr); 3265 3266 when others => 3267 Error_Kind ("execute_expression", Expr); 3268 end case; 3269 end Execute_Expression; 3270 3271 procedure Execute_Dyadic_Association (Out_Block: Block_Instance_Acc; 3272 In_Block: Block_Instance_Acc; 3273 Expr : Iir; 3274 Inter_Chain: Iir) 3275 is 3276 Inter: Iir; 3277 Val: Iir_Value_Literal_Acc; 3278 begin 3279 Inter := Inter_Chain; 3280 for I in 0 .. 1 loop 3281 if I = 0 then 3282 Val := Execute_Expression (Out_Block, Get_Left (Expr)); 3283 else 3284 Val := Execute_Expression (Out_Block, Get_Right (Expr)); 3285 end if; 3286 Implicit_Array_Conversion (In_Block, Val, Get_Type (Inter), Expr); 3287 Check_Constraints (In_Block, Val, Get_Type (Inter), Expr); 3288 3289 Elaboration.Create_Object (In_Block, Inter); 3290 In_Block.Objects (Get_Info (Inter).Slot) := 3291 Unshare (Val, Instance_Pool); 3292 Inter := Get_Chain (Inter); 3293 end loop; 3294 end Execute_Dyadic_Association; 3295 3296 procedure Execute_Monadic_Association (Out_Block: Block_Instance_Acc; 3297 In_Block: Block_Instance_Acc; 3298 Expr : Iir; 3299 Inter: Iir) 3300 is 3301 Val: Iir_Value_Literal_Acc; 3302 begin 3303 Val := Execute_Expression (Out_Block, Get_Operand (Expr)); 3304 Implicit_Array_Conversion (In_Block, Val, Get_Type (Inter), Expr); 3305 Check_Constraints (In_Block, Val, Get_Type (Inter), Expr); 3306 3307 Elaboration.Create_Object (In_Block, Inter); 3308 In_Block.Objects (Get_Info (Inter).Slot) := 3309 Unshare (Val, Instance_Pool); 3310 end Execute_Monadic_Association; 3311 3312 -- Like Get_Protected_Type_Body, but also works for instances, where 3313 -- instantiated nodes have no bodies. 3314 -- FIXME: maybe fix the issue directly in Sem_Inst ? 3315 function Get_Protected_Type_Body_Origin (Spec : Iir) return Iir 3316 is 3317 Res : constant Iir := Get_Protected_Type_Body (Spec); 3318 Orig : Iir; 3319 begin 3320 if Res /= Null_Iir then 3321 return Res; 3322 else 3323 Orig := Vhdl.Sem_Inst.Get_Origin (Spec); 3324 return Get_Protected_Type_Body_Origin (Orig); 3325 end if; 3326 end Get_Protected_Type_Body_Origin; 3327 3328 -- Create a block instance for subprogram IMP. 3329 function Create_Subprogram_Instance (Instance : Block_Instance_Acc; 3330 Prot_Obj : Block_Instance_Acc; 3331 Imp : Iir) 3332 return Block_Instance_Acc 3333 is 3334 Parent : Iir; 3335 Bod : Iir; 3336 3337 Up_Block: Block_Instance_Acc; 3338 Up_Info : Sim_Info_Acc; 3339 3340 Label : Iir; 3341 begin 3342 case Get_Kind (Imp) is 3343 when Iir_Kinds_Subprogram_Declaration => 3344 Bod := Vhdl.Sem_Inst.Get_Subprogram_Body_Origin (Imp); 3345 Parent := Get_Parent (Imp); 3346 Label := Get_Subprogram_Specification (Bod); 3347 when Iir_Kind_Protected_Type_Declaration => 3348 -- The parent of the protected type body must have the same scope 3349 -- as the parent of the protected type declaration. 3350 Bod := Get_Protected_Type_Body_Origin (Imp); 3351 Parent := Get_Parent (Get_Type_Declarator (Imp)); 3352 Label := Imp; 3353 when others => 3354 Error_Kind ("create_subprogram_instance", Imp); 3355 end case; 3356 3357 if Prot_Obj /= null then 3358 -- This is a call to a method (from the outside to a subprogram of 3359 -- a protected type). Put the protected object as upblock. 3360 Up_Block := Prot_Obj; 3361 else 3362 -- This is a normal subprogram call. 3363 Up_Info := Get_Info_For_Scope (Parent); 3364 Up_Block := Get_Instance_By_Scope (Instance, Up_Info); 3365 end if; 3366 3367 -- Extract the info from the body, as it is complete (has slot for 3368 -- internal declarations). Usually, body and spec share the same info, 3369 -- but there are exceptions: there can be multiple spec for the same 3370 -- body for shared generic packages. 3371 declare 3372 Func_Info : constant Sim_Info_Acc := Get_Info (Bod); 3373 3374 subtype Block_Type is Block_Instance_Type (Func_Info.Nbr_Objects); 3375 function To_Block_Instance_Acc is new 3376 Ada.Unchecked_Conversion (System.Address, Block_Instance_Acc); 3377 function Alloc_Block_Instance is new 3378 Alloc_On_Pool_Addr (Block_Type); 3379 3380 Res : Block_Instance_Acc; 3381 begin 3382 Res := To_Block_Instance_Acc 3383 (Alloc_Block_Instance 3384 (Instance_Pool, 3385 Block_Instance_Type'(Max_Objs => Func_Info.Nbr_Objects, 3386 Id => No_Block_Instance_Id, 3387 Block_Scope => Get_Info (Label), 3388 Uninst_Scope => null, 3389 Up_Block => Up_Block, 3390 Label => Imp, 3391 Bod => Bod, 3392 Stmt => Null_Iir, 3393 Parent => Instance, 3394 Children => null, 3395 Brother => null, 3396 Marker => Empty_Marker, 3397 Objects => (others => null), 3398 Elab_Objects => 0, 3399 In_Wait_Flag => False, 3400 Actuals_Ref => null, 3401 Result => null))); 3402 return Res; 3403 end; 3404 end Create_Subprogram_Instance; 3405 3406 function Get_Protected_Object_Instance 3407 (Block : Block_Instance_Acc; Call : Iir) return Block_Instance_Acc 3408 is 3409 Meth_Obj : constant Iir := Get_Method_Object (Call); 3410 Obj : Iir_Value_Literal_Acc; 3411 begin 3412 if Meth_Obj = Null_Iir then 3413 return null; 3414 else 3415 Obj := Execute_Name (Block, Meth_Obj, True); 3416 return Protected_Table.Table (Obj.Prot); 3417 end if; 3418 end Get_Protected_Object_Instance; 3419 3420 -- Destroy a dynamic block_instance. 3421 procedure Execute_Subprogram_Call_Final (Instance : Block_Instance_Acc) is 3422 begin 3423 Finalize_Declarative_Part 3424 (Instance, Get_Declaration_Chain (Instance.Bod)); 3425 end Execute_Subprogram_Call_Final; 3426 3427 function Execute_Function_Body (Instance : Block_Instance_Acc) 3428 return Iir_Value_Literal_Acc 3429 is 3430 Res : Iir_Value_Literal_Acc; 3431 begin 3432 Current_Process.Instance := Instance; 3433 3434 Elaborate_Declarative_Part 3435 (Instance, Get_Declaration_Chain (Instance.Bod)); 3436 3437 -- execute statements 3438 Instance.Stmt := Get_Sequential_Statement_Chain (Instance.Bod); 3439 Execute_Sequential_Statements (Current_Process); 3440 pragma Assert (Current_Process.Instance = Instance); 3441 3442 if Instance.Result = null then 3443 Error_Msg_Exec 3444 ("function scope exited without a return statement", 3445 Instance.Label); 3446 end if; 3447 3448 -- Free variables, slots... 3449 -- Need to copy the return value, because it can contains values from 3450 -- arguments. 3451 Res := Instance.Result; 3452 3453 Current_Process.Instance := Instance.Parent; 3454 Execute_Subprogram_Call_Final (Instance); 3455 3456 return Res; 3457 end Execute_Function_Body; 3458 3459 function Execute_Assoc_Function_Conversion (Block : Block_Instance_Acc; 3460 Func : Iir; 3461 Prot_Block : Block_Instance_Acc; 3462 Val : Iir_Value_Literal_Acc) 3463 return Iir_Value_Literal_Acc 3464 is 3465 Inter : Iir; 3466 Instance : Block_Instance_Acc; 3467 Res : Iir_Value_Literal_Acc; 3468 Marker : Mark_Type; 3469 begin 3470 Mark (Marker, Instance_Pool.all); 3471 3472 -- Create an instance for this function. 3473 Instance := Create_Subprogram_Instance (Block, Prot_Block, Func); 3474 3475 Inter := Get_Interface_Declaration_Chain (Func); 3476 Elaboration.Create_Object (Instance, Inter); 3477 -- FIXME: implicit conversion 3478 Instance.Objects (Get_Info (Inter).Slot) := Val; 3479 3480 Res := Execute_Function_Body (Instance); 3481 Res := Unshare (Res, Expr_Pool'Access); 3482 Release (Marker, Instance_Pool.all); 3483 return Res; 3484 end Execute_Assoc_Function_Conversion; 3485 3486 function Execute_Assoc_Conversion 3487 (Block : Block_Instance_Acc; Conv : Iir; Val : Iir_Value_Literal_Acc) 3488 return Iir_Value_Literal_Acc 3489 is 3490 Ent : Iir; 3491 Prot_Block : Block_Instance_Acc; 3492 begin 3493 case Get_Kind (Conv) is 3494 when Iir_Kind_Function_Call => 3495 -- FIXME: shouldn't CONV always be a denoting_name ? 3496 Prot_Block := Get_Protected_Object_Instance (Block, Conv); 3497 return Execute_Assoc_Function_Conversion 3498 (Block, Get_Implementation (Conv), Prot_Block, Val); 3499 when Iir_Kind_Type_Conversion => 3500 -- FIXME: shouldn't CONV always be a denoting_name ? 3501 return Execute_Type_Conversion (Block, Val, Get_Type (Conv), Conv); 3502 when Iir_Kinds_Denoting_Name 3503 | Iir_Kind_Function_Declaration => 3504 Ent := Strip_Denoting_Name (Conv); 3505 if Get_Kind (Ent) = Iir_Kind_Function_Declaration then 3506 return Execute_Assoc_Function_Conversion 3507 (Block, Ent, null, Val); 3508 elsif Get_Kind (Ent) in Iir_Kinds_Type_Declaration then 3509 return Execute_Type_Conversion 3510 (Block, Val, Get_Type (Ent), Ent); 3511 else 3512 Error_Kind ("execute_assoc_conversion(1)", Ent); 3513 end if; 3514 when others => 3515 Error_Kind ("execute_assoc_conversion(2)", Conv); 3516 end case; 3517 end Execute_Assoc_Conversion; 3518 3519 procedure Associate_By_Reference (Block : Block_Instance_Acc; 3520 Formal : Iir; 3521 Formal_Base : Iir_Value_Literal_Acc; 3522 Actual : Iir_Value_Literal_Acc) 3523 is 3524 Prefix : constant Iir := Strip_Denoting_Name (Get_Prefix (Formal)); 3525 Is_Sig : Boolean; 3526 Pfx : Iir_Value_Literal_Acc; 3527 Pos : Iir_Index32; 3528 begin 3529 if Get_Kind (Prefix) = Iir_Kind_Slice_Name then 3530 -- That case is not handled correctly. 3531 raise Program_Error; 3532 end if; 3533 Execute_Name_With_Base (Block, Prefix, Formal_Base, Pfx, Is_Sig); 3534 3535 case Get_Kind (Formal) is 3536 when Iir_Kind_Indexed_Name => 3537 Execute_Indexed_Name (Block, Formal, Pfx, Pos); 3538 Store (Pfx.Val_Array.V (Pos + 1), Actual); 3539 when Iir_Kind_Slice_Name => 3540 declare 3541 Low, High : Iir_Index32; 3542 Srange : Iir_Value_Literal_Acc; 3543 begin 3544 Srange := Execute_Bounds (Block, Get_Suffix (Formal)); 3545 Execute_Slice_Name (Pfx, Srange, Low, High, Formal); 3546 for I in 1 .. High - Low + 1 loop 3547 Store (Pfx.Val_Array.V (Low + I), Actual.Val_Array.V (I)); 3548 end loop; 3549 end; 3550 when Iir_Kind_Selected_Element => 3551 Pos := Get_Element_Position (Get_Named_Entity (Formal)); 3552 Store (Pfx.Val_Record.V (Pos + 1), Actual); 3553 when others => 3554 Error_Kind ("associate_by_reference", Formal); 3555 end case; 3556 end Associate_By_Reference; 3557 3558 -- Establish correspondance for association list ASSOC_LIST from block 3559 -- instance OUT_BLOCK for subprogram of block SUBPRG_BLOCK. 3560 procedure Execute_Association (Out_Block : Block_Instance_Acc; 3561 Subprg_Block : Block_Instance_Acc; 3562 Inter_Chain : Iir; 3563 Assoc_Chain : Iir) 3564 is 3565 Nbr_Assoc : constant Natural := Get_Chain_Length (Assoc_Chain); 3566 Assoc: Iir; 3567 Assoc_Inter : Iir; 3568 Actual : Iir; 3569 Inter: Iir; 3570 Formal : Iir; 3571 Conv : Iir; 3572 Val: Iir_Value_Literal_Acc; 3573 Assoc_Idx : Iir_Index32; 3574 Last_Individual : Iir_Value_Literal_Acc; 3575 Mode : Iir_Mode; 3576 Marker : Mark_Type; 3577 begin 3578 Subprg_Block.Actuals_Ref := null; 3579 Mark (Marker, Expr_Pool); 3580 3581 Assoc := Assoc_Chain; 3582 Assoc_Inter := Inter_Chain; 3583 Assoc_Idx := 1; 3584 while Assoc /= Null_Iir loop 3585 Inter := Get_Association_Interface (Assoc, Assoc_Inter); 3586 Formal := Get_Association_Formal (Assoc, Inter); 3587 3588 -- Extract the actual value. 3589 case Get_Kind (Assoc) is 3590 when Iir_Kind_Association_Element_Open => 3591 -- Not allowed in individual association. 3592 pragma Assert (Formal = Inter); 3593 pragma Assert (Get_Whole_Association_Flag (Assoc)); 3594 Actual := Get_Default_Value (Inter); 3595 when Iir_Kind_Association_Element_By_Expression => 3596 Actual := Get_Actual (Assoc); 3597 when Iir_Kind_Association_Element_By_Individual => 3598 -- Directly create the whole value on the instance pool, as its 3599 -- life is longer than the statement. 3600 if Get_Kind (Inter) = Iir_Kind_Interface_Signal_Declaration then 3601 Last_Individual := Create_Value_For_Type 3602 (Out_Block, Get_Actual_Type (Assoc), Init_Value_Signal); 3603 else 3604 Last_Individual := Create_Value_For_Type 3605 (Out_Block, Get_Actual_Type (Assoc), Init_Value_Any); 3606 end if; 3607 Last_Individual := 3608 Unshare (Last_Individual, Instance_Pool); 3609 Elaboration.Create_Object (Subprg_Block, Inter); 3610 Subprg_Block.Objects (Get_Info (Inter).Slot) := Last_Individual; 3611 goto Continue; 3612 when others => 3613 Error_Kind ("execute_association(1)", Assoc); 3614 end case; 3615 3616 -- Compute actual value. 3617 case Get_Kind (Inter) is 3618 when Iir_Kind_Interface_Constant_Declaration 3619 | Iir_Kind_Interface_File_Declaration => 3620 Val := Execute_Expression (Out_Block, Actual); 3621 Implicit_Array_Conversion 3622 (Out_Block, Val, Get_Type (Formal), Assoc); 3623 Check_Constraints (Out_Block, Val, Get_Type (Formal), Assoc); 3624 when Iir_Kind_Interface_Signal_Declaration => 3625 Val := Execute_Name (Out_Block, Actual, True); 3626 Implicit_Array_Conversion 3627 (Out_Block, Val, Get_Type (Formal), Assoc); 3628 when Iir_Kind_Interface_Variable_Declaration => 3629 Mode := Get_Mode (Inter); 3630 if Mode = Iir_In_Mode then 3631 -- FIXME: Ref ? 3632 Val := Execute_Expression (Out_Block, Actual); 3633 else 3634 Val := Execute_Name (Out_Block, Actual, False); 3635 end if; 3636 3637 -- FIXME: by value for scalars ? 3638 3639 -- Keep ref for back-copy 3640 if Mode /= Iir_In_Mode then 3641 if Subprg_Block.Actuals_Ref = null then 3642 declare 3643 subtype Actuals_Ref_Type is 3644 Value_Array (Iir_Index32 (Nbr_Assoc)); 3645 function To_Value_Array_Acc is new 3646 Ada.Unchecked_Conversion (System.Address, 3647 Value_Array_Acc); 3648 function Alloc_Actuals_Ref is new 3649 Alloc_On_Pool_Addr (Actuals_Ref_Type); 3650 3651 begin 3652 Subprg_Block.Actuals_Ref := To_Value_Array_Acc 3653 (Alloc_Actuals_Ref 3654 (Instance_Pool, 3655 Actuals_Ref_Type'(Len => Iir_Index32 (Nbr_Assoc), 3656 V => (others => null)))); 3657 end; 3658 end if; 3659 Subprg_Block.Actuals_Ref.V (Assoc_Idx) := 3660 Unshare_Bounds (Val, Instance_Pool); 3661 end if; 3662 3663 if Mode = Iir_Out_Mode then 3664 if Get_Formal_Conversion (Assoc) /= Null_Iir then 3665 -- For an OUT variable using an out conversion, don't 3666 -- associate with the actual, create a temporary value. 3667 Val := Create_Value_For_Type 3668 (Out_Block, Get_Type (Formal), Init_Value_Default); 3669 elsif Get_Kind (Get_Type (Formal)) in 3670 Iir_Kinds_Scalar_Type_And_Subtype_Definition 3671 then 3672 -- These are passed by value. Must be reset. 3673 Val := Create_Value_For_Type 3674 (Out_Block, Get_Type (Formal), Init_Value_Default); 3675 end if; 3676 else 3677 if Get_Kind (Assoc) = 3678 Iir_Kind_Association_Element_By_Expression 3679 then 3680 Conv := Get_Actual_Conversion (Assoc); 3681 if Conv /= Null_Iir then 3682 Val := Execute_Assoc_Conversion 3683 (Out_Block, Conv, Val); 3684 end if; 3685 end if; 3686 3687 -- FIXME: check constraints ? 3688 end if; 3689 3690 Implicit_Array_Conversion 3691 (Out_Block, Val, Get_Type (Formal), Assoc); 3692 3693 when others => 3694 Error_Kind ("execute_association(2)", Inter); 3695 end case; 3696 3697 if Get_Whole_Association_Flag (Assoc) then 3698 case Get_Kind (Inter) is 3699 when Iir_Kind_Interface_Constant_Declaration 3700 | Iir_Kind_Interface_Variable_Declaration 3701 | Iir_Kind_Interface_File_Declaration => 3702 -- FIXME: Arguments are passed by copy. 3703 Elaboration.Create_Object (Subprg_Block, Inter); 3704 Subprg_Block.Objects (Get_Info (Inter).Slot) := 3705 Unshare (Val, Instance_Pool); 3706 when Iir_Kind_Interface_Signal_Declaration => 3707 Elaboration.Create_Signal (Subprg_Block, Inter); 3708 Subprg_Block.Objects (Get_Info (Inter).Slot) := 3709 Unshare_Bounds (Val, Instance_Pool); 3710 when others => 3711 Error_Kind ("execute_association", Inter); 3712 end case; 3713 else 3714 Associate_By_Reference 3715 (Subprg_Block, Formal, Last_Individual, Val); 3716 end if; 3717 3718 << Continue >> null; 3719 Next_Association_Interface (Assoc, Assoc_Inter); 3720 Assoc_Idx := Assoc_Idx + 1; 3721 end loop; 3722 3723 Release (Marker, Expr_Pool); 3724 end Execute_Association; 3725 3726 procedure Execute_Back_Association (Instance : Block_Instance_Acc) 3727 is 3728 Call : constant Iir := Get_Procedure_Call (Instance.Parent.Stmt); 3729 Imp : constant Iir := Get_Implementation (Call); 3730 Assoc : Iir; 3731 Assoc_Inter : Iir; 3732 Inter : Iir; 3733 Formal : Iir; 3734 Assoc_Idx : Iir_Index32; 3735 begin 3736 Assoc := Get_Parameter_Association_Chain (Call); 3737 Assoc_Inter := Get_Interface_Declaration_Chain (Imp); 3738 Assoc_Idx := 1; 3739 while Assoc /= Null_Iir loop 3740 if Get_Kind (Assoc) /= Iir_Kind_Association_Element_By_Individual then 3741 Inter := Get_Association_Interface (Assoc, Assoc_Inter); 3742 Formal := Get_Association_Formal (Assoc, Inter); 3743 3744 case Get_Kind (Inter) is 3745 when Iir_Kind_Interface_Variable_Declaration => 3746 if Get_Mode (Inter) /= Iir_In_Mode 3747 and then Get_Kind (Get_Type (Inter)) /= 3748 Iir_Kind_File_Type_Definition 3749 then 3750 -- For out/inout variable interface, the value must 3751 -- be copied (FIXME: unless when passed by reference ?). 3752 declare 3753 Targ : constant Iir_Value_Literal_Acc := 3754 Instance.Actuals_Ref.V (Assoc_Idx); 3755 Base : constant Iir_Value_Literal_Acc := 3756 Instance.Objects (Get_Info (Inter).Slot); 3757 Val : Iir_Value_Literal_Acc; 3758 Conv : Iir; 3759 Is_Sig : Boolean; 3760 Expr_Mark : Mark_Type; 3761 begin 3762 Mark (Expr_Mark, Expr_Pool); 3763 3764 -- Extract for individual association. 3765 Execute_Name_With_Base 3766 (Instance, Formal, Base, Val, Is_Sig); 3767 Conv := Get_Formal_Conversion (Assoc); 3768 if Conv /= Null_Iir then 3769 Val := Execute_Assoc_Conversion 3770 (Instance, Conv, Val); 3771 -- FIXME: free val ? 3772 end if; 3773 Store (Targ, Val); 3774 3775 Release (Expr_Mark, Expr_Pool); 3776 end; 3777 end if; 3778 when Iir_Kind_Interface_File_Declaration => 3779 null; 3780 when Iir_Kind_Interface_Signal_Declaration 3781 | Iir_Kind_Interface_Constant_Declaration => 3782 null; 3783 when others => 3784 Error_Kind ("execute_back_association", Inter); 3785 end case; 3786 end if; 3787 Next_Association_Interface (Assoc, Assoc_Inter); 3788 Assoc_Idx := Assoc_Idx + 1; 3789 end loop; 3790 end Execute_Back_Association; 3791 3792 function Execute_Foreign_Function_Call 3793 (Block: Block_Instance_Acc; Expr : Iir; Imp : Iir) 3794 return Iir_Value_Literal_Acc 3795 is 3796 Res : Iir_Value_Literal_Acc; 3797 begin 3798 case Get_Identifier (Imp) is 3799 when Std_Names.Name_Get_Resolution_Limit => 3800 Res := Create_I64_Value (1); 3801 when Std_Names.Name_Textio_Read_Real => 3802 Res := Create_F64_Value 3803 (File_Operation.Textio_Read_Real (Block.Objects (1))); 3804 when others => 3805 Error_Msg_Exec ("unsupported foreign function call", Expr); 3806 end case; 3807 return Res; 3808 end Execute_Foreign_Function_Call; 3809 3810 -- BLOCK is the block instance in which the function call appears. 3811 function Execute_Function_Call 3812 (Block: Block_Instance_Acc; Expr: Iir; Imp : Iir) 3813 return Iir_Value_Literal_Acc 3814 is 3815 Inter_Chain : constant Iir := Get_Interface_Declaration_Chain (Imp); 3816 Subprg_Block: Block_Instance_Acc; 3817 Prot_Block : Block_Instance_Acc; 3818 Assoc_Chain: Iir; 3819 Res : Iir_Value_Literal_Acc; 3820 begin 3821 Mark (Block.Marker, Instance_Pool.all); 3822 3823 case Get_Kind (Expr) is 3824 when Iir_Kind_Function_Call => 3825 Prot_Block := Get_Protected_Object_Instance (Block, Expr); 3826 Subprg_Block := 3827 Create_Subprogram_Instance (Block, Prot_Block, Imp); 3828 Assoc_Chain := Get_Parameter_Association_Chain (Expr); 3829 Execute_Association 3830 (Block, Subprg_Block, Inter_Chain, Assoc_Chain); 3831 -- No out/inout interface for functions. 3832 pragma Assert (Subprg_Block.Actuals_Ref = null); 3833 when Iir_Kinds_Dyadic_Operator => 3834 Subprg_Block := Create_Subprogram_Instance (Block, null, Imp); 3835 Execute_Dyadic_Association 3836 (Block, Subprg_Block, Expr, Inter_Chain); 3837 when Iir_Kinds_Monadic_Operator => 3838 Subprg_Block := Create_Subprogram_Instance (Block, null, Imp); 3839 Execute_Monadic_Association 3840 (Block, Subprg_Block, Expr, Inter_Chain); 3841 when others => 3842 Error_Kind ("execute_subprogram_call_init", Expr); 3843 end case; 3844 3845 if Get_Foreign_Flag (Imp) then 3846 Res := Execute_Foreign_Function_Call (Subprg_Block, Expr, Imp); 3847 else 3848 Res := Execute_Function_Body (Subprg_Block); 3849 end if; 3850 3851 -- Unfortunately, we don't know where the result has been allocated, 3852 -- so copy it before releasing the instance pool. 3853 Res := Unshare (Res, Expr_Pool'Access); 3854 3855 Release (Block.Marker, Instance_Pool.all); 3856 3857 return Res; 3858 end Execute_Function_Call; 3859 3860 -- Slide an array VALUE using bounds from REF_VALUE. Do not modify 3861 -- VALUE if not an array. 3862 procedure Implicit_Array_Conversion (Value : in out Iir_Value_Literal_Acc; 3863 Ref_Value : Iir_Value_Literal_Acc; 3864 Expr : Iir) 3865 is 3866 Res : Iir_Value_Literal_Acc; 3867 begin 3868 if Value.Kind /= Iir_Value_Array then 3869 return; 3870 end if; 3871 Res := Create_Array_Value (Value.Bounds.Nbr_Dims); 3872 Res.Val_Array := Value.Val_Array; 3873 for I in Value.Bounds.D'Range loop 3874 if Value.Bounds.D (I).Length /= Ref_Value.Bounds.D (I).Length then 3875 Error_Msg_Constraint (Expr); 3876 return; 3877 end if; 3878 Res.Bounds.D (I) := Ref_Value.Bounds.D (I); 3879 end loop; 3880 Value := Res; 3881 end Implicit_Array_Conversion; 3882 3883 procedure Implicit_Array_Conversion (Instance : Block_Instance_Acc; 3884 Value : in out Iir_Value_Literal_Acc; 3885 Ref_Type : Iir; 3886 Expr : Iir) 3887 is 3888 Ref_Value : Iir_Value_Literal_Acc; 3889 begin 3890 -- Do array conversion only if REF_TYPE is a constrained array type 3891 -- definition. 3892 if Value.Kind /= Iir_Value_Array then 3893 return; 3894 end if; 3895 if Get_Constraint_State (Ref_Type) /= Fully_Constrained then 3896 return; 3897 end if; 3898 Ref_Value := Create_Array_Bounds_From_Type (Instance, Ref_Type, True); 3899 for I in Value.Bounds.D'Range loop 3900 if Value.Bounds.D (I).Length /= Ref_Value.Bounds.D (I).Length then 3901 Error_Msg_Constraint (Expr); 3902 return; 3903 end if; 3904 end loop; 3905 Ref_Value.Val_Array.V := Value.Val_Array.V; 3906 Value := Ref_Value; 3907 end Implicit_Array_Conversion; 3908 3909 procedure Check_Range_Constraints (Instance : Block_Instance_Acc; 3910 Rng : Iir_Value_Literal_Acc; 3911 Rng_Type : Iir; 3912 Loc : Iir) is 3913 begin 3914 if not Is_Null_Range (Rng) then 3915 Check_Constraints (Instance, Rng.Left, Get_Type (Rng_Type), Loc); 3916 Check_Constraints (Instance, Rng.Right, Get_Type (Rng_Type), Loc); 3917 end if; 3918 end Check_Range_Constraints; 3919 3920 procedure Check_Array_Constraints (Instance: Block_Instance_Acc; 3921 Value: Iir_Value_Literal_Acc; 3922 Def: Iir; 3923 Expr: Iir) 3924 is 3925 Index_List : Iir_Flist; 3926 Element_Subtype : Iir; 3927 New_Bounds : Iir_Value_Literal_Acc; 3928 begin 3929 -- Nothing to check for unconstrained arrays. 3930 if not Get_Index_Constraint_Flag (Def) then 3931 return; 3932 end if; 3933 3934 Index_List := Get_Index_Subtype_List (Def); 3935 for I in Value.Bounds.D'Range loop 3936 New_Bounds := Execute_Bounds 3937 (Instance, Get_Nth_Element (Index_List, Natural (I - 1))); 3938 if not Is_Equal (Value.Bounds.D (I), New_Bounds) then 3939 Error_Msg_Constraint (Expr); 3940 return; 3941 end if; 3942 end loop; 3943 3944 if Boolean'(False) then 3945 Index_List := Get_Index_List (Def); 3946 Element_Subtype := Get_Element_Subtype (Def); 3947 for I in Value.Val_Array.V'Range loop 3948 Check_Constraints 3949 (Instance, Value.Val_Array.V (I), Element_Subtype, Expr); 3950 end loop; 3951 end if; 3952 end Check_Array_Constraints; 3953 3954 -- Check DEST and SRC are array compatible. 3955 procedure Check_Array_Match (Instance: Block_Instance_Acc; 3956 Dest: Iir_Value_Literal_Acc; 3957 Src : Iir_Value_Literal_Acc; 3958 Expr: Iir) 3959 is 3960 pragma Unreferenced (Instance); 3961 begin 3962 for I in Dest.Bounds.D'Range loop 3963 if Dest.Bounds.D (I).Length /= Src.Bounds.D (I).Length then 3964 Error_Msg_Constraint (Expr); 3965 exit; 3966 end if; 3967 end loop; 3968 end Check_Array_Match; 3969 pragma Unreferenced (Check_Array_Match); 3970 3971 procedure Check_Constraints (Instance: Block_Instance_Acc; 3972 Value: Iir_Value_Literal_Acc; 3973 Def: Iir; 3974 Expr: Iir) 3975 is 3976 High, Low: Iir_Value_Literal_Acc; 3977 Bound : Iir_Value_Literal_Acc; 3978 begin 3979 case Get_Kind (Def) is 3980 when Iir_Kind_Integer_Subtype_Definition 3981 | Iir_Kind_Floating_Subtype_Definition 3982 | Iir_Kind_Enumeration_Subtype_Definition 3983 | Iir_Kind_Physical_Subtype_Definition 3984 | Iir_Kind_Enumeration_Type_Definition => 3985 Bound := Execute_Bounds (Instance, Def); 3986 if Bound.Dir = Dir_To then 3987 High := Bound.Right; 3988 Low := Bound.Left; 3989 else 3990 High := Bound.Left; 3991 Low := Bound.Right; 3992 end if; 3993 case Iir_Value_Scalars (Value.Kind) is 3994 when Iir_Value_I64 => 3995 if Value.I64 in Low.I64 .. High.I64 then 3996 return; 3997 end if; 3998 when Iir_Value_E8 => 3999 if Value.E8 in Low.E8 .. High.E8 then 4000 return; 4001 end if; 4002 when Iir_Value_E32 => 4003 if Value.E32 in Low.E32 .. High.E32 then 4004 return; 4005 end if; 4006 when Iir_Value_F64 => 4007 if Value.F64 in Low.F64 .. High.F64 then 4008 return; 4009 end if; 4010 when Iir_Value_B1 => 4011 if Value.B1 in Low.B1 .. High.B1 then 4012 return; 4013 end if; 4014 end case; 4015 when Iir_Kind_Array_Subtype_Definition 4016 | Iir_Kind_Array_Type_Definition => 4017 Check_Array_Constraints (Instance, Value, Def, Expr); 4018 return; 4019 when Iir_Kind_Record_Type_Definition 4020 | Iir_Kind_Record_Subtype_Definition => 4021 declare 4022 List : constant Iir_Flist := 4023 Get_Elements_Declaration_List (Get_Base_Type (Def)); 4024 El : Iir_Element_Declaration; 4025 begin 4026 for I in Flist_First .. Flist_Last (List) loop 4027 El := Get_Nth_Element (List, I); 4028 Check_Constraints 4029 (Instance, 4030 Value.Val_Record.V (Get_Element_Position (El) + 1), 4031 Get_Type (El), 4032 Expr); 4033 end loop; 4034 end; 4035 return; 4036 when Iir_Kind_Integer_Type_Definition => 4037 return; 4038 when Iir_Kind_Floating_Type_Definition => 4039 return; 4040 when Iir_Kind_Physical_Type_Definition => 4041 return; 4042 when Iir_Kind_Access_Type_Definition 4043 | Iir_Kind_Access_Subtype_Definition => 4044 return; 4045 when Iir_Kind_File_Type_Definition => 4046 return; 4047 when others => 4048 Error_Kind ("check_constraints", Def); 4049 end case; 4050 Error_Msg_Constraint (Expr); 4051 end Check_Constraints; 4052 4053 function Execute_Resolution_Function 4054 (Block: Block_Instance_Acc; Imp : Iir; Arr : Iir_Value_Literal_Acc) 4055 return Iir_Value_Literal_Acc 4056 is 4057 Inter : Iir; 4058 Instance : Block_Instance_Acc; 4059 begin 4060 -- Create a frame for this function. 4061 Instance := Create_Subprogram_Instance (Block, null, Imp); 4062 4063 Inter := Get_Interface_Declaration_Chain (Imp); 4064 Elaboration.Create_Object (Instance, Inter); 4065 Instance.Objects (Get_Info (Inter).Slot) := Arr; 4066 4067 return Execute_Function_Body (Instance); 4068 end Execute_Resolution_Function; 4069 4070 procedure Execute_Signal_Assignment (Instance: Block_Instance_Acc; 4071 Stmt: Iir_Signal_Assignment_Statement; 4072 Wf : Iir) 4073 is 4074 Nbr_We : constant Natural := Get_Chain_Length (Wf); 4075 4076 Transactions : Transaction_Type (Nbr_We); 4077 4078 We: Iir_Waveform_Element; 4079 Res: Iir_Value_Literal_Acc; 4080 Rdest: Iir_Value_Literal_Acc; 4081 Targ_Type : Iir; 4082 Marker : Mark_Type; 4083 begin 4084 Mark (Marker, Expr_Pool); 4085 4086 Rdest := Execute_Name (Instance, Get_Target (Stmt), True); 4087 Targ_Type := Get_Type (Get_Target (Stmt)); 4088 4089 -- Disconnection statement. 4090 if Wf = Null_Iir then 4091 Disconnect_Signal (Rdest); 4092 Release (Marker, Expr_Pool); 4093 return; 4094 elsif Get_Kind (Wf) = Iir_Kind_Unaffected_Waveform then 4095 return; 4096 end if; 4097 4098 Transactions.Stmt := Stmt; 4099 4100 -- LRM93 8.4.1 4101 -- Evaluation of a waveform consists of the evaluation of each waveform 4102 -- elements in the waveform. 4103 We := Wf; 4104 for I in Transactions.Els'Range loop 4105 declare 4106 Trans : Transaction_El_Type renames Transactions.Els (I); 4107 begin 4108 if Get_Time (We) /= Null_Iir then 4109 Res := Execute_Expression (Instance, Get_Time (We)); 4110 -- LRM93 8.4.1 4111 -- It is an error if the time expression in a waveform element 4112 -- evaluates to a negative value. 4113 if Res.I64 < 0 then 4114 Error_Msg_Exec ("time value is negative", Get_Time (We)); 4115 end if; 4116 Trans.After := Std_Time (Res.I64); 4117 else 4118 -- LRM93 8.4.1 4119 -- If the after clause of a waveform element is not present, 4120 -- then an implicit "after 0 ns" is assumed. 4121 Trans.After := 0; 4122 end if; 4123 4124 -- LRM93 8.4.1 4125 -- It is an error if the sequence of new transactions is not in 4126 -- ascending order with respect to time. 4127 if I > 1 4128 and then Trans.After <= Transactions.Els (I - 1).After 4129 then 4130 Error_Msg_Exec 4131 ("sequence not in ascending order with respect to time", We); 4132 end if; 4133 4134 if Get_Kind (Get_We_Value (We)) = Iir_Kind_Null_Literal then 4135 -- null transaction. 4136 Trans.Value := null; 4137 else 4138 -- LRM93 8.4.1 4139 -- For the first form of waveform element, the value component 4140 -- of the transaction is determined by the value expression in 4141 -- the waveform element. 4142 Trans.Value := Execute_Expression_With_Type 4143 (Instance, Get_We_Value (We), Targ_Type); 4144 end if; 4145 end; 4146 We := Get_Chain (We); 4147 end loop; 4148 pragma Assert (We = Null_Iir); 4149 4150 case Get_Delay_Mechanism (Stmt) is 4151 when Iir_Transport_Delay => 4152 Transactions.Reject := 0; 4153 when Iir_Inertial_Delay => 4154 -- LRM93 8.4 4155 -- or, in the case that a pulse rejection limit is specified, 4156 -- a pulse whose duration is shorter than that limit will not 4157 -- be transmitted. 4158 -- Every inertially delayed signal assignment has a pulse 4159 -- rejection limit. 4160 if Get_Reject_Time_Expression (Stmt) /= Null_Iir then 4161 -- LRM93 8.4 4162 -- If the delay mechanism specifies inertial delay, and if the 4163 -- reserved word reject followed by a time expression is 4164 -- present, then the time expression specifies the pulse 4165 -- rejection limit. 4166 Res := Execute_Expression 4167 (Instance, Get_Reject_Time_Expression (Stmt)); 4168 -- LRM93 8.4 4169 -- It is an error if the pulse rejection limit for any 4170 -- inertially delayed signal assignement statement is either 4171 -- negative ... 4172 if Res.I64 < 0 then 4173 Error_Msg_Exec ("reject time negative", Stmt); 4174 end if; 4175 -- LRM93 8.4 4176 -- ... or greather than the time expression associated with 4177 -- the first waveform element. 4178 Transactions.Reject := Std_Time (Res.I64); 4179 if Transactions.Reject > Transactions.Els (1).After then 4180 Error_Msg_Exec 4181 ("reject time greather than time expression", Stmt); 4182 end if; 4183 else 4184 -- LRM93 8.4 4185 -- In all other cases, the pulse rejection limit is the time 4186 -- expression associated ith the first waveform element. 4187 Transactions.Reject := Transactions.Els (1).After; 4188 end if; 4189 end case; 4190 4191 -- FIXME: slice Transactions to remove transactions after end of time. 4192 Assign_Value_To_Signal (Instance, Rdest, Transactions); 4193 4194 Release (Marker, Expr_Pool); 4195 end Execute_Signal_Assignment; 4196 4197 -- Display a message when an assertion has failed. 4198 -- REPORT is the value (string) to display, or null to use default message. 4199 -- SEVERITY is the severity or null to use default (error). 4200 -- STMT is used to display location. 4201 procedure Execute_Failed_Assertion (Msg : String; 4202 Report : String; 4203 Severity : Natural; 4204 Stmt: Iir) is 4205 begin 4206 -- LRM93 8.2 4207 -- The error message consists of at least: 4208 4209 -- 4: name of the design unit containing the assertion. 4210 Put (Disp_Location (Stmt)); 4211 4212 Put (":@"); 4213 Grt.Astdio.Vhdl.Put_Time (Grt.Stdio.stdout, Current_Time); 4214 4215 -- 1: an indication that this message is from an assertion. 4216 Put (":("); 4217 Put (Msg); 4218 Put (' '); 4219 4220 -- 2: the value of the severity level. 4221 case Severity is 4222 when 0 => 4223 Put ("note"); 4224 when 1 => 4225 Put ("warning"); 4226 when 2 => 4227 Put ("error"); 4228 when 3 => 4229 Put ("failure"); 4230 when others => 4231 Error_Internal (Null_Iir, "execute_failed_assertion"); 4232 end case; 4233 Put ("): "); 4234 4235 -- 3: the value of the message string. 4236 Put_Line (Report); 4237 4238 -- Stop execution if the severity is too high. 4239 if Severity >= Grt.Options.Severity_Level then 4240 Debug (Reason_Assert); 4241 Grt.Errors.Fatal_Error; 4242 end if; 4243 end Execute_Failed_Assertion; 4244 4245 procedure Execute_Failed_Assertion (Instance: Block_Instance_Acc; 4246 Label : String; 4247 Stmt : Iir; 4248 Default_Msg : String; 4249 Default_Severity : Natural) 4250 is 4251 Expr: Iir; 4252 Report, Severity_Lit: Iir_Value_Literal_Acc; 4253 Severity : Natural; 4254 Marker : Mark_Type; 4255 begin 4256 Mark (Marker, Expr_Pool); 4257 Expr := Get_Report_Expression (Stmt); 4258 if Expr /= Null_Iir then 4259 Report := Execute_Expression (Instance, Expr); 4260 else 4261 Report := null; 4262 end if; 4263 Expr := Get_Severity_Expression (Stmt); 4264 if Expr /= Null_Iir then 4265 Severity_Lit := Execute_Expression (Instance, Expr); 4266 Severity := Natural'Val (Severity_Lit.E8); 4267 else 4268 Severity := Default_Severity; 4269 end if; 4270 if Report /= null then 4271 declare 4272 Msg : String (1 .. Natural (Report.Val_Array.Len)); 4273 begin 4274 for I in Report.Val_Array.V'Range loop 4275 Msg (Positive (I)) := 4276 Character'Val (Report.Val_Array.V (I).E8); 4277 end loop; 4278 Execute_Failed_Assertion (Label, Msg, Severity, Stmt); 4279 end; 4280 else 4281 Execute_Failed_Assertion (Label, Default_Msg, Severity, Stmt); 4282 end if; 4283 Release (Marker, Expr_Pool); 4284 end Execute_Failed_Assertion; 4285 4286 function Is_In_Choice (Instance : Block_Instance_Acc; 4287 Choice : Iir; 4288 Expr : Iir_Value_Literal_Acc) 4289 return Boolean 4290 is 4291 Res : Boolean; 4292 begin 4293 case Get_Kind (Choice) is 4294 when Iir_Kind_Choice_By_Others => 4295 return True; 4296 when Iir_Kind_Choice_By_Expression => 4297 declare 4298 Expr1: Iir_Value_Literal_Acc; 4299 begin 4300 Expr1 := Execute_Expression 4301 (Instance, Get_Choice_Expression (Choice)); 4302 Res := Is_Equal (Expr, Expr1); 4303 return Res; 4304 end; 4305 when Iir_Kind_Choice_By_Range => 4306 declare 4307 A_Range : Iir_Value_Literal_Acc; 4308 begin 4309 A_Range := Execute_Bounds 4310 (Instance, Get_Choice_Range (Choice)); 4311 Res := Is_In_Range (Expr, A_Range); 4312 end; 4313 return Res; 4314 when others => 4315 Error_Kind ("is_in_choice", Choice); 4316 end case; 4317 end Is_In_Choice; 4318 4319 function Execute_Choice (Instance : Block_Instance_Acc; 4320 Expr : Iir; 4321 First_Assoc : Iir) return Iir 4322 is 4323 Value: Iir_Value_Literal_Acc; 4324 Assoc: Iir; 4325 Assoc_Res : Iir; 4326 Marker : Mark_Type; 4327 begin 4328 Mark (Marker, Expr_Pool); 4329 Assoc := First_Assoc; 4330 4331 Value := Execute_Expression (Instance, Expr); 4332 if Get_Type_Staticness (Get_Type (Expr)) /= Locally 4333 and then Get_Kind (Assoc) = Iir_Kind_Choice_By_Expression 4334 then 4335 -- Choice is not locally constrained, check length. 4336 declare 4337 Choice_Type : constant Iir := 4338 Get_Type (Get_Choice_Expression (Assoc)); 4339 Choice_Len : Int64; 4340 begin 4341 Choice_Len := Vhdl.Evaluation.Eval_Discrete_Type_Length 4342 (Get_String_Type_Bound_Type (Choice_Type)); 4343 if Choice_Len /= Int64 (Value.Bounds.D (1).Length) then 4344 Error_Msg_Constraint (Expr); 4345 end if; 4346 end; 4347 end if; 4348 4349 while Assoc /= Null_Iir loop 4350 if not Get_Same_Alternative_Flag (Assoc) then 4351 Assoc_Res := Assoc; 4352 end if; 4353 4354 if Is_In_Choice (Instance, Assoc, Value) then 4355 Release (Marker, Expr_Pool); 4356 return Assoc_Res; 4357 end if; 4358 4359 Assoc := Get_Chain (Assoc); 4360 end loop; 4361 -- FIXME: infinite loop??? 4362 Error_Msg_Exec ("no choice for expression", Expr); 4363 raise Internal_Error; 4364 end Execute_Choice; 4365 4366 -- Return TRUE iff VAL is in the range defined by BOUNDS. 4367 function Is_In_Range (Val : Iir_Value_Literal_Acc; 4368 Bounds : Iir_Value_Literal_Acc) 4369 return Boolean 4370 is 4371 Max, Min : Iir_Value_Literal_Acc; 4372 begin 4373 case Bounds.Dir is 4374 when Dir_To => 4375 Min := Bounds.Left; 4376 Max := Bounds.Right; 4377 when Dir_Downto => 4378 Min := Bounds.Right; 4379 Max := Bounds.Left; 4380 end case; 4381 4382 case Iir_Value_Discrete (Val.Kind) is 4383 when Iir_Value_E8 => 4384 return Val.E8 >= Min.E8 and Val.E8 <= Max.E8; 4385 when Iir_Value_E32 => 4386 return Val.E32 >= Min.E32 and Val.E32 <= Max.E32; 4387 when Iir_Value_B1 => 4388 return Val.B1 >= Min.B1 and Val.B1 <= Max.B1; 4389 when Iir_Value_I64 => 4390 return Val.I64 >= Min.I64 and Val.I64 <= Max.I64; 4391 end case; 4392 end Is_In_Range; 4393 4394 -- Increment or decrement VAL according to BOUNDS.DIR. 4395 -- FIXME: use increment ? 4396 procedure Update_Loop_Index (Val : Iir_Value_Literal_Acc; 4397 Bounds : Iir_Value_Literal_Acc) 4398 is 4399 begin 4400 case Iir_Value_Discrete (Val.Kind) is 4401 when Iir_Value_E8 => 4402 case Bounds.Dir is 4403 when Dir_To => 4404 Val.E8 := Val.E8 + 1; 4405 when Dir_Downto => 4406 Val.E8 := Val.E8 - 1; 4407 end case; 4408 when Iir_Value_E32 => 4409 case Bounds.Dir is 4410 when Dir_To => 4411 Val.E32 := Val.E32 + 1; 4412 when Dir_Downto => 4413 Val.E32 := Val.E32 - 1; 4414 end case; 4415 when Iir_Value_B1 => 4416 case Bounds.Dir is 4417 when Dir_To => 4418 Val.B1 := True; 4419 when Dir_Downto => 4420 Val.B1 := False; 4421 end case; 4422 when Iir_Value_I64 => 4423 case Bounds.Dir is 4424 when Dir_To => 4425 Val.I64 := Val.I64 + 1; 4426 when Dir_Downto => 4427 Val.I64 := Val.I64 - 1; 4428 end case; 4429 end case; 4430 end Update_Loop_Index; 4431 4432 procedure Finalize_For_Loop_Statement (Instance : Block_Instance_Acc; 4433 Stmt : Iir) 4434 is 4435 begin 4436 Destroy_Iterator_Declaration 4437 (Instance, Get_Parameter_Specification (Stmt)); 4438 end Finalize_For_Loop_Statement; 4439 4440 procedure Finalize_Loop_Statement (Instance : Block_Instance_Acc; 4441 Stmt : Iir) 4442 is 4443 begin 4444 if Get_Kind (Stmt) = Iir_Kind_For_Loop_Statement then 4445 Finalize_For_Loop_Statement (Instance, Stmt); 4446 end if; 4447 end Finalize_Loop_Statement; 4448 4449 procedure Execute_For_Loop_Statement (Proc : Process_State_Acc) 4450 is 4451 Instance : constant Block_Instance_Acc := Proc.Instance; 4452 Stmt : constant Iir_For_Loop_Statement := Instance.Stmt; 4453 Iterator : constant Iir := Get_Parameter_Specification (Stmt); 4454 Bounds : Iir_Value_Literal_Acc; 4455 Index : Iir_Value_Literal_Acc; 4456 Stmt_Chain : Iir; 4457 Is_Nul : Boolean; 4458 Marker : Mark_Type; 4459 begin 4460 -- Elaborate the iterator (and its type). 4461 Elaborate_Declaration (Instance, Iterator); 4462 4463 -- Extract bounds. 4464 Mark (Marker, Expr_Pool); 4465 Bounds := Execute_Bounds (Instance, Get_Type (Iterator)); 4466 Index := Instance.Objects (Get_Info (Iterator).Slot); 4467 Store (Index, Bounds.Left); 4468 Is_Nul := Is_Null_Range (Bounds); 4469 Release (Marker, Expr_Pool); 4470 4471 if Is_Nul then 4472 -- Loop is complete. 4473 Finalize_For_Loop_Statement (Instance, Stmt); 4474 Update_Next_Statement (Proc); 4475 else 4476 Stmt_Chain := Get_Sequential_Statement_Chain (Stmt); 4477 if Stmt_Chain = Null_Iir then 4478 -- Nothing to do for an empty loop. 4479 Finalize_For_Loop_Statement (Instance, Stmt); 4480 Update_Next_Statement (Proc); 4481 else 4482 Instance.Stmt := Stmt_Chain; 4483 end if; 4484 end if; 4485 end Execute_For_Loop_Statement; 4486 4487 -- This function is called when there is no more statements to execute 4488 -- in the statement list of a for_loop. Returns FALSE in case of end of 4489 -- loop. 4490 function Finish_For_Loop_Statement (Instance : Block_Instance_Acc) 4491 return Boolean 4492 is 4493 Iterator : constant Iir := Get_Parameter_Specification (Instance.Stmt); 4494 Bounds : Iir_Value_Literal_Acc; 4495 Index : Iir_Value_Literal_Acc; 4496 Marker : Mark_Type; 4497 begin 4498 -- FIXME: avoid allocation. 4499 Mark (Marker, Expr_Pool); 4500 Bounds := Execute_Bounds (Instance, Get_Type (Iterator)); 4501 Index := Instance.Objects (Get_Info (Iterator).Slot); 4502 4503 if Is_Equal (Index, Bounds.Right) then 4504 -- Loop is complete. 4505 Release (Marker, Expr_Pool); 4506 Finalize_For_Loop_Statement (Instance, Instance.Stmt); 4507 return False; 4508 else 4509 -- Update the loop index. 4510 Update_Loop_Index (Index, Bounds); 4511 4512 Release (Marker, Expr_Pool); 4513 4514 -- start the loop again. 4515 Instance.Stmt := Get_Sequential_Statement_Chain (Instance.Stmt); 4516 return True; 4517 end if; 4518 end Finish_For_Loop_Statement; 4519 4520 -- Evaluate boolean condition COND. If COND is Null_Iir, returns true. 4521 function Execute_Condition (Instance : Block_Instance_Acc; 4522 Cond : Iir) return Boolean 4523 is 4524 V : Iir_Value_Literal_Acc; 4525 Res : Boolean; 4526 Marker : Mark_Type; 4527 begin 4528 if Cond = Null_Iir then 4529 return True; 4530 end if; 4531 4532 Mark (Marker, Expr_Pool); 4533 V := Execute_Expression (Instance, Cond); 4534 Res := V.B1 = True; 4535 Release (Marker, Expr_Pool); 4536 return Res; 4537 end Execute_Condition; 4538 4539 -- Start a while loop statement, or return FALSE if the loop is not 4540 -- executed. 4541 procedure Execute_While_Loop_Statement (Proc : Process_State_Acc) 4542 is 4543 Instance: constant Block_Instance_Acc := Proc.Instance; 4544 Stmt : constant Iir := Instance.Stmt; 4545 Cond : Boolean; 4546 begin 4547 Cond := Execute_Condition (Instance, Get_Condition (Stmt)); 4548 if Cond then 4549 Init_Sequential_Statements (Proc, Stmt); 4550 else 4551 Update_Next_Statement (Proc); 4552 end if; 4553 end Execute_While_Loop_Statement; 4554 4555 -- This function is called when there is no more statements to execute 4556 -- in the statement list of a while loop. Returns FALSE iff loop is 4557 -- completed. 4558 function Finish_While_Loop_Statement (Instance : Block_Instance_Acc) 4559 return Boolean 4560 is 4561 Cond : Boolean; 4562 begin 4563 Cond := Execute_Condition (Instance, Get_Condition (Instance.Stmt)); 4564 4565 if Cond then 4566 -- start the loop again. 4567 Instance.Stmt := Get_Sequential_Statement_Chain (Instance.Stmt); 4568 return True; 4569 else 4570 -- Loop is complete. 4571 return False; 4572 end if; 4573 end Finish_While_Loop_Statement; 4574 4575 -- Return TRUE if the loop must be executed again 4576 function Finish_Loop_Statement (Instance : Block_Instance_Acc; Stmt : Iir) 4577 return Boolean is 4578 begin 4579 Instance.Stmt := Stmt; 4580 case Get_Kind (Stmt) is 4581 when Iir_Kind_While_Loop_Statement => 4582 return Finish_While_Loop_Statement (Instance); 4583 when Iir_Kind_For_Loop_Statement => 4584 return Finish_For_Loop_Statement (Instance); 4585 when others => 4586 Error_Kind ("finish_loop_statement", Stmt); 4587 end case; 4588 end Finish_Loop_Statement; 4589 4590 -- Return FALSE if the next statement should be executed (possibly 4591 -- updated). 4592 procedure Execute_Exit_Next_Statement (Proc : Process_State_Acc; 4593 Is_Exit : Boolean) 4594 is 4595 Instance : constant Block_Instance_Acc := Proc.Instance; 4596 Stmt : constant Iir := Instance.Stmt; 4597 Label : constant Iir := Get_Named_Entity (Get_Loop_Label (Stmt)); 4598 Cond : Boolean; 4599 Parent : Iir; 4600 begin 4601 Cond := Execute_Condition (Instance, Get_Condition (Stmt)); 4602 if not Cond then 4603 Update_Next_Statement (Proc); 4604 return; 4605 end if; 4606 4607 Parent := Stmt; 4608 loop 4609 Parent := Get_Parent (Parent); 4610 case Get_Kind (Parent) is 4611 when Iir_Kind_For_Loop_Statement 4612 | Iir_Kind_While_Loop_Statement => 4613 if Label = Null_Iir or else Label = Parent then 4614 -- Target is this statement. 4615 if Is_Exit then 4616 Finalize_Loop_Statement (Instance, Parent); 4617 Instance.Stmt := Parent; 4618 Update_Next_Statement (Proc); 4619 elsif not Finish_Loop_Statement (Instance, Parent) then 4620 Update_Next_Statement (Proc); 4621 else 4622 Init_Sequential_Statements (Proc, Parent); 4623 end if; 4624 return; 4625 else 4626 Finalize_Loop_Statement (Instance, Parent); 4627 end if; 4628 when others => 4629 null; 4630 end case; 4631 end loop; 4632 end Execute_Exit_Next_Statement; 4633 4634 procedure Execute_Case_Statement (Proc : Process_State_Acc) 4635 is 4636 Instance : constant Block_Instance_Acc := Proc.Instance; 4637 Stmt : constant Iir := Instance.Stmt; 4638 Assoc: Iir; 4639 Stmt_Chain : Iir; 4640 begin 4641 Assoc := Execute_Choice (Instance, Get_Expression (Stmt), 4642 Get_Case_Statement_Alternative_Chain (Stmt)); 4643 Stmt_Chain := Get_Associated_Chain (Assoc); 4644 if Stmt_Chain = Null_Iir then 4645 Update_Next_Statement (Proc); 4646 else 4647 Instance.Stmt := Stmt_Chain; 4648 end if; 4649 end Execute_Case_Statement; 4650 4651 procedure Execute_Call_Statement (Proc : Process_State_Acc) 4652 is 4653 Instance : constant Block_Instance_Acc := Proc.Instance; 4654 Stmt : constant Iir := Instance.Stmt; 4655 Call : constant Iir := Get_Procedure_Call (Stmt); 4656 Imp : constant Iir := Get_Implementation (Call); 4657 Subprg_Instance : Block_Instance_Acc; 4658 Prot_Block : Block_Instance_Acc; 4659 Assoc_Chain: Iir; 4660 Inter_Chain : Iir; 4661 begin 4662 if Get_Implicit_Definition (Imp) in Iir_Predefined_Implicit then 4663 Execute_Implicit_Procedure (Instance, Call); 4664 Update_Next_Statement (Proc); 4665 elsif Get_Foreign_Flag (Imp) then 4666 Execute_Foreign_Procedure (Instance, Call); 4667 Update_Next_Statement (Proc); 4668 else 4669 Mark (Instance.Marker, Instance_Pool.all); 4670 Prot_Block := Get_Protected_Object_Instance (Instance, Call); 4671 Subprg_Instance := 4672 Create_Subprogram_Instance (Instance, Prot_Block, Imp); 4673 Assoc_Chain := Get_Parameter_Association_Chain (Call); 4674 Inter_Chain := Get_Interface_Declaration_Chain (Imp); 4675 Execute_Association 4676 (Instance, Subprg_Instance, Inter_Chain, Assoc_Chain); 4677 4678 Current_Process.Instance := Subprg_Instance; 4679 Elaborate_Declarative_Part 4680 (Subprg_Instance, Get_Declaration_Chain (Subprg_Instance.Bod)); 4681 4682 Init_Sequential_Statements (Proc, Subprg_Instance.Bod); 4683 end if; 4684 end Execute_Call_Statement; 4685 4686 procedure Finish_Procedure_Frame (Proc : Process_State_Acc) 4687 is 4688 Old_Instance : constant Block_Instance_Acc := Proc.Instance; 4689 begin 4690 Execute_Back_Association (Old_Instance); 4691 Proc.Instance := Old_Instance.Parent; 4692 Execute_Subprogram_Call_Final (Old_Instance); 4693 Release (Proc.Instance.Marker, Instance_Pool.all); 4694 end Finish_Procedure_Frame; 4695 4696 procedure Execute_If_Statement (Proc : Process_State_Acc; Stmt : Iir) 4697 is 4698 Clause: Iir; 4699 Cond: Boolean; 4700 begin 4701 Clause := Stmt; 4702 loop 4703 Cond := Execute_Condition (Proc.Instance, Get_Condition (Clause)); 4704 if Cond then 4705 Init_Sequential_Statements (Proc, Clause); 4706 return; 4707 end if; 4708 Clause := Get_Else_Clause (Clause); 4709 exit when Clause = Null_Iir; 4710 end loop; 4711 Update_Next_Statement (Proc); 4712 end Execute_If_Statement; 4713 4714 procedure Execute_Variable_Assignment (Proc : Process_State_Acc; Stmt : Iir) 4715 is 4716 Instance : constant Block_Instance_Acc := Proc.Instance; 4717 Target : constant Iir := Get_Target (Stmt); 4718 Target_Type : constant Iir := Get_Type (Target); 4719 Expr : constant Iir := Get_Expression (Stmt); 4720 Expr_Type : constant Iir := Get_Type (Expr); 4721 Target_Val: Iir_Value_Literal_Acc; 4722 Res : Iir_Value_Literal_Acc; 4723 Marker : Mark_Type; 4724 begin 4725 Mark (Marker, Expr_Pool); 4726 Target_Val := Execute_Expression (Instance, Target); 4727 4728 -- If the type of the target is not static and the value is 4729 -- an aggregate, then the aggregate may be contrained by the 4730 -- target. 4731 if Get_Kind (Expr) = Iir_Kind_Aggregate 4732 and then Get_Kind (Expr_Type) in Iir_Kinds_Array_Type_Definition 4733 then 4734 Res := Copy_Array_Bound (Target_Val); 4735 Fill_Array_Aggregate (Instance, Expr, Res); 4736 else 4737 Res := Execute_Expression (Instance, Expr); 4738 end if; 4739 if Get_Kind (Target_Type) in Iir_Kinds_Array_Type_Definition then 4740 -- Note: target_type may be dynamic (slice case), so 4741 -- check_constraints is not called. 4742 Implicit_Array_Conversion (Res, Target_Val, Stmt); 4743 else 4744 Check_Constraints (Instance, Res, Target_Type, Stmt); 4745 end if; 4746 4747 -- Note: we need to unshare before copying to avoid 4748 -- overwrites (in assignments like: v (1 to 4) := v (3 to 6)). 4749 -- FIXME: improve that handling (detect overlaps before). 4750 Store (Target_Val, Unshare (Res, Expr_Pool'Access)); 4751 4752 Release (Marker, Expr_Pool); 4753 end Execute_Variable_Assignment; 4754 4755 function Execute_Return_Statement (Proc : Process_State_Acc) 4756 return Boolean 4757 is 4758 Res : Iir_Value_Literal_Acc; 4759 Instance : constant Block_Instance_Acc := Proc.Instance; 4760 Stmt : constant Iir := Instance.Stmt; 4761 Expr : constant Iir := Get_Expression (Stmt); 4762 begin 4763 if Expr /= Null_Iir then 4764 Res := Execute_Expression (Instance, Expr); 4765 Implicit_Array_Conversion (Instance, Res, Get_Type (Stmt), Stmt); 4766 Check_Constraints (Instance, Res, Get_Type (Stmt), Stmt); 4767 Instance.Result := Res; 4768 end if; 4769 4770 case Get_Kind (Instance.Label) is 4771 when Iir_Kind_Procedure_Declaration => 4772 Finish_Procedure_Frame (Proc); 4773 Update_Next_Statement (Proc); 4774 return False; 4775 when Iir_Kind_Function_Declaration => 4776 return True; 4777 when others => 4778 raise Internal_Error; 4779 end case; 4780 end Execute_Return_Statement; 4781 4782 procedure Finish_Sequential_Statements 4783 (Proc : Process_State_Acc; Complex_Stmt : Iir) 4784 is 4785 Instance : Block_Instance_Acc := Proc.Instance; 4786 Stmt : Iir; 4787 begin 4788 Stmt := Complex_Stmt; 4789 loop 4790 Instance.Stmt := Stmt; 4791 case Get_Kind (Stmt) is 4792 when Iir_Kind_For_Loop_Statement => 4793 if Finish_For_Loop_Statement (Instance) then 4794 return; 4795 end if; 4796 when Iir_Kind_While_Loop_Statement => 4797 if Finish_While_Loop_Statement (Instance) then 4798 return; 4799 end if; 4800 when Iir_Kind_Case_Statement 4801 | Iir_Kind_If_Statement => 4802 null; 4803 when Iir_Kind_Sensitized_Process_Statement => 4804 Instance.Stmt := Null_Iir; 4805 return; 4806 when Iir_Kind_Process_Statement => 4807 -- Start again. 4808 Instance.Stmt := Get_Sequential_Statement_Chain (Stmt); 4809 return; 4810 when Iir_Kind_Procedure_Body => 4811 Finish_Procedure_Frame (Proc); 4812 Instance := Proc.Instance; 4813 when Iir_Kind_Function_Body => 4814 Error_Msg_Exec ("missing return statement in function", Stmt); 4815 when others => 4816 Error_Kind ("execute_next_statement", Stmt); 4817 end case; 4818 Stmt := Get_Chain (Instance.Stmt); 4819 if Stmt /= Null_Iir then 4820 Instance.Stmt := Stmt; 4821 return; 4822 end if; 4823 Stmt := Get_Parent (Instance.Stmt); 4824 end loop; 4825 end Finish_Sequential_Statements; 4826 4827 procedure Init_Sequential_Statements 4828 (Proc : Process_State_Acc; Complex_Stmt : Iir) 4829 is 4830 Stmt : Iir; 4831 begin 4832 Stmt := Get_Sequential_Statement_Chain (Complex_Stmt); 4833 if Stmt /= Null_Iir then 4834 Proc.Instance.Stmt := Stmt; 4835 else 4836 Finish_Sequential_Statements (Proc, Complex_Stmt); 4837 end if; 4838 end Init_Sequential_Statements; 4839 4840 procedure Update_Next_Statement (Proc : Process_State_Acc) 4841 is 4842 Instance : constant Block_Instance_Acc := Proc.Instance; 4843 Stmt : Iir; 4844 begin 4845 Stmt := Get_Chain (Instance.Stmt); 4846 if Stmt /= Null_Iir then 4847 Instance.Stmt := Stmt; 4848 return; 4849 end if; 4850 Finish_Sequential_Statements (Proc, Get_Parent (Instance.Stmt)); 4851 end Update_Next_Statement; 4852 4853 procedure Execute_Sequential_Statements (Proc : Process_State_Acc) 4854 is 4855 Instance : Block_Instance_Acc; 4856 Stmt: Iir; 4857 begin 4858 loop 4859 Instance := Proc.Instance; 4860 Stmt := Instance.Stmt; 4861 4862 -- End of process or subprogram. 4863 exit when Stmt = Null_Iir; 4864 4865 if Trace_Statements then 4866 declare 4867 Name : Name_Id; 4868 Line : Natural; 4869 Col : Natural; 4870 begin 4871 Files_Map.Location_To_Position 4872 (Get_Location (Stmt), Name, Line, Col); 4873 Put_Line ("Execute statement at " 4874 & Name_Table.Image (Name) 4875 & Natural'Image (Line)); 4876 end; 4877 end if; 4878 4879 if Flag_Need_Debug then 4880 Debug (Reason_Break); 4881 end if; 4882 4883 -- execute statement STMT. 4884 case Get_Kind (Stmt) is 4885 when Iir_Kind_Null_Statement => 4886 Update_Next_Statement (Proc); 4887 4888 when Iir_Kind_If_Statement => 4889 Execute_If_Statement (Proc, Stmt); 4890 4891 when Iir_Kind_Simple_Signal_Assignment_Statement => 4892 Execute_Signal_Assignment 4893 (Instance, Stmt, Get_Waveform_Chain (Stmt)); 4894 Update_Next_Statement (Proc); 4895 4896 when Iir_Kind_Selected_Waveform_Assignment_Statement => 4897 declare 4898 Assoc : Iir; 4899 begin 4900 Assoc := Execute_Choice (Instance, Get_Expression (Stmt), 4901 Get_Selected_Waveform_Chain (Stmt)); 4902 Execute_Signal_Assignment 4903 (Instance, Stmt, Get_Associated_Chain (Assoc)); 4904 Update_Next_Statement (Proc); 4905 end; 4906 when Iir_Kind_Assertion_Statement => 4907 declare 4908 Res : Boolean; 4909 begin 4910 Res := Execute_Condition 4911 (Instance, Get_Assertion_Condition (Stmt)); 4912 if not Res then 4913 Execute_Failed_Assertion (Instance, "assertion", Stmt, 4914 "Assertion violation.", 2); 4915 end if; 4916 end; 4917 Update_Next_Statement (Proc); 4918 4919 when Iir_Kind_Report_Statement => 4920 Execute_Failed_Assertion (Instance, "report", Stmt, 4921 "Assertion violation.", 0); 4922 Update_Next_Statement (Proc); 4923 4924 when Iir_Kind_Variable_Assignment_Statement => 4925 Execute_Variable_Assignment (Proc, Stmt); 4926 Update_Next_Statement (Proc); 4927 4928 when Iir_Kind_Return_Statement => 4929 if Execute_Return_Statement (Proc) then 4930 return; 4931 end if; 4932 4933 when Iir_Kind_For_Loop_Statement => 4934 Execute_For_Loop_Statement (Proc); 4935 4936 when Iir_Kind_While_Loop_Statement => 4937 Execute_While_Loop_Statement (Proc); 4938 4939 when Iir_Kind_Case_Statement => 4940 Execute_Case_Statement (Proc); 4941 4942 when Iir_Kind_Wait_Statement => 4943 if Execute_Wait_Statement (Instance, Stmt) then 4944 return; 4945 end if; 4946 Update_Next_Statement (Proc); 4947 4948 when Iir_Kind_Procedure_Call_Statement => 4949 Execute_Call_Statement (Proc); 4950 4951 when Iir_Kind_Exit_Statement => 4952 Execute_Exit_Next_Statement (Proc, True); 4953 when Iir_Kind_Next_Statement => 4954 Execute_Exit_Next_Statement (Proc, False); 4955 4956 when others => 4957 Error_Kind ("execute_sequential_statements", Stmt); 4958 end case; 4959 end loop; 4960 end Execute_Sequential_Statements; 4961end Simul.Execution; 4962