aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth/synth-expr.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/synth/synth-expr.adb')
-rw-r--r--src/synth/synth-expr.adb113
1 files changed, 75 insertions, 38 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb
index a4837e65b..9ddd906d1 100644
--- a/src/synth/synth-expr.adb
+++ b/src/synth/synth-expr.adb
@@ -31,15 +31,16 @@ with Vhdl.Evaluation; use Vhdl.Evaluation;
with Vhdl.Annotations; use Vhdl.Annotations;
-with Synth.Errors; use Synth.Errors;
-with Synth.Types; use Synth.Types;
-with Synth.Stmts; use Synth.Stmts;
-with Synth.Oper; use Synth.Oper;
-
with Netlists.Gates; use Netlists.Gates;
with Netlists.Builders; use Netlists.Builders;
with Netlists.Locations; use Netlists.Locations;
+with Synth.Types; use Synth.Types;
+with Synth.Errors; use Synth.Errors;
+with Synth.Environment;
+with Synth.Stmts; use Synth.Stmts;
+with Synth.Oper; use Synth.Oper;
+
package body Synth.Expr is
function Synth_Name (Syn_Inst : Synth_Instance_Acc; Name : Node)
return Value_Acc;
@@ -57,6 +58,37 @@ package body Synth.Expr is
end if;
end Set_Location;
+ function Get_Const_Discrete (V : Value_Acc) return Int64
+ is
+ N : Net;
+ Inst : Instance;
+ begin
+ case V.Kind is
+ when Value_Discrete =>
+ return V.Scal;
+ when Value_Net =>
+ N := V.N;
+ when Value_Wire =>
+ N := Synth.Environment.Get_Const_Wire (V.W);
+ when others =>
+ raise Internal_Error;
+ end case;
+ Inst := Get_Net_Parent (N);
+ case Get_Id (Inst) is
+ when Id_Const_UB32 =>
+ declare
+ Va : constant Uns32 := Get_Param_Uns32 (Inst, 0);
+ Wd : constant Natural := Natural (Get_Width (N));
+ T : Uns64;
+ begin
+ T := Shift_Left (Uns64 (Va), 64 - Wd);
+ return To_Int64 (Shift_Right_Arithmetic (T, 64 - Wd));
+ end;
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Get_Const_Discrete;
+
procedure From_Std_Logic (Enum : Int64; Val : out Uns32; Zx : out Uns32) is
begin
case Enum is
@@ -1155,39 +1187,44 @@ package body Synth.Expr is
return;
end if;
- if Is_Const (Left) and then Is_Const (Right) then
- Inp := No_Net;
- Step := 0;
-
- if not In_Bounds (Pfx_Bnd, Int32 (Left.Scal))
- or else not In_Bounds (Pfx_Bnd, Int32 (Right.Scal))
- then
- Error_Msg_Synth (+Name, "index not within bounds");
- Wd := 0;
- Off := 0;
- return;
- end if;
+ if Is_Const_Val (Left) and then Is_Const_Val (Right) then
+ declare
+ L : constant Int64 := Get_Const_Discrete (Left);
+ R : constant Int64 := Get_Const_Discrete (Right);
+ begin
+ Inp := No_Net;
+ Step := 0;
+
+ if not In_Bounds (Pfx_Bnd, Int32 (L))
+ or else not In_Bounds (Pfx_Bnd, Int32 (R))
+ then
+ Error_Msg_Synth (+Name, "index not within bounds");
+ Wd := 0;
+ Off := 0;
+ return;
+ end if;
- case Pfx_Bnd.Dir is
- when Iir_To =>
- Wd := Width (Right.Scal - Left.Scal + 1);
- Res_Bnd := (Dir => Iir_To,
- Wlen => Wd,
- Wbounds => Wd,
- Len => Wd,
- Left => Int32 (Left.Scal),
- Right => Int32 (Right.Scal));
- Off := Pfx_Bnd.Right - Res_Bnd.Right;
- when Iir_Downto =>
- Wd := Width (Left.Scal - Right.Scal + 1);
- Res_Bnd := (Dir => Iir_Downto,
- Wlen => Wd,
- Wbounds => Wd,
- Len => Wd,
- Left => Int32 (Left.Scal),
- Right => Int32 (Right.Scal));
- Off := Res_Bnd.Right - Pfx_Bnd.Right;
- end case;
+ case Pfx_Bnd.Dir is
+ when Iir_To =>
+ Wd := Width (R - L + 1);
+ Res_Bnd := (Dir => Iir_To,
+ Wlen => Wd,
+ Wbounds => Wd,
+ Len => Wd,
+ Left => Int32 (L),
+ Right => Int32 (R));
+ Off := Pfx_Bnd.Right - Res_Bnd.Right;
+ when Iir_Downto =>
+ Wd := Width (L - R + 1);
+ Res_Bnd := (Dir => Iir_Downto,
+ Wlen => Wd,
+ Wbounds => Wd,
+ Len => Wd,
+ Left => Int32 (L),
+ Right => Int32 (R));
+ Off := Res_Bnd.Right - Pfx_Bnd.Right;
+ end case;
+ end;
else
if Is_Const (Left) or else Is_Const (Right) then
Error_Msg_Synth
@@ -1339,7 +1376,7 @@ package body Synth.Expr is
Val := Synth_Expression (Syn_Inst, Expr);
case Get_Kind (Conv_Type) is
when Iir_Kind_Integer_Subtype_Definition =>
- if Is_Float (Val) then
+ if Val.Typ.Kind = Type_Float then
return Create_Value_Discrete
(Int64 (Val.Fp), Get_Value_Type (Syn_Inst, Conv_Type));
else