diff options
author | Patrick Lehmann <Paebbels@gmail.com> | 2021-12-15 22:10:09 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-15 22:10:09 +0100 |
commit | 918e15bb6fab7da8719624ac9d37a47db4751375 (patch) | |
tree | e343b717af2139c142b660a1c918bce06ecd946a | |
parent | 75bd31ff74ba3965bec27bf34a93b9c451e0d749 (diff) | |
parent | f32d77707a2639fed94978965b3a9690c2bf7904 (diff) | |
download | ghdl-918e15bb6fab7da8719624ac9d37a47db4751375.tar.gz ghdl-918e15bb6fab7da8719624ac9d37a47db4751375.tar.bz2 ghdl-918e15bb6fab7da8719624ac9d37a47db4751375.zip |
Merge branch 'ghdl:master' into paebbels/pyGHDL-updates
31 files changed, 648 insertions, 90 deletions
diff --git a/src/ghdldrv/ghdllocal.adb b/src/ghdldrv/ghdllocal.adb index 4e0b0b05b..722c1a26f 100644 --- a/src/ghdldrv/ghdllocal.adb +++ b/src/ghdldrv/ghdllocal.adb @@ -86,7 +86,6 @@ package body Ghdllocal is pragma Assert (Opt'First = 1); pragma Assert (Opt'Last >= 5); Eq_Pos : Natural; - Id : Name_Id; begin Eq_Pos := 0; for I in 3 .. Opt'Last loop @@ -106,21 +105,9 @@ package body Ghdllocal is return Option_Err; end if; - declare - Res : String (1 .. Eq_Pos - 3) := Opt (3 .. Eq_Pos - 1); - Err : Boolean; - begin - Vhdl.Scanner.Convert_Identifier (Res, Err); - if Err then - Error_Msg_Option - ("incorrect generic name in generic override option"); - return Option_Err; - end if; - Id := Name_Table.Get_Identifier (Res); - end; - Vhdl.Configuration.Add_Generic_Override - (Id, Opt (Eq_Pos + 1 .. Opt'Last)); + (Opt (3 .. Eq_Pos - 1), Opt (Eq_Pos + 1 .. Opt'Last)); + return Option_Ok; end Decode_Generic_Override_Option; diff --git a/src/ghdldrv/ghdlsynth.adb b/src/ghdldrv/ghdlsynth.adb index cfc5f281b..ced5b71c9 100644 --- a/src/ghdldrv/ghdlsynth.adb +++ b/src/ghdldrv/ghdlsynth.adb @@ -378,20 +378,25 @@ package body Ghdlsynth is Foreign_Resolve_Instances.all; end if; - if Get_Kind (Get_Library_Unit (Config)) /= Iir_Kind_Foreign_Module then - -- Check (and possibly abandon) if entity can be at the top of the - -- hierarchy. - declare - Entity : constant Iir := - Vhdl.Utils.Get_Entity_From_Configuration (Config); - begin - Vhdl.Configuration.Apply_Generic_Override (Entity); - Vhdl.Configuration.Check_Entity_Declaration_Top (Entity, False); - if Nbr_Errors > 0 then - return Null_Iir; - end if; - end; - end if; + -- Check (and possibly abandon) if entity can be at the top of the + -- hierarchy. + declare + Config_Unit : constant Iir := Get_Library_Unit (Config); + Top : Iir; + begin + if Get_Kind (Config_Unit) = Iir_Kind_Foreign_Module then + Top := Config_Unit; + Vhdl.Configuration.Apply_Generic_Override (Top); + -- No Check_Entity_Declaration (yet). + else + Top := Vhdl.Utils.Get_Entity_From_Configuration (Config); + Vhdl.Configuration.Apply_Generic_Override (Top); + Vhdl.Configuration.Check_Entity_Declaration_Top (Top, False); + end if; + if Nbr_Errors > 0 then + return Null_Iir; + end if; + end; return Config; end Ghdl_Synth_Configure; diff --git a/src/ortho/mcode/binary_file.ads b/src/ortho/mcode/binary_file.ads index 08770ae3b..423f6b153 100644 --- a/src/ortho/mcode/binary_file.ads +++ b/src/ortho/mcode/binary_file.ads @@ -128,6 +128,7 @@ package Binary_File is procedure Prealloc (L : Pc_Type); -- Add bits in the current section. + -- Space must be pre-allocated. procedure Gen_8 (B : Byte); procedure Gen_8 (B0, B1 : Byte); @@ -136,6 +137,7 @@ package Binary_File is procedure Gen_64 (B : Unsigned_64); -- Add bits in the current section, but as stand-alone data. + -- Displayed if Dump_Asm. procedure Gen_Data_8 (B : Unsigned_8); procedure Gen_Data_16 (B : Unsigned_32); procedure Gen_Data_32 (Sym : Symbol; Offset : Integer_32); diff --git a/src/ortho/mcode/ortho_code-dwarf.adb b/src/ortho/mcode/ortho_code-dwarf.adb index cb0676891..66e527a16 100644 --- a/src/ortho/mcode/ortho_code-dwarf.adb +++ b/src/ortho/mcode/ortho_code-dwarf.adb @@ -13,11 +13,13 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see <gnu.org/licenses>. + +with Ada.Text_IO; with GNAT.Directory_Operations; + with Tables; -with Interfaces; use Interfaces; + with Dwarf; use Dwarf; -with Ada.Text_IO; with Ortho_Code.Flags; use Ortho_Code.Flags; with Ortho_Code.Decls; with Ortho_Code.Types; diff --git a/src/ortho/mcode/ortho_code-dwarf.ads b/src/ortho/mcode/ortho_code-dwarf.ads index 41803be84..86d5689c4 100644 --- a/src/ortho/mcode/ortho_code-dwarf.ads +++ b/src/ortho/mcode/ortho_code-dwarf.ads @@ -13,6 +13,8 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see <gnu.org/licenses>. +with Interfaces; use Interfaces; + with Binary_File; use Binary_File; package Ortho_Code.Dwarf is @@ -29,6 +31,10 @@ package Ortho_Code.Dwarf is procedure Set_Line_Stmt (Line : Int32); procedure Set_Filename (Dir : String; File : String); + -- Low-level procedure (also used to generate .eh_frame) + procedure Gen_Uleb128 (V : Unsigned_32); + procedure Gen_Sleb128 (V : Int32); + type Mark_Type is limited private; procedure Mark (M : out Mark_Type); procedure Release (M : Mark_Type); diff --git a/src/ortho/mcode/ortho_code-x86-abi.adb b/src/ortho/mcode/ortho_code-x86-abi.adb index ea9be4471..306335124 100644 --- a/src/ortho/mcode/ortho_code-x86-abi.adb +++ b/src/ortho/mcode/ortho_code-x86-abi.adb @@ -13,6 +13,9 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see <gnu.org/licenses>. +with System; + +with Ada.Text_IO; with Ortho_Code.Decls; use Ortho_Code.Decls; with Ortho_Code.Exprs; use Ortho_Code.Exprs; with Ortho_Code.Consts; @@ -25,7 +28,6 @@ with Ortho_Code.X86.Insns; with Ortho_Code.X86.Emits; with Binary_File; with Binary_File.Memory; -with Ada.Text_IO; package body Ortho_Code.X86.Abi is -- First argument is at %ebp + 8 / %rbp + 16 @@ -861,4 +863,62 @@ package body Ortho_Code.X86.Abi is (Ortho_Code.X86.Emits.Chkstk_Symbol, Chkstk'Address); end if; end Link_Intrinsics; + + type Void is null record; + type Void_Ptr is access Void; + + -- From GCC unwind-dw2-fde.h + type Frame_Info_Object is record + pc_begin : Void_Ptr; + tbase : Void_Ptr; + dbase : Void_Ptr; + U : Void_Ptr; + S : Void_Ptr; + fde_end : Void_Ptr; -- Maybe optional + next : Void_Ptr; + end record; + pragma Convention (C, Frame_Info_Object); + + -- Object for the generated code. + This_Object : Frame_Info_Object; + + procedure Register_Unwind + is + use Binary_File.Memory; + use System; + + -- From GCC unwind-dw2-fde.h + procedure Register_Frame_Info_Bases + (Eh_Frame : Address; + Object : Address; + Tbase : Address; + Dbase : Address); + pragma Import (C, Register_Frame_Info_Bases, + "__register_frame_info_bases"); + begin + if X86.Flags.Eh_Frame then + Register_Frame_Info_Bases + (Get_Section_Addr (X86.Emits.Sect_Eh_Frame), + This_Object'Address, + Get_Section_Addr (X86.Emits.Sect_Text), + Get_Section_Addr (X86.Emits.Sect_Bss)); + end if; + end Register_Unwind; + + procedure Unregister_Unwind + is + use Binary_File.Memory; + use System; + + -- From GCC unwind-dw2-fde.h + procedure Deregister_Frame_Info_Bases (Eh_Frame : Address); + pragma Import (C, Deregister_Frame_Info_Bases, + "__deregister_frame_info_bases"); + begin + if X86.Flags.Eh_Frame then + Deregister_Frame_Info_Bases + (Get_Section_Addr (X86.Emits.Sect_Eh_Frame)); + end if; + end Unregister_Unwind; + end Ortho_Code.X86.Abi; diff --git a/src/ortho/mcode/ortho_code-x86-abi.ads b/src/ortho/mcode/ortho_code-x86-abi.ads index cc6cf560b..6e720e1e1 100644 --- a/src/ortho/mcode/ortho_code-x86-abi.ads +++ b/src/ortho/mcode/ortho_code-x86-abi.ads @@ -79,6 +79,10 @@ package Ortho_Code.X86.Abi is -- Link in memory intrinsics symbols. procedure Link_Intrinsics; + -- Register unwinding info for JIT. + procedure Register_Unwind; + procedure Unregister_Unwind; + -- Target specific data for subprograms. type Target_Subprg is record Fp_Slot : Uns32 := 0; diff --git a/src/ortho/mcode/ortho_code-x86-emits.adb b/src/ortho/mcode/ortho_code-x86-emits.adb index 132f7287b..84336818c 100644 --- a/src/ortho/mcode/ortho_code-x86-emits.adb +++ b/src/ortho/mcode/ortho_code-x86-emits.adb @@ -46,11 +46,6 @@ package body Ortho_Code.X86.Emits is Mode_U32 | Mode_I32 => Sz_32, Mode_U64 | Mode_I64 => Sz_64); - -- Well known sections. - Sect_Text : Binary_File.Section_Acc; - Sect_Rodata : Binary_File.Section_Acc; - Sect_Bss : Binary_File.Section_Acc; - -- For 64 bit to 32 bit conversion, we need an extra register. Just before -- the conversion, there is an OE_Reg instruction containing the extra -- register. Its value is saved here. @@ -2936,7 +2931,7 @@ package body Ortho_Code.X86.Emits is -- Emit prolog. -- push %ebp / push %rbp Push_Reg (R_Bp); - -- movl %esp, %ebp / movl %rsp, %rbp + -- movl %esp, %ebp / movq %rsp, %rbp Start_Insn; Gen_Rex (16#48#); Gen_8 (Opc_Mov_Rm_Reg + 1); @@ -2971,7 +2966,7 @@ package body Ortho_Code.X86.Emits is end; end if; - -- subl XXX, %esp / subl XXX, %rsp + -- subl XXX, %esp / subq XXX, %rsp if Frame_Size /= 0 then if not X86.Flags.Flag_Alloca_Call or else Frame_Size <= 4096 @@ -3090,6 +3085,24 @@ package body Ortho_Code.X86.Emits is end if; end Emit_Epilogue; + procedure Gen_FDE + is + Subprg_Size : Unsigned_32; + begin + Subprg_Size := Unsigned_32 (Get_Current_Pc - Subprg_Pc); + + Set_Current_Section (Sect_Eh_Frame); + Prealloc (20); + Gen_32 (16); -- Length + Gen_32 (Unsigned_32 (Get_Current_Pc)); -- CIE pointer + Gen_32 (Unsigned_32 (Subprg_Pc)); -- Initial location (.text rel) + Gen_32 (Subprg_Size); -- Function size + Gen_8 (0); -- Length + Gen_8 (0); + Gen_8 (0); + Gen_8 (0); + end Gen_FDE; + procedure Emit_Subprg (Subprg : Subprogram_Data_Acc) is pragma Assert (Subprg = Cur_Subprg); @@ -3114,6 +3127,10 @@ package body Ortho_Code.X86.Emits is end loop; Emit_Epilogue (Subprg); + + if Flags.Eh_Frame then + Gen_FDE; + end if; end Emit_Subprg; procedure Emit_Var_Decl (Decl : O_Dnode) @@ -3295,6 +3312,51 @@ package body Ortho_Code.X86.Emits is Debug_Hex := True; end if; + if Flags.Eh_Frame then + Create_Section (Sect_Eh_Frame, ".eh_frame", 0); + Set_Current_Section (Sect_Eh_Frame); + Prealloc (32); + + -- Generate CIE + Gen_32 (28); -- Length + Gen_32 (0); -- CIE id = 0 + Gen_8 (1); -- Version = 1 + Gen_8 (Character'Pos ('z')); -- Augmentation + Gen_8 (Character'Pos ('R')); -- Augmentation + Gen_8 (0); -- End of Augmentation + Gen_8 (1); -- Code align factor + if Flags.M64 then + Dwarf.Gen_Sleb128 (-8); -- Data align factor + Dwarf.Gen_Uleb128 (16); -- Return address (16 = rip) + else + Dwarf.Gen_Sleb128 (-4); + Dwarf.Gen_Uleb128 (0); -- TODO + end if; + Dwarf.Gen_Uleb128 (1); -- z: length of the remainder of augmentation + Gen_8 (16#23#); -- R: pointer encoding: .text relative, udata4 + + -- CFIs (call frame instructions) + -- Initial state: cfa = rsp + 8, rip = -8@cfa + Gen_8 (16#0c#); -- DW_CFA_def_cfa + Gen_8 (16#07#); -- reg 7 (rsp) + Gen_8 (16#08#); -- offset 8 + Gen_8 (16#80# or 16#10#); -- DW_CFA_def_offset reg 16 (rip) + Gen_8 (16#01#); -- offset 1 * (-8) = -8 + -- push %rbp, cfa = rsp + 16 + Gen_8 (16#40# or 16#01#); -- DW_CFA_advance_loc +1 + Gen_8 (16#0e#); -- DW_CFA_def_cfa_offset + Gen_8 (16#10#); -- offset 16 + Gen_8 (16#80# or 16#06#); -- DW_CFA_def_offset reg 6 (rbp) + Gen_8 (16#02#); -- offset 2 * (-8) = -16 + -- movq %rsp, %rbp, cfa = rbp + 16 + Gen_8 (16#40# or 16#03#); -- DW_CFA_advance_loc +3 + Gen_8 (16#0d#); -- DW_CFA_def_cfa_register + Gen_8 (16#06#); -- reg 6 (rbp) + Gen_8 (0); -- nop + Gen_8 (0); -- nop + Set_Current_Section (Sect_Text); + end if; + if Flag_Debug /= Debug_None then Dwarf.Init; Set_Current_Section (Sect_Text); @@ -3309,6 +3371,12 @@ package body Ortho_Code.X86.Emits is Set_Current_Section (Sect_Text); Dwarf.Finish; end if; + + if Flags.Eh_Frame then + Set_Current_Section (Sect_Eh_Frame); + Prealloc (4); + Gen_32 (0); -- Size = 0 -> end. + end if; end Finish; end Ortho_Code.X86.Emits; diff --git a/src/ortho/mcode/ortho_code-x86-emits.ads b/src/ortho/mcode/ortho_code-x86-emits.ads index 97802cd19..edd327884 100644 --- a/src/ortho/mcode/ortho_code-x86-emits.ads +++ b/src/ortho/mcode/ortho_code-x86-emits.ads @@ -31,6 +31,12 @@ package Ortho_Code.X86.Emits is type Intrinsic_Symbols_Map is array (Intrinsics_X86) of Symbol; Intrinsics_Symbol : Intrinsic_Symbols_Map; + -- Well known sections. + Sect_Text : Section_Acc; + Sect_Rodata : Section_Acc; + Sect_Bss : Section_Acc; + Sect_Eh_Frame : Section_Acc; + Mcount_Symbol : Symbol; Chkstk_Symbol : Symbol; end Ortho_Code.X86.Emits; diff --git a/src/ortho/mcode/ortho_code-x86-flags_linux.ads b/src/ortho/mcode/ortho_code-x86-flags_linux.ads index a6ef992b8..119158ee8 100644 --- a/src/ortho/mcode/ortho_code-x86-flags_linux.ads +++ b/src/ortho/mcode/ortho_code-x86-flags_linux.ads @@ -30,6 +30,9 @@ package Ortho_Code.X86.Flags_Linux is -- 32 bits. M64 : constant Boolean := False; + -- Generate eh_frame for unwinding. + Eh_Frame : constant Boolean := False; + -- Not Windows x64 calling convention. Win64 : constant Boolean := False; end Ortho_Code.X86.Flags_Linux; diff --git a/src/ortho/mcode/ortho_code-x86-flags_linux64.ads b/src/ortho/mcode/ortho_code-x86-flags_linux64.ads index 6a34106fc..bb46a732d 100644 --- a/src/ortho/mcode/ortho_code-x86-flags_linux64.ads +++ b/src/ortho/mcode/ortho_code-x86-flags_linux64.ads @@ -27,9 +27,12 @@ package Ortho_Code.X86.Flags_Linux64 is -- Alignment for double (64 bit float). Mode_F64_Align : constant Natural := 3; - -- 32 bits. + -- 64 bits. M64 : constant Boolean := True; + -- Generate eh_frame for unwinding. + Eh_Frame : constant Boolean := True; + -- Not Windows x64 calling convention. Win64 : constant Boolean := False; end Ortho_Code.X86.Flags_Linux64; diff --git a/src/ortho/mcode/ortho_code-x86-flags_macosx.ads b/src/ortho/mcode/ortho_code-x86-flags_macosx.ads index 552cf00a9..a14b310a6 100644 --- a/src/ortho/mcode/ortho_code-x86-flags_macosx.ads +++ b/src/ortho/mcode/ortho_code-x86-flags_macosx.ads @@ -30,6 +30,9 @@ package Ortho_Code.X86.Flags_Macosx is -- 32 bits. M64 : constant Boolean := False; + -- Generate eh_frame for unwinding. + Eh_Frame : constant Boolean := False; + -- Not Windows x64 calling convention. Win64 : constant Boolean := False; end Ortho_Code.X86.Flags_Macosx; diff --git a/src/ortho/mcode/ortho_code-x86-flags_macosx64.ads b/src/ortho/mcode/ortho_code-x86-flags_macosx64.ads index a32291766..6f133afa9 100644 --- a/src/ortho/mcode/ortho_code-x86-flags_macosx64.ads +++ b/src/ortho/mcode/ortho_code-x86-flags_macosx64.ads @@ -30,6 +30,9 @@ package Ortho_Code.X86.Flags_Macosx64 is -- 64 bits. M64 : constant Boolean := True; + -- Generate eh_frame for unwinding. + Eh_Frame : constant Boolean := False; + -- Not Windows x64 calling convention. Win64 : constant Boolean := False; end Ortho_Code.X86.Flags_Macosx64; diff --git a/src/ortho/mcode/ortho_code-x86-flags_windows.ads b/src/ortho/mcode/ortho_code-x86-flags_windows.ads index fa74bca58..921868410 100644 --- a/src/ortho/mcode/ortho_code-x86-flags_windows.ads +++ b/src/ortho/mcode/ortho_code-x86-flags_windows.ads @@ -30,6 +30,9 @@ package Ortho_Code.X86.Flags_Windows is -- 32 bits. M64 : constant Boolean := False; + -- Generate eh_frame for unwinding. + Eh_Frame : constant Boolean := False; + -- Not Windows x64 calling convention. Win64 : constant Boolean := False; end Ortho_Code.X86.Flags_Windows; diff --git a/src/ortho/mcode/ortho_code-x86-flags_windows64.ads b/src/ortho/mcode/ortho_code-x86-flags_windows64.ads index 8fd76f2ae..cf7320188 100644 --- a/src/ortho/mcode/ortho_code-x86-flags_windows64.ads +++ b/src/ortho/mcode/ortho_code-x86-flags_windows64.ads @@ -30,6 +30,9 @@ package Ortho_Code.X86.Flags_Windows64 is -- 64 bits. M64 : constant Boolean := True; + -- Generate eh_frame for unwinding. + Eh_Frame : constant Boolean := False; + -- Windows x64 calling convention. Win64 : constant Boolean := True; end Ortho_Code.X86.Flags_Windows64; diff --git a/src/ortho/mcode/ortho_jit.adb b/src/ortho/mcode/ortho_jit.adb index 9be0f054a..84145f747 100644 --- a/src/ortho/mcode/ortho_jit.adb +++ b/src/ortho/mcode/ortho_jit.adb @@ -66,6 +66,8 @@ package body Ortho_Jit is return; end if; + Ortho_Code.Abi.Register_Unwind; + if Snap_Filename /= null then declare use Ada.Text_IO; diff --git a/src/synth/elab-vhdl_insts.adb b/src/synth/elab-vhdl_insts.adb index 71adc953d..b8b53517d 100644 --- a/src/synth/elab-vhdl_insts.adb +++ b/src/synth/elab-vhdl_insts.adb @@ -106,6 +106,15 @@ package body Elab.Vhdl_Insts is Create_Package_Interface (Sub_Inst, Inter, Pkg_Inst); end; + when Iir_Kind_Interface_Type_Declaration => + declare + Act_Typ : Type_Acc; + begin + Act_Typ := Synth_Subtype_Indication + (Syn_Inst, Get_Actual (Assoc)); + Create_Subtype_Object (Sub_Inst, Get_Type (Inter), Act_Typ); + end; + when Iir_Kind_Interface_Variable_Declaration | Iir_Kind_Interface_File_Declaration | Iir_Kind_Interface_Signal_Declaration @@ -113,8 +122,7 @@ package body Elab.Vhdl_Insts is | Iir_Kind_Interface_Terminal_Declaration => raise Internal_Error; - when Iir_Kinds_Interface_Subprogram_Declaration - | Iir_Kind_Interface_Type_Declaration => + when Iir_Kinds_Interface_Subprogram_Declaration => raise Internal_Error; end case; diff --git a/src/synth/elab-vhdl_types.adb b/src/synth/elab-vhdl_types.adb index 300f57427..7d726d154 100644 --- a/src/synth/elab-vhdl_types.adb +++ b/src/synth/elab-vhdl_types.adb @@ -530,7 +530,9 @@ package body Elab.Vhdl_Types is when Iir_Kinds_Denoting_Name => Atype := Get_Named_Entity (Atype); when Iir_Kind_Subtype_Declaration - | Iir_Kind_Type_Declaration => + | Iir_Kind_Type_Declaration + | Iir_Kind_Subtype_Attribute + | Iir_Kind_Interface_Type_Declaration => -- Type already declared, so already handled. return Null_Node; when Iir_Kind_Array_Subtype_Definition diff --git a/src/synth/synth-vhdl_insts.adb b/src/synth/synth-vhdl_insts.adb index dfb42b532..235d9ed8e 100644 --- a/src/synth/synth-vhdl_insts.adb +++ b/src/synth/synth-vhdl_insts.adb @@ -254,28 +254,34 @@ package body Synth.Vhdl_Insts is Gen_Decl := Generics; while Gen_Decl /= Null_Node loop - Gen := Get_Value (Params.Syn_Inst, Gen_Decl); - Strip_Const (Gen); - case Gen.Typ.Kind is - when Type_Discrete => - declare - S : constant String := - Uns64'Image (To_Uns64 (Read_Discrete (Gen))); - begin - if Len + S'Length > Str_Len then - Has_Hash := True; - Hash_Const (Ctxt, Gen.Val, Gen.Typ); - else - Str (Len + 1 .. Len + S'Length) := S; - pragma Assert (Str (Len + 1) = ' '); - Str (Len + 1) := '_'; -- Overwrite the space. - Len := Len + S'Length; - end if; - end; - when others => - Has_Hash := True; - Hash_Const (Ctxt, Gen.Val, Gen.Typ); - end case; + if Get_Kind (Gen_Decl) = Iir_Kind_Interface_Constant_Declaration + then + Gen := Get_Value (Params.Syn_Inst, Gen_Decl); + Strip_Const (Gen); + case Gen.Typ.Kind is + when Type_Discrete => + declare + S : constant String := + Uns64'Image (To_Uns64 (Read_Discrete (Gen))); + begin + if Len + S'Length > Str_Len then + Has_Hash := True; + Hash_Const (Ctxt, Gen.Val, Gen.Typ); + else + Str (Len + 1 .. Len + S'Length) := S; + pragma Assert (Str (Len + 1) = ' '); + Str (Len + 1) := '_'; -- Overwrite the space. + Len := Len + S'Length; + end if; + end; + when others => + Has_Hash := True; + Hash_Const (Ctxt, Gen.Val, Gen.Typ); + end case; + else + -- TODO: add a unique number (index) + null; + end if; Gen_Decl := Get_Chain (Gen_Decl); end loop; diff --git a/src/vhdl/vhdl-annotations.adb b/src/vhdl/vhdl-annotations.adb index b1a36646e..13aa8bf3b 100644 --- a/src/vhdl/vhdl-annotations.adb +++ b/src/vhdl/vhdl-annotations.adb @@ -431,7 +431,8 @@ package body Vhdl.Annotations is when Iir_Kind_Protected_Type_Declaration => Annotate_Protected_Type_Declaration (Block_Info, Def); - when Iir_Kind_Incomplete_Type_Definition => + when Iir_Kind_Incomplete_Type_Definition + | Iir_Kind_Subtype_Attribute => null; when Iir_Kind_Foreign_Vector_Type_Definition => @@ -509,8 +510,12 @@ package body Vhdl.Annotations is Create_Object_Info (Block_Info, Decl); when Iir_Kind_Interface_Package_Declaration => Annotate_Interface_Package_Declaration (Block_Info, Decl); - when Iir_Kinds_Interface_Subprogram_Declaration - | Iir_Kind_Interface_Type_Declaration => + when Iir_Kind_Interface_Type_Declaration => + if Flag_Synthesis then + -- Create an info on the interface_type_definition + Create_Object_Info (Block_Info, Get_Type (Decl)); + end if; + when Iir_Kinds_Interface_Subprogram_Declaration => -- Macro-expanded null; when others => diff --git a/src/vhdl/vhdl-configuration.adb b/src/vhdl/vhdl-configuration.adb index aeb737028..64a615bfb 100644 --- a/src/vhdl/vhdl-configuration.adb +++ b/src/vhdl/vhdl-configuration.adb @@ -27,6 +27,7 @@ with Vhdl.Sem_Scopes; with Vhdl.Sem_Lib; use Vhdl.Sem_Lib; with Vhdl.Canon; with Vhdl.Evaluation; +with Vhdl.Scanner; package body Vhdl.Configuration is procedure Add_Design_Concurrent_Stmts (Parent : Iir); @@ -1167,7 +1168,7 @@ package body Vhdl.Configuration is end Find_Top_Entity; type Override_Entry is record - Gen : Name_Id; + Gen : String_Acc; Value : String_Acc; end record; @@ -1177,9 +1178,9 @@ package body Vhdl.Configuration is Table_Low_Bound => 1, Table_Initial => 16); - procedure Add_Generic_Override (Id : Name_Id; Value : String) is + procedure Add_Generic_Override (Name : String; Value : String) is begin - Override_Table.Append (Override_Entry'(Gen => Id, + Override_Table.Append (Override_Entry'(Gen => new String'(Name), Value => new String'(Value))); end Add_Generic_Override; @@ -1325,29 +1326,57 @@ package body Vhdl.Configuration is procedure Apply_Generic_Override (Ent : Iir) is - Inter_Chain : constant Iir := Get_Generic_Chain (Ent); - Inter : Iir; begin for I in Override_Table.First .. Override_Table.Last loop declare Over : constant Override_Entry := Override_Table.Table (I); begin - Inter := Inter_Chain; - while Inter /= Null_Iir loop - exit when Get_Identifier (Inter) = Over.Gen; - Inter := Get_Chain (Inter); - end loop; + case Get_Kind (Ent) is + when Iir_Kind_Entity_Declaration => + declare + Inter_Chain : constant Iir := Get_Generic_Chain (Ent); + Gen_Name : String := Over.Gen.all; + Gen_Id : Name_Id; + Inter : Iir; + Err : Boolean; + begin + Vhdl.Scanner.Convert_Identifier (Gen_Name, Err); + if Err then + Error_Msg_Option + ("incorrect name in generic override option"); + Gen_Id := Null_Identifier; + else + Gen_Id := Name_Table.Get_Identifier (Gen_Name); - if Inter = Null_Iir then - Error_Msg_Elab ("no generic %i for -g", +Over.Gen); - elsif Get_Kind (Inter) /= Iir_Kind_Interface_Constant_Declaration - then - Error_Msg_Elab - ("generic %n cannot be overriden (not a constant)", - +Over.Gen); - else - Override_Generic (Inter, Over.Value); - end if; + Inter := Inter_Chain; + while Inter /= Null_Iir loop + exit when Get_Identifier (Inter) = Gen_Id; + Inter := Get_Chain (Inter); + end loop; + end if; + + if Gen_Id = Null_Identifier then + -- Skip it + null; + elsif Inter = Null_Iir then + Error_Msg_Elab ("no generic %i for -g", +Gen_Id); + elsif (Get_Kind (Inter) + /= Iir_Kind_Interface_Constant_Declaration) + then + -- Could be a generic package, a generic type... + Error_Msg_Elab + ("generic %n cannot be overriden (not a constant)", + +Gen_Id); + else + Override_Generic (Inter, Over.Value); + end if; + end; + when Iir_Kind_Foreign_Module => + Apply_Foreign_Override + (Get_Foreign_Node (Ent), Over.Gen.all, Over.Value.all); + when others => + raise Internal_Error; + end case; end; end loop; end Apply_Generic_Override; diff --git a/src/vhdl/vhdl-configuration.ads b/src/vhdl/vhdl-configuration.ads index d272d23e9..dfd59c516 100644 --- a/src/vhdl/vhdl-configuration.ads +++ b/src/vhdl/vhdl-configuration.ads @@ -69,8 +69,12 @@ package Vhdl.Configuration is type Mark_Instantiated_Units_Access is access procedure (N : Int32); Mark_Foreign_Module : Mark_Instantiated_Units_Access; + type Apply_Foreign_Override_Access is access procedure + (Top : Int32; Gen : String; Value : String); + Apply_Foreign_Override : Apply_Foreign_Override_Access; + -- Add an override for generic ID. - procedure Add_Generic_Override (Id : Name_Id; Value : String); + procedure Add_Generic_Override (Name : String; Value : String); -- Apply generic overrides to entity ENT. procedure Apply_Generic_Override (Ent : Iir); diff --git a/src/vhdl/vhdl-sem_expr.adb b/src/vhdl/vhdl-sem_expr.adb index 21e7b2237..04a73071c 100644 --- a/src/vhdl/vhdl-sem_expr.adb +++ b/src/vhdl/vhdl-sem_expr.adb @@ -4767,7 +4767,8 @@ package body Vhdl.Sem_Expr is Obj := Get_Named_Entity (Obj); when Iir_Kinds_Psl_Builtin => return; - when Iir_Kind_Error => + when Iir_Kind_Parenthesis_Name + | Iir_Kind_Error => return; when others => Error_Kind ("check_read", Obj); diff --git a/testsuite/gna/bug0100/name4.vhdl b/testsuite/gna/bug0100/name4.vhdl new file mode 100644 index 000000000..5c88203ad --- /dev/null +++ b/testsuite/gna/bug0100/name4.vhdl @@ -0,0 +1,14 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity name4 is + port (leds_o : std_logic_vector(3 downto 0); + leds_init : std_logic_vector(3 downto 0); + led_init_en : std_logic); +end; + +architecture behav of name4 is +begin + leds_o <= (led_init()); +end behav; + diff --git a/testsuite/gna/bug0100/testsuite.sh b/testsuite/gna/bug0100/testsuite.sh index 2e9d2203e..3733548f3 100755 --- a/testsuite/gna/bug0100/testsuite.sh +++ b/testsuite/gna/bug0100/testsuite.sh @@ -29,6 +29,7 @@ analyze_failure compon.vhdl analyze_failure --force-analysis varcomp.vhdl #analyze_failure --force-analysis name1.vhdl #analyze_failure --force-analysis name2.vhdl +analyze_failure --force-analysis name4.vhdl analyze_failure --force-analysis inst2.vhdl if analyze_failure --force-analysis notype1.vhdl 2>&1 | grep -q "indexed name"; then diff --git a/testsuite/synth/issue412/generic_pkg.vhdl b/testsuite/synth/issue412/generic_pkg.vhdl new file mode 100644 index 000000000..3a97c2961 --- /dev/null +++ b/testsuite/synth/issue412/generic_pkg.vhdl @@ -0,0 +1,42 @@ +-- package containing a type-generic D Flip Flop +-- may not be 100% valid VHDL code, contact ktbarrett on gitter +-- non-generic version does synthesize correctly +package generic_pkg is + + procedure generic_FF + generic ( + constant T: type) + paramater ( + signal q : out T; + signal d : in T; + signal clk : in std_logic; + signal rst : in std_logic; + constant INIT : in T; + signal en : in std_logic := '1'); + +end package generic_pkg; + +package body generic_pkg is + + procedure generic_FF + generic ( + constant T: type) + paramater ( + signal q : out T; + signal d : in T; + signal clk : in std_logic; + signal rst : in std_logic; + constant INIT : in T; + signal en : in std_logic := '1') + is + begin + if (rising_edge(clk)) then + if (rst /= '0') then + q <= INIT; + elsif (en = '1') then + q <= d; + end if; + end if; + end procedure generic_FF; + +end package body generic_pkg; diff --git a/testsuite/synth/issue412/generic_sfifo-orig.vhdl b/testsuite/synth/issue412/generic_sfifo-orig.vhdl new file mode 100644 index 000000000..d1ea90685 --- /dev/null +++ b/testsuite/synth/issue412/generic_sfifo-orig.vhdl @@ -0,0 +1,88 @@ +-- A simple type-generic stream-style synchronous FIFO +-- may not be 100% valid VHDL code, contact ktbarrett on gitter +-- non-generic version does synthesize correctly +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +entity generic_SFIFO is + generic ( + T : type; + MIN_DEPTH : natural); + port ( + clk : in std_ulogic; + rst : in std_ulogic; + data_in : in T; + valid_in : in std_ulogic; + ready_out : out std_ulogic; + data_out : out T; + valid_out : out std_ulogic; + ready_in : in std_ulogic); +end entity generic_SFIFO; + +architecture rtl of generic_SFIFO is + + function clog2 (n: natural) return natural is + variable i : natural; + variable test : natural; + begin + test := 1; + i := 0; + while (test < n) loop + i := i + 1; + test := test * 2; + end loop; + return i; + end function clog2; + + constant ptr_size : natural := clog2(MIN_DEPTH); + constant depth : natural := 2 ** ptr_size; + signal rd_ptr : unsigned(ptr_size downto 0); + signal wr_ptr : unsigned(ptr_size downto 0); + + type ram_type is array(0 to depth - 1) of T; + + signal ram : ram_type; + +begin + + fifo_proc : process (clk) is + + variable next_wr_ptr : wr_ptr'subtype; + variable next_rd_ptr : rd_ptr'subtype; + + begin + + if (rising_edge(clk)) then + if (rst /= '0') then + rd_ptr <= (others => '0'); + wr_ptr <= (others => '0'); + ready_out <= '0'; + valid_out <= '0'; + else + next_wr_ptr := wr_ptr; + next_rd_ptr := rd_ptr; + if ((valid_in='1') and (ready_out='1')) then + ram(to_integer(wr_ptr(wr_ptr'left - 1 downto 0))) <= data_in; + next_wr_ptr := wr_ptr + 1; + end if; + if ((valid_out='1') and (ready_in='1')) then + next_rd_ptr := rd_ptr + 1; + end if; + ready_out <= '0' when + (next_wr_ptr(next_wr_ptr'left) /= next_rd_ptr(next_rd_ptr'left)) and + (next_wr_ptr(next_wr_ptr'left - 1 downto 0) = next_rd_ptr(next_rd_ptr'left - 1 downto 0)) else + '1'; + valid_out <= '0' when + (wr_ptr(wr_ptr'left) = next_rd_ptr(next_rd_ptr'left)) and + (wr_ptr(wr_ptr'left - 1 downto 0) = next_rd_ptr(next_rd_ptr'left - 1 downto 0)) else + '1'; + wr_ptr <= next_wr_ptr; + rd_ptr <= next_rd_ptr; + data_out <= ram(to_integer(next_rd_ptr(next_rd_ptr'left - 1 downto 0))); + end if; + end if; + + end process fifo_proc; + +end architecture rtl; diff --git a/testsuite/synth/issue412/generic_sfifo.vhdl b/testsuite/synth/issue412/generic_sfifo.vhdl new file mode 100644 index 000000000..92e72a970 --- /dev/null +++ b/testsuite/synth/issue412/generic_sfifo.vhdl @@ -0,0 +1,88 @@ +-- A simple type-generic stream-style synchronous FIFO +-- may not be 100% valid VHDL code, contact ktbarrett on gitter +-- non-generic version does synthesize correctly +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +entity generic_SFIFO is + generic ( + type T; + MIN_DEPTH : natural); + port ( + clk : in std_ulogic; + rst : in std_ulogic; + data_in : in T; + valid_in : in std_ulogic; + ready_out : out std_ulogic; -- If true, can accept data + data_out : out T; + valid_out : out std_ulogic; + ready_in : in std_ulogic); -- To consume data +end entity generic_SFIFO; + +architecture rtl of generic_SFIFO is + + function clog2 (n: natural) return natural is + variable i : natural; + variable test : natural; + begin + test := 1; + i := 0; + while (test < n) loop + i := i + 1; + test := test * 2; + end loop; + return i; + end function clog2; + + constant ptr_size : natural := clog2(MIN_DEPTH); + constant depth : natural := 2 ** ptr_size; + signal rd_ptr : unsigned(ptr_size downto 0); + signal wr_ptr : unsigned(ptr_size downto 0); + + type ram_type is array(0 to depth - 1) of T; + + signal ram : ram_type; + +begin + + fifo_proc : process (clk) is + + variable next_wr_ptr : wr_ptr'subtype; + variable next_rd_ptr : rd_ptr'subtype; + + begin + + if (rising_edge(clk)) then + if (rst /= '0') then + rd_ptr <= (others => '0'); + wr_ptr <= (others => '0'); + ready_out <= '0'; + valid_out <= '0'; + else + next_wr_ptr := wr_ptr; + next_rd_ptr := rd_ptr; + if ((valid_in='1') and (ready_out='1')) then + ram(to_integer(wr_ptr(wr_ptr'left - 1 downto 0))) <= data_in; + next_wr_ptr := wr_ptr + 1; + end if; + if ((valid_out='1') and (ready_in='1')) then + next_rd_ptr := rd_ptr + 1; + end if; + ready_out <= '0' when + (next_wr_ptr(next_wr_ptr'left) /= next_rd_ptr(next_rd_ptr'left)) and + (next_wr_ptr(next_wr_ptr'left - 1 downto 0) = next_rd_ptr(next_rd_ptr'left - 1 downto 0)) else + '1'; + valid_out <= '0' when + (wr_ptr(wr_ptr'left) = next_rd_ptr(next_rd_ptr'left)) and + (wr_ptr(wr_ptr'left - 1 downto 0) = next_rd_ptr(next_rd_ptr'left - 1 downto 0)) else + '1'; + wr_ptr <= next_wr_ptr; + rd_ptr <= next_rd_ptr; + data_out <= ram(to_integer(next_rd_ptr(next_rd_ptr'left - 1 downto 0))); + end if; + end if; + + end process fifo_proc; + +end architecture rtl; diff --git a/testsuite/synth/issue412/my_fifo.vhdl b/testsuite/synth/issue412/my_fifo.vhdl new file mode 100644 index 000000000..c06f1a776 --- /dev/null +++ b/testsuite/synth/issue412/my_fifo.vhdl @@ -0,0 +1,31 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity my_FIFO is + port ( + clk : in std_ulogic; + rst : in std_ulogic; + data_in : in std_logic_vector(7 downto 0); + valid_in : in std_ulogic; + ready_out : out std_ulogic; + data_out : out std_logic_vector(7 downto 0); + valid_out : out std_ulogic; + ready_in : in std_ulogic); +end entity my_FIFO; + +architecture behav of my_fifo is +begin + inst: entity work.generic_sfifo + generic map ( + t => std_logic_vector (7 downto 0), + min_depth => 8) + port map ( + clk => clk, + rst => rst, + data_in => data_in, + valid_in => valid_in, + ready_out => ready_out, + data_out => data_out, + valid_out => valid_out, + ready_in => ready_in); +end behav; diff --git a/testsuite/synth/issue412/tb_my_fifo.vhdl b/testsuite/synth/issue412/tb_my_fifo.vhdl new file mode 100644 index 000000000..8f3def0de --- /dev/null +++ b/testsuite/synth/issue412/tb_my_fifo.vhdl @@ -0,0 +1,66 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity tb_my_FIFO is +end; + +architecture behav of tb_my_fifo is + signal clk : std_ulogic; + signal rst : std_ulogic; + signal data_in : std_logic_vector(7 downto 0); + signal valid_in : std_ulogic; + signal ready_out : std_ulogic; + signal data_out : std_logic_vector(7 downto 0); + signal valid_out : std_ulogic; + signal ready_in : std_ulogic; +begin + inst_my_FIFO: entity work.my_FIFO + port map ( + clk => clk, + rst => rst, + data_in => data_in, + valid_in => valid_in, + ready_out => ready_out, + data_out => data_out, + valid_out => valid_out, + ready_in => ready_in); + + process + procedure pulse is + begin + clk <= '0'; + wait for 5 ns; + clk <= '1'; + wait for 5 ns; + end pulse; + begin + rst <= '1'; + valid_in <= '0'; + ready_in <= '0'; + pulse; + + rst <= '0'; + pulse; + + assert valid_out = '0' severity failure; + assert ready_out = '1' severity failure; + + data_in <= x"d5"; + valid_in <= '1'; + pulse; + + valid_in <= '0'; + + -- Need a second cycle to see the data on the outputs. + pulse; + assert valid_out = '1' severity failure; + assert data_out = x"d5" severity failure; + + ready_in <= '1'; + pulse; + assert valid_out = '0' severity failure; + + ready_in <= '0'; + wait; + end process; +end behav; diff --git a/testsuite/synth/issue412/testsuite.sh b/testsuite/synth/issue412/testsuite.sh new file mode 100755 index 000000000..0fe7c9ba9 --- /dev/null +++ b/testsuite/synth/issue412/testsuite.sh @@ -0,0 +1,13 @@ +#! /bin/sh + +. ../../testenv.sh + +GHDL_STD_FLAGS=--std=08 + +synth generic_sfifo.vhdl my_fifo.vhdl -e > syn_my_fifo.vhdl + +analyze syn_my_fifo.vhdl tb_my_fifo.vhdl +elab_simulate tb_my_fifo +clean + +echo "Test successful" |