diff options
author | Tristan Gingold <tgingold@free.fr> | 2022-09-25 07:12:23 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2022-09-25 11:43:32 +0200 |
commit | 8e56ee72b5095412f0de3d358668f41579c1194e (patch) | |
tree | 90728d5165a98068c896a5b6076aad3fe43b3d7f | |
parent | 2991bf61a75b1154fc77862ebe1e5c381b4fb7ba (diff) | |
download | ghdl-8e56ee72b5095412f0de3d358668f41579c1194e.tar.gz ghdl-8e56ee72b5095412f0de3d358668f41579c1194e.tar.bz2 ghdl-8e56ee72b5095412f0de3d358668f41579c1194e.zip |
synth-vhdl_eval: handle vhdl-87 array array concatenation
-rw-r--r-- | src/synth/synth-vhdl_eval.adb | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/src/synth/synth-vhdl_eval.adb b/src/synth/synth-vhdl_eval.adb index 0ce6fcc91..1cb9f0ad1 100644 --- a/src/synth/synth-vhdl_eval.adb +++ b/src/synth/synth-vhdl_eval.adb @@ -18,6 +18,7 @@ with Types; use Types; with Types_Utils; use Types_Utils; +with Flags; with Name_Table; with Grt.Types; use Grt.Types; @@ -593,6 +594,7 @@ package body Synth.Vhdl_Eval is when Iir_Predefined_Array_Array_Concat => declare + use Flags; L_Len : constant Iir_Index32 := Iir_Index32 (Get_Bound_Length (Left.Typ)); R_Len : constant Iir_Index32 := @@ -611,8 +613,35 @@ package body Synth.Vhdl_Eval is -- concatenation is the right operand. return Right; end if; - Bnd := Elab.Vhdl_Types.Create_Bounds_From_Length - (Get_Uarray_Index (Res_Typ).Drange, L_Len + R_Len); + if Vhdl_Std > Vhdl_87 then + Bnd := Elab.Vhdl_Types.Create_Bounds_From_Length + (Get_Uarray_Index (Res_Typ).Drange, L_Len + R_Len); + else + -- LRM87 7.2.3 + -- [...], unless the left operand is a null array, in which + -- case the result of the concatenation is the right + -- operand. + if L_Len = 0 then + return Right; + end if; + + -- LRM87 7.2.3 + -- The left bound of the result is the left operand, [...] + -- + -- LRM87 7.2.3 + -- The direction of the result is the direction of the left + -- operand, [...] + Bnd.Left := Left.Typ.Abound.Left; + Bnd.Dir := Left.Typ.Abound.Dir; + Bnd.Len := Uns32 (L_Len + R_Len); + -- TODO: overflow. + case Bnd.Dir is + when Dir_To => + Bnd.Right := Bnd.Left + Int32 (L_Len + R_Len - 1); + when Dir_Downto => + Bnd.Right := Bnd.Left - Int32 (L_Len + R_Len - 1); + end case; + end if; El_Typ := Unshare_Type_Expr (Le_Typ, Get_Array_Element (Res_Typ)); Res_St := Create_Onedimensional_Array_Subtype |