aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-03-13 05:40:07 +0100
committerTristan Gingold <tgingold@free.fr>2020-03-13 06:30:35 +0100
commit32e785f4108e1b4afd9a4aa20b908fb5c11cb737 (patch)
treeb84a2fe34a0d9fabbd47d4368945a1b733b6f7a8
parent0c130072578b486ad74e19e96571c500138f81dc (diff)
downloadghdl-32e785f4108e1b4afd9a4aa20b908fb5c11cb737.tar.gz
ghdl-32e785f4108e1b4afd9a4aa20b908fb5c11cb737.tar.bz2
ghdl-32e785f4108e1b4afd9a4aa20b908fb5c11cb737.zip
synth-static_oper: handle unsigned "<".
-rw-r--r--src/synth/synth-ieee-std_logic_1164.ads6
-rw-r--r--src/synth/synth-static_oper.adb61
2 files changed, 66 insertions, 1 deletions
diff --git a/src/synth/synth-ieee-std_logic_1164.ads b/src/synth/synth-ieee-std_logic_1164.ads
index 433825e86..a328f6dec 100644
--- a/src/synth/synth-ieee-std_logic_1164.ads
+++ b/src/synth/synth-ieee-std_logic_1164.ads
@@ -35,12 +35,18 @@ package Synth.Ieee.Std_Logic_1164 is
'-' -- Don't care.
);
+ subtype X01 is Std_Ulogic range 'X' .. '1';
+
-- 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;
+ type Table_1d_X01 is array (Std_Ulogic) of X01;
+
+ To_X01 : constant Table_1d_X01 := "XX01XX01X";
+
And_Table : constant Table_2d :=
-- UX01ZWLH-
("UU0UUU0UU", -- U
diff --git a/src/synth/synth-static_oper.adb b/src/synth/synth-static_oper.adb
index 5af38cc42..30169c8a4 100644
--- a/src/synth/synth-static_oper.adb
+++ b/src/synth/synth-static_oper.adb
@@ -41,7 +41,8 @@ package body Synth.Static_Oper is
-- (math library) on unix systems.
pragma Linker_Options ("-lm");
- -- From openiee:
+ type Compare_Type is
+ (Compare_Less, Compare_Equal, Compare_Greater, Compare_Unknown);
type Static_Arr_Kind is (Sarr_Value, Sarr_Net);
@@ -106,6 +107,56 @@ package body Synth.Static_Oper is
end case;
end Get_Static_Std_Logic;
+ function Synth_Ucompare (Left, Right : Value_Acc) return Compare_Type
+ is
+ Lw : constant Uns32 := Left.Typ.W;
+ Rw : constant Uns32 := Right.Typ.W;
+ Larr : constant Static_Arr_Type := Get_Static_Array (Left);
+ Rarr : constant Static_Arr_Type := Get_Static_Array (Right);
+ Len : constant Uns32 := Uns32'Min (Left.Typ.W, Right.Typ.W);
+ L, R : Std_Ulogic;
+ begin
+ if Lw > Rw then
+ for I in 0 .. Lw - Rw - 1 loop
+ case To_X01 (Get_Static_Std_Logic (Larr, I)) is
+ when '0' =>
+ null;
+ when '1' =>
+ return Compare_Greater;
+ when 'X' =>
+ -- TODO: assert
+ return Compare_Unknown;
+ end case;
+ end loop;
+ else
+ for I in 0 .. Rw - Lw - 1 loop
+ case To_X01 (Get_Static_Std_Logic (Rarr, I)) is
+ when '0' =>
+ null;
+ when '1' =>
+ return Compare_Less;
+ when 'X' =>
+ -- TODO: assert
+ return Compare_Unknown;
+ end case;
+ end loop;
+ end if;
+
+ for I in 0 .. Len loop
+ L := To_X01 (Get_Static_Std_Logic (Larr, Lw - Len + I));
+ R := To_X01 (Get_Static_Std_Logic (Rarr, Rw - Len + I));
+ if L = 'X' or R = 'X' then
+ -- TODO: assert
+ return Compare_Unknown;
+ elsif L = '1' and R = '0' then
+ return Compare_Greater;
+ elsif L = '0' and R = '1' then
+ return Compare_Less;
+ end if;
+ end loop;
+ return Compare_Equal;
+ end Synth_Ucompare;
+
function Create_Res_Bound (Prev : Type_Acc) return Type_Acc is
begin
if Prev.Vbound.Dir = Iir_Downto
@@ -570,6 +621,14 @@ package body Synth.Static_Oper is
Get_Static_Ulogic (Right))),
Res_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Gt_Uns_Uns =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Synth_Ucompare (Left, Right) = Compare_Greater;
+ return Create_Value_Discrete (Boolean'Pos (Res), Res_Typ);
+ end;
+
when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Uns =>
return Synth_Add_Uns_Uns (Left, Right, Expr);