aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2022-06-04 07:43:49 +0200
committerTristan Gingold <tgingold@free.fr>2022-06-04 16:27:47 +0200
commit90ae71139bc39dc158f54e0337ed73f15033e77f (patch)
tree3be01f01b58f9a5ff82f2c8fa31187c6ba19a4a6 /src/synth
parentadfe96ecbe5795f65f8214ce30073385de37bbc6 (diff)
downloadghdl-90ae71139bc39dc158f54e0337ed73f15033e77f.tar.gz
ghdl-90ae71139bc39dc158f54e0337ed73f15033e77f.tar.bz2
ghdl-90ae71139bc39dc158f54e0337ed73f15033e77f.zip
synth-vhdl_eval: handle rotations
Diffstat (limited to 'src/synth')
-rw-r--r--src/synth/synth-ieee-numeric_std.adb42
-rw-r--r--src/synth/synth-ieee-numeric_std.ads5
-rw-r--r--src/synth/synth-vhdl_eval.adb9
3 files changed, 55 insertions, 1 deletions
diff --git a/src/synth/synth-ieee-numeric_std.adb b/src/synth/synth-ieee-numeric_std.adb
index cbe34db47..656337ef6 100644
--- a/src/synth/synth-ieee-numeric_std.adb
+++ b/src/synth/synth-ieee-numeric_std.adb
@@ -844,7 +844,6 @@ package body Synth.Ieee.Numeric_Std is
Res := Create_Memory (Res.Typ);
if Len = 0 then
- Fill (Res, '0');
return Res;
end if;
@@ -883,6 +882,47 @@ package body Synth.Ieee.Numeric_Std is
return Res;
end Shift_Vec;
+ function Rotate_Vec (Val : Memtyp;
+ Amt : Uns32;
+ Right : Boolean) return Memtyp
+ is
+ Len : constant Uns32 := Uns32 (Vec_Length (Val.Typ));
+ Cnt : Uns32;
+ Res : Memtyp;
+ B : Std_Ulogic;
+ begin
+ Res.Typ := Create_Res_Type (Val.Typ, Len);
+ Res := Create_Memory (Res.Typ);
+
+ if Len = 0 then
+ return Res;
+ end if;
+
+ Cnt := Amt rem Len;
+ pragma Unreferenced (Amt);
+
+ if Right then
+ for I in 1 .. Len - Cnt loop
+ B := Read_Std_Logic (Val.Mem, I - 1);
+ Write_Std_Logic (Res.Mem, Cnt + I - 1, B);
+ end loop;
+ for I in 1 .. Cnt loop
+ B := Read_Std_Logic (Val.Mem, Len - I);
+ Write_Std_Logic (Res.Mem, Cnt - I, B);
+ end loop;
+ else
+ for I in 1 .. Cnt loop
+ B := Read_Std_Logic (Val.Mem, I - 1);
+ Write_Std_Logic (Res.Mem, Len - Cnt + I - 1, B);
+ end loop;
+ for I in 1 .. Len - Cnt loop
+ B := Read_Std_Logic (Val.Mem, Len - I);
+ Write_Std_Logic (Res.Mem, Len - Cnt - I, B);
+ end loop;
+ end if;
+ return Res;
+ end Rotate_Vec;
+
function Resize_Vec (Val : Memtyp;
Size : Uns32;
Signed : Boolean) return Memtyp
diff --git a/src/synth/synth-ieee-numeric_std.ads b/src/synth/synth-ieee-numeric_std.ads
index 884c8378f..82e431584 100644
--- a/src/synth/synth-ieee-numeric_std.ads
+++ b/src/synth/synth-ieee-numeric_std.ads
@@ -89,6 +89,11 @@ package Synth.Ieee.Numeric_Std is
Right : Boolean;
Arith : Boolean) return Memtyp;
+ -- Rotate
+ function Rotate_Vec (Val : Memtyp;
+ Amt : Uns32;
+ Right : Boolean) return Memtyp;
+
function Resize_Vec (Val : Memtyp;
Size : Uns32;
Signed : Boolean) return Memtyp;
diff --git a/src/synth/synth-vhdl_eval.adb b/src/synth/synth-vhdl_eval.adb
index 6eaf035e8..5baced201 100644
--- a/src/synth/synth-vhdl_eval.adb
+++ b/src/synth/synth-vhdl_eval.adb
@@ -1881,6 +1881,14 @@ package body Synth.Vhdl_Eval is
return Shift_Vec
(Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)),
False, False);
+ when Iir_Predefined_Ieee_Numeric_Std_Rot_Left_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Rot_Left_Sgn_Nat =>
+ return Rotate_Vec
+ (Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)), False);
+ when Iir_Predefined_Ieee_Numeric_Std_Rot_Right_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Rot_Right_Sgn_Nat =>
+ return Rotate_Vec
+ (Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)), True);
when Iir_Predefined_Ieee_Numeric_Std_Shf_Right_Uns_Nat =>
return Shift_Vec
(Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)),
@@ -1889,6 +1897,7 @@ package body Synth.Vhdl_Eval is
return Shift_Vec
(Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)),
True, True);
+
when Iir_Predefined_Ieee_Numeric_Std_Resize_Sgn_Nat =>
return Resize_Vec
(Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)), True);