aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2022-06-03 18:54:32 +0200
committerTristan Gingold <tgingold@free.fr>2022-06-03 18:54:32 +0200
commitd6ff9d26397138dbfef4c15a5e4d4781c37d4267 (patch)
tree06c3deccc0202d84268523b08d7b77876102bd59
parent0875ce87c2e565023a350faf444ca2b3e3477ec7 (diff)
downloadghdl-d6ff9d26397138dbfef4c15a5e4d4781c37d4267.tar.gz
ghdl-d6ff9d26397138dbfef4c15a5e4d4781c37d4267.tar.bz2
ghdl-d6ff9d26397138dbfef4c15a5e4d4781c37d4267.zip
synth-vhdl_eval: handle more operations, fix resize corner case
-rw-r--r--src/synth/synth-ieee-numeric_std.adb10
-rw-r--r--src/synth/synth-vhdl_eval.adb88
2 files changed, 74 insertions, 24 deletions
diff --git a/src/synth/synth-ieee-numeric_std.adb b/src/synth/synth-ieee-numeric_std.adb
index d23b4e858..cbe34db47 100644
--- a/src/synth/synth-ieee-numeric_std.adb
+++ b/src/synth/synth-ieee-numeric_std.adb
@@ -888,19 +888,27 @@ package body Synth.Ieee.Numeric_Std is
Signed : Boolean) return Memtyp
is
Old_Size : constant Uns32 := Uns32 (Vec_Length (Val.Typ));
+ L : Uns32;
Res : Memtyp;
Pad, B : Std_Ulogic;
begin
Res.Typ := Create_Res_Type (Val.Typ, Size);
Res := Create_Memory (Res.Typ);
+ if Size = 0 then
+ return Res;
+ end if;
+
if Signed and then Old_Size > 0 then
Pad := Read_Std_Logic (Val.Mem, 0);
+ Write_Std_Logic (Res.Mem, 0, Pad);
+ L := Size - 1;
else
Pad := '0';
+ L := Size;
end if;
- for I in 1 .. Size loop
+ for I in 1 .. L loop
if I <= Old_Size then
B := Read_Std_Logic (Val.Mem, Old_Size - I);
else
diff --git a/src/synth/synth-vhdl_eval.adb b/src/synth/synth-vhdl_eval.adb
index 17d4548c8..6eaf035e8 100644
--- a/src/synth/synth-vhdl_eval.adb
+++ b/src/synth/synth-vhdl_eval.adb
@@ -846,42 +846,42 @@ package body Synth.Vhdl_Eval is
Res : Boolean;
begin
Res := Compare_Uns_Uns (Left, Right, Greater, Expr) = Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Ne_Uns_Uns =>
declare
Res : Boolean;
begin
Res := Compare_Uns_Uns (Left, Right, Greater, Expr) /= Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Ne_Uns_Nat =>
declare
Res : Boolean;
begin
Res := Compare_Uns_Nat (Left, Right, Greater, Expr) /= Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Eq_Sgn_Sgn =>
declare
Res : Boolean;
begin
Res := Compare_Sgn_Sgn (Left, Right, Greater, Expr) = Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Eq_Uns_Nat =>
declare
Res : Boolean;
begin
Res := Compare_Uns_Nat (Left, Right, Greater, Expr) = Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Eq_Sgn_Int =>
declare
Res : Boolean;
begin
Res := Compare_Sgn_Int (Left, Right, Greater, Expr) = Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Gt_Uns_Uns =>
@@ -889,50 +889,71 @@ package body Synth.Vhdl_Eval is
Res : Boolean;
begin
Res := Compare_Uns_Uns (Left, Right, Less, Expr) = Greater;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Gt_Sgn_Sgn =>
declare
Res : Boolean;
begin
Res := Compare_Sgn_Sgn (Left, Right, Less, Expr) = Greater;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Gt_Nat_Uns =>
declare
Res : Boolean;
begin
Res := Compare_Nat_Uns (Left, Right, Less, Expr) = Greater;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Gt_Uns_Nat =>
declare
Res : Boolean;
begin
Res := Compare_Uns_Nat (Left, Right, Less, Expr) = Greater;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Ge_Uns_Uns =>
declare
Res : Boolean;
begin
- Res := Compare_Uns_Uns (Left, Right, Greater, Expr) >= Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Uns_Uns (Left, Right, Less, Expr) >= Equal;
+ return Create_Memory_Boolean (Res);
end;
- when Iir_Predefined_Ieee_Numeric_Std_Ge_Sgn_Sgn =>
+ when Iir_Predefined_Ieee_Numeric_Std_Ge_Nat_Uns =>
declare
Res : Boolean;
begin
- Res := Compare_Sgn_Sgn (Left, Right, Less, Expr) >= Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Nat_Uns (Left, Right, Less, Expr) >= Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Ge_Uns_Nat =>
declare
Res : Boolean;
begin
Res := Compare_Uns_Nat (Left, Right, Less, Expr) >= Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Ge_Sgn_Sgn =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Sgn (Left, Right, Less, Expr) >= Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Ge_Sgn_Int =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Int (Left, Right, Less, Expr) >= Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Ge_Int_Sgn =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Int (Right, Left, Greater, Expr) <= Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Le_Uns_Uns =>
@@ -940,21 +961,42 @@ package body Synth.Vhdl_Eval is
Res : Boolean;
begin
Res := Compare_Uns_Uns (Left, Right, Greater, Expr) <= Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Le_Uns_Nat =>
declare
Res : Boolean;
begin
Res := Compare_Uns_Nat (Left, Right, Greater, Expr) <= Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Le_Nat_Uns =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Nat_Uns (Left, Right, Greater, Expr) <= Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Le_Sgn_Sgn =>
declare
Res : Boolean;
begin
Res := Compare_Sgn_Sgn (Left, Right, Greater, Expr) <= Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Le_Int_Sgn =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Int (Right, Left, Less, Expr) >= Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Le_Sgn_Int =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Int (Left, Right, Greater, Expr) <= Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Lt_Uns_Uns =>
@@ -962,28 +1004,28 @@ package body Synth.Vhdl_Eval is
Res : Boolean;
begin
Res := Compare_Uns_Uns (Left, Right, Greater, Expr) < Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Lt_Uns_Nat =>
declare
Res : Boolean;
begin
Res := Compare_Uns_Nat (Left, Right, Greater, Expr) < Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Lt_Nat_Uns =>
declare
Res : Boolean;
begin
Res := Compare_Nat_Uns (Left, Right, Greater, Expr) < Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Lt_Sgn_Sgn =>
declare
Res : Boolean;
begin
Res := Compare_Sgn_Sgn (Left, Right, Greater, Expr) < Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Uns