diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-05-17 08:38:34 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-05-17 08:38:34 +0200 |
commit | 202f7d2e8cbd12911a18d22741e2856e57a03074 (patch) | |
tree | 2ccea7213ac3cab51e570881ee3d256cf8c12c57 | |
parent | 612e79e4aafa00e2908bf857023c779aebf64d15 (diff) | |
download | ghdl-202f7d2e8cbd12911a18d22741e2856e57a03074.tar.gz ghdl-202f7d2e8cbd12911a18d22741e2856e57a03074.tar.bz2 ghdl-202f7d2e8cbd12911a18d22741e2856e57a03074.zip |
synth: handle static shift in synth.ieee.numeric_std.
-rw-r--r-- | src/synth/synth-ieee-numeric_std.adb | 51 | ||||
-rw-r--r-- | src/synth/synth-ieee-numeric_std.ads | 6 | ||||
-rw-r--r-- | src/synth/synth-static_oper.adb | 84 |
3 files changed, 78 insertions, 63 deletions
diff --git a/src/synth/synth-ieee-numeric_std.adb b/src/synth/synth-ieee-numeric_std.adb index 5101734ad..ae7f7a2d1 100644 --- a/src/synth/synth-ieee-numeric_std.adb +++ b/src/synth/synth-ieee-numeric_std.adb @@ -494,4 +494,55 @@ package body Synth.Ieee.Numeric_Std is return Res; end Neg_Vec; + function Shift_Vec (Val : Memtyp; + Amt : Uns32; + Right : Boolean; + Arith : Boolean) return Memtyp + is + Len : constant Uns32 := Uns32 (Vec_Length (Val.Typ)); + Res : Memtyp; + Pad, B : Std_Ulogic; + begin + Res.Typ := Create_Res_Type (Val.Typ, Len); + Res := Create_Memory (Res.Typ); + + if Len = 0 then + Fill (Res, '0'); + return Res; + end if; + + if Arith then + Pad := Read_Std_Logic (Val.Mem, 0); + else + Pad := '0'; + end if; + + if Amt >= Len then + if Right then + Fill (Res, Pad); + else + Fill (Res, '0'); + end if; + return Res; + end if; + + if Right then + for I in 1 .. Amt loop + Write_Std_Logic (Res.Mem, I - 1, Pad); + end loop; + for I in Amt + 1 .. Len loop + B := Read_Std_Logic (Val.Mem, I - 1 - Amt); + Write_Std_Logic (Res.Mem, I - 1, B); + end loop; + else + for I in 1 .. Len - Amt loop + B := Read_Std_Logic (Val.Mem, Amt + I - 1); + Write_Std_Logic (Res.Mem, I - 1, B); + end loop; + for I in Len - Amt + 1 .. Len loop + Write_Std_Logic (Res.Mem, I - 1, Pad); + end loop; + end if; + return Res; + end Shift_Vec; end Synth.Ieee.Numeric_Std; diff --git a/src/synth/synth-ieee-numeric_std.ads b/src/synth/synth-ieee-numeric_std.ads index d390b14b3..f3e5817f1 100644 --- a/src/synth/synth-ieee-numeric_std.ads +++ b/src/synth/synth-ieee-numeric_std.ads @@ -49,4 +49,10 @@ package Synth.Ieee.Numeric_Std is function Mul_Sgn_Sgn (L, R : Memtyp; Loc : Syn_Src) return Memtyp; function Mul_Int_Sgn (L : Int64; R : Memtyp; Loc : Syn_Src) return Memtyp; function Mul_Sgn_Int (L : Memtyp; R : Int64; Loc : Syn_Src) return Memtyp; + + -- Shift + function Shift_Vec (Val : Memtyp; + Amt : Uns32; + Right : Boolean; + Arith : Boolean) return Memtyp; end Synth.Ieee.Numeric_Std; diff --git a/src/synth/synth-static_oper.adb b/src/synth/synth-static_oper.adb index ecfc0db80..fa4176115 100644 --- a/src/synth/synth-static_oper.adb +++ b/src/synth/synth-static_oper.adb @@ -355,65 +355,6 @@ package body Synth.Static_Oper is return Res; end Synth_Vector_Dyadic; - procedure To_Std_Logic_Vector (Val : Memtyp; Arr : out Std_Logic_Vector) is - begin - for I in 1 .. Uns32 (Vec_Length (Val.Typ)) loop - Arr (Natural (I)) := Read_Std_Logic (Val.Mem, I - 1); - end loop; - end To_Std_Logic_Vector; - - function To_Memtyp (Vec : Std_Logic_Vector; El_Typ : Type_Acc) return Memtyp - is - pragma Assert (Vec'First = 1); - Res_Typ : Type_Acc; - Res : Memtyp; - begin - Res_Typ := Create_Vec_Type_By_Length (Uns32 (Vec'Last), El_Typ); - Res := Create_Memory (Res_Typ); - for I in 1 .. Vec'Last loop - Write_Std_Logic (Res.Mem, Uns32 (I - 1), Vec (I)); - end loop; - return Res; - end To_Memtyp; - - function Synth_Shift (Val : Memtyp; - Amt : Uns32; - Right : Boolean; - Arith : Boolean) return Memtyp - is - Len : constant Uns32 := Uns32 (Vec_Length (Val.Typ)); - Arr : Std_Logic_Vector (1 .. Natural (Len)); - Pad : Std_Ulogic; - begin - if Len = 0 or Amt >= Len then - Arr := (others => '0'); - else - To_Std_Logic_Vector (Val, Arr); - if Arith then - Pad := Arr (1); - else - Pad := '0'; - end if; - - if Right then - for I in reverse Amt + 1 .. Len loop - Arr (Natural (I)) := Arr (Natural (I - Amt)); - end loop; - for I in 1 .. Amt loop - Arr (Natural (I)) := Pad; - end loop; - else - for I in 1 .. Len - Amt loop - Arr (Natural (I)) := Arr (Natural (I + Amt)); - end loop; - for I in Len - Amt + 1 .. Len loop - Arr (Natural (I)) := Pad; - end loop; - end if; - end if; - return To_Memtyp (Arr, Val.Typ.Vec_El); - end Synth_Shift; - function Get_Static_Ulogic (Op : Memtyp) return Std_Ulogic is begin pragma Assert (Op.Typ.Kind = Type_Logic); @@ -877,9 +818,9 @@ package body Synth.Static_Oper is begin Amt := Read_Discrete (Right); if Amt >= 0 then - return Synth_Shift (Left, Uns32 (Amt), True, False); + return Shift_Vec (Left, Uns32 (Amt), True, False); else - return Synth_Shift (Left, Uns32 (-Amt), False, False); + return Shift_Vec (Left, Uns32 (-Amt), False, False); end if; end; when Iir_Predefined_Ieee_Numeric_Std_Sll_Uns_Int @@ -889,9 +830,9 @@ package body Synth.Static_Oper is begin Amt := Read_Discrete (Right); if Amt >= 0 then - return Synth_Shift (Left, Uns32 (Amt), False, False); + return Shift_Vec (Left, Uns32 (Amt), False, False); else - return Synth_Shift (Left, Uns32 (-Amt), True, False); + return Shift_Vec (Left, Uns32 (-Amt), True, False); end if; end; @@ -1146,6 +1087,23 @@ package body Synth.Static_Oper is return Create_Memory_Discrete (Eval_Signed_To_Integer (Get_Memtyp (Param1), Expr), Res_Typ); + when Iir_Predefined_Ieee_Numeric_Std_Shl_Uns_Nat => + return Shift_Vec + (Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)), + False, False); + when Iir_Predefined_Ieee_Numeric_Std_Shl_Sgn_Nat => + return Shift_Vec + (Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)), + False, False); + when Iir_Predefined_Ieee_Numeric_Std_Shr_Uns_Nat => + return Shift_Vec + (Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)), + True, False); + when Iir_Predefined_Ieee_Numeric_Std_Shr_Sgn_Nat => + return Shift_Vec + (Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)), + True, True); + when Iir_Predefined_Ieee_1164_To_Stdlogicvector_Bv => declare El_Type : constant Type_Acc := Get_Array_Element (Res_Typ); |