diff options
-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; |