diff options
| author | Tristan Gingold <tgingold@free.fr> | 2019-07-01 18:21:59 +0200 | 
|---|---|---|
| committer | Tristan Gingold <tgingold@free.fr> | 2019-07-01 18:21:59 +0200 | 
| commit | 10e0d932d67e90263dfd393be8b3719e26fe6514 (patch) | |
| tree | 1ed2df92180c602fb428378ef9fadac452f5bc8c | |
| parent | 5ee88f60d0052fc028cfc55e9182349343260e2f (diff) | |
| download | ghdl-10e0d932d67e90263dfd393be8b3719e26fe6514.tar.gz ghdl-10e0d932d67e90263dfd393be8b3719e26fe6514.tar.bz2 ghdl-10e0d932d67e90263dfd393be8b3719e26fe6514.zip | |
synth: add dyn_insert module.
| -rw-r--r-- | src/synth/netlists-builders.adb | 51 | ||||
| -rw-r--r-- | src/synth/netlists-builders.ads | 7 | ||||
| -rw-r--r-- | src/synth/netlists-disp_vhdl.adb | 46 | ||||
| -rw-r--r-- | src/synth/netlists-gates.ads | 14 | ||||
| -rw-r--r-- | src/synth/synth-expr.adb | 18 | ||||
| -rw-r--r-- | src/synth/synth-expr.ads | 2 | ||||
| -rw-r--r-- | src/synth/synth-stmts.adb | 20 | 
7 files changed, 130 insertions, 28 deletions
| diff --git a/src/synth/netlists-builders.adb b/src/synth/netlists-builders.adb index bc5e4aa68..957ba565c 100644 --- a/src/synth/netlists-builders.adb +++ b/src/synth/netlists-builders.adb @@ -202,6 +202,28 @@ package body Netlists.Builders is                       Typ => Param_Uns32)));     end Create_Insert_Module; +   procedure Create_Dyn_Insert_Module (Ctxt : Context_Acc) +   is +      Outputs : Port_Desc_Array (0 .. 0); +      Inputs : Port_Desc_Array (0 .. 2); +      Res : Module; +   begin +      Res := New_User_Module +        (Ctxt.Design, New_Sname_Artificial (Get_Identifier ("dyn_insert")), +         Id_Dyn_Insert, 3, 1, 2); +      Ctxt.M_Dyn_Insert := Res; +      Outputs := (0 => Create_Output ("o")); +      Inputs := (0 => Create_Input ("i"), +                 1 => Create_Input ("v"), +                 2 => Create_Input ("p")); +      Set_Port_Desc (Res, Inputs, Outputs); +      Set_Param_Desc +        (Res, (0 => (New_Sname_Artificial (Get_Identifier ("step")), +                     Typ => Param_Uns32), +               1 => (New_Sname_Artificial (Get_Identifier ("offset")), +                     Typ => Param_Uns32))); +   end Create_Dyn_Insert_Module; +     procedure Create_Edge_Module (Ctxt : Context_Acc;                                   Res : out Module;                                   Name : Name_Id) @@ -363,6 +385,7 @@ package body Netlists.Builders is        Create_Extract_Module (Res);        Create_Dyn_Extract_Module (Res);        Create_Insert_Module (Res); +      Create_Dyn_Insert_Module (Res);        Create_Monadic_Module (Design, Res.M_Truncate (Id_Utrunc),                               Get_Identifier ("utrunc"), Id_Utrunc); @@ -630,6 +653,27 @@ package body Netlists.Builders is        return O;     end Build_Insert; +   function Build_Dyn_Insert +     (Ctxt : Context_Acc; +      I : Net; V : Net; P : Net; Step : Uns32; Off : Int32) +     return Net +   is +      Wd : constant Width := Get_Width (I); +      pragma Assert (Wd /= No_Width); +      Inst : Instance; +      O : Net; +   begin +      Inst := New_Internal_Instance (Ctxt, Ctxt.M_Dyn_Insert); +      O := Get_Output (Inst, 0); +      Set_Width (O, Wd); +      Connect (Get_Input (Inst, 0), I); +      Connect (Get_Input (Inst, 1), V); +      Connect (Get_Input (Inst, 2), P); +      Set_Param_Uns32 (Inst, 0, Step); +      Set_Param_Uns32 (Inst, 1, To_Uns32 (Off)); +      return O; +   end Build_Dyn_Insert; +     function Build_Object (Ctxt : Context_Acc; M : Module; W : Width) return Net     is        Inst : Instance; @@ -775,12 +819,11 @@ package body Netlists.Builders is     function Build_Dyn_Extract       (Ctxt : Context_Acc; -      I : Net; V : Net; Step : Uns32; Off : Uns32; W : Width) return Net +      I : Net; P : Net; Step : Uns32; Off : Int32; W : Width) return Net     is        Wd : constant Width := Get_Width (I);        pragma Assert (Wd /= No_Width);        pragma Assert (W > 0); -      pragma Assert (W + Off <= Wd);        Inst : Instance;        O : Net;     begin @@ -788,9 +831,9 @@ package body Netlists.Builders is        O := Get_Output (Inst, 0);        Set_Width (O, W);        Connect (Get_Input (Inst, 0), I); -      Connect (Get_Input (Inst, 1), V); +      Connect (Get_Input (Inst, 1), P);        Set_Param_Uns32 (Inst, 0, Step); -      Set_Param_Uns32 (Inst, 1, Off); +      Set_Param_Uns32 (Inst, 1, To_Uns32 (Off));        return O;     end Build_Dyn_Extract; diff --git a/src/synth/netlists-builders.ads b/src/synth/netlists-builders.ads index 644e558c4..214484168 100644 --- a/src/synth/netlists-builders.ads +++ b/src/synth/netlists-builders.ads @@ -73,13 +73,15 @@ package Netlists.Builders is       (Ctxt : Context_Acc; I : Net; Off, W : Width) return Net;     function Build_Extract_Bit       (Ctxt : Context_Acc; I : Net; Off : Width) return Net; -     function Build_Dyn_Extract       (Ctxt : Context_Acc; -      I : Net; V : Net; Step : Uns32; Off : Uns32; W : Width) return Net; +      I : Net; P : Net; Step : Uns32; Off : Int32; W : Width) return Net;     function Build_Insert       (Ctxt : Context_Acc; I : Net; V : Net; Off : Width) return Net; +   function Build_Dyn_Insert +     (Ctxt : Context_Acc; I : Net; V : Net; P : Net; Step : Uns32; Off : Int32) +     return Net;     function Build_Output (Ctxt : Context_Acc; W : Width) return Net;     function Build_Signal (Ctxt : Context_Acc; Name : Sname; W : Width) @@ -131,5 +133,6 @@ private        M_Extract : Module;        M_Insert : Module;        M_Dyn_Extract : Module; +      M_Dyn_Insert : Module;     end record;  end Netlists.Builders; diff --git a/src/synth/netlists-disp_vhdl.adb b/src/synth/netlists-disp_vhdl.adb index 44d8ad848..42916179e 100644 --- a/src/synth/netlists-disp_vhdl.adb +++ b/src/synth/netlists-disp_vhdl.adb @@ -449,6 +449,52 @@ package body Netlists.Disp_Vhdl is                 Put_Uns32 (Off);                 Put_Line (");");              end; +         when Id_Insert => +            declare +               O : constant Net := Get_Output (Inst, 0); +               Ow : constant Width := Get_Width (O); +               Iw : constant Width := Get_Width (Get_Input_Net (Inst, 1)); +               Off : constant Uns32 := Get_Param_Uns32 (Inst, 0); +            begin +               Disp_Template +                 ("  process (\i0, \i1)" & NL & +                  "  begin" & NL & +                  "    \o0 <= \i0;" & NL, +                  Inst, (0 => Ow - 1)); +               if Iw > 1 then +                  Disp_Template ("    \o0 (\n0 downto \n1)", Inst, +                                 (0 => Off + Iw - 1, 1 => Off)); +               else +                  Disp_Template ("    \o0 (\n0)", Inst, (0 => Off)); +               end if; +               Disp_Template +                 (" <= \i1;" & NL & +                  "  end process;" & NL, Inst); +            end; +         when Id_Dyn_Insert => +            declare +               --  I0: Input, I1: Value, I2: position +               --  P0: Step, P1: offset +               O : constant Net := Get_Output (Inst, 0); +               Ow : constant Width := Get_Width (O); +               Iw : constant Width := Get_Width (Get_Input_Net (Inst, 1)); +               Off : constant Uns32 := Get_Param_Uns32 (Inst, 0); +            begin +               Disp_Template +                 ("  process (\i0, \i1)" & NL & +                  "  begin" & NL & +                  "    \o0 <= \i0;" & NL, +                  Inst, (0 => Ow - 1)); +               if Iw > 1 then +                  Disp_Template ("    \o0 (\n0 downto \n1)", Inst, +                                 (0 => Off + Iw - 1, 1 => Off)); +               else +                  Disp_Template ("    \o0 (\n0)", Inst, (0 => Off)); +               end if; +               Disp_Template +                 (" <= \i1;" & NL & +                  "  end process;" & NL, Inst); +            end;           when Id_Const_UB32 =>              declare                 O : constant Net := Get_Output (Inst, 0); diff --git a/src/synth/netlists-gates.ads b/src/synth/netlists-gates.ads index 60955221c..120088760 100644 --- a/src/synth/netlists-gates.ads +++ b/src/synth/netlists-gates.ads @@ -117,13 +117,19 @@ package Netlists.Gates is     --  OUT := IN0[IN1*STEP+OFF+WD-1:IN1*STEP+OFF]     Id_Dyn_Extract : constant Module_Id := 47; -   --  This gate has two inputs A, B and one parameter POS. -   --  It replaces bits POS + width(B) - 1 .. POS of A by B, ie: -   --  T := A; -   --  T (POS + width(B) - 1 .. POS) := B +   --  This gate has two inputs I, V and one parameter POS. +   --  It replaces bits POS + width(V) - 1 .. POS of I by V, ie: +   --  T := I; +   --  T [POS+width(V)-1:POS] := V     --  OUT := T.     Id_Insert : constant Module_Id := 48; +   --  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 := 49; +     --  Positive/rising edge detector.  This is a pseudo gate.     --  A negative edge detector can be made using by negating the clock before     --  the detector. diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb index 0c7b636b4..4dfa7225e 100644 --- a/src/synth/synth-expr.adb +++ b/src/synth/synth-expr.adb @@ -1021,7 +1021,7 @@ package body Synth.Expr is                                         Right : Net;                                         Inp : out Net;                                         Step : out Uns32; -                                       Off : out Uns32; +                                       Off : out Int32;                                         Width : out Uns32)     is        L_Inp, R_Inp : Net; @@ -1047,7 +1047,7 @@ package body Synth.Expr is        if L_Inp /= R_Inp then           Error_Msg_Synth -           (+Loc, "cannot extract same variable factor for dynamic slice"); +           (+Loc, "cannot extract same variable part for dynamic slice");           return;        end if;        Inp := L_Inp; @@ -1062,10 +1062,10 @@ package body Synth.Expr is        case Pfx_Bnd.Dir is           when Iir_To => -            Off := Uns32 (L_Add - Pfx_Bnd.Left); +            Off := L_Add - Pfx_Bnd.Left;              Width := Uns32 (R_Add - L_Add + 1);           when Iir_Downto => -            Off := Uns32 (R_Add - Pfx_Bnd.Right); +            Off := R_Add - Pfx_Bnd.Right;              Width := Uns32 (L_Add - R_Add + 1);        end case;     end Synth_Extract_Dyn_Suffix; @@ -1076,7 +1076,7 @@ package body Synth.Expr is                                   Res_Bnd : out Value_Bound_Acc;                                   Inp : out Net;                                   Step : out Uns32; -                                 Off : out Uns32; +                                 Off : out Int32;                                   Wd : out Uns32)     is        Expr : constant Node := Get_Suffix (Name); @@ -1133,7 +1133,7 @@ package body Synth.Expr is                                      Len => Wd,                                      Left => Int32 (Left.Scal),                                      Right => Int32 (Right.Scal))); -               Off := Uns32 (Pfx_Bnd.Right - Res_Bnd.Right); +               Off := Pfx_Bnd.Right - Res_Bnd.Right;              when Iir_Downto =>                 Wd := Width (Left.Scal - Right.Scal + 1);                 Res_Bnd := Create_Value_Bound @@ -1141,7 +1141,7 @@ package body Synth.Expr is                                      Len => Wd,                                      Left => Int32 (Left.Scal),                                      Right => Int32 (Right.Scal))); -               Off := Uns32 (Res_Bnd.Right - Pfx_Bnd.Right); +               Off := Res_Bnd.Right - Pfx_Bnd.Right;           end case;        end if;     end Synth_Slice_Suffix; @@ -1155,7 +1155,7 @@ package body Synth.Expr is        Res_Bnd : Value_Bound_Acc;        Inp : Net;        Step : Uns32; -      Off : Uns32; +      Off : Int32;        Wd : Uns32;     begin        Bnd := Extract_Bound (Pfx); @@ -1170,7 +1170,7 @@ package body Synth.Expr is           return Create_Value_Net             (Build_Extract (Build_Context,                             Get_Net (Pfx, Get_Type (Pfx_Node)), -                           Off, Wd), +                           Uns32 (Off), Wd),              Res_Bnd);        end if;     end Synth_Slice_Name; diff --git a/src/synth/synth-expr.ads b/src/synth/synth-expr.ads index 84c7e6860..f41eb626d 100644 --- a/src/synth/synth-expr.ads +++ b/src/synth/synth-expr.ads @@ -62,6 +62,6 @@ package Synth.Expr is                                   Res_Bnd : out Value_Bound_Acc;                                   Inp : out Net;                                   Step : out Uns32; -                                 Off : out Uns32; +                                 Off : out Int32;                                   Wd : out Uns32);  end Synth.Expr; diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index f0240836a..c83c44b56 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -154,12 +154,14 @@ package body Synth.Stmts is                 Pfx : constant Node := Get_Prefix (Target);                 Targ : constant Value_Acc :=                   Get_Value (Syn_Inst, Get_Base_Name (Pfx)); -               V : Net;                 Res_Bnd : Value_Bound_Acc;                 Inp : Net;                 Step : Uns32; -               Off : Uns32; +               Off : Int32;                 Wd : Uns32; +               I : Net; +               V : Net; +               Res : Net;              begin                 if Targ.Kind /= Value_Wire then                    --  Only support assignment of vector. @@ -167,14 +169,16 @@ package body Synth.Stmts is                 end if;                 Synth_Slice_Suffix (Syn_Inst, Target, Extract_Bound (Targ),                                     Res_Bnd, Inp, Step, Off, Wd); -               if Step /= 0 then -                  raise Internal_Error; +               I := Get_Net (Targ, Get_Type (Pfx)); +               V := Get_Net (Val, Get_Type (Target)); +               if Inp /= No_Net then +                  Res := Build_Dyn_Insert +                    (Build_Context, I, V, Inp, Step, Off); +               else +                  Res := Build_Insert (Build_Context, I, V, Uns32 (Off));                 end if; -               V := Build_Insert (Build_Context, -                                  Get_Net (Targ, Get_Type (Pfx)), -                                  Get_Net (Val, Get_Type (Target)), Off);                 Synth_Assign -                 (Targ, Create_Value_Net (V, Res_Bnd), Get_Type (Pfx)); +                 (Targ, Create_Value_Net (Res, Res_Bnd), Get_Type (Pfx));              end;           when others =>              Error_Kind ("synth_assignment", Target); | 
