aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/synth/ghdlsynth_gates.h2
-rw-r--r--src/synth/netlists-builders.adb49
-rw-r--r--src/synth/netlists-builders.ads6
-rw-r--r--src/synth/netlists-disp_vhdl.adb31
-rw-r--r--src/synth/netlists-gates.ads4
-rw-r--r--src/synth/synth-decls.adb5
-rw-r--r--src/synth/synth-stmts.adb74
-rw-r--r--src/synth/synth-stmts.ads2
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;