From 90ae71139bc39dc158f54e0337ed73f15033e77f Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Sat, 4 Jun 2022 07:43:49 +0200 Subject: synth-vhdl_eval: handle rotations --- src/synth/synth-ieee-numeric_std.adb | 42 +++++++++++++++++++++++++++++++++++- src/synth/synth-ieee-numeric_std.ads | 5 +++++ src/synth/synth-vhdl_eval.adb | 9 ++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) 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); -- cgit v1.2.3