aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-03-21 17:16:08 +0100
committerTristan Gingold <tgingold@free.fr>2020-03-21 17:16:08 +0100
commit134c6ed91339538eeb0c62b25de4c2ea79e89e37 (patch)
tree9b3da160a0b299533ee8a5c0c7553ff29be0469b /src
parente63bc8249ddfca1176b72f038ba8b9fa12b0f38c (diff)
downloadghdl-134c6ed91339538eeb0c62b25de4c2ea79e89e37.tar.gz
ghdl-134c6ed91339538eeb0c62b25de4c2ea79e89e37.tar.bz2
ghdl-134c6ed91339538eeb0c62b25de4c2ea79e89e37.zip
synth: handle numeric_std minimum/maximum. Fix #1168
Diffstat (limited to 'src')
-rw-r--r--src/synth/ghdlsynth_gates.h92
-rw-r--r--src/synth/netlists-builders.adb9
-rw-r--r--src/synth/netlists-disp_vhdl.adb12
-rw-r--r--src/synth/netlists-gates.ads92
-rw-r--r--src/synth/synth-oper.adb352
5 files changed, 296 insertions, 261 deletions
diff --git a/src/synth/ghdlsynth_gates.h b/src/synth/ghdlsynth_gates.h
index 1611a81e1..adc1e87b9 100644
--- a/src/synth/ghdlsynth_gates.h
+++ b/src/synth/ghdlsynth_gates.h
@@ -14,50 +14,54 @@ enum Module_Id {
Id_Xnor = 8,
Id_Add = 9,
Id_Sub = 10,
- Id_Umul = 11,
- Id_Smul = 12,
- Id_Udiv = 13,
- Id_Sdiv = 14,
- Id_Umod = 15,
- Id_Smod = 16,
- Id_Srem = 17,
- Id_Not = 18,
- Id_Neg = 19,
- Id_Abs = 20,
- Id_Lsl = 22,
- Id_Lsr = 23,
- Id_Asr = 24,
- Id_Rol = 25,
- Id_Ror = 26,
- Id_Eq = 27,
- Id_Ne = 28,
- Id_Ule = 29,
- Id_Sle = 30,
- Id_Ult = 31,
- Id_Slt = 32,
- Id_Uge = 33,
- Id_Sge = 34,
- Id_Ugt = 35,
- Id_Sgt = 36,
- Id_Red_And = 37,
- Id_Red_Or = 38,
- Id_Concat2 = 40,
- Id_Concat3 = 41,
- Id_Concat4 = 42,
- Id_Concatn = 43,
- Id_Mux2 = 44,
- Id_Mux4 = 45,
- Id_Signal = 46,
- Id_Isignal = 47,
- Id_Output = 48,
- Id_Ioutput = 49,
- Id_Port = 50,
- Id_Dff = 52,
- Id_Adff = 53,
- Id_Idff = 54,
- Id_Iadff = 55,
- Id_Mdff = 56,
- Id_Midff = 57,
+ Id_Umin = 11,
+ Id_Smin = 12,
+ Id_Umax = 13,
+ Id_Smax = 14,
+ Id_Umul = 15,
+ Id_Smul = 16,
+ Id_Udiv = 17,
+ Id_Sdiv = 18,
+ Id_Umod = 19,
+ Id_Smod = 20,
+ Id_Srem = 21,
+ Id_Not = 22,
+ Id_Neg = 23,
+ Id_Abs = 24,
+ Id_Lsl = 25,
+ Id_Lsr = 26,
+ Id_Asr = 27,
+ Id_Rol = 28,
+ Id_Ror = 29,
+ Id_Eq = 30,
+ Id_Ne = 31,
+ Id_Ule = 32,
+ Id_Sle = 33,
+ Id_Ult = 34,
+ Id_Slt = 35,
+ Id_Uge = 36,
+ Id_Sge = 37,
+ Id_Ugt = 38,
+ Id_Sgt = 39,
+ Id_Red_And = 40,
+ Id_Red_Or = 41,
+ Id_Concat2 = 42,
+ Id_Concat3 = 43,
+ Id_Concat4 = 44,
+ Id_Concatn = 45,
+ Id_Mux2 = 46,
+ Id_Mux4 = 47,
+ Id_Signal = 48,
+ Id_Isignal = 49,
+ Id_Output = 50,
+ Id_Ioutput = 51,
+ Id_Port = 52,
+ Id_Dff = 56,
+ Id_Adff = 57,
+ Id_Idff = 58,
+ Id_Iadff = 59,
+ Id_Mdff = 60,
+ Id_Midff = 61,
Id_Utrunc = 64,
Id_Strunc = 65,
Id_Uextend = 66,
diff --git a/src/synth/netlists-builders.adb b/src/synth/netlists-builders.adb
index 0e7f16815..6262295de 100644
--- a/src/synth/netlists-builders.adb
+++ b/src/synth/netlists-builders.adb
@@ -592,6 +592,15 @@ package body Netlists.Builders is
Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Sub),
Get_Identifier ("sub"), Id_Sub);
+ Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Umin),
+ Get_Identifier ("umin"), Id_Umin);
+ Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Smin),
+ Get_Identifier ("smin"), Id_Smin);
+ Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Umax),
+ Get_Identifier ("umax"), Id_Umax);
+ Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Smax),
+ Get_Identifier ("smax"), Id_Smax);
+
Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Umul),
Get_Identifier ("umul"), Id_Umul);
Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Smul),
diff --git a/src/synth/netlists-disp_vhdl.adb b/src/synth/netlists-disp_vhdl.adb
index 22dc86e84..423a9ed96 100644
--- a/src/synth/netlists-disp_vhdl.adb
+++ b/src/synth/netlists-disp_vhdl.adb
@@ -943,6 +943,18 @@ package body Netlists.Disp_Vhdl is
Disp_Template (" \o0 <= std_logic_vector (\ui0 - \ui1);" & NL,
Inst);
end if;
+ when Id_Umin =>
+ Disp_Template (" \o0 <= \i0 when \ui0 < \ui1 else \i1;" & NL,
+ Inst);
+ when Id_Smin =>
+ Disp_Template (" \o0 <= \i0 when \si0 < \si1 else \i1;" & NL,
+ Inst);
+ when Id_Umax =>
+ Disp_Template (" \o0 <= \i0 when \ui0 > \ui1 else \i1;" & NL,
+ Inst);
+ when Id_Smax =>
+ Disp_Template (" \o0 <= \i0 when \si0 > \si1 else \i1;" & NL,
+ Inst);
when Id_Umul =>
Disp_Template
(" \o0 <= std_logic_vector (resize (\ui0 * \ui1, \n0));" & NL,
diff --git a/src/synth/netlists-gates.ads b/src/synth/netlists-gates.ads
index c6c1c4815..b60420c22 100644
--- a/src/synth/netlists-gates.ads
+++ b/src/synth/netlists-gates.ads
@@ -33,72 +33,76 @@ package Netlists.Gates is
Id_Add : constant Module_Id := 9;
Id_Sub : constant Module_Id := 10;
- Id_Umul : constant Module_Id := 11;
- Id_Smul : constant Module_Id := 12;
- Id_Udiv : constant Module_Id := 13;
- Id_Sdiv : constant Module_Id := 14;
- Id_Umod : constant Module_Id := 15;
- Id_Smod : constant Module_Id := 16;
- Id_Srem : constant Module_Id := 17;
+ Id_Umin : constant Module_Id := 11;
+ Id_Smin : constant Module_Id := 12;
+ Id_Umax : constant Module_Id := 13;
+ Id_Smax : constant Module_Id := 14;
+ Id_Umul : constant Module_Id := 15;
+ Id_Smul : constant Module_Id := 16;
+ Id_Udiv : constant Module_Id := 17;
+ Id_Sdiv : constant Module_Id := 18;
+ Id_Umod : constant Module_Id := 19;
+ Id_Smod : constant Module_Id := 20;
+ Id_Srem : constant Module_Id := 21;
subtype Dyadic_Module_Id is Module_Id range Id_And .. Id_Srem;
- Id_Not : constant Module_Id := 18;
- Id_Neg : constant Module_Id := 19;
- Id_Abs : constant Module_Id := 20;
+ Id_Not : constant Module_Id := 22;
+ Id_Neg : constant Module_Id := 23;
+ Id_Abs : constant Module_Id := 24;
subtype Monadic_Module_Id is Module_Id range Id_Not .. Id_Abs;
-- Logical and arithmetic shifts.
-- FIXME: clarify right operand: width, large values
- Id_Lsl : constant Module_Id := 22;
- Id_Lsr : constant Module_Id := 23;
- Id_Asr : constant Module_Id := 24;
+ Id_Lsl : constant Module_Id := 25;
+ Id_Lsr : constant Module_Id := 26;
+ Id_Asr : constant Module_Id := 27;
subtype Shift_Module_Id is Module_Id range Id_Lsl .. Id_Asr;
-- Rotations.
-- FIXME: clarify right operand.
- Id_Rol : constant Module_Id := 25;
- Id_Ror : constant Module_Id := 26;
+ Id_Rol : constant Module_Id := 28;
+ Id_Ror : constant Module_Id := 29;
subtype Rotate_Module_Id is Module_Id range Id_Lsl .. Id_Asr;
subtype Shift_Rotate_Module_Id is Module_Id range Id_Lsl .. Id_Ror;
- Id_Eq : constant Module_Id := 27;
- Id_Ne : constant Module_Id := 28;
- Id_Ule : constant Module_Id := 29;
- Id_Sle : constant Module_Id := 30;
- Id_Ult : constant Module_Id := 31;
- Id_Slt : constant Module_Id := 32;
- Id_Uge : constant Module_Id := 33;
- Id_Sge : constant Module_Id := 34;
- Id_Ugt : constant Module_Id := 35;
- Id_Sgt : constant Module_Id := 36;
+ Id_Eq : constant Module_Id := 30;
+ Id_Ne : constant Module_Id := 31;
+ Id_Ule : constant Module_Id := 32;
+ Id_Sle : constant Module_Id := 33;
+ Id_Ult : constant Module_Id := 34;
+ Id_Slt : constant Module_Id := 35;
+ Id_Uge : constant Module_Id := 36;
+ Id_Sge : constant Module_Id := 37;
+ Id_Ugt : constant Module_Id := 38;
+ Id_Sgt : constant Module_Id := 39;
subtype Compare_Module_Id is Module_Id range Id_Eq .. Id_Sgt;
- Id_Red_And : constant Module_Id := 37;
- Id_Red_Or : constant Module_Id := 38;
+ Id_Red_And : constant Module_Id := 40;
+ Id_Red_Or : constant Module_Id := 41;
subtype Reduce_Module_Id is Module_Id range Id_Red_And .. Id_Red_Or;
- Id_Concat2 : constant Module_Id := 40;
- Id_Concat3 : constant Module_Id := 41;
- Id_Concat4 : constant Module_Id := 42;
+ Id_Concat2 : constant Module_Id := 42;
+ Id_Concat3 : constant Module_Id := 43;
+ Id_Concat4 : constant Module_Id := 44;
subtype Concat_Module_Id is Module_Id range Id_Concat2 .. Id_Concat4;
-- Concatenation with N inputs.
- Id_Concatn : constant Module_Id := 43;
+ Id_Concatn : constant Module_Id := 45;
-- Inputs: s, i0, i1
-- Output: o
- Id_Mux2 : constant Module_Id := 44;
+ Id_Mux2 : constant Module_Id := 46;
-- Inputs: s, i0, i1, s2, s3
-- Output: o
- Id_Mux4 : constant Module_Id := 45;
+ Id_Mux4 : constant Module_Id := 47;
subtype Mux_Module_Id is Module_Id range Id_Mux2 .. Id_Mux4;
@@ -110,11 +114,11 @@ package Netlists.Gates is
-- by a gate (and thus the value of the output could be read), but that
-- driving value may not be available early enough.
-- Id_Ioutput is an output with an initial value.
- Id_Signal : constant Module_Id := 46;
- Id_Isignal : constant Module_Id := 47;
- Id_Output : constant Module_Id := 48;
- Id_Ioutput : constant Module_Id := 49;
- Id_Port : constant Module_Id := 50;
+ Id_Signal : constant Module_Id := 48;
+ Id_Isignal : constant Module_Id := 49;
+ Id_Output : constant Module_Id := 50;
+ Id_Ioutput : constant Module_Id := 51;
+ Id_Port : constant Module_Id := 52;
-- Note: initial values must be constant nets.
--
@@ -124,7 +128,7 @@ package Netlists.Gates is
-- Inputs: 0: CLK
-- 1: D
-- Output: 0: Q
- Id_Dff : constant Module_Id := 52;
+ Id_Dff : constant Module_Id := 56;
-- A DFF with an asynchronous reset. Note that the asynchronous reset
-- has priority over the clock. When RST is asserted, the value is
@@ -134,7 +138,7 @@ package Netlists.Gates is
-- 2: RST
-- 3: RST_VAL
-- Output: 0: Q
- Id_Adff : constant Module_Id := 53;
+ Id_Adff : constant Module_Id := 57;
-- A simple DFF with an initial value (must be constant). This is
-- for FPGAs.
@@ -142,7 +146,7 @@ package Netlists.Gates is
-- 1: D
-- 2: INIT (initial value)
-- Output: 0: Q
- Id_Idff : constant Module_Id := 54;
+ Id_Idff : constant Module_Id := 58;
-- A DFF with an asynchronous reset and an initial value.
-- Inputs: 0: CLK
@@ -151,14 +155,14 @@ package Netlists.Gates is
-- 3: RST_VAL
-- 4: INIT (initial value)
-- Output: 0: Q
- Id_Iadff : constant Module_Id := 55;
+ Id_Iadff : constant Module_Id := 59;
-- Multi clock dff. ELSE is the output of the next DFF.
-- Inputs: 0: CLK
-- 1: D
-- 2: ELSE
-- Output: 0: Q
- Id_Mdff : constant Module_Id := 56;
+ Id_Mdff : constant Module_Id := 60;
-- Multi clock dff with initial value. ELSE is the output of the next DFF.
-- Inputs: 0: CLK
@@ -166,7 +170,7 @@ package Netlists.Gates is
-- 2: ELSE
-- 3: Init
-- Output: 0: Q
- Id_Midff : constant Module_Id := 57;
+ Id_Midff : constant Module_Id := 61;
-- Width change: truncate or extend. Sign is know in order to possibly
-- detect loss of value.
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