aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2022-04-27 19:22:54 +0200
committerTristan Gingold <tgingold@free.fr>2022-04-27 19:22:54 +0200
commita2550cae21230060c3a5c5c210781a8c66938a3f (patch)
tree56eb6ba20f4fbef6c637871f8e58197b5bfab867
parentd3883c99871f56fbcc29580f8ca02ce6d5167989 (diff)
downloadghdl-a2550cae21230060c3a5c5c210781a8c66938a3f.tar.gz
ghdl-a2550cae21230060c3a5c5c210781a8c66938a3f.tar.bz2
ghdl-a2550cae21230060c3a5c5c210781a8c66938a3f.zip
synth-vhdl_eval: handle abs
-rw-r--r--src/synth/synth-ieee-numeric_std.adb75
-rw-r--r--src/synth/synth-ieee-numeric_std.ads3
-rw-r--r--src/synth/synth-vhdl_eval.adb2
3 files changed, 61 insertions, 19 deletions
diff --git a/src/synth/synth-ieee-numeric_std.adb b/src/synth/synth-ieee-numeric_std.adb
index 0697a7697..e35ac950c 100644
--- a/src/synth/synth-ieee-numeric_std.adb
+++ b/src/synth/synth-ieee-numeric_std.adb
@@ -65,7 +65,7 @@ package body Synth.Ieee.Numeric_Std is
end loop;
end Fill;
- procedure Warn_Compare_Null (Loc : Syn_Src) is
+ procedure Warn_Compare_Null (Loc : Syn_Src) is
begin
Warning_Msg_Synth (+Loc, "null argument detected, returning false");
end Warn_Compare_Null;
@@ -742,36 +742,34 @@ package body Synth.Ieee.Numeric_Std is
return Mul_Sgn_Sgn (L, Rv, Loc);
end Mul_Sgn_Int;
- function Neg_Vec_Notyp (V : Memtyp) return Memory_Ptr
+ -- Note: SRC = DST is allowed.
+ procedure Neg_Vec (Src : Memory_Ptr; Dst : Memory_Ptr; Typ : Type_Acc)
is
- Len : constant Uns32 := V.Typ.Vbound.Len;
+ Len : constant Uns32 := Typ.Vbound.Len;
Vb, Carry : Sl_X01;
- Res : Memory_Ptr;
begin
- Res := Alloc_Memory (V.Typ);
-
Carry := '1';
for I in 1 .. Len loop
- Vb := Sl_To_X01 (Read_Std_Logic (V.Mem, Len - I));
+ Vb := Sl_To_X01 (Read_Std_Logic (Src, Len - I));
Vb := Not_Table (Vb);
- Write_Std_Logic (Res, Len - I, Xor_Table (Carry, Vb));
+ Write_Std_Logic (Dst, Len - I, Xor_Table (Carry, Vb));
Carry := And_Table (Carry, Vb);
end loop;
+ end Neg_Vec;
+
+ function Neg_Vec_Notyp (V : Memtyp) return Memory_Ptr
+ is
+ Res : Memory_Ptr;
+ begin
+ Res := Alloc_Memory (V.Typ);
+
+ Neg_Vec (V.Mem, Res, V.Typ);
return Res;
end Neg_Vec_Notyp;
- procedure Neg_Vec (V : Memtyp)
- is
- Len : constant Uns32 := V.Typ.Vbound.Len;
- Vb, Carry : Sl_X01;
+ procedure Neg_Vec (V : Memtyp) is
begin
- Carry := '1';
- for I in 1 .. Len loop
- Vb := Sl_To_X01 (Read_Std_Logic (V.Mem, Len - I));
- Vb := Not_Table (Vb);
- Write_Std_Logic (V.Mem, Len - I, Xor_Table (Carry, Vb));
- Carry := And_Table (Carry, Vb);
- end loop;
+ Neg_Vec (V.Mem, V.Mem, V.Typ);
end Neg_Vec;
function Neg_Vec (V : Memtyp; Loc : Syn_Src) return Memtyp
@@ -803,6 +801,45 @@ package body Synth.Ieee.Numeric_Std is
return Res;
end Neg_Vec;
+ procedure To_01X (Src : Memory_Ptr; Dst : Memory_Ptr; Len : Uns32)
+ is
+ V : Sl_X01;
+ begin
+ for I in 1 .. Len loop
+ V := Sl_To_X01 (Read_Std_Logic (Src, Len - I));
+ if V = 'X' then
+ for J in 1 .. Len loop
+ Write_Std_Logic (Dst, J - 1, 'X');
+ end loop;
+ return;
+ end if;
+ Write_Std_Logic (Dst, Len - I, V);
+ end loop;
+ end To_01X;
+
+ function Abs_Vec (V : Memtyp; Loc : Syn_Src) return Memtyp
+ is
+ pragma Unreferenced (Loc);
+ Len : constant Uns32 := V.Typ.Vbound.Len;
+ Res : Memtyp;
+ Msb : Sl_X01;
+ begin
+ Res.Typ := Create_Res_Type (V.Typ, Len);
+ Res := Create_Memory (Res.Typ);
+
+ if Len = 0 then
+ return Res;
+ end if;
+
+ -- Convert to 01, check for X.
+ To_01X (V.Mem, Res.Mem, Len);
+ Msb := Read_Std_Logic (Res.Mem, 0);
+ if Msb = '1' then
+ Neg_Vec (Res);
+ end if;
+ return Res;
+ end Abs_Vec;
+
function Shift_Vec (Val : Memtyp;
Amt : Uns32;
Right : Boolean;
diff --git a/src/synth/synth-ieee-numeric_std.ads b/src/synth/synth-ieee-numeric_std.ads
index b3bc9a632..2d6ba68d5 100644
--- a/src/synth/synth-ieee-numeric_std.ads
+++ b/src/synth/synth-ieee-numeric_std.ads
@@ -38,6 +38,9 @@ package Synth.Ieee.Numeric_Std is
-- Unary "-"
function Neg_Vec (V : Memtyp; Loc : Syn_Src) return Memtyp;
+ -- "abs"
+ function Abs_Vec (V : Memtyp; Loc : Syn_Src) return Memtyp;
+
-- "+"
function Add_Uns_Uns (L, R : Memtyp; Loc : Syn_Src) return Memtyp;
function Add_Sgn_Sgn (L, R : Memtyp; Loc : Syn_Src) return Memtyp;
diff --git a/src/synth/synth-vhdl_eval.adb b/src/synth/synth-vhdl_eval.adb
index b2aec5aaa..8c205051d 100644
--- a/src/synth/synth-vhdl_eval.adb
+++ b/src/synth/synth-vhdl_eval.adb
@@ -748,6 +748,8 @@ package body Synth.Vhdl_Eval is
when Iir_Predefined_Ieee_Numeric_Std_Neg_Sgn =>
return Neg_Vec (Operand, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Abs_Sgn =>
+ return Abs_Vec (Operand, Expr);
when Iir_Predefined_Ieee_1164_Vector_Not
| Iir_Predefined_Ieee_Numeric_Std_Not_Uns