aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-07-19 08:29:07 +0200
committerTristan Gingold <tgingold@free.fr>2019-07-19 18:48:23 +0200
commit932a2beb675d155b1e71804d7e18f61e166d26bb (patch)
tree93f173cad8f4d4d41bdaaf0f9bad171a7c3ba502
parent51fb29f988e3d4d2cf2192fcc0f0a64d07f9d91e (diff)
downloadghdl-932a2beb675d155b1e71804d7e18f61e166d26bb.tar.gz
ghdl-932a2beb675d155b1e71804d7e18f61e166d26bb.tar.bz2
ghdl-932a2beb675d155b1e71804d7e18f61e166d26bb.zip
synth: add concatn gate
-rw-r--r--src/synth/netlists-builders.adb24
-rw-r--r--src/synth/netlists-builders.ads5
-rw-r--r--src/synth/netlists-disp_vhdl.adb17
-rw-r--r--src/synth/netlists-dump.adb2
-rw-r--r--src/synth/netlists-gates.ads3
-rw-r--r--src/synth/netlists-utils.adb21
-rw-r--r--src/synth/netlists.adb67
-rw-r--r--src/synth/netlists.ads8
-rw-r--r--src/synth/synth-environment.adb11
9 files changed, 126 insertions, 32 deletions
diff --git a/src/synth/netlists-builders.adb b/src/synth/netlists-builders.adb
index 9cb357b34..27a45470d 100644
--- a/src/synth/netlists-builders.adb
+++ b/src/synth/netlists-builders.adb
@@ -115,6 +115,15 @@ package body Netlists.Builders is
Id_Concat4, 4, 1, 0);
Ctxt.M_Concat (Id_Concat4) := Res;
Set_Port_Desc (Res, Inputs (0 .. 3), Outputs);
+
+ Res := New_User_Module
+ (Ctxt.Design, New_Sname_Artificial (Get_Identifier ("concatn")),
+ Id_Concatn, 0, 1, 1);
+ Ctxt.M_Concatn := Res;
+ Set_Port_Desc (Res, Inputs (1 .. 0), Outputs);
+ Set_Param_Desc
+ (Res, (0 => (New_Sname_Artificial (Get_Identifier ("n")),
+ Typ => Param_Uns32)));
end Create_Concat_Modules;
procedure Create_Const_Modules (Ctxt : Context_Acc)
@@ -681,6 +690,21 @@ package body Netlists.Builders is
return O;
end Build_Concat4;
+ function Build_Concatn (Ctxt : Context_Acc; W : Width; Nbr_Inputs : Uns32)
+ return Net
+ is
+ Inst : Instance;
+ O : Net;
+ begin
+ Inst := New_Var_Instance (Ctxt.Parent, Ctxt.M_Concatn,
+ New_Internal_Name (Ctxt),
+ Port_Nbr (Nbr_Inputs), 1, 1);
+ Set_Param_Uns32 (Inst, 0, Nbr_Inputs);
+ O := Get_Output (Inst, 0);
+ Set_Width (O, W);
+ return O;
+ end Build_Concatn;
+
function Build_Trunc
(Ctxt : Context_Acc; Id : Module_Id; I : Net; W : Width) return Net
is
diff --git a/src/synth/netlists-builders.ads b/src/synth/netlists-builders.ads
index 654fc6e9a..67d200ead 100644
--- a/src/synth/netlists-builders.ads
+++ b/src/synth/netlists-builders.ads
@@ -73,6 +73,10 @@ package Netlists.Builders is
function Build_Concat3 (Ctxt : Context_Acc; I0, I1, I2 : Net) return Net;
function Build_Concat4 (Ctxt : Context_Acc; I0, I1, I2, I3 : Net)
return Net;
+ -- NBR_INPUTS is the number of inputs ports, W is the width of the
+ -- output.
+ function Build_Concatn (Ctxt : Context_Acc; W : Width; Nbr_Inputs : Uns32)
+ return Net;
function Build_Trunc
(Ctxt : Context_Acc; Id : Module_Id; I : Net; W : Width) return Net;
@@ -131,6 +135,7 @@ private
M_Monadic : Module_Arr (Monadic_Module_Id);
M_Compare : Module_Arr (Compare_Module_Id);
M_Concat : Module_Arr (Concat_Module_Id);
+ M_Concatn : Module;
M_Const_UB32 : Module;
M_Const_UL32 : Module;
M_Const_Z : Module;
diff --git a/src/synth/netlists-disp_vhdl.adb b/src/synth/netlists-disp_vhdl.adb
index 5525d54ee..2bd1b9911 100644
--- a/src/synth/netlists-disp_vhdl.adb
+++ b/src/synth/netlists-disp_vhdl.adb
@@ -226,6 +226,7 @@ package body Netlists.Disp_Vhdl is
is
Imod : constant Module := Get_Module (Inst);
Idx : Port_Idx;
+ Max_Idx : Port_Idx;
P_Idx : Param_Idx;
Name : Sname;
First : Boolean;
@@ -275,6 +276,7 @@ package body Netlists.Disp_Vhdl is
First := True;
-- Inputs
Idx := 0;
+ Max_Idx := Get_Nbr_Inputs (Imod);
for I of Inputs (Inst) loop
if First then
First := False;
@@ -282,9 +284,11 @@ package body Netlists.Disp_Vhdl is
Put_Line (",");
end if;
Put (" ");
- Put_Interface_Name (Get_Input_Desc (Imod, Idx).Name);
- Idx := Idx + 1;
- Put (" => ");
+ if Idx < Max_Idx then
+ Put_Interface_Name (Get_Input_Desc (Imod, Idx).Name);
+ Idx := Idx + 1;
+ Put (" => ");
+ end if;
Disp_Net_Name (Get_Driver (I));
end loop;
-- Outputs
@@ -625,6 +629,13 @@ package body Netlists.Disp_Vhdl is
Disp_Template (" \o0 <= \i0 & \i1 & \i2;" & NL, Inst);
when Id_Concat4 =>
Disp_Template (" \o0 <= \i0 & \i1 & \i2 & \i3;" & NL, Inst);
+ when Id_Concatn =>
+ Disp_Template (" \o0 <= \i0", Inst);
+ for I in 1 .. Get_Nbr_Inputs (Inst) - 1 loop
+ Disp_Template (" & ", Inst);
+ Disp_Net_Expr (Get_Input_Net (Inst, I), Conv_None);
+ end loop;
+ Disp_Template(";" & NL, Inst);
when Id_Utrunc
| Id_Strunc =>
declare
diff --git a/src/synth/netlists-dump.adb b/src/synth/netlists-dump.adb
index 6ec87ced8..9e04570ff 100644
--- a/src/synth/netlists-dump.adb
+++ b/src/synth/netlists-dump.adb
@@ -419,7 +419,7 @@ package body Netlists.Dump is
Put (']');
end if;
- if Get_Nbr_Inputs (M) > 0 then
+ if Get_Nbr_Inputs (Inst) > 0 then
declare
First : Boolean;
begin
diff --git a/src/synth/netlists-gates.ads b/src/synth/netlists-gates.ads
index 61d5ab8d4..9a077f2f7 100644
--- a/src/synth/netlists-gates.ads
+++ b/src/synth/netlists-gates.ads
@@ -156,4 +156,7 @@ package Netlists.Gates is
Id_Const_SL32 : constant Module_Id := 71;
Id_Const_Z : constant Module_Id := 72;
Id_Const_0 : constant Module_Id := 73;
+
+ -- Concatenation with N inputs.
+ Id_Concatn : constant Module_Id := 80;
end Netlists.Gates;
diff --git a/src/synth/netlists-utils.adb b/src/synth/netlists-utils.adb
index 1b8d08b1a..f04fafb2d 100644
--- a/src/synth/netlists-utils.adb
+++ b/src/synth/netlists-utils.adb
@@ -18,18 +18,23 @@
-- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
-- MA 02110-1301, USA.
-with Netlists.Gates;
+with Netlists.Gates; use Netlists.Gates;
package body Netlists.Utils is
function Get_Nbr_Inputs (Inst : Instance) return Port_Nbr
is
M : constant Module := Get_Module (Inst);
begin
- if Is_Self_Instance (Inst) then
- return Get_Nbr_Outputs (M);
- else
- return Get_Nbr_Inputs (M);
- end if;
+ case Get_Id (M) is
+ when Id_Concatn =>
+ return Port_Nbr (Get_Param_Uns32 (Inst, 0));
+ when others =>
+ if Is_Self_Instance (Inst) then
+ return Get_Nbr_Outputs (M);
+ else
+ return Get_Nbr_Inputs (M);
+ end if;
+ end case;
end Get_Nbr_Inputs;
function Get_Nbr_Outputs (Inst : Instance) return Port_Nbr
@@ -76,9 +81,7 @@ package body Netlists.Utils is
return Get_Driver (Get_Input (Inst, Idx));
end Get_Input_Net;
- function Is_Const (Id : Module_Id) return Boolean
- is
- use Netlists.Gates;
+ function Is_Const (Id : Module_Id) return Boolean is
begin
case Id is
when Id_Const_UB32
diff --git a/src/synth/netlists.adb b/src/synth/netlists.adb
index ef05a7021..f6180f715 100644
--- a/src/synth/netlists.adb
+++ b/src/synth/netlists.adb
@@ -319,8 +319,7 @@ package body Netlists is
Name : Sname;
Nbr_Inputs : Port_Nbr;
Nbr_Outputs : Port_Nbr;
- Nbr_Params : Param_Nbr;
- Outputs_Desc : Port_Desc_Idx)
+ Nbr_Params : Param_Nbr)
return Instance
is
pragma Assert (Is_Valid (Parent));
@@ -331,14 +330,13 @@ package body Netlists is
Params : constant Param_Idx :=
Params_Table.Allocate (Natural (Nbr_Params));
begin
- Instances_Table.Append
- ((Parent => Parent,
- Next_Instance => No_Instance,
- Klass => M,
- Name => Name,
- First_Param => Params,
- First_Input => Inputs,
- First_Output => Outputs));
+ Instances_Table.Append ((Parent => Parent,
+ Next_Instance => No_Instance,
+ Klass => M,
+ Name => Name,
+ First_Param => Params,
+ First_Input => Inputs,
+ First_Output => Outputs));
Res := Instances_Table.Last;
-- Setup inputs.
@@ -354,10 +352,9 @@ package body Netlists is
-- Setup nets.
if Nbr_Outputs > 0 then
for I in 0 .. Nbr_Outputs - 1 loop
- Nets_Table.Table (Outputs + Net (I)) :=
- (Parent => Res,
- First_Sink => No_Input,
- W => Get_Port_Desc (Outputs_Desc + Port_Desc_Idx (I)).W);
+ Nets_Table.Table (Outputs + Net (I)) := (Parent => Res,
+ First_Sink => No_Input,
+ W => 0);
end loop;
end if;
@@ -371,6 +368,19 @@ package body Netlists is
return Res;
end New_Instance_Internal;
+ procedure Set_Outputs_Width_From_Desc (Inst : Instance;
+ Nbr_Outputs : Port_Nbr;
+ Outputs_Desc : Port_Desc_Idx) is
+ begin
+ if Nbr_Outputs > 0 then
+ for I in 0 .. Nbr_Outputs - 1 loop
+ Set_Width
+ (Get_Output (Inst, I),
+ Get_Port_Desc (Outputs_Desc + Port_Desc_Idx (I)).W);
+ end loop;
+ end if;
+ end Set_Outputs_Width_From_Desc;
+
function New_Instance (Parent : Module; M : Module; Name : Sname)
return Instance
is
@@ -380,8 +390,9 @@ package body Netlists is
Res : Instance;
begin
Res := New_Instance_Internal
- (Parent, M, Name, Nbr_Inputs, Nbr_Outputs, Nbr_Params,
- Get_Output_First_Desc (M));
+ (Parent, M, Name, Nbr_Inputs, Nbr_Outputs, Nbr_Params);
+ Set_Outputs_Width_From_Desc
+ (Res, Nbr_Outputs, Get_Output_First_Desc (M));
-- Link instance
Append_Instance (Parent, Res);
@@ -389,6 +400,25 @@ package body Netlists is
return Res;
end New_Instance;
+ function New_Var_Instance (Parent : Module;
+ M : Module;
+ Name : Sname;
+ Nbr_Inputs : Port_Nbr;
+ Nbr_Outputs : Port_Nbr;
+ Nbr_Params : Param_Nbr)
+ return Instance
+ is
+ Res : Instance;
+ begin
+ Res := New_Instance_Internal
+ (Parent, M, Name, Nbr_Inputs, Nbr_Outputs, Nbr_Params);
+
+ -- Link instance
+ Append_Instance (Parent, Res);
+
+ return Res;
+ end New_Var_Instance;
+
function Create_Self_Instance (M : Module) return Instance
is
-- Can be done only once.
@@ -399,8 +429,9 @@ package body Netlists is
begin
-- Swap inputs and outputs; no parameters.
Res := New_Instance_Internal
- (M, M, Get_Name (M), Nbr_Outputs, Nbr_Inputs, 0,
- Get_Input_First_Desc (M));
+ (M, M, Get_Name (M), Nbr_Outputs, Nbr_Inputs, 0);
+ Set_Outputs_Width_From_Desc
+ (Res, Nbr_Inputs, Get_Input_First_Desc (M));
Append_Instance (M, Res);
diff --git a/src/synth/netlists.ads b/src/synth/netlists.ads
index 324d55a31..6cf021ec1 100644
--- a/src/synth/netlists.ads
+++ b/src/synth/netlists.ads
@@ -226,6 +226,14 @@ package Netlists is
-- Instance
function New_Instance (Parent : Module; M : Module; Name : Sname)
return Instance;
+ -- For instances non-fixed number of inputs/outputs/params.
+ function New_Var_Instance (Parent : Module;
+ M : Module;
+ Name : Sname;
+ Nbr_Inputs : Port_Nbr;
+ Nbr_Outputs : Port_Nbr;
+ Nbr_Params : Param_Nbr)
+ return Instance;
-- Mark INST as free, but keep it in the module.
-- Use Remove_Free_Instances for a cleanup.
diff --git a/src/synth/synth-environment.adb b/src/synth/synth-environment.adb
index 3443a741a..0986d5f69 100644
--- a/src/synth/synth-environment.adb
+++ b/src/synth/synth-environment.adb
@@ -345,7 +345,16 @@ package body Synth.Environment is
Get_Conc_Value (Last_Asgn),
Get_Conc_Value (First_Assign));
else
- raise Internal_Error;
+ Value := Build_Concatn (Ctxt, Last_Off, Uns32 (Nbr_Assign));
+ declare
+ Inst : constant Instance := Get_Parent (Value);
+ begin
+ Asgn := First_Assign;
+ for I in reverse 0 .. Nbr_Assign - 1 loop
+ Connect (Get_Input (Inst, Port_Idx (I)), Get_Conc_Value (Asgn));
+ Asgn := Get_Conc_Chain (Asgn);
+ end loop;
+ end;
end if;
end Finalize_Complex_Assignment;