aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-05-09 08:44:08 +0200
committerTristan Gingold <tgingold@free.fr>2020-05-09 11:22:00 +0200
commitb13b9e9fa26121a68d74589ef35ea5ed45316cd9 (patch)
tree569cb14e705ccada21fef2bfed6dfc497a47e3f1
parent06f3682dc85a965c9d3ccee26d0457e6df2869d6 (diff)
downloadghdl-b13b9e9fa26121a68d74589ef35ea5ed45316cd9.tar.gz
ghdl-b13b9e9fa26121a68d74589ef35ea5ed45316cd9.tar.bz2
ghdl-b13b9e9fa26121a68d74589ef35ea5ed45316cd9.zip
netlists-builders: add Build_Pmux.
-rw-r--r--src/synth/netlists-builders.adb29
-rw-r--r--src/synth/netlists-builders.ads7
-rw-r--r--src/synth/netlists-disp_vhdl.adb29
-rw-r--r--src/synth/netlists-utils.adb3
4 files changed, 67 insertions, 1 deletions
diff --git a/src/synth/netlists-builders.adb b/src/synth/netlists-builders.adb
index 34ba4a3f1..85b2eece9 100644
--- a/src/synth/netlists-builders.adb
+++ b/src/synth/netlists-builders.adb
@@ -426,6 +426,17 @@ package body Netlists.Builders is
(Ctxt.Design, New_Sname_Artificial (Get_Identifier ("mux4"), No_Sname),
Id_Mux4, 5, 1, 0);
Set_Ports_Desc (Ctxt.M_Mux4, Inputs (0 .. 4), Outputs);
+
+ Inputs (0).W := 0;
+ Inputs (1) := Create_Input ("def");
+ Ctxt.M_Pmux := New_User_Module
+ (Ctxt.Design, New_Sname_Artificial (Get_Identifier ("pmux"), No_Sname),
+ Id_Pmux, 2, 1, 1);
+ Set_Ports_Desc (Ctxt.M_Pmux, Inputs (0 .. 1), Outputs);
+ Set_Params_Desc
+ (Ctxt.M_Pmux,
+ (0 => (New_Sname_Artificial (Get_Identifier ("n"), No_Sname),
+ Typ => Param_Uns32)));
end Create_Mux_Modules;
procedure Create_Objects_Module (Ctxt : Context_Acc)
@@ -1030,6 +1041,24 @@ package body Netlists.Builders is
return O;
end Build_Mux4;
+ function Build_Pmux (Ctxt : Context_Acc; Sel : Net; Def : Net) return Net
+ is
+ Sel_W : constant Width := Get_Width (Sel);
+ Def_W : constant Width := Get_Width (Def);
+ Inst : Instance;
+ O : Net;
+ begin
+ Inst := New_Var_Instance (Ctxt.Parent, Ctxt.M_Pmux,
+ New_Internal_Name (Ctxt),
+ 2 + Port_Nbr (Sel_W), 1, 1);
+ Set_Param_Uns32 (Inst, 0, 2 + Sel_W);
+ O := Get_Output (Inst, 0);
+ Set_Width (O, Def_W);
+ Connect (Get_Input (Inst, 0), Sel);
+ Connect (Get_Input (Inst, 1), Def);
+ return O;
+ end Build_Pmux;
+
function Build_Concat2 (Ctxt : Context_Acc; I0, I1 : Net) return Net
is
Inst : Instance;
diff --git a/src/synth/netlists-builders.ads b/src/synth/netlists-builders.ads
index dc45caf04..6a1c0fb82 100644
--- a/src/synth/netlists-builders.ads
+++ b/src/synth/netlists-builders.ads
@@ -96,6 +96,12 @@ package Netlists.Builders is
Sel : Net;
I0, I1, I2, I3 : Net) return Net;
+ -- The width of SEL gives the number of inputs (+ 2).
+ -- The width of DEF (default value) gives the width of the output.
+ function Build_Pmux (Ctxt : Context_Acc;
+ Sel : Net;
+ Def : Net) return Net;
+
-- Build: I0 & I1 [ & I2 [ & I3 ]]
function Build_Concat2 (Ctxt : Context_Acc; I0, I1 : Net) return Net;
function Build_Concat3 (Ctxt : Context_Acc; I0, I1, I2 : Net) return Net;
@@ -232,6 +238,7 @@ private
M_Negedge : Module;
M_Mux2 : Module;
M_Mux4 : Module;
+ M_Pmux : Module;
M_Nop : Module;
M_Output : Module;
M_Ioutput : Module;
diff --git a/src/synth/netlists-disp_vhdl.adb b/src/synth/netlists-disp_vhdl.adb
index 41ef62e36..be60f4c19 100644
--- a/src/synth/netlists-disp_vhdl.adb
+++ b/src/synth/netlists-disp_vhdl.adb
@@ -808,6 +808,33 @@ package body Netlists.Disp_Vhdl is
Put_Line (" end process;");
end Disp_Memory;
+ procedure Disp_Pmux (Inst : Instance)
+ is
+ Def : constant Net := Get_Input_Net (Inst, 0);
+ W : constant Width := Get_Width (Def);
+ Q : constant Character := Get_Lit_Quote (W);
+ begin
+ Disp_Template (" with \i0 select \o0 <=" & NL, Inst);
+ for I in 1 .. W loop
+ Put (" ");
+ Disp_Net_Expr
+ (Get_Input_Net (Inst, Port_Idx (2 + W - I)), Inst, Conv_None);
+ Put (" when ");
+ -- One hot encoding.
+ Put (Q);
+ for J in 1 .. W loop
+ if I = J then
+ Put ('1');
+ else
+ Put ('0');
+ end if;
+ end loop;
+ Put (Q);
+ Put ("," & NL);
+ end loop;
+ Disp_Template (" \i1 when others;" & NL, Inst);
+ end Disp_Pmux;
+
procedure Disp_Instance_Inline (Inst : Instance)
is
Imod : constant Module := Get_Module (Inst);
@@ -1033,6 +1060,8 @@ package body Netlists.Disp_Vhdl is
Put (" ");
Disp_X_Lit (Get_Width (Get_Output (Inst, 0)), 'X');
Put_Line (" when others;");
+ when Id_Pmux =>
+ Disp_Pmux (Inst);
when Id_Add =>
if Get_Width (Get_Output (Inst, 0)) = 1 then
Disp_Template (" \o0 <= \i0 xor \i1; -- add" & NL, Inst);
diff --git a/src/synth/netlists-utils.adb b/src/synth/netlists-utils.adb
index fa1494820..6a8f1a2bf 100644
--- a/src/synth/netlists-utils.adb
+++ b/src/synth/netlists-utils.adb
@@ -30,7 +30,8 @@ package body Netlists.Utils is
M : constant Module := Get_Module (Inst);
begin
case Get_Id (M) is
- when Id_Concatn =>
+ when Id_Concatn
+ | Id_Pmux =>
return Port_Nbr (Get_Param_Uns32 (Inst, 0));
when others =>
if Is_Self_Instance (Inst) then