aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/synth/synth-ieee-numeric_std.adb79
-rw-r--r--src/synth/synth-ieee-numeric_std.ads25
-rw-r--r--src/synth/synth-ieee-std_logic_1164.ads3
-rw-r--r--src/synth/synth-static_oper.adb49
4 files changed, 153 insertions, 3 deletions
diff --git a/src/synth/synth-ieee-numeric_std.adb b/src/synth/synth-ieee-numeric_std.adb
new file mode 100644
index 000000000..56e8742c4
--- /dev/null
+++ b/src/synth/synth-ieee-numeric_std.adb
@@ -0,0 +1,79 @@
+-- numeric_std
+-- Copyright (C) 2019 Tristan Gingold
+--
+-- This file is part of GHDL.
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 2 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+-- MA 02110-1301, USA.
+
+package body Synth.Ieee.Numeric_Std is
+ Null_Vec : constant Std_Logic_Vector (1 .. 0) := (others => '0');
+
+ subtype Sl_01 is Std_Ulogic range '0' .. '1';
+ subtype Sl_X01 is Std_Ulogic range 'X' .. '1';
+
+ type Carry_Array is array (Sl_01, Sl_01, Sl_01) of Sl_01;
+ Compute_Carry : constant Carry_Array :=
+ ('0' => ('0' => ('0' => '0', '1' => '0'),
+ '1' => ('0' => '0', '1' => '1')),
+ '1' => ('0' => ('0' => '0', '1' => '1'),
+ '1' => ('0' => '1', '1' => '1')));
+ Compute_Sum : constant Carry_Array :=
+ ('0' => ('0' => ('0' => '0', '1' => '1'),
+ '1' => ('0' => '1', '1' => '0')),
+ '1' => ('0' => ('0' => '1', '1' => '0'),
+ '1' => ('0' => '0', '1' => '1')));
+
+ type Sl_To_X01_Array is array (Std_Ulogic) of Sl_X01;
+ Sl_To_X01 : constant Sl_To_X01_Array :=
+ ('0' | 'L' => '0', '1' | 'H' => '1', others => 'X');
+
+ function Add_Uns_Uns (L, R : Std_Logic_Vector) return Std_Logic_Vector
+ is
+ pragma Assert (L'First = 1);
+ pragma Assert (R'First = 1);
+ Len : constant Integer := Integer'Max (L'Last, R'Last);
+ subtype Res_Type is Std_Logic_Vector (1 .. Len);
+ Res : Res_Type;
+ Lb, Rb, Carry : Sl_X01;
+ begin
+ if L'Last < 1 or R'Last < 1 then
+ return Null_Vec;
+ end if;
+ Carry := '0';
+ for I in 1 .. Len loop
+ if I > L'Last then
+ Lb := '0';
+ else
+ Lb := Sl_To_X01 (L (I));
+ end if;
+ if I > R'Last then
+ Rb := '0';
+ else
+ Rb := Sl_To_X01 (R (I));
+ end if;
+ if Lb = 'X' or Rb = 'X' then
+ --assert NO_WARNING
+ -- report "NUMERIC_STD.""+"": non logical value detected"
+ -- severity warning;
+ Res := (others => 'X');
+ exit;
+ end if;
+ Res (I) := Compute_Sum (Carry, Rb, Lb);
+ Carry := Compute_Carry (Carry, Rb, Lb);
+ end loop;
+ return Res;
+ end Add_Uns_Uns;
+end Synth.Ieee.Numeric_Std;
diff --git a/src/synth/synth-ieee-numeric_std.ads b/src/synth/synth-ieee-numeric_std.ads
new file mode 100644
index 000000000..051881d0e
--- /dev/null
+++ b/src/synth/synth-ieee-numeric_std.ads
@@ -0,0 +1,25 @@
+-- numeric_std
+-- Copyright (C) 2019 Tristan Gingold
+--
+-- This file is part of GHDL.
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 2 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+-- MA 02110-1301, USA.
+
+with Synth.Ieee.Std_Logic_1164; use Synth.Ieee.Std_Logic_1164;
+
+package Synth.Ieee.Numeric_Std is
+ function Add_Uns_Uns (L, R : Std_Logic_Vector) return Std_Logic_Vector;
+end Synth.Ieee.Numeric_Std;
diff --git a/src/synth/synth-ieee-std_logic_1164.ads b/src/synth/synth-ieee-std_logic_1164.ads
index 36ef3bc34..f54ef0257 100644
--- a/src/synth/synth-ieee-std_logic_1164.ads
+++ b/src/synth/synth-ieee-std_logic_1164.ads
@@ -35,6 +35,9 @@ package Synth.Ieee.Std_Logic_1164 is
'-' -- Don't care.
);
+ -- Vector of logic state.
+ type Std_Logic_Vector is array (Natural range <>) of Std_Ulogic;
+
-- type Table_1d is array (Std_Ulogic) of Std_Ulogic;
type Table_2d is array (Std_Ulogic, Std_Ulogic) of Std_Ulogic;
diff --git a/src/synth/synth-static_oper.adb b/src/synth/synth-static_oper.adb
index efa59989b..9bf3ddb0d 100644
--- a/src/synth/synth-static_oper.adb
+++ b/src/synth/synth-static_oper.adb
@@ -23,7 +23,8 @@ with Types; use Types;
with Synth.Errors; use Synth.Errors;
with Synth.Source; use Synth.Source;
with Synth.Expr; use Synth.Expr;
-with Synth.Ieee.Std_Logic_1164;
+with Synth.Ieee.Std_Logic_1164; use Synth.Ieee.Std_Logic_1164;
+with Synth.Ieee.Numeric_Std; use Synth.Ieee.Numeric_Std;
package body Synth.Static_Oper is
-- From openiee:
@@ -43,7 +44,6 @@ package body Synth.Static_Oper is
function Synth_Vector_And (L, R : Value_Acc; Loc : Syn_Src)
return Value_Acc
is
- use Synth.Ieee.Std_Logic_1164;
El_Typ : constant Type_Acc := L.Typ.Vec_El;
Arr : Value_Array_Acc;
begin
@@ -65,9 +65,49 @@ package body Synth.Static_Oper is
end;
end loop;
- return Create_Value_Array (Create_Res_Bound (L.Typ), Arr);
+ return Create_Value_Const_Array (Create_Res_Bound (L.Typ), Arr);
end Synth_Vector_And;
+ procedure To_Std_Logic_Vector
+ (Val : Value_Acc; Arr : out Std_Logic_Vector) is
+ begin
+ for I in Val.Arr.V'Range loop
+ Arr (Natural (I)) := Std_Ulogic'Val (Val.Arr.V (I).Scal);
+ end loop;
+ end To_Std_Logic_Vector;
+
+ function To_Value_Acc (Vec : Std_Logic_Vector; El_Typ : Type_Acc)
+ return Value_Acc
+ is
+ pragma Assert (Vec'First = 1);
+ Res_Typ : Type_Acc;
+ Arr : Value_Array_Acc;
+ begin
+ Res_Typ := Create_Vec_Type_By_Length (Uns32 (Vec'Last), El_Typ);
+ Arr := Create_Value_Array (Iir_Index32 (Vec'Last));
+ for I in Vec'Range loop
+ Arr.V (Iir_Index32 (I)) :=
+ Create_Value_Discrete (Std_Ulogic'Pos (Vec (I)), El_Typ);
+ end loop;
+ return Create_Value_Const_Array (Res_Typ, Arr);
+ end To_Value_Acc;
+
+ function Synth_Add_Uns_Uns (L, R : Value_Acc; Loc : Syn_Src)
+ return Value_Acc
+ is
+ pragma Unreferenced (Loc);
+ L_Arr : Std_Logic_Vector (1 .. Natural (L.Arr.Len));
+ R_Arr : Std_Logic_Vector (1 .. Natural (R.Arr.Len));
+ begin
+ To_Std_Logic_Vector (L, L_Arr);
+ To_Std_Logic_Vector (R, R_Arr);
+ declare
+ Res_Arr : constant Std_Logic_Vector := Add_Uns_Uns (L_Arr, R_Arr);
+ begin
+ return To_Value_Acc (Res_Arr, L.Typ.Vec_El);
+ end;
+ end Synth_Add_Uns_Uns;
+
function Synth_Static_Dyadic_Predefined (Syn_Inst : Synth_Instance_Acc;
Imp : Node;
Left : Value_Acc;
@@ -149,6 +189,9 @@ package body Synth.Static_Oper is
when Iir_Predefined_Ieee_1164_Vector_And =>
return Synth_Vector_And (Left, Right, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Uns =>
+ return Synth_Add_Uns_Uns (Left, Right, Expr);
+
when others =>
Error_Msg_Synth
(+Expr, "synth_static_dyadic_predefined: unhandled "