From 8af64459f397e5037dd7e25317491edad39d8006 Mon Sep 17 00:00:00 2001
From: Tristan Gingold <tgingold@free.fr>
Date: Sat, 7 Mar 2015 07:30:07 +0100
Subject: Implement ticket 37: add switch -gNAME=VAL to override top entity
 generics.

---
 src/grt/grt-avhpi.adb               |   3 +-
 src/grt/grt-avhpi_utils.adb         |  65 +++++++++++
 src/grt/grt-avhpi_utils.ads         |  38 +++++++
 src/grt/grt-change_generics.adb     | 207 ++++++++++++++++++++++++++++++++++++
 src/grt/grt-change_generics.ads     |  29 +++++
 src/grt/grt-main.adb                |   3 +-
 src/grt/grt-options.adb             |  46 ++++++++
 src/grt/grt-options.ads             |  18 ++++
 src/grt/grt-values.adb              |   2 +-
 src/grt/grt-vital_annotate.adb      |  36 +------
 testsuite/gna/ticket37/dispgen.vhdl |   8 ++
 testsuite/gna/ticket37/testsuite.sh |  12 +++
 12 files changed, 430 insertions(+), 37 deletions(-)
 create mode 100644 src/grt/grt-avhpi_utils.adb
 create mode 100644 src/grt/grt-avhpi_utils.ads
 create mode 100644 src/grt/grt-change_generics.adb
 create mode 100644 src/grt/grt-change_generics.ads
 create mode 100644 testsuite/gna/ticket37/dispgen.vhdl
 create mode 100755 testsuite/gna/ticket37/testsuite.sh

diff --git a/src/grt/grt-avhpi.adb b/src/grt/grt-avhpi.adb
index af2dc1b05..535cb0ad3 100644
--- a/src/grt/grt-avhpi.adb
+++ b/src/grt/grt-avhpi.adb
@@ -1166,7 +1166,8 @@ package body Grt.Avhpi is
            | VhpiEnumTypeDeclK =>
             return Obj.Atype;
          when VhpiSigDeclK
-           | VhpiPortDeclK =>
+           | VhpiPortDeclK
+           | VhpiGenericDeclK =>
             return To_Ghdl_Rti_Access (Obj.Obj);
          when others =>
             return null;
diff --git a/src/grt/grt-avhpi_utils.adb b/src/grt/grt-avhpi_utils.adb
new file mode 100644
index 000000000..6fedf1b4c
--- /dev/null
+++ b/src/grt/grt-avhpi_utils.adb
@@ -0,0 +1,65 @@
+--  GHDL Run Time (GRT) - Utility functions for AVHPI.
+--  Copyright (C) 2015 Tristan Gingold
+--
+--  GHDL is free software; you can redistribute it and/or modify it under
+--  the terms of the GNU General Public License as published by the Free
+--  Software Foundation; either version 2, or (at your option) any later
+--  version.
+--
+--  GHDL is distributed in the hope that it will be useful, but WITHOUT ANY
+--  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+--  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+--  for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with GCC; see the file COPYING.  If not, write to the Free
+--  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+--  02111-1307, USA.
+--
+--  As a special exception, if other files instantiate generics from this
+--  unit, or you link this unit with other files to produce an executable,
+--  this unit does not by itself cause the resulting executable to be
+--  covered by the GNU General Public License. This exception does not
+--  however invalidate any other reasons why the executable file might be
+--  covered by the GNU Public License.
+
+with Grt.Errors; use Grt.Errors;
+
+package body Grt.Avhpi_Utils is
+   function Get_Root_Entity (Root : VhpiHandleT) return VhpiHandleT
+   is
+      Hdl : VhpiHandleT;
+      Error : AvhpiErrorT;
+   begin
+      Vhpi_Handle (VhpiDesignUnit, Root, Hdl, Error);
+      if Error /= AvhpiErrorOk then
+         Internal_Error ("VhpiDesignUnit");
+      end if;
+
+      case Vhpi_Get_Kind (Hdl) is
+         when VhpiArchBodyK =>
+            Vhpi_Handle (VhpiPrimaryUnit, Hdl, Hdl, Error);
+            if Error /= AvhpiErrorOk then
+               Internal_Error ("VhpiPrimaryUnit");
+            end if;
+         when others =>
+            Internal_Error ("get_root_entity");
+      end case;
+      return Hdl;
+   end Get_Root_Entity;
+
+   function Name_Compare (Handle : VhpiHandleT;
+                          Name : String;
+                          Property : VhpiStrPropertyT := VhpiNameP)
+                         return Boolean
+   is
+      Obj_Name : String (1 .. Name'Length);
+      Len : Natural;
+   begin
+      Vhpi_Get_Str (Property, Handle, Obj_Name, Len);
+      return Len = Name'Length and then Obj_Name = Name;
+   end Name_Compare;
+
+end Grt.Avhpi_Utils;
+
+
diff --git a/src/grt/grt-avhpi_utils.ads b/src/grt/grt-avhpi_utils.ads
new file mode 100644
index 000000000..d16b9c2d3
--- /dev/null
+++ b/src/grt/grt-avhpi_utils.ads
@@ -0,0 +1,38 @@
+--  GHDL Run Time (GRT) - Utility functions for AVHPI.
+--  Copyright (C) 2015 Tristan Gingold
+--
+--  GHDL is free software; you can redistribute it and/or modify it under
+--  the terms of the GNU General Public License as published by the Free
+--  Software Foundation; either version 2, or (at your option) any later
+--  version.
+--
+--  GHDL is distributed in the hope that it will be useful, but WITHOUT ANY
+--  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+--  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+--  for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with GCC; see the file COPYING.  If not, write to the Free
+--  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+--  02111-1307, USA.
+--
+--  As a special exception, if other files instantiate generics from this
+--  unit, or you link this unit with other files to produce an executable,
+--  this unit does not by itself cause the resulting executable to be
+--  covered by the GNU General Public License. This exception does not
+--  however invalidate any other reasons why the executable file might be
+--  covered by the GNU Public License.
+
+with Grt.Avhpi; use Grt.Avhpi;
+
+package Grt.Avhpi_Utils is
+   function Get_Root_Entity (Root : VhpiHandleT) return VhpiHandleT;
+
+   --  Return TRUE if name of HANDLE (using PROPERTY) is NAME.
+   function Name_Compare (Handle : VhpiHandleT;
+                          Name : String;
+                          Property : VhpiStrPropertyT := VhpiNameP)
+                         return Boolean;
+end Grt.Avhpi_Utils;
+
+
diff --git a/src/grt/grt-change_generics.adb b/src/grt/grt-change_generics.adb
new file mode 100644
index 000000000..bbec5e47f
--- /dev/null
+++ b/src/grt/grt-change_generics.adb
@@ -0,0 +1,207 @@
+--  GHDL Run Time (GRT) - Override top entity generics
+--  Copyright (C) 2015 Tristan Gingold
+--
+--  GHDL is free software; you can redistribute it and/or modify it under
+--  the terms of the GNU General Public License as published by the Free
+--  Software Foundation; either version 2, or (at your option) any later
+--  version.
+--
+--  GHDL is distributed in the hope that it will be useful, but WITHOUT ANY
+--  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+--  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+--  for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with GCC; see the file COPYING.  If not, write to the Free
+--  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+--  02111-1307, USA.
+--
+--  As a special exception, if other files instantiate generics from this
+--  unit, or you link this unit with other files to produce an executable,
+--  this unit does not by itself cause the resulting executable to be
+--  covered by the GNU General Public License. This exception does not
+--  however invalidate any other reasons why the executable file might be
+--  covered by the GNU Public License.
+
+with Grt.Types; use Grt.Types;
+with Grt.Lib; use Grt.Lib;
+with Grt.Options; use Grt.Options;
+with Grt.Avhpi; use Grt.Avhpi;
+with Grt.Avhpi_Utils; use Grt.Avhpi_Utils;
+with Grt.Errors; use Grt.Errors;
+with Grt.Rtis; use Grt.Rtis;
+with Grt.Rtis_Addr; use Grt.Rtis_Addr;
+
+package body Grt.Change_Generics is
+   procedure Error_Override (Msg : String; Over : Generic_Override_Acc) is
+   begin
+      Error_C (Msg);
+      Error_E (" '");
+      Error_C (Over.Name.all);
+      Error_E ("'");
+   end Error_Override;
+
+   --  Convert C to E8 values
+   procedure Ghdl_Value_E8_Char (Res : out Ghdl_E8;
+                                 Err : out Boolean;
+                                 C : Character;
+                                 Rti : Ghdl_Rti_Access)
+   is
+      Enum_Rti : constant Ghdl_Rtin_Type_Enum_Acc :=
+        To_Ghdl_Rtin_Type_Enum_Acc (Rti);
+      Lit_Name : Ghdl_C_String;
+   begin
+      for I in 0 .. Enum_Rti.Nbr - 1 loop
+         Lit_Name := Enum_Rti.Names (I);
+         if Lit_Name (1) = ''' and Lit_Name (2) = C and Lit_Name (3) = ''' then
+            Res := Ghdl_E8 (I);
+            Err := False;
+            return;
+         end if;
+      end loop;
+      Res := 0;
+      Err := True;
+   end Ghdl_Value_E8_Char;
+
+   --  Override for unconstrained array generic.
+   procedure Override_Generic_Array (Obj_Rti : Ghdl_Rtin_Object_Acc;
+                                     Ctxt : Rti_Context;
+                                     Over : Generic_Override_Acc)
+   is
+      Type_Rti : constant Ghdl_Rtin_Type_Array_Acc :=
+        To_Ghdl_Rtin_Type_Array_Acc (Obj_Rti.Obj_Type);
+      El_Rti : constant Ghdl_Rti_Access := Type_Rti.Element;
+      Idx_Rti : constant Ghdl_Rti_Access := Type_Rti.Indexes (0);
+      Idx_Base_Rti : Ghdl_Rti_Access;
+      St_Rng, Rng : Ghdl_Range_Ptr;
+      Arr : Ghdl_E8_Array_Base_Ptr;
+      Err : Boolean;
+      Len : Ghdl_Index_Type;
+      Uc_Array : Ghdl_Uc_Array_Acc;
+   begin
+      --  Check array type:
+      --  - Must be one dimension
+      if Type_Rti.Nbr_Dim /= 1 then
+         Error_Override ("multi-dimension array not supported for "
+                           & "override of generic", Over);
+         return;
+      end if;
+      --  - Index must be a scalar integer
+      if Idx_Rti.Kind /= Ghdl_Rtik_Subtype_Scalar then
+         Internal_Error ("override_generic_array");
+      end if;
+      Idx_Base_Rti := To_Ghdl_Rtin_Subtype_Scalar_Acc (Idx_Rti).Basetype;
+      if Idx_Base_Rti.Kind /= Ghdl_Rtik_Type_I32 then
+         Error_Override ("non Integer array index not supported for "
+                           & "override of generic", Over);
+         return;
+      end if;
+      --  - Element must be E8 enum.
+      if El_Rti.Kind /= Ghdl_Rtik_Type_E8 then
+         Error_Override ("non enumerated element type not supported for "
+                           & "override of generic", Over);
+         return;
+      end if;
+
+      --  The real work can start.
+      St_Rng := To_Ghdl_Range_Ptr
+        (Loc_To_Addr (Idx_Rti.Depth,
+                      To_Ghdl_Rtin_Subtype_Scalar_Acc (Idx_Rti).Range_Loc,
+                      Ctxt));
+
+      --  Create the value.
+      Len := Over.Value'Length;
+      Arr := To_Ghdl_E8_Array_Base_Ptr (Ghdl_Malloc (Len));
+      for I in Over.Value'range loop
+         Ghdl_Value_E8_Char (Arr (Ghdl_Index_Type (I - Over.Value'First)), Err,
+                             Over.Value (I), El_Rti);
+         if Err then
+            Error_Override ("invalid character for override of generic", Over);
+            return;
+         end if;
+      end loop;
+
+      --  Create the range.
+      Rng := new Ghdl_Range_Type (Mode_I32);
+      Rng.I32.Left := St_Rng.I32.Left;
+      Rng.I32.Dir := St_Rng.I32.Dir;
+      case Rng.I32.Dir is
+         when Dir_To =>
+            Rng.I32.Right := Rng.I32.Left + Ghdl_I32 (Len - 1);
+         when Dir_Downto =>
+            Rng.I32.Right := Rng.I32.Left - Ghdl_I32 (Len - 1);
+      end case;
+      Rng.I32.Len := Len;
+
+      --  Override the generic.  Don't try to free previous value as it may
+      --  not have been dynamically allocated.
+      Uc_Array := To_Ghdl_Uc_Array_Acc
+        (Loc_To_Addr (Obj_Rti.Common.Depth, Obj_Rti.Loc, Ctxt));
+      Uc_Array.all := (Base => Arr (0)'Address,
+                       Bounds => Rng.all'Address);
+   end Override_Generic_Array;
+
+   --  Override DECL with OVER.  Dispatch according to generic type.
+   procedure Override_Generic_Value (Decl : VhpiHandleT;
+                                     Over : Generic_Override_Acc)
+   is
+      Rti : constant Ghdl_Rti_Access := Avhpi_Get_Rti (Decl);
+      Obj_Rti : constant Ghdl_Rtin_Object_Acc :=
+        To_Ghdl_Rtin_Object_Acc (Rti);
+      Type_Rti : constant Ghdl_Rti_Access := Obj_Rti.Obj_Type;
+      Ctxt : constant Rti_Context := Avhpi_Get_Context (Decl);
+   begin
+      pragma Assert (Rti.Kind = Ghdl_Rtik_Generic);
+      case Type_Rti.Kind is
+         when Ghdl_Rtik_Type_Array =>
+            Override_Generic_Array (Obj_Rti, Ctxt, Over);
+         when others =>
+            Error_Override ("unhandled type for generic override of", Over);
+      end case;
+   end Override_Generic_Value;
+
+   --  Handle generic override OVER.  Find the generic declaration.
+   procedure Override_Generic (Over : Generic_Override_Acc)
+   is
+      Root, It, Decl : VhpiHandleT;
+      Error : AvhpiErrorT;
+   begin
+      Get_Root_Inst (Root);
+
+      --  Find generic.
+      Vhpi_Iterator (VhpiDecls, Root, It, Error);
+      if Error /= AvhpiErrorOk then
+         Internal_Error ("override_generic(1)");
+         return;
+      end if;
+
+      --  Look for the generic.
+      loop
+         Vhpi_Scan (It, Decl, Error);
+         exit when Error = AvhpiErrorIteratorEnd;
+         if Error /= AvhpiErrorOk then
+            Internal_Error ("override_generic(2)");
+            return;
+         end if;
+         exit when Vhpi_Get_Kind (Decl) /= VhpiGenericDeclK;
+         if Name_Compare (Decl, Over.Name.all) then
+            Override_Generic_Value (Decl, Over);
+            return;
+         end if;
+      end loop;
+
+      Error_Override ("cannot find in top entity generic", Over);
+   end Override_Generic;
+
+   procedure Change_All_Generics
+   is
+      Over : Generic_Override_Acc;
+   begin
+      --  Handle overrides one by one (in order).
+      Over := First_Generic_Override;
+      while Over /= null loop
+         Override_Generic (Over);
+         Over := Over.Next;
+      end loop;
+   end Change_All_Generics;
+end Grt.Change_Generics;
diff --git a/src/grt/grt-change_generics.ads b/src/grt/grt-change_generics.ads
new file mode 100644
index 000000000..e3439b47b
--- /dev/null
+++ b/src/grt/grt-change_generics.ads
@@ -0,0 +1,29 @@
+--  GHDL Run Time (GRT) - Override top entity generics
+--  Copyright (C) 2015 Tristan Gingold
+--
+--  GHDL is free software; you can redistribute it and/or modify it under
+--  the terms of the GNU General Public License as published by the Free
+--  Software Foundation; either version 2, or (at your option) any later
+--  version.
+--
+--  GHDL is distributed in the hope that it will be useful, but WITHOUT ANY
+--  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+--  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+--  for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with GCC; see the file COPYING.  If not, write to the Free
+--  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+--  02111-1307, USA.
+--
+--  As a special exception, if other files instantiate generics from this
+--  unit, or you link this unit with other files to produce an executable,
+--  this unit does not by itself cause the resulting executable to be
+--  covered by the GNU General Public License. This exception does not
+--  however invalidate any other reasons why the executable file might be
+--  covered by the GNU Public License.
+
+package Grt.Change_Generics is
+   --  Override top entity generics, using Generic_Override list from Options.
+   procedure Change_All_Generics;
+end Grt.Change_Generics;
diff --git a/src/grt/grt-main.adb b/src/grt/grt-main.adb
index 32547774b..ad21a245a 100644
--- a/src/grt/grt-main.adb
+++ b/src/grt/grt-main.adb
@@ -35,6 +35,7 @@ with Grt.Hooks;
 with Grt.Disp_Signals;
 with Grt.Disp;
 with Grt.Modules;
+with Grt.Change_Generics;
 
 --  The following packages are not referenced in this package.
 --  These are subprograms called only from GHDL generated code.
@@ -62,7 +63,7 @@ package body Grt.Main is
 
    procedure Ghdl_Init_Top_Generics is
    begin
-      null;
+      Grt.Change_Generics.Change_All_Generics;
    end Ghdl_Init_Top_Generics;
 
    procedure Disp_Stats_Hook (Code : Integer);
diff --git a/src/grt/grt-options.adb b/src/grt/grt-options.adb
index df1eb4ec8..f3b9e8cdb 100644
--- a/src/grt/grt-options.adb
+++ b/src/grt/grt-options.adb
@@ -470,6 +470,52 @@ package body Grt.Options is
                Nbr_Threads := Integer (Val);
             end if;
          end;
+      elsif Len > 4 and then Option (1 .. 2) = "-g" then
+         if Option (3) = '=' then
+            Error_C ("missing generic name in '");
+            Error_C (Option);
+            Error_E ("'");
+            return;
+         end if;
+         declare
+            Eq_Pos : Natural;
+            Over : Generic_Override_Acc;
+            Name : String_Access;
+         begin
+            if Option (3) = '\' then
+               --  Extended identifier (not yet handled).
+               raise Program_Error;
+            else
+               --  Search for '='.
+               Eq_Pos := 0;
+               for I in 3 .. Option'Last loop
+                  if Option (I) = '=' then
+                     Eq_Pos := I;
+                     exit;
+                  end if;
+               end loop;
+               if Eq_Pos = 0 then
+                  Error_C ("missing '=' after generic name in '");
+                  Error_C (Option);
+                  Error_E ("'");
+               end if;
+               Name := new String (1 .. Eq_Pos - 3);
+               for I in 3 .. Eq_Pos - 1 loop
+                  Name (I - 2) := To_Lower (Option (I));
+               end loop;
+            end if;
+            Over := new Generic_Override_Type'
+              (Name => Name,
+               Value => new String'(Option (Eq_Pos + 1 .. Option'Last)),
+               Next => null);
+            --  Append.
+            if Last_Generic_Override /= null then
+               Last_Generic_Override.Next := Over;
+            else
+               First_Generic_Override := Over;
+            end if;
+            Last_Generic_Override := Over;
+         end;
       elsif not Grt.Hooks.Call_Option_Hooks (Option) then
          Error_C ("unknown option '");
          Error_C (Option);
diff --git a/src/grt/grt-options.ads b/src/grt/grt-options.ads
index 88b1f5084..eaf3d022d 100644
--- a/src/grt/grt-options.ads
+++ b/src/grt/grt-options.ads
@@ -147,6 +147,24 @@ package Grt.Options is
    --  Set the time resolution.
    --  Only call this subprogram if you are allowed to set the time resolution.
    procedure Set_Time_Resolution (Res : Character);
+
+   --  Simply linked list of generic override (option -gIDENT=VALUE).
+   type Generic_Override_Type;
+   type Generic_Override_Acc is access Generic_Override_Type;
+
+   type Generic_Override_Type is record
+      --  Name of the generic (lower case).
+      Name : String_Access;
+
+      --  Value.
+      Value : String_Access;
+
+      --  Simply linked list.
+      Next : Generic_Override_Acc;
+   end record;
+
+   First_Generic_Override : Generic_Override_Acc;
+   Last_Generic_Override : Generic_Override_Acc;
 private
    pragma Export (C, Stack_Size);
    pragma Export (C, Stack_Max_Size);
diff --git a/src/grt/grt-values.adb b/src/grt/grt-values.adb
index 3d703bc85..2454e175e 100644
--- a/src/grt/grt-values.adb
+++ b/src/grt/grt-values.adb
@@ -61,7 +61,7 @@ package body Grt.Values is
    --  Convert C to lowercase.
    function To_LC (C : in Character) return Character is
    begin
-      if C >= 'A' and then C <= 'Z' then
+      if C in 'A' .. 'Z' then
          return Character'Val
            (Character'Pos (C) + Character'Pos ('a') - Character'Pos ('A'));
       else
diff --git a/src/grt/grt-vital_annotate.adb b/src/grt/grt-vital_annotate.adb
index 3ff089087..1b5ae471a 100644
--- a/src/grt/grt-vital_annotate.adb
+++ b/src/grt/grt-vital_annotate.adb
@@ -28,6 +28,7 @@ with Grt.Astdio; use Grt.Astdio;
 with Grt.Stdio; use Grt.Stdio;
 with Grt.Options;
 with Grt.Avhpi; use Grt.Avhpi;
+with Grt.Avhpi_Utils; use Grt.Avhpi_Utils;
 with Grt.Errors; use Grt.Errors;
 
 package body Grt.Vital_Annotate is
@@ -40,22 +41,6 @@ package body Grt.Vital_Annotate is
    Flag_Dump : Boolean := False;
    Flag_Verbose : constant Boolean := False;
 
-   function Name_Compare (Handle : VhpiHandleT;
-                          Name : String;
-                          Property : VhpiStrPropertyT := VhpiNameP)
-                         return Boolean
-   is
-      Obj_Name : String (1 .. Name'Length);
-      Len : Natural;
-   begin
-      Vhpi_Get_Str (Property, Handle, Obj_Name, Len);
-      if Len = Name'Length and then Obj_Name = Name then
-         return True;
-      else
-         return False;
-      end if;
-   end Name_Compare;
-
    --  Note: RES may alias CUR.
    procedure Find_Instance (Cur : VhpiHandleT;
                             Res : out VhpiHandleT;
@@ -204,24 +189,8 @@ package body Grt.Vital_Annotate is
          when VhpiRootInstK =>
             declare
                Hdl : VhpiHandleT;
-               Error : AvhpiErrorT;
             begin
-               Status := False;
-               Vhpi_Handle (VhpiDesignUnit, Sdf_Inst, Hdl, Error);
-               if Error /= AvhpiErrorOk then
-                  Internal_Error ("VhpiDesignUnit");
-                  return;
-               end if;
-               case Vhpi_Get_Kind (Hdl) is
-                  when VhpiArchBodyK =>
-                     Vhpi_Handle (VhpiPrimaryUnit, Hdl, Hdl, Error);
-                     if Error /= AvhpiErrorOk then
-                        Internal_Error ("VhpiPrimaryUnit");
-                        return;
-                     end if;
-                  when others =>
-                     Internal_Error ("sdf_instance_end");
-               end case;
+               Hdl := Get_Root_Entity (Sdf_Inst);
                Status := Name_Compare
                  (Hdl, Context.Celltype (1 .. Context.Celltype_Len));
             end;
@@ -483,7 +452,6 @@ package body Grt.Vital_Annotate is
       end if;
    end Sdf_Generic;
 
-
    procedure Annotate (Arg : String)
    is
       S, E : Natural;
diff --git a/testsuite/gna/ticket37/dispgen.vhdl b/testsuite/gna/ticket37/dispgen.vhdl
new file mode 100644
index 000000000..73dd48619
--- /dev/null
+++ b/testsuite/gna/ticket37/dispgen.vhdl
@@ -0,0 +1,8 @@
+entity dispgen is
+  generic (str : string := "init");
+end dispgen;
+
+architecture behav of dispgen is
+begin
+  assert false report "str: " & str severity note;
+end behav;
diff --git a/testsuite/gna/ticket37/testsuite.sh b/testsuite/gna/ticket37/testsuite.sh
new file mode 100755
index 000000000..ea51e5c79
--- /dev/null
+++ b/testsuite/gna/ticket37/testsuite.sh
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+. ../../testenv.sh
+
+analyze dispgen.vhdl
+elab_simulate dispgen
+
+elab_simulate dispgen -gstr=Hello
+
+clean
+
+echo "Test successful"
-- 
cgit v1.2.3