diff options
author | Tristan Gingold <tgingold@free.fr> | 2019-09-11 20:31:06 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2019-09-11 20:31:06 +0200 |
commit | 854dbc3a0f780a8cbad5a0cee2611ee24fdb2c8e (patch) | |
tree | 74f455132b18bd6c70dbf600362286cf297e8cc3 /src | |
parent | 6df69fa59e5a33ee8e103bfba16ba77a7a94826a (diff) | |
download | ghdl-854dbc3a0f780a8cbad5a0cee2611ee24fdb2c8e.tar.gz ghdl-854dbc3a0f780a8cbad5a0cee2611ee24fdb2c8e.tar.bz2 ghdl-854dbc3a0f780a8cbad5a0cee2611ee24fdb2c8e.zip |
synth: handle unsigned shift left.
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/ghdlsynth_gates.h | 102 | ||||
-rw-r--r-- | src/synth/netlists-builders.adb | 26 | ||||
-rw-r--r-- | src/synth/netlists-builders.ads | 5 | ||||
-rw-r--r-- | src/synth/netlists-gates.ads | 110 | ||||
-rw-r--r-- | src/synth/synth-expr.adb | 27 |
5 files changed, 163 insertions, 107 deletions
diff --git a/src/synth/ghdlsynth_gates.h b/src/synth/ghdlsynth_gates.h index 7eff74f93..bb8f6a4af 100644 --- a/src/synth/ghdlsynth_gates.h +++ b/src/synth/ghdlsynth_gates.h @@ -16,54 +16,56 @@ enum Module_Id { Id_Sub = 10, Id_Umul = 11, Id_Smul = 12, - Id_Buf = 13, - Id_Not = 14, - Id_Neg = 15, - Id_Eq = 16, - Id_Ne = 17, - Id_Ule = 18, - Id_Sle = 19, - Id_Ult = 20, - Id_Slt = 21, - Id_Uge = 22, - Id_Sge = 23, - Id_Ugt = 24, - Id_Sgt = 25, - Id_Red_And = 26, - Id_Red_Or = 27, - Id_Concat2 = 28, - Id_Concat3 = 29, - Id_Concat4 = 30, - Id_Split2 = 31, - Id_Split3 = 32, - Id_Mux2 = 33, - Id_Mux4 = 34, - Id_Signal = 35, - Id_Isignal = 36, - Id_Output = 37, - Id_Port = 38, - Id_Dff = 40, - Id_Adff = 41, - Id_Idff = 42, - Id_Iadff = 43, - Id_Utrunc = 46, - Id_Strunc = 47, - Id_Uextend = 48, - Id_Sextend = 49, - Id_Extract = 50, - Id_Dyn_Extract = 51, - Id_Dyn_Insert = 53, - Id_Edge = 55, - Id_Assert = 56, - Id_Assume = 57, - Id_Const_UB32 = 64, - Id_Const_SB32 = 65, - Id_Const_UL32 = 70, - Id_Const_UB64 = 66, - Id_Const_UL64 = 67, - Id_Const_Z = 72, - Id_Const_0 = 73, - Id_Const_Bit = 74, - Id_Const_Log = 75, - Id_Concatn = 80, + Id_Lsl = 13, + Id_Lsr = 14, + Id_Asr = 15, + Id_Buf = 16, + Id_Not = 17, + Id_Neg = 18, + Id_Eq = 20, + Id_Ne = 21, + Id_Ule = 22, + Id_Sle = 23, + Id_Ult = 24, + Id_Slt = 25, + Id_Uge = 26, + Id_Sge = 27, + Id_Ugt = 28, + Id_Sgt = 29, + Id_Red_And = 30, + Id_Red_Or = 31, + Id_Concat2 = 32, + Id_Concat3 = 33, + Id_Concat4 = 34, + Id_Concatn = 35, + Id_Mux2 = 36, + Id_Mux4 = 37, + Id_Signal = 38, + Id_Isignal = 39, + Id_Output = 40, + Id_Port = 41, + Id_Dff = 50, + Id_Adff = 51, + Id_Idff = 52, + Id_Iadff = 53, + Id_Utrunc = 64, + Id_Strunc = 65, + Id_Uextend = 66, + Id_Sextend = 67, + Id_Extract = 68, + Id_Dyn_Extract = 69, + Id_Dyn_Insert = 70, + Id_Edge = 71, + Id_Assert = 72, + Id_Assume = 73, + Id_Const_UB32 = 96, + Id_Const_SB32 = 97, + Id_Const_UL32 = 98, + Id_Const_UB64 = 99, + Id_Const_UL64 = 100, + Id_Const_X = 101, + Id_Const_Z = 102, + Id_Const_0 = 103, + Id_Const_Bit = 104, + Id_Const_Log = 105, }; diff --git a/src/synth/netlists-builders.adb b/src/synth/netlists-builders.adb index 740a0d867..418daf308 100644 --- a/src/synth/netlists-builders.adb +++ b/src/synth/netlists-builders.adb @@ -388,6 +388,7 @@ package body Netlists.Builders is Parent => No_Module, Num => 0, M_Dyadic => (others => No_Module), + M_Shift => (others => No_Module), M_Monadic => (others => No_Module), M_Compare => (others => No_Module), M_Concat => (others => No_Module), @@ -414,6 +415,12 @@ package body Netlists.Builders is Get_Identifier ("smul"), Id_Smul); Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Umul), Get_Identifier ("umul"), Id_Umul); + Create_Dyadic_Module (Design, Res.M_Shift (Id_Lsl), + Get_Identifier ("lsl"), Id_Lsl); + Create_Dyadic_Module (Design, Res.M_Shift (Id_Lsr), + Get_Identifier ("lsr"), Id_Lsr); + Create_Dyadic_Module (Design, Res.M_Shift (Id_Asr), + Get_Identifier ("asr"), Id_Asr); Create_Monadic_Module (Design, Res.M_Monadic (Id_Not), Name_Not, Id_Not); Create_Monadic_Module (Design, Res.M_Monadic (Id_Neg), @@ -519,6 +526,25 @@ package body Netlists.Builders is return O; end Build_Dyadic; + function Build_Shift (Ctxt : Context_Acc; + Id : Shift_Module_Id; + L, R : Net) return Net + is + Wd : constant Width := Get_Width (L); + pragma Assert (Wd /= No_Width); + pragma Assert (Get_Width (R) /= No_Width); + pragma Assert (Ctxt.M_Shift (Id) /= No_Module); + Inst : Instance; + O : Net; + begin + Inst := New_Internal_Instance (Ctxt, Ctxt.M_Shift (Id)); + O := Get_Output (Inst, 0); + Set_Width (O, Wd); + Connect (Get_Input (Inst, 0), L); + Connect (Get_Input (Inst, 1), R); + return O; + end Build_Shift; + function Build_Monadic (Ctxt : Context_Acc; Id : Monadic_Module_Id; Op : Net) return Net diff --git a/src/synth/netlists-builders.ads b/src/synth/netlists-builders.ads index aeeaaa53d..1493ed194 100644 --- a/src/synth/netlists-builders.ads +++ b/src/synth/netlists-builders.ads @@ -37,6 +37,10 @@ package Netlists.Builders is Id : Dyadic_Module_Id; L, R : Net) return Net; + function Build_Shift (Ctxt : Context_Acc; + Id : Shift_Module_Id; + L, R : Net) return Net; + function Build_Monadic (Ctxt : Context_Acc; Id : Monadic_Module_Id; Op : Net) return Net; @@ -160,6 +164,7 @@ private Parent : Module; Num : Uns32; M_Dyadic : Module_Arr (Dyadic_Module_Id); + M_Shift : Module_Arr (Shift_Module_Id); M_Monadic : Module_Arr (Monadic_Module_Id); M_Compare : Module_Arr (Compare_Module_Id); M_Concat : Module_Arr (Concat_Module_Id); diff --git a/src/synth/netlists-gates.ads b/src/synth/netlists-gates.ads index 72b29266f..7a2ffa94f 100644 --- a/src/synth/netlists-gates.ads +++ b/src/synth/netlists-gates.ads @@ -34,53 +34,60 @@ package Netlists.Gates is subtype Dyadic_Module_Id is Module_Id range Id_And .. Id_Smul; - Id_Buf : constant Module_Id := 13; - Id_Not : constant Module_Id := 14; + -- Logical and arithmetic shifts. + Id_Lsl : constant Module_Id := 13; + Id_Lsr : constant Module_Id := 14; + Id_Asr : constant Module_Id := 15; - Id_Neg : constant Module_Id := 15; + subtype Shift_Module_Id is Module_Id range Id_Lsl .. Id_Asr; + + Id_Buf : constant Module_Id := 16; + Id_Not : constant Module_Id := 17; + + Id_Neg : constant Module_Id := 18; subtype Monadic_Module_Id is Module_Id range Id_Buf .. Id_Neg; - Id_Eq : constant Module_Id := 16; - Id_Ne : constant Module_Id := 17; - Id_Ule : constant Module_Id := 18; - Id_Sle : constant Module_Id := 19; - Id_Ult : constant Module_Id := 20; - Id_Slt : constant Module_Id := 21; - Id_Uge : constant Module_Id := 22; - Id_Sge : constant Module_Id := 23; - Id_Ugt : constant Module_Id := 24; - Id_Sgt : constant Module_Id := 25; + Id_Eq : constant Module_Id := 20; + Id_Ne : constant Module_Id := 21; + Id_Ule : constant Module_Id := 22; + Id_Sle : constant Module_Id := 23; + Id_Ult : constant Module_Id := 24; + Id_Slt : constant Module_Id := 25; + Id_Uge : constant Module_Id := 26; + Id_Sge : constant Module_Id := 27; + Id_Ugt : constant Module_Id := 28; + Id_Sgt : constant Module_Id := 29; subtype Compare_Module_Id is Module_Id range Id_Eq .. Id_Sgt; - Id_Red_And : constant Module_Id := 26; - Id_Red_Or : constant Module_Id := 27; + Id_Red_And : constant Module_Id := 30; + Id_Red_Or : constant Module_Id := 31; subtype Reduce_Module_Id is Module_Id range Id_Red_And .. Id_Red_Or; - Id_Concat2 : constant Module_Id := 28; - Id_Concat3 : constant Module_Id := 29; - Id_Concat4 : constant Module_Id := 30; + Id_Concat2 : constant Module_Id := 32; + Id_Concat3 : constant Module_Id := 33; + Id_Concat4 : constant Module_Id := 34; subtype Concat_Module_Id is Module_Id range Id_Concat2 .. Id_Concat4; - Id_Split2 : constant Module_Id := 31; - Id_Split3 : constant Module_Id := 32; + -- Concatenation with N inputs. + Id_Concatn : constant Module_Id := 35; -- Inputs: s, i0, i1 -- Output: o - Id_Mux2 : constant Module_Id := 33; + Id_Mux2 : constant Module_Id := 36; -- Inputs: s, i0, i1, s2, s3 -- Output: o - Id_Mux4 : constant Module_Id := 34; + Id_Mux4 : constant Module_Id := 37; -- Like a wire: the output is equal to the input, but could be elimited -- at any time. Isignal has an initial value. - Id_Signal : constant Module_Id := 35; - Id_Isignal : constant Module_Id := 36; - Id_Output : constant Module_Id := 37; - Id_Port : constant Module_Id := 38; + Id_Signal : constant Module_Id := 38; + Id_Isignal : constant Module_Id := 39; + Id_Output : constant Module_Id := 40; + Id_Port : constant Module_Id := 41; -- Note: initial values must be constant nets. -- @@ -89,69 +96,66 @@ package Netlists.Gates is -- input. -- Inputs: CLK, D -- Output: Q - Id_Dff : constant Module_Id := 40; + Id_Dff : constant Module_Id := 50; -- A DFF with an asynchronous reset. Note that the asynchronous reset -- has priority over the clock. When RST is asserted, the value is -- set to RST_VAL. -- Inputs: CLK, D, RST, RST_VAL -- Output: Q - Id_Adff : constant Module_Id := 41; + Id_Adff : constant Module_Id := 51; -- A simple DFF with an initial value (must be constant). This is -- for FPGAs. - Id_Idff : constant Module_Id := 42; + Id_Idff : constant Module_Id := 52; -- A DFF with an asynchronous reset and an initial value. - Id_Iadff : constant Module_Id := 43; + Id_Iadff : constant Module_Id := 53; -- Width change: truncate or extend. Sign is know in order to possibly -- detect loss of value. - Id_Utrunc : constant Module_Id := 46; - Id_Strunc : constant Module_Id := 47; - Id_Uextend : constant Module_Id := 48; - Id_Sextend : constant Module_Id := 49; + Id_Utrunc : constant Module_Id := 64; + Id_Strunc : constant Module_Id := 65; + Id_Uextend : constant Module_Id := 66; + Id_Sextend : constant Module_Id := 67; subtype Truncate_Module_Id is Module_Id range Id_Utrunc .. Id_Strunc; subtype Extend_Module_Id is Module_Id range Id_Uextend .. Id_Sextend; -- Extract a bit or a slice at a constant offset. -- OUT := IN0[OFF+WD-1:OFF] - Id_Extract : constant Module_Id := 50; + Id_Extract : constant Module_Id := 68; -- OUT := IN0[IN1*STEP+OFF+WD-1:IN1*STEP+OFF] - Id_Dyn_Extract : constant Module_Id := 51; + Id_Dyn_Extract : constant Module_Id := 69; -- Like Insert but for dynamic values. -- T := IN0 -- T [IN2*STEP+OFF+WD-1:IN2*STEP+OFF] := IN1 -- OUT := T - Id_Dyn_Insert : constant Module_Id := 53; + Id_Dyn_Insert : constant Module_Id := 70; -- Positive/rising edge detector. This is a pseudo gate. -- A negative edge detector can be made using by negating the clock before -- the detector. - Id_Edge : constant Module_Id := 55; + Id_Edge : constant Module_Id := 71; -- Input signal must always be true. - Id_Assert : constant Module_Id := 56; - Id_Assume : constant Module_Id := 57; + Id_Assert : constant Module_Id := 72; + Id_Assume : constant Module_Id := 73; -- Constants are gates with only one constant output. There are multiple -- kind of constant gates: for small width, the value is stored as a -- parameter, possibly signed or unsigned extended. - Id_Const_UB32 : constant Module_Id := 64; - Id_Const_SB32 : constant Module_Id := 65; - Id_Const_UL32 : constant Module_Id := 70; - Id_Const_UB64 : constant Module_Id := 66; - Id_Const_UL64 : constant Module_Id := 67; - Id_Const_X : constant Module_Id := 71; - Id_Const_Z : constant Module_Id := 72; - Id_Const_0 : constant Module_Id := 73; + Id_Const_UB32 : constant Module_Id := 96; + Id_Const_SB32 : constant Module_Id := 97; + Id_Const_UL32 : constant Module_Id := 98; + Id_Const_UB64 : constant Module_Id := 99; + Id_Const_UL64 : constant Module_Id := 100; + Id_Const_X : constant Module_Id := 101; + Id_Const_Z : constant Module_Id := 102; + Id_Const_0 : constant Module_Id := 103; -- Large width. - Id_Const_Bit : constant Module_Id := 74; - Id_Const_Log : constant Module_Id := 75; - - -- Concatenation with N inputs. - Id_Concatn : constant Module_Id := 80; + Id_Const_Bit : constant Module_Id := 104; + Id_Const_Log : constant Module_Id := 105; end Netlists.Gates; diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb index 479249fa1..ac9eeae6e 100644 --- a/src/synth/synth-expr.adb +++ b/src/synth/synth-expr.adb @@ -2166,6 +2166,18 @@ package body Synth.Expr is return Create_Value_Const_Array (Bnd, Arr); end Eval_To_Unsigned; + function Synth_Shift (Id : Shift_Module_Id; + Left, Right : Value_Acc; + Expr : Node) return Value_Acc + is + L : constant Net := Get_Net (Left); + N : Net; + begin + N := Build_Shift (Build_Context, Id, L, Get_Net (Right)); + Set_Location (N, Expr); + return Create_Value_Net (N, Create_Res_Bound (Left, L)); + end Synth_Shift; + function Synth_Predefined_Function_Call (Syn_Inst : Synth_Instance_Acc; Expr : Node) return Value_Acc is @@ -2210,14 +2222,14 @@ package body Synth.Expr is when Iir_Predefined_Ieee_Numeric_Std_Toint_Uns_Nat => -- UNSIGNED to Natural. declare - Nat_Type : constant Type_Acc := + Int_Type : constant Type_Acc := Get_Value_Type (Syn_Inst, - Vhdl.Std_Package.Natural_Subtype_Definition); + Vhdl.Std_Package.Integer_Subtype_Definition); begin return Create_Value_Net (Synth_Uresize (Get_Net (Subprg_Inst.Objects (1)), - Nat_Type.W, Expr), - Nat_Type); + Int_Type.W, Expr), + Int_Type); end; when Iir_Predefined_Ieee_Numeric_Std_Resize_Uns_Nat => declare @@ -2249,6 +2261,13 @@ package body Synth.Expr is (Synth_Sresize (Get_Net (V), W, Expr), Create_Vec_Type_By_Length (W, Logic_Type)); end; + when Iir_Predefined_Ieee_Numeric_Std_Shl_Uns_Nat => + declare + L : constant Value_Acc := Subprg_Inst.Objects (1); + R : constant Value_Acc := Subprg_Inst.Objects (2); + begin + return Synth_Shift (Id_Lsl, L, R, Expr); + end; when Iir_Predefined_Ieee_Math_Real_Log2 => declare V : constant Value_Acc := Subprg_Inst.Objects (1); |