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 | |
| parent | 6df69fa59e5a33ee8e103bfba16ba77a7a94826a (diff) | |
| download | ghdl-854dbc3a0f780a8cbad5a0cee2611ee24fdb2c8e.tar.gz ghdl-854dbc3a0f780a8cbad5a0cee2611ee24fdb2c8e.tar.bz2 ghdl-854dbc3a0f780a8cbad5a0cee2611ee24fdb2c8e.zip | |
synth: handle unsigned shift left.
| -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); | 
