aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-05-27 08:00:42 +0200
committerTristan Gingold <tgingold@free.fr>2020-05-27 08:00:42 +0200
commit67f926fc1323c375d14fee36a092e39a92d505dd (patch)
tree2721ed6d11218bd9db3358e913d08f874dc9bc6a /src
parentdefe3b033f1c3026312c94e5ce661172c670e9a5 (diff)
downloadghdl-67f926fc1323c375d14fee36a092e39a92d505dd.tar.gz
ghdl-67f926fc1323c375d14fee36a092e39a92d505dd.tar.bz2
ghdl-67f926fc1323c375d14fee36a092e39a92d505dd.zip
synth: handle reduction operators. Fix #1342
Diffstat (limited to 'src')
-rw-r--r--src/synth/ghdlsynth_gates.h15
-rw-r--r--src/synth/netlists-builders.adb2
-rw-r--r--src/synth/netlists-disp_vhdl.adb16
-rw-r--r--src/synth/netlists-gates.ads17
-rw-r--r--src/synth/synth-oper.adb25
-rw-r--r--src/synth/synth-static_oper.adb2
-rw-r--r--src/vhdl/vhdl-ieee-std_logic_1164.adb14
-rw-r--r--src/vhdl/vhdl-nodes.ads8
8 files changed, 72 insertions, 27 deletions
diff --git a/src/synth/ghdlsynth_gates.h b/src/synth/ghdlsynth_gates.h
index 951b9dc2b..78e4a6ef9 100644
--- a/src/synth/ghdlsynth_gates.h
+++ b/src/synth/ghdlsynth_gates.h
@@ -46,13 +46,14 @@ enum Module_Id {
Id_Sgt = 39,
Id_Red_And = 40,
Id_Red_Or = 41,
- Id_Concat2 = 42,
- Id_Concat3 = 43,
- Id_Concat4 = 44,
- Id_Concatn = 45,
- Id_Mux2 = 46,
- Id_Mux4 = 47,
- Id_Pmux = 48,
+ Id_Red_Xor = 42,
+ Id_Concat2 = 43,
+ Id_Concat3 = 44,
+ Id_Concat4 = 45,
+ Id_Concatn = 46,
+ Id_Mux2 = 47,
+ Id_Mux4 = 48,
+ Id_Pmux = 49,
Id_Signal = 52,
Id_Isignal = 53,
Id_Output = 54,
diff --git a/src/synth/netlists-builders.adb b/src/synth/netlists-builders.adb
index 626debfa7..7e8f7b3f7 100644
--- a/src/synth/netlists-builders.adb
+++ b/src/synth/netlists-builders.adb
@@ -748,6 +748,8 @@ package body Netlists.Builders is
Get_Identifier ("red_or"), Id_Red_Or);
Create_Monadic_Module (Design, Res.M_Reduce (Id_Red_And),
Get_Identifier ("red_and"), Id_Red_And);
+ Create_Monadic_Module (Design, Res.M_Reduce (Id_Red_Xor),
+ Get_Identifier ("red_xor"), Id_Red_Xor);
Create_Edge_Module (Res);
diff --git a/src/synth/netlists-disp_vhdl.adb b/src/synth/netlists-disp_vhdl.adb
index ef1ebe3ff..513dadbbb 100644
--- a/src/synth/netlists-disp_vhdl.adb
+++ b/src/synth/netlists-disp_vhdl.adb
@@ -1296,6 +1296,22 @@ package body Netlists.Disp_Vhdl is
(" \o0 <= \i0; -- reduce and" & NL, Inst);
end if;
end;
+ when Id_Red_Xor =>
+ declare
+ Iw : constant Width := Get_Width (Get_Input_Net (Inst, 0));
+ begin
+ if Iw > 1 then
+ Disp_Template (" \o0 <= \i0(0)", Inst);
+ for I in 1 .. Iw - 1 loop
+ Disp_Template (" xor \i0(\n0)", Inst, (0 => I));
+ end loop;
+ Disp_Template (";" & NL, Inst);
+ else
+ Disp_Template
+ (" \o0 <= \i0; -- reduce xor" & NL, Inst);
+ end if;
+ end;
+
when Id_Posedge =>
Disp_Template
(" \o0 <= '1' when rising_edge (\i0) else '0';" & NL, Inst);
diff --git a/src/synth/netlists-gates.ads b/src/synth/netlists-gates.ads
index bef8c3245..8fe40d83d 100644
--- a/src/synth/netlists-gates.ads
+++ b/src/synth/netlists-gates.ads
@@ -85,30 +85,31 @@ package Netlists.Gates is
Id_Red_And : constant Module_Id := 40;
Id_Red_Or : constant Module_Id := 41;
+ Id_Red_Xor : constant Module_Id := 42;
- subtype Reduce_Module_Id is Module_Id range Id_Red_And .. Id_Red_Or;
+ subtype Reduce_Module_Id is Module_Id range Id_Red_And .. Id_Red_Xor;
- Id_Concat2 : constant Module_Id := 42;
- Id_Concat3 : constant Module_Id := 43;
- Id_Concat4 : constant Module_Id := 44;
+ Id_Concat2 : constant Module_Id := 43;
+ Id_Concat3 : constant Module_Id := 44;
+ Id_Concat4 : constant Module_Id := 45;
subtype Concat_Module_Id is Module_Id range Id_Concat2 .. Id_Concat4;
-- Concatenation with N inputs.
- Id_Concatn : constant Module_Id := 45;
+ Id_Concatn : constant Module_Id := 46;
-- Inputs: s, i0, i1
-- Output: o
- Id_Mux2 : constant Module_Id := 46;
+ Id_Mux2 : constant Module_Id := 47;
-- Inputs: s, i0, i1, s2, s3
-- Output: o
- Id_Mux4 : constant Module_Id := 47;
+ Id_Mux4 : constant Module_Id := 48;
-- Inputs: 0: Selector as one-hot encoding
-- 1: Default value (when the selector is 0)
-- 2..1+W: values (2: MSB of sel, 1+W: LSB of sel)
-- Output: 0: selected value
- Id_Pmux : constant Module_Id := 48;
+ Id_Pmux : constant Module_Id := 49;
subtype Mux_Module_Id is Module_Id range Id_Mux2 .. Id_Mux4;
diff --git a/src/synth/synth-oper.adb b/src/synth/synth-oper.adb
index a63a0a571..3059298f3 100644
--- a/src/synth/synth-oper.adb
+++ b/src/synth/synth-oper.adb
@@ -1430,13 +1430,18 @@ package body Synth.Oper is
return Create_Value_Net (N, Create_Res_Bound (Operand));
end Synth_Vec_Monadic;
- function Synth_Vec_Reduce_Monadic (Id : Reduce_Module_Id) return Valtyp
+ function Synth_Vec_Reduce_Monadic
+ (Id : Reduce_Module_Id; Neg : Boolean := False) return Valtyp
is
Op: constant Net := Get_Net (Ctxt, Operand);
N : Net;
begin
N := Build_Reduce (Ctxt, Id, Op);
Set_Location (N, Loc);
+ if Neg then
+ N := Build_Monadic (Ctxt, Id_Not, N);
+ Set_Location (N, Loc);
+ end if;
return Create_Value_Net (N, Operand.Typ.Vec_El);
end Synth_Vec_Reduce_Monadic;
begin
@@ -1471,10 +1476,20 @@ package body Synth.Oper is
return Synth_Vec_Monadic (Id_Neg);
when Iir_Predefined_Ieee_Numeric_Std_Abs_Sgn =>
return Synth_Vec_Monadic (Id_Abs);
- when Iir_Predefined_Ieee_1164_Vector_And_Reduce =>
- return Synth_Vec_Reduce_Monadic(Id_Red_And);
- when Iir_Predefined_Ieee_1164_Vector_Or_Reduce =>
- return Synth_Vec_Reduce_Monadic(Id_Red_Or);
+
+ when Iir_Predefined_Ieee_1164_And_Suv =>
+ return Synth_Vec_Reduce_Monadic (Id_Red_And);
+ when Iir_Predefined_Ieee_1164_Nand_Suv =>
+ return Synth_Vec_Reduce_Monadic (Id_Red_And, True);
+ when Iir_Predefined_Ieee_1164_Or_Suv =>
+ return Synth_Vec_Reduce_Monadic (Id_Red_Or);
+ when Iir_Predefined_Ieee_1164_Nor_Suv =>
+ return Synth_Vec_Reduce_Monadic (Id_Red_Or, True);
+ when Iir_Predefined_Ieee_1164_Xor_Suv =>
+ return Synth_Vec_Reduce_Monadic (Id_Red_Xor);
+ when Iir_Predefined_Ieee_1164_Xnor_Suv =>
+ return Synth_Vec_Reduce_Monadic (Id_Red_Xor, True);
+
when Iir_Predefined_Ieee_1164_Condition_Operator =>
return Create_Value_Net
(Get_Net (Ctxt, Operand),
diff --git a/src/synth/synth-static_oper.adb b/src/synth/synth-static_oper.adb
index ade651703..8b72dc3e7 100644
--- a/src/synth/synth-static_oper.adb
+++ b/src/synth/synth-static_oper.adb
@@ -697,7 +697,7 @@ package body Synth.Static_Oper is
(Std_Ulogic'Pos (Not_Table (Read_Std_Logic (Operand.Mem, 0))),
Oper_Typ);
- when Iir_Predefined_Ieee_1164_Vector_Or_Reduce =>
+ when Iir_Predefined_Ieee_1164_Or_Suv =>
return Synth_Vector_Reduce ('0', Operand, Or_Table);
when others =>
diff --git a/src/vhdl/vhdl-ieee-std_logic_1164.adb b/src/vhdl/vhdl-ieee-std_logic_1164.adb
index 58fe96229..bb4b12bce 100644
--- a/src/vhdl/vhdl-ieee-std_logic_1164.adb
+++ b/src/vhdl/vhdl-ieee-std_logic_1164.adb
@@ -375,11 +375,17 @@ package body Vhdl.Ieee.Std_Logic_1164 is
when Name_Not =>
Predefined := Iir_Predefined_Ieee_1164_Vector_Not;
when Name_And =>
- Predefined :=
- Iir_Predefined_Ieee_1164_Vector_And_Reduce;
+ Predefined := Iir_Predefined_Ieee_1164_And_Suv;
+ when Name_Nand =>
+ Predefined := Iir_Predefined_Ieee_1164_Nand_Suv;
when Name_Or =>
- Predefined :=
- Iir_Predefined_Ieee_1164_Vector_Or_Reduce;
+ Predefined := Iir_Predefined_Ieee_1164_Or_Suv;
+ when Name_Nor =>
+ Predefined := Iir_Predefined_Ieee_1164_Nor_Suv;
+ when Name_Xor =>
+ Predefined := Iir_Predefined_Ieee_1164_Xor_Suv;
+ when Name_Xnor =>
+ Predefined := Iir_Predefined_Ieee_1164_Xnor_Suv;
when Name_Is_X =>
Predefined :=
Iir_Predefined_Ieee_1164_Scalar_Is_X;
diff --git a/src/vhdl/vhdl-nodes.ads b/src/vhdl/vhdl-nodes.ads
index 2460e7bfc..8f3c003fa 100644
--- a/src/vhdl/vhdl-nodes.ads
+++ b/src/vhdl/vhdl-nodes.ads
@@ -5471,8 +5471,12 @@ package Vhdl.Nodes is
Iir_Predefined_Ieee_1164_Falling_Edge,
-- VHDL-2008 unary logic operators
- Iir_Predefined_Ieee_1164_Vector_And_Reduce,
- Iir_Predefined_Ieee_1164_Vector_Or_Reduce,
+ Iir_Predefined_Ieee_1164_And_Suv,
+ Iir_Predefined_Ieee_1164_Nand_Suv,
+ Iir_Predefined_Ieee_1164_Or_Suv,
+ Iir_Predefined_Ieee_1164_Nor_Suv,
+ Iir_Predefined_Ieee_1164_Xor_Suv,
+ Iir_Predefined_Ieee_1164_Xnor_Suv,
Iir_Predefined_Ieee_1164_Vector_Sll,
Iir_Predefined_Ieee_1164_Vector_Srl,