aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-05-17 08:38:34 +0200
committerTristan Gingold <tgingold@free.fr>2020-05-17 08:38:34 +0200
commit202f7d2e8cbd12911a18d22741e2856e57a03074 (patch)
tree2ccea7213ac3cab51e570881ee3d256cf8c12c57
parent612e79e4aafa00e2908bf857023c779aebf64d15 (diff)
downloadghdl-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.adb51
-rw-r--r--src/synth/synth-ieee-numeric_std.ads6
-rw-r--r--src/synth/synth-static_oper.adb84
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);