aboutsummaryrefslogtreecommitdiffstats
path: root/src/vhdl
diff options
context:
space:
mode:
authorBrian Padalino <bpadalino@gmail.com>2021-09-22 01:27:51 -0400
committerGitHub <noreply@github.com>2021-09-22 07:27:51 +0200
commitb4b25fe5e5d77ba712552acc5edae7c64832d1ca (patch)
tree152d73a22b34d98b79b2eb35da368c4444280ff6 /src/vhdl
parent140ec48166f9c8c478d1433507c632cea80929bc (diff)
downloadghdl-b4b25fe5e5d77ba712552acc5edae7c64832d1ca.tar.gz
ghdl-b4b25fe5e5d77ba712552acc5edae7c64832d1ca.tar.bz2
ghdl-b4b25fe5e5d77ba712552acc5edae7c64832d1ca.zip
Implement Matching Operators (#1872)
Implement the matching operators ?<, ?<=, ?>, ?>=, ?/=.
Diffstat (limited to 'src/vhdl')
-rw-r--r--src/vhdl/vhdl-evaluation.adb156
1 files changed, 148 insertions, 8 deletions
diff --git a/src/vhdl/vhdl-evaluation.adb b/src/vhdl/vhdl-evaluation.adb
index 6305cdbae..76faa1b73 100644
--- a/src/vhdl/vhdl-evaluation.adb
+++ b/src/vhdl/vhdl-evaluation.adb
@@ -1556,6 +1556,124 @@ package body Vhdl.Evaluation is
end if;
end Eval_Logic_Match_Equality;
+ function Eval_Logic_Or(L, R : Iir_Index32)
+ return Iir_Index32
+ is
+ use Vhdl.Ieee.Std_Logic_1164;
+ begin
+ if L = Std_Logic_1_Pos or L = Std_Logic_H_Pos or
+ R = Std_Logic_1_Pos or R = Std_Logic_H_Pos then
+ return Std_Logic_1_Pos ;
+ elsif (L = Std_Logic_0_Pos or L = Std_Logic_L_Pos) and
+ (R = Std_Logic_0_Pos or R = Std_Logic_L_Pos) then
+ return Std_Logic_0_Pos ;
+ elsif L = Std_Logic_U_Pos or R = Std_Logic_U_Pos then
+ return Std_Logic_U_Pos ;
+ else
+ return Std_Logic_X_Pos ;
+ end if ;
+ end Eval_Logic_Or ;
+
+ function Eval_Logic_Not(X : Iir_Index32) return Iir_Index32
+ is
+ use Vhdl.Ieee.Std_Logic_1164;
+ begin
+ if X = Std_Logic_0_Pos or X = Std_Logic_L_Pos then
+ return Std_Logic_1_Pos ;
+ elsif X = Std_Logic_1_Pos or X = Std_Logic_H_Pos then
+ return Std_Logic_0_Pos ;
+ elsif X = Std_Logic_U_Pos then
+ return Std_Logic_U_Pos ;
+ else
+ return Std_Logic_X_Pos ;
+ end if ;
+ end Eval_Logic_Not ;
+
+ function Eval_Logic_Match_Inequality (L, R : Iir_Int32; Loc : Iir)
+ return Iir_Index32
+ is
+ E : Iir_Index32;
+ begin
+ -- Defined as the not operator applied to the equal operator
+ E := Eval_Logic_Match_Equality(L, R, Loc) ;
+ return Eval_Logic_Not(E) ;
+ end Eval_Logic_Match_Inequality;
+
+ function Eval_Logic_Match_Less (L, R : Iir_Int32; Loc : Iir)
+ return Iir_Index32
+ is
+ use Vhdl.Ieee.Std_Logic_1164;
+ begin
+ -- LRM19 9.2.3 table
+ -- '-' always returns 'X'
+ if L = Std_Logic_D_Pos or R = Std_Logic_D_Pos then
+ Warning_Msg_Sem
+ (Warnid_Analyze_Assert, +Loc,
+ "STD_LOGIC_1164: '-' operand for matching ordering operator");
+ return Std_Logic_X_Pos;
+ end if;
+
+ -- 'U' always returns 'U'
+ if L = Std_Logic_U_Pos or R = Std_Logic_U_Pos then
+ return Std_Logic_U_Pos ;
+ end if ;
+
+ -- Only when R is '1' or 'H' will we ever return '1'
+ if R = Std_Logic_1_Pos or R = Std_Logic_H_Pos then
+ if L = Std_Logic_0_Pos or L = Std_Logic_L_Pos then
+ -- L = [0,L] R = [1,H]
+ return Std_Logic_1_Pos ;
+ elsif L = Std_Logic_1_Pos or L = Std_Logic_H_Pos then
+ -- L = [1,H] R = [1,H]
+ return Std_Logic_0_Pos ;
+ else
+ -- Everything else is 'X'
+ return Std_Logic_X_Pos ;
+ end if ;
+ elsif R = Std_Logic_0_Pos or R = Std_Logic_L_Pos then
+ -- R = [0,1]
+ return Std_Logic_0_Pos ;
+ else
+ -- Everything else is 'X'
+ return Std_Logic_X_Pos ;
+ end if ;
+ end Eval_Logic_Match_Less ;
+
+ function Eval_Logic_Match_Less_Equal (L, R : Iir_Int32; Loc : Iir)
+ return Iir_Index32
+ is
+ Less : Iir_Index32 ;
+ Equal : Iir_Index32 ;
+ begin
+ -- LRM19 9.2.3
+ -- ?<= is defined as (< or =)
+ Less := Eval_Logic_Match_Less(L, R, Loc) ;
+ Equal := Eval_Logic_Match_Equality(L, R, Loc) ;
+ return Eval_Logic_Or(Less, Equal) ;
+ end Eval_Logic_Match_Less_Equal ;
+
+ function Eval_Logic_Match_Greater (L, R : Iir_Int32; Loc : Iir)
+ return Iir_Index32
+ is
+ Le : Iir_Index32;
+ begin
+ -- LRM19 9.2.3
+ -- ?> is defined as not(?<=)
+ Le := Eval_Logic_Match_Less_Equal(L, R, Loc);
+ return Eval_Logic_Not(Le);
+ end Eval_Logic_Match_Greater ;
+
+ function Eval_Logic_Match_Greater_Equal (L, R : Iir_Int32; Loc : Iir)
+ return Iir_Index32
+ is
+ Less : Iir_Index32 ;
+ begin
+ -- LRM19 9.2.3
+ -- ?>= is defined as not(?<)
+ Less := Eval_Logic_Match_Less(L, R, Loc) ;
+ return Eval_Logic_Not(Less) ;
+ end Eval_Logic_Match_Greater_Equal ;
+
function Eval_Equality (Left, Right : Iir) return Boolean;
-- CHOICES is a chain of choice from a record aggregate; FEL is an Flist
@@ -1591,7 +1709,6 @@ package body Vhdl.Evaluation is
end loop;
end Fill_Flist_From_Record_Aggregate;
-
function Eval_Record_Equality (Left, Right : Iir) return Boolean
is
pragma Assert (Get_Kind (Left) = Iir_Kind_Aggregate);
@@ -2075,13 +2192,36 @@ package body Vhdl.Evaluation is
(Eval_Logic_Match_Equality (Get_Enum_Pos (Left),
Get_Enum_Pos (Right), Orig),
Orig);
- when Iir_Predefined_Std_Ulogic_Match_Inequality
- | Iir_Predefined_Std_Ulogic_Match_Less
- | Iir_Predefined_Std_Ulogic_Match_Less_Equal
- | Iir_Predefined_Std_Ulogic_Match_Greater
- | Iir_Predefined_Std_Ulogic_Match_Greater_Equal =>
- -- TODO
- raise Internal_Error;
+
+ when Iir_Predefined_Std_Ulogic_Match_Inequality =>
+ return Build_Enumeration
+ (Eval_Logic_Match_Inequality (Get_Enum_Pos (Left),
+ Get_Enum_Pos (Right), Orig),
+ Orig);
+
+ when Iir_Predefined_Std_Ulogic_Match_Less =>
+ return Build_Enumeration
+ (Eval_Logic_Match_Less (Get_Enum_Pos (Left),
+ Get_Enum_Pos (Right), Orig),
+ Orig);
+
+ when Iir_Predefined_Std_Ulogic_Match_Greater =>
+ return Build_Enumeration
+ (Eval_Logic_Match_Greater (Get_Enum_Pos (Left),
+ Get_Enum_Pos (Right), Orig),
+ Orig);
+
+ when Iir_Predefined_Std_Ulogic_Match_Greater_Equal =>
+ return Build_Enumeration
+ (Eval_Logic_Match_Greater_Equal (Get_Enum_Pos (Left),
+ Get_Enum_Pos (Right), Orig),
+ Orig);
+
+ when Iir_Predefined_Std_Ulogic_Match_Less_Equal =>
+ return Build_Enumeration
+ (Eval_Logic_Match_Less_Equal (Get_Enum_Pos (Left),
+ Get_Enum_Pos (Right), Orig),
+ Orig);
when Iir_Predefined_Real_To_String_Digits
| Iir_Predefined_Time_To_String_Unit =>