diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/synth/ghdlsynth_gates.h | 2 | ||||
| -rw-r--r-- | src/synth/netlists-builders.adb | 49 | ||||
| -rw-r--r-- | src/synth/netlists-builders.ads | 6 | ||||
| -rw-r--r-- | src/synth/netlists-disp_vhdl.adb | 31 | ||||
| -rw-r--r-- | src/synth/netlists-gates.ads | 4 | ||||
| -rw-r--r-- | src/synth/synth-decls.adb | 5 | ||||
| -rw-r--r-- | src/synth/synth-stmts.adb | 74 | ||||
| -rw-r--r-- | src/synth/synth-stmts.ads | 2 | 
8 files changed, 115 insertions, 58 deletions
| diff --git a/src/synth/ghdlsynth_gates.h b/src/synth/ghdlsynth_gates.h index f8310ec9c..94529f356 100644 --- a/src/synth/ghdlsynth_gates.h +++ b/src/synth/ghdlsynth_gates.h @@ -62,7 +62,7 @@ enum Module_Id {     Id_Dyn_Extract = 69,     Id_Dyn_Insert = 70,     Id_Memidx1 = 71, -   Id_Memidx2 = 72, +   Id_Addidx = 72,     Id_Edge = 80,     Id_Assert = 81,     Id_Assume = 82, diff --git a/src/synth/netlists-builders.adb b/src/synth/netlists-builders.adb index 7c95fd68c..73c86929b 100644 --- a/src/synth/netlists-builders.adb +++ b/src/synth/netlists-builders.adb @@ -264,21 +264,23 @@ package body Netlists.Builders is                       Typ => Param_Uns32),                 1 => (New_Sname_Artificial (Get_Identifier ("max")),                       Typ => Param_Uns32))); +   end Create_Memidx_Module; +   procedure Create_Addidx_Module (Ctxt : Context_Acc) +   is +      Outputs : Port_Desc_Array (0 .. 0); +      Inputs : Port_Desc_Array (0 .. 1); +      Res : Module; +   begin        Res := New_User_Module -        (Ctxt.Design, New_Sname_Artificial (Get_Identifier ("memidx2")), -         Id_Memidx2, 2, 1, 2); -      Ctxt.M_Memidx2 := Res; +        (Ctxt.Design, New_Sname_Artificial (Get_Identifier ("addidx")), +         Id_Addidx, 2, 1, 0); +      Ctxt.M_Addidx := Res;        Outputs := (0 => Create_Output ("o")); -      Inputs := (0 => Create_Input ("i"), -                 1 => Create_Input ("add")); +      Inputs := (0 => Create_Input ("i0"), +                 1 => Create_Input ("i1"));        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 ("max")), -                     Typ => Param_Uns32))); -   end Create_Memidx_Module; +   end Create_Addidx_Module;     procedure Create_Edge_Module (Ctxt : Context_Acc;                                   Res : out Module; @@ -512,6 +514,7 @@ package body Netlists.Builders is        Create_Dyn_Extract_Module (Res);        Create_Dyn_Insert_Module (Res);        Create_Memidx_Module (Res); +      Create_Addidx_Module (Res);        Create_Monadic_Module (Design, Res.M_Truncate (Id_Utrunc),                               Get_Identifier ("utrunc"), Id_Utrunc); @@ -993,26 +996,22 @@ package body Netlists.Builders is        return O;     end Build_Memidx1; -   function Build_Memidx2 -     (Ctxt : Context_Acc; -      I : Net; Add : Net; Step : Uns32; Max : Uns32; W : Width) return Net +   function Build_Addidx (Ctxt : Context_Acc; L, R : Net) return Net     is -      pragma Assert (Get_Width (I) /= No_Width); -      pragma Assert (Get_Width (Add) /= No_Width); -      pragma Assert (Step > 0); -      pragma Assert (W > 0); +      Wl : constant Width := Get_Width (L); +      Wr : constant Width := Get_Width (R); +      pragma Assert (Wl > 0); +      pragma Assert (Wr > 0);        Inst : Instance;        O : Net;     begin -      Inst := New_Internal_Instance (Ctxt, Ctxt.M_Memidx2); +      Inst := New_Internal_Instance (Ctxt, Ctxt.M_Addidx);        O := Get_Output (Inst, 0); -      Set_Width (O, W); -      Connect (Get_Input (Inst, 0), I); -      Connect (Get_Input (Inst, 1), Add); -      Set_Param_Uns32 (Inst, 0, Step); -      Set_Param_Uns32 (Inst, 1, Max); +      Set_Width (O, Width'Max (Wl, Wr)); +      Connect (Get_Input (Inst, 0), L); +      Connect (Get_Input (Inst, 1), R);        return O; -   end Build_Memidx2; +   end Build_Addidx;     function Build_Object (Ctxt : Context_Acc; M : Module; W : Width) return Net     is diff --git a/src/synth/netlists-builders.ads b/src/synth/netlists-builders.ads index 45dfed81d..fc8d65dd4 100644 --- a/src/synth/netlists-builders.ads +++ b/src/synth/netlists-builders.ads @@ -137,9 +137,7 @@ package Netlists.Builders is     function Build_Memidx1       (Ctxt : Context_Acc;        I : Net; Step : Uns32; Max : Uns32; W : Width) return Net; -   function Build_Memidx2 -     (Ctxt : Context_Acc; -      I : Net; Add : Net; Step : Uns32; Max : Uns32; W : Width) return Net; +   function Build_Addidx (Ctxt : Context_Acc; L, R : Net) return Net;     function Build_Output (Ctxt : Context_Acc; W : Width) return Net;     function Build_Signal (Ctxt : Context_Acc; Name : Sname; W : Width) @@ -210,7 +208,7 @@ private        M_Dyn_Extract : Module;        M_Dyn_Insert : Module;        M_Memidx1 : Module; -      M_Memidx2 : Module; +      M_Addidx : Module;        M_Assert : Module;        M_Assume : Module;        M_Cover : Module; diff --git a/src/synth/netlists-disp_vhdl.adb b/src/synth/netlists-disp_vhdl.adb index 353f14475..1aa362b08 100644 --- a/src/synth/netlists-disp_vhdl.adb +++ b/src/synth/netlists-disp_vhdl.adb @@ -594,13 +594,38 @@ package body Netlists.Disp_Vhdl is              begin                 if Step /= 1 then                    Disp_Template -                    ("  \o0 <= std_logic_vector " -                       & "(resize (resize (\ui0, \n0) * \up0, \n0));" -                       & NL, Inst, (0 => Wd)); +                    ("  \o0 <= std_logic_vector (resize (resize (", Inst); +                  if Get_Width (Get_Input_Net (Inst, 0)) = 1 then +                     Disp_Template ("unsigned'(0 => \i0)", Inst); +                  else +                     Disp_Template ("\ui0", Inst); +                  end if; +                  Disp_Template +                    (", \n0) * \up0, \n0));" & NL, Inst, (0 => Wd));                 else                    Disp_Template ("  \o0 <= \i0;" & NL, Inst);                 end if;              end; +         when Id_Addidx => +            declare +               W0 : constant Width := Get_Width (Get_Input_Net (Inst, 0)); +               W1 : constant Width := Get_Width (Get_Input_Net (Inst, 1)); +            begin +               if W0 > W1 then +                  Disp_Template +                    ("  \o0 <= std_logic_vector (\ui0 + resize(\ui1, \n0));" +                       & NL, Inst, (0 => W0)); +               elsif W0 < W1 then +                  Disp_Template +                    ("  \o0 <= std_logic_vector (resize (\ui0, \n0) + \ui1);" +                       & NL, Inst, (0 => W1)); +               else +                  pragma Assert (W0 = W1); +                  Disp_Template +                    ("  \o0 <= std_logic_vector (\ui0 + \ui1);" +                       & NL, Inst); +               end if; +            end;           when Id_Dyn_Extract =>              declare                 O : constant Net := Get_Output (Inst, 0); diff --git a/src/synth/netlists-gates.ads b/src/synth/netlists-gates.ads index b156b2986..067c6d7c7 100644 --- a/src/synth/netlists-gates.ads +++ b/src/synth/netlists-gates.ads @@ -156,8 +156,8 @@ package Netlists.Gates is     --  OUT := IN0 * STEP,  IN0 < MAX     Id_Memidx1 : constant Module_Id := 71; -   --  OUT := IN0 * STEP + IN1,  IN0 < MAX, size extension. -   Id_Memidx2 : constant Module_Id := 72; +   --  OUT := IN0 + IN1, size extension. +   Id_Addidx : constant Module_Id := 72;     --  Positive/rising edge detector.  This is a pseudo gate.     --  A negative edge detector can be made using by negating the clock before diff --git a/src/synth/synth-decls.adb b/src/synth/synth-decls.adb index 19a5f75ba..fcdc721d0 100644 --- a/src/synth/synth-decls.adb +++ b/src/synth/synth-decls.adb @@ -554,13 +554,16 @@ package body Synth.Decls is              declare                 Obj : Value_Acc;                 Off : Uns32; +               Voff : Net; +               Rdwd : Width;                 Typ : Type_Acc;                 Res : Value_Acc;                 Obj_Type : Type_Acc;              begin                 Obj_Type := Get_Value_Type (Syn_Inst, Get_Type (Decl));                 Stmts.Synth_Assignment_Prefix (Syn_Inst, Get_Name (Decl), -                                              Obj, Off, Typ); +                                              Obj, Off, Voff, Rdwd, Typ); +               pragma Assert (Voff = No_Net);                 Res := Create_Value_Alias (Obj, Off, Typ);                 Res := Synth_Subtype_Conversion (Res, Obj_Type, True, Decl);                 Create_Object (Syn_Inst, Decl, Res); diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index bf4e03a38..da0e3dd39 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -120,12 +120,15 @@ package body Synth.Stmts is                                        Pfx : Node;                                        Dest_Obj : out Value_Acc;                                        Dest_Off : out Uns32; +                                      Dest_Voff : out Net; +                                      Dest_Rdwd : out Width;                                        Dest_Type : out Type_Acc) is     begin        case Get_Kind (Pfx) is           when Iir_Kind_Simple_Name =>              Synth_Assignment_Prefix (Syn_Inst, Get_Named_Entity (Pfx), -                                     Dest_Obj, Dest_Off, Dest_Type); +                                     Dest_Obj, Dest_Off, +                                     Dest_Voff, Dest_Rdwd, Dest_Type);           when Iir_Kind_Interface_Signal_Declaration             | Iir_Kind_Variable_Declaration             | Iir_Kind_Signal_Declaration @@ -135,6 +138,8 @@ package body Synth.Stmts is              begin                 Dest_Obj := Targ;                 Dest_Off := 0; +               Dest_Voff := No_Net; +               Dest_Rdwd := 0;                 Dest_Type := Targ.Typ;              end;           when Iir_Kind_Object_Alias_Declaration => @@ -143,6 +148,8 @@ package body Synth.Stmts is              begin                 Dest_Obj := Targ.A_Obj;                 Dest_Off := Targ.A_Off; +               Dest_Voff := No_Net; +               Dest_Rdwd := 0;                 Dest_Type := Targ.Typ;              end;           when Iir_Kind_Indexed_Name => @@ -150,21 +157,26 @@ package body Synth.Stmts is                 Voff : Net;                 Off : Uns32;                 W : Width; +               Dest_W : Width;              begin -               Synth_Assignment_Prefix (Syn_Inst, Get_Prefix (Pfx), -                                        Dest_Obj, Dest_Off, Dest_Type); +               Synth_Assignment_Prefix +                 (Syn_Inst, Get_Prefix (Pfx), +                  Dest_Obj, Dest_Off, Dest_Voff, Dest_Rdwd, Dest_Type); +               Dest_W := Dest_Type.W;                 Synth_Indexed_Name (Syn_Inst, Pfx, Dest_Type, Voff, Off, W); +               Dest_Off := Dest_Off + Off; +               Dest_Type := Get_Array_Element (Dest_Type); +                 if Voff /= No_Net then -                  Error_Msg_Synth -                    (+Pfx, "dynamic index must be the last suffix"); -               else -                  --  FIXME: check index. -                  null; +                  if Dest_Voff = No_Net then +                     Dest_Voff := Voff; +                     Dest_Rdwd := Dest_W; +                  else +                     raise Internal_Error; +                  end if;                 end if; -               Dest_Off := Dest_Off + Off; -               Dest_Type := Get_Array_Element (Dest_Type);              end;           when Iir_Kind_Selected_Element => @@ -172,8 +184,9 @@ package body Synth.Stmts is                 Idx : constant Iir_Index32 :=                   Get_Element_Position (Get_Named_Entity (Pfx));              begin -               Synth_Assignment_Prefix (Syn_Inst, Get_Prefix (Pfx), -                                        Dest_Obj, Dest_Off, Dest_Type); +               Synth_Assignment_Prefix +                 (Syn_Inst, Get_Prefix (Pfx), +                  Dest_Obj, Dest_Off, Dest_Voff, Dest_Rdwd, Dest_Type);                 Dest_Off := Dest_Off + Dest_Type.Rec.E (Idx + 1).Off;                 Dest_Type := Dest_Type.Rec.E (Idx + 1).Typ;              end; @@ -187,8 +200,9 @@ package body Synth.Stmts is                 Sl_Off : Uns32;                 Wd : Uns32;              begin -               Synth_Assignment_Prefix (Syn_Inst, Get_Prefix (Pfx), -                                        Dest_Obj, Dest_Off, Dest_Type); +               Synth_Assignment_Prefix +                 (Syn_Inst, Get_Prefix (Pfx), +                  Dest_Obj, Dest_Off, Dest_Voff, Dest_Rdwd, Dest_Type);                 Get_Onedimensional_Array_Bounds (Dest_Type, Pfx_Bnd, El_Typ);                 Synth_Slice_Suffix (Syn_Inst, Pfx, Pfx_Bnd, El_Typ.W, @@ -268,9 +282,13 @@ package body Synth.Stmts is              declare                 Obj : Value_Acc;                 Off : Uns32; +               Voff : Net; +               Rdwd : Width;                 Typ : Type_Acc;              begin -               Synth_Assignment_Prefix (Syn_Inst, Target, Obj, Off, Typ); +               Synth_Assignment_Prefix +                 (Syn_Inst, Target, Obj, Off, Voff, Rdwd, Typ); +               pragma Assert (Voff = No_Net);                 return Target_Info'(Kind => Target_Simple,                                     Targ_Type => Typ,                                     Obj => Obj, @@ -284,11 +302,13 @@ package body Synth.Stmts is                 El_Typ : Type_Acc;                 Voff : Net; +               Rdwd : Width;                 Idx_Off : Uns32;                 W : Width;              begin                 Synth_Assignment_Prefix (Syn_Inst, Get_Prefix (Target), -                                        Obj, Off, Typ); +                                        Obj, Off, Voff, Rdwd, Typ); +               pragma Assert (Voff = No_Net);                 Synth_Indexed_Name (Syn_Inst, Target, Typ, Voff, Idx_Off, W);                 El_Typ := Get_Array_Element (Typ); @@ -311,33 +331,43 @@ package body Synth.Stmts is              declare                 Obj : Value_Acc;                 Off : Uns32; +               Voff : Net; +               Rdwd : Width;                 Typ : Type_Acc;                 Pfx_Bnd : Bound_Type;                 El_Typ : Type_Acc;                 Res_Bnd : Bound_Type; -               Inp : Net; +               Sl_Voff : Net;                 Sl_Off : Uns32;                 Wd : Uns32;                 Res_Type : Type_Acc;              begin                 Synth_Assignment_Prefix (Syn_Inst, Get_Prefix (Target), -                                        Obj, Off, Typ); +                                        Obj, Off, Voff, Rdwd, Typ);                 Get_Onedimensional_Array_Bounds (Typ, Pfx_Bnd, El_Typ);                 Synth_Slice_Suffix (Syn_Inst, Target, Pfx_Bnd, El_Typ.W, -                                   Res_Bnd, Inp, Sl_Off, Wd); +                                   Res_Bnd, Sl_Voff, Sl_Off, Wd);                 Res_Type := Create_Vector_Type (Res_Bnd, El_Typ); -               if Inp /= No_Net then +               if Sl_Voff /= No_Net then +                  if Voff /= No_Net then +                     Sl_Voff := Build_Addidx +                       (Get_Build (Syn_Inst), Voff, Sl_Voff); +                  else +                     Rdwd := Typ.W; +                  end if;                    return Target_Info'(Kind => Target_Memory,                                        Targ_Type => Res_Type,                                        Mem_Wid => Obj.W, -                                      Mem_Width => Typ.W, -                                      Mem_Voff => Inp, +                                      Mem_Width => Rdwd, +                                      Mem_Voff => Sl_Voff,                                        Mem_Off => Off + Sl_Off);                 else +                  pragma Assert (Voff = No_Net); +                    return Target_Info'(Kind => Target_Simple,                                        Targ_Type => Res_Type,                                        Obj => Obj, diff --git a/src/synth/synth-stmts.ads b/src/synth/synth-stmts.ads index c583328c0..b561e1853 100644 --- a/src/synth/synth-stmts.ads +++ b/src/synth/synth-stmts.ads @@ -37,6 +37,8 @@ package Synth.Stmts is                                        Pfx : Node;                                        Dest_Obj : out Value_Acc;                                        Dest_Off : out Uns32; +                                      Dest_Voff : out Net; +                                      Dest_Rdwd : out Width;                                        Dest_Type : out Type_Acc);     procedure Synth_Assignment (Syn_Inst : Synth_Instance_Acc; | 
