aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth/synth-oper.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/synth/synth-oper.adb')
-rw-r--r--src/synth/synth-oper.adb352
1 files changed, 179 insertions, 173 deletions
diff --git a/src/synth/synth-oper.adb b/src/synth/synth-oper.adb
index e3fd0c714..8efaca0c3 100644
--- a/src/synth/synth-oper.adb
+++ b/src/synth/synth-oper.adb
@@ -245,6 +245,114 @@ package body Synth.Oper is
return Res;
end Synth_Match;
+ -- Note: LEFT or RIGHT can be a single bit.
+ function Synth_Dyadic_Uns_Uns
+ (Id : Dyadic_Module_Id; Left, Right : Value_Acc; Expr : Node)
+ return Value_Acc
+ is
+ W : constant Width := Width'Max (Left.Typ.W, Right.Typ.W);
+ El_Typ : Type_Acc;
+ Rtype : Type_Acc;
+ L1, R1 : Net;
+ N : Net;
+ begin
+ if Left.Typ.Kind = Type_Vector then
+ El_Typ := Left.Typ.Vec_El;
+ elsif Right.Typ.Kind = Type_Vector then
+ El_Typ := Right.Typ.Vec_El;
+ else
+ raise Internal_Error;
+ end if;
+ Rtype := Create_Vec_Type_By_Length (W, El_Typ);
+ L1 := Synth_Uresize (Left, W, Expr);
+ R1 := Synth_Uresize (Right, W, Expr);
+ N := Build_Dyadic (Build_Context, Id, L1, R1);
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Rtype);
+ end Synth_Dyadic_Uns_Uns;
+
+ function Synth_Dyadic_Uns_Nat
+ (Id : Dyadic_Module_Id; Left, Right : Value_Acc; Expr : Node)
+ return Value_Acc
+ is
+ L : constant Net := Get_Net (Left);
+ R1 : Net;
+ N : Net;
+ begin
+ R1 := Synth_Uresize (Right, Left.Typ.W, Expr);
+ N := Build_Dyadic (Build_Context, Id, L, R1);
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Create_Res_Bound (Left));
+ end Synth_Dyadic_Uns_Nat;
+
+ function Synth_Dyadic_Nat_Uns
+ (Id : Dyadic_Module_Id; Left, Right : Value_Acc; Expr : Node)
+ return Value_Acc
+ is
+ R : constant Net := Get_Net (Right);
+ L1 : Net;
+ N : Net;
+ begin
+ L1 := Synth_Uresize (Left, Right.Typ.W, Expr);
+ N := Build_Dyadic (Build_Context, Id, L1, R);
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Create_Res_Bound (Right));
+ end Synth_Dyadic_Nat_Uns;
+
+ -- Note: LEFT or RIGHT can be a single bit.
+ function Synth_Dyadic_Sgn_Sgn
+ (Id : Dyadic_Module_Id; Left, Right : Value_Acc; Expr : Node)
+ return Value_Acc
+ is
+ W : constant Width := Width'Max (Left.Typ.W, Right.Typ.W);
+ El_Typ : Type_Acc;
+ Rtype : Type_Acc;
+ L1, R1 : Net;
+ N : Net;
+ begin
+ if Left.Typ.Kind = Type_Vector then
+ El_Typ := Left.Typ.Vec_El;
+ elsif Right.Typ.Kind = Type_Vector then
+ El_Typ := Right.Typ.Vec_El;
+ else
+ raise Internal_Error;
+ end if;
+ Rtype := Create_Vec_Type_By_Length (W, El_Typ);
+ L1 := Synth_Sresize (Left, W, Expr);
+ R1 := Synth_Sresize (Right, W, Expr);
+ N := Build_Dyadic (Build_Context, Id, L1, R1);
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Rtype);
+ end Synth_Dyadic_Sgn_Sgn;
+
+ function Synth_Dyadic_Sgn_Int
+ (Id : Dyadic_Module_Id; Left, Right : Value_Acc; Expr : Node)
+ return Value_Acc
+ is
+ L : constant Net := Get_Net (Left);
+ R1 : Net;
+ N : Net;
+ begin
+ R1 := Synth_Sresize (Right, Left.Typ.W, Expr);
+ N := Build_Dyadic (Build_Context, Id, L, R1);
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Create_Res_Bound (Left));
+ end Synth_Dyadic_Sgn_Int;
+
+ function Synth_Dyadic_Int_Sgn
+ (Id : Dyadic_Module_Id; Left, Right : Value_Acc; Expr : Node)
+ return Value_Acc
+ is
+ R : constant Net := Get_Net (Right);
+ L1 : Net;
+ N : Net;
+ begin
+ L1 := Synth_Sresize (Left, Right.Typ.W, Expr);
+ N := Build_Dyadic (Build_Context, Id, R, L1);
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Create_Res_Bound (Right));
+ end Synth_Dyadic_Int_Sgn;
+
function Synth_Dyadic_Operation (Syn_Inst : Synth_Instance_Acc;
Imp : Node;
Left_Expr : Node;
@@ -394,57 +502,6 @@ package body Synth.Oper is
return Create_Value_Net (N, Etype);
end Synth_Int_Dyadic;
- function Synth_Dyadic_Uns (Id : Dyadic_Module_Id; Is_Res_Vec : Boolean)
- return Value_Acc
- is
- W : constant Width := Width'Max (Left.Typ.W, Right.Typ.W);
- El_Typ : Type_Acc;
- Rtype : Type_Acc;
- L1, R1 : Net;
- N : Net;
- begin
- if Is_Res_Vec then
- if Left.Typ.Kind = Type_Vector then
- El_Typ := Left.Typ.Vec_El;
- elsif Right.Typ.Kind = Type_Vector then
- El_Typ := Right.Typ.Vec_El;
- else
- raise Internal_Error;
- end if;
- Rtype := Create_Vec_Type_By_Length (W, El_Typ);
- else
- Rtype := Left.Typ;
- end if;
- L1 := Synth_Uresize (Left, W, Expr);
- R1 := Synth_Uresize (Right, W, Expr);
- N := Build_Dyadic (Build_Context, Id, L1, R1);
- Set_Location (N, Expr);
- return Create_Value_Net (N, Rtype);
- end Synth_Dyadic_Uns;
-
- function Synth_Dyadic_Sgn (Id : Dyadic_Module_Id; Is_Res_Vec : Boolean)
- return Value_Acc
- is
- W : constant Width := Width'Max (Left.Typ.W, Right.Typ.W);
- Rtype : Type_Acc;
- L1, R1 : Net;
- N : Net;
- begin
- Rtype := Left.Typ;
- if Rtype.Kind = Type_Vector then
- Rtype := Rtype.Vec_El;
- end if;
-
- if Is_Res_Vec then
- Rtype := Create_Vec_Type_By_Length (W, Rtype);
- end if;
- L1 := Synth_Sresize (Left, W, Expr);
- R1 := Synth_Sresize (Right, W, Expr);
- N := Build_Dyadic (Build_Context, Id, L1, R1);
- Set_Location (N, Expr);
- return Create_Value_Net (N, Rtype);
- end Synth_Dyadic_Sgn;
-
function Synth_Compare_Uns_Uns
(Id : Compare_Module_Id; Res_Type : Type_Acc) return Value_Acc
is
@@ -459,54 +516,6 @@ package body Synth.Oper is
return Create_Value_Net (N, Res_Type);
end Synth_Compare_Uns_Uns;
- function Synth_Dyadic_Uns_Nat (Id : Dyadic_Module_Id) return Value_Acc
- is
- L : constant Net := Get_Net (Left);
- R1 : Net;
- N : Net;
- begin
- R1 := Synth_Uresize (Right, Left.Typ.W, Expr);
- N := Build_Dyadic (Build_Context, Id, L, R1);
- Set_Location (N, Expr);
- return Create_Value_Net (N, Create_Res_Bound (Left));
- end Synth_Dyadic_Uns_Nat;
-
- function Synth_Dyadic_Nat_Uns (Id : Dyadic_Module_Id) return Value_Acc
- is
- R : constant Net := Get_Net (Right);
- L1 : Net;
- N : Net;
- begin
- L1 := Synth_Uresize (Left, Right.Typ.W, Expr);
- N := Build_Dyadic (Build_Context, Id, L1, R);
- Set_Location (N, Expr);
- return Create_Value_Net (N, Create_Res_Bound (Right));
- end Synth_Dyadic_Nat_Uns;
-
- function Synth_Dyadic_Sgn_Int (Id : Dyadic_Module_Id) return Value_Acc
- is
- L : constant Net := Get_Net (Left);
- R1 : Net;
- N : Net;
- begin
- R1 := Synth_Sresize (Right, Left.Typ.W, Expr);
- N := Build_Dyadic (Build_Context, Id, L, R1);
- Set_Location (N, Expr);
- return Create_Value_Net (N, Create_Res_Bound (Left));
- end Synth_Dyadic_Sgn_Int;
-
- function Synth_Dyadic_Int_Sgn (Id : Dyadic_Module_Id) return Value_Acc
- is
- R : constant Net := Get_Net (Right);
- L1 : Net;
- N : Net;
- begin
- L1 := Synth_Sresize (Left, Right.Typ.W, Expr);
- N := Build_Dyadic (Build_Context, Id, R, L1);
- Set_Location (N, Expr);
- return Create_Value_Net (N, Create_Res_Bound (Right));
- end Synth_Dyadic_Int_Sgn;
-
function Synth_Compare_Sgn_Sgn
(Id : Compare_Module_Id; Res_Typ : Type_Acc) return Value_Acc
is
@@ -811,23 +820,23 @@ package body Synth.Oper is
when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Nat
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Int =>
-- "+" (Unsigned, Natural)
- return Synth_Dyadic_Uns_Nat (Id_Add);
+ return Synth_Dyadic_Uns_Nat (Id_Add, Left, Right, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Add_Nat_Uns =>
-- "+" (Natural, Unsigned)
- return Synth_Dyadic_Nat_Uns (Id_Add);
+ return Synth_Dyadic_Nat_Uns (Id_Add, Left, Right, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Uns
| Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Log
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Log
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Slv
| Iir_Predefined_Ieee_Std_Logic_Arith_Add_Uns_Uns_Slv =>
-- "+" (Unsigned, Unsigned)
- return Synth_Dyadic_Uns (Id_Add, True);
+ return Synth_Dyadic_Uns_Uns (Id_Add, Left, Right, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Int =>
-- "+" (Signed, Integer)
- return Synth_Dyadic_Sgn_Int (Id_Add);
+ return Synth_Dyadic_Sgn_Int (Id_Add, Left, Right, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Add_Int_Sgn =>
-- "+" (Integer, Signed)
- return Synth_Dyadic_Int_Sgn (Id_Add);
+ return Synth_Dyadic_Int_Sgn (Id_Add, Left, Right, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Sgn
| Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Log
| Iir_Predefined_Ieee_Numeric_Std_Add_Log_Sgn
@@ -837,30 +846,30 @@ package body Synth.Oper is
| Iir_Predefined_Ieee_Std_Logic_Arith_Add_Sgn_Sgn_Slv
| Iir_Predefined_Ieee_Std_Logic_Signed_Add_Slv_Slv =>
-- "+" (Signed, Signed)
- return Synth_Dyadic_Sgn (Id_Add, True);
+ return Synth_Dyadic_Sgn_Sgn (Id_Add, Left, Right, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Nat
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Slv_Int =>
-- "-" (Unsigned, Natural)
- return Synth_Dyadic_Uns_Nat (Id_Sub);
+ return Synth_Dyadic_Uns_Nat (Id_Sub, Left, Right, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Uns
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Slv_Slv
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Log_Slv
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Slv_Log =>
-- "-" (Unsigned, Unsigned)
- return Synth_Dyadic_Uns (Id_Sub, True);
+ return Synth_Dyadic_Uns_Uns (Id_Sub, Left, Right, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Int
| Iir_Predefined_Ieee_Std_Logic_Signed_Sub_Slv_Int =>
-- "-" (Signed, Integer)
- return Synth_Dyadic_Sgn_Int (Id_Sub);
+ return Synth_Dyadic_Sgn_Int (Id_Sub, Left, Right, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Sub_Int_Sgn =>
-- "-" (Integer, Signed)
- return Synth_Dyadic_Int_Sgn (Id_Sub);
+ return Synth_Dyadic_Int_Sgn (Id_Sub, Left, Right, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Sgn
| Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Log
| Iir_Predefined_Ieee_Numeric_Std_Sub_Log_Sgn =>
-- "-" (Signed, Signed)
- return Synth_Dyadic_Sgn (Id_Sub, True);
+ return Synth_Dyadic_Sgn_Sgn (Id_Sub, Left, Right, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Mul_Sgn_Sgn
| Iir_Predefined_Ieee_Std_Logic_Arith_Mul_Sgn_Sgn_Sgn
@@ -1429,11 +1438,22 @@ package body Synth.Oper is
return Create_Value_Net
(Arg_Net, Create_Vec_Type_By_Length (Size, Logic_Type));
end Synth_Conv_Vector;
+
+ L : Value_Acc;
+ R : Value_Acc;
begin
Param1 := Inter_Chain;
if Param1 /= Null_Node then
+ L := Get_Value (Subprg_Inst, Param1);
Param2 := Get_Chain (Inter_Chain);
+ if Param2 /= Null_Node then
+ R := Get_Value (Subprg_Inst, Param2);
+ else
+ R := null;
+ end if;
else
+ L := null;
+ R := null;
Param2 := Null_Node;
end if;
@@ -1443,7 +1463,7 @@ package body Synth.Oper is
Clk : Net;
Edge : Net;
begin
- Clk := Get_Net (Get_Value (Subprg_Inst, Param1));
+ Clk := Get_Net (L);
Edge := Build_Edge (Ctxt, Clk);
return Create_Value_Net (Edge, Boolean_Type);
end;
@@ -1452,7 +1472,7 @@ package body Synth.Oper is
Clk : Net;
Edge : Net;
begin
- Clk := Get_Net (Get_Value (Subprg_Inst, Param1));
+ Clk := Get_Net (L);
Clk := Build_Monadic (Ctxt, Id_Not, Clk);
Edge := Build_Edge (Ctxt, Clk);
return Create_Value_Net (Edge, Boolean_Type);
@@ -1462,26 +1482,16 @@ package body Synth.Oper is
-- Always false.
return Create_Value_Discrete (0, Boolean_Type);
when Iir_Predefined_Ieee_1164_To_Bitvector =>
- declare
- L : constant Value_Acc := Get_Value (Subprg_Inst, Param1);
- R : constant Value_Acc := Get_Value (Subprg_Inst, Param2);
- pragma Unreferenced (R);
- begin
- if Is_Static (L) then
- raise Internal_Error;
- end if;
- return Create_Value_Net (Get_Net (L), Create_Res_Bound (L));
- end;
+ if Is_Static (L) then
+ raise Internal_Error;
+ end if;
+ return Create_Value_Net (Get_Net (L), Create_Res_Bound (L));
when Iir_Predefined_Ieee_1164_To_Stdlogicvector_Suv
| Iir_Predefined_Ieee_1164_To_Stdlogicvector_Bv =>
- declare
- L : constant Value_Acc := Get_Value (Subprg_Inst, Param1);
- begin
- if Is_Static (L) then
- raise Internal_Error;
- end if;
- return Create_Value_Net (Get_Net (L), Create_Res_Bound (L));
- end;
+ if Is_Static (L) then
+ raise Internal_Error;
+ end if;
+ return Create_Value_Net (Get_Net (L), Create_Res_Bound (L));
when Iir_Predefined_Ieee_Numeric_Std_Touns_Nat_Nat_Uns
| Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Unsigned_Int =>
return Synth_Conv_Vector (False);
@@ -1497,76 +1507,72 @@ package body Synth.Oper is
Get_Value_Type (Subprg_Inst, Get_Type (Imp));
begin
return Create_Value_Net
- (Synth_Uresize (Get_Net (Get_Value (Subprg_Inst, Param1)),
- Int_Type.W, Expr),
- Int_Type);
+ (Synth_Uresize (Get_Net (L), Int_Type.W, Expr), Int_Type);
end;
when Iir_Predefined_Ieee_Numeric_Std_Resize_Uns_Nat =>
declare
- V : constant Value_Acc := Get_Value (Subprg_Inst, Param1);
- Sz : constant Value_Acc := Get_Value (Subprg_Inst, Param2);
W : Width;
begin
- if not Is_Static (Sz) then
+ if not Is_Static (R) then
Error_Msg_Synth (+Expr, "size must be constant");
return null;
end if;
- W := Uns32 (Sz.Scal);
+ W := Uns32 (R.Scal);
return Create_Value_Net
- (Synth_Uresize (Get_Net (V), W, Expr),
+ (Synth_Uresize (Get_Net (L), W, Expr),
Create_Vec_Type_By_Length (W, Logic_Type));
end;
when Iir_Predefined_Ieee_Numeric_Std_Resize_Sgn_Nat =>
declare
- V : constant Value_Acc := Get_Value (Subprg_Inst, Param1);
- Sz : constant Value_Acc := Get_Value (Subprg_Inst, Param2);
W : Width;
begin
- if not Is_Static (Sz) then
+ if not Is_Static (R) then
Error_Msg_Synth (+Expr, "size must be constant");
return null;
end if;
- W := Uns32 (Sz.Scal);
+ W := Uns32 (R.Scal);
return Create_Value_Net
- (Build2_Sresize (Ctxt, Get_Net (V), W, Get_Location (Expr)),
+ (Build2_Sresize (Ctxt, Get_Net (L), W, Get_Location (Expr)),
Create_Vec_Type_By_Length (W, Logic_Type));
end;
when Iir_Predefined_Ieee_Numeric_Std_Shl_Uns_Nat
| Iir_Predefined_Ieee_Numeric_Std_Shl_Sgn_Nat =>
- declare
- L : constant Value_Acc := Get_Value (Subprg_Inst, Param1);
- R : constant Value_Acc := Get_Value (Subprg_Inst, Param2);
- begin
- return Synth_Shift_Rotate (Id_Lsl, L, R, Expr);
- end;
+ return Synth_Shift_Rotate (Id_Lsl, L, R, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Shr_Uns_Nat =>
- declare
- L : constant Value_Acc := Get_Value (Subprg_Inst, Param1);
- R : constant Value_Acc := Get_Value (Subprg_Inst, Param2);
- begin
- return Synth_Shift_Rotate (Id_Lsr, L, R, Expr);
- end;
+ return Synth_Shift_Rotate (Id_Lsr, L, R, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Shr_Sgn_Nat =>
- declare
- L : constant Value_Acc := Get_Value (Subprg_Inst, Param1);
- R : constant Value_Acc := Get_Value (Subprg_Inst, Param2);
- begin
- return Synth_Shift_Rotate (Id_Asr, L, R, Expr);
- end;
+ return Synth_Shift_Rotate (Id_Asr, L, R, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Rol_Uns_Nat =>
- declare
- L : constant Value_Acc := Get_Value (Subprg_Inst, Param1);
- R : constant Value_Acc := Get_Value (Subprg_Inst, Param2);
- begin
- return Synth_Shift_Rotate (Id_Rol, L, R, Expr);
- end;
+ return Synth_Shift_Rotate (Id_Rol, L, R, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Ror_Uns_Nat =>
- declare
- L : constant Value_Acc := Get_Value (Subprg_Inst, Param1);
- R : constant Value_Acc := Get_Value (Subprg_Inst, Param2);
- begin
- return Synth_Shift_Rotate (Id_Ror, L, R, Expr);
- end;
+ return Synth_Shift_Rotate (Id_Ror, L, R, Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Min_Uns_Uns =>
+ return Synth_Dyadic_Uns_Uns (Id_Umin, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Min_Uns_Nat =>
+ return Synth_Dyadic_Uns_Nat (Id_Umin, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Min_Nat_Uns =>
+ return Synth_Dyadic_Nat_Uns (Id_Umin, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Min_Sgn_Sgn =>
+ return Synth_Dyadic_Sgn_Sgn (Id_Smin, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Min_Sgn_Int =>
+ return Synth_Dyadic_Sgn_Int (Id_Smin, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Min_Int_Sgn =>
+ return Synth_Dyadic_Int_Sgn (Id_Smin, L, R, Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Max_Uns_Uns =>
+ return Synth_Dyadic_Uns_Uns (Id_Umax, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Max_Uns_Nat =>
+ return Synth_Dyadic_Uns_Nat (Id_Umax, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Max_Nat_Uns =>
+ return Synth_Dyadic_Nat_Uns (Id_Umax, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Max_Sgn_Sgn =>
+ return Synth_Dyadic_Sgn_Sgn (Id_Smax, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Max_Sgn_Int =>
+ return Synth_Dyadic_Sgn_Int (Id_Smax, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Max_Int_Sgn =>
+ return Synth_Dyadic_Int_Sgn (Id_Smax, L, R, Expr);
+
when Iir_Predefined_Ieee_Numeric_Std_Match_Suv
| Iir_Predefined_Ieee_Numeric_Std_Match_Slv =>
declare