aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-11-16 11:28:20 +0100
committerTristan Gingold <tgingold@free.fr>2019-11-16 11:28:20 +0100
commitf1046168bd29e08372159d99768ce9e8a014f61a (patch)
tree7b2eb8adfe8871ae5ded4e2a00f00f8a226ad406 /src
parent244a972901e539098fca2f120e53119f4a28724e (diff)
downloadghdl-f1046168bd29e08372159d99768ce9e8a014f61a.tar.gz
ghdl-f1046168bd29e08372159d99768ce9e8a014f61a.tar.bz2
ghdl-f1046168bd29e08372159d99768ce9e8a014f61a.zip
synth: handle static mul uns uns. Fix bit order for add.
Diffstat (limited to 'src')
-rw-r--r--src/synth/synth-ieee-numeric_std.adb64
-rw-r--r--src/synth/synth-ieee-numeric_std.ads4
-rw-r--r--src/synth/synth-ieee-std_logic_1164.ads12
-rw-r--r--src/synth/synth-static_oper.adb19
4 files changed, 87 insertions, 12 deletions
diff --git a/src/synth/synth-ieee-numeric_std.adb b/src/synth/synth-ieee-numeric_std.adb
index 5319a3113..096e7fd9f 100644
--- a/src/synth/synth-ieee-numeric_std.adb
+++ b/src/synth/synth-ieee-numeric_std.adb
@@ -58,16 +58,16 @@ package body Synth.Ieee.Numeric_Std is
return Null_Vec;
end if;
Carry := '0';
- for I in 1 .. Len loop
- if I > L'Last then
+ for I in 0 .. Len - 1 loop
+ if I >= L'Last then
Lb := '0';
else
- Lb := Sl_To_X01 (L (I));
+ Lb := Sl_To_X01 (L (L'Last - I));
end if;
- if I > R'Last then
+ if I >= R'Last then
Rb := '0';
else
- Rb := Sl_To_X01 (R (I));
+ Rb := Sl_To_X01 (R (R'Last - I));
end if;
if Lb = 'X' or Rb = 'X' then
--assert NO_WARNING
@@ -76,7 +76,7 @@ package body Synth.Ieee.Numeric_Std is
Res := (others => 'X');
exit;
end if;
- Res (I) := Compute_Sum (Carry, Rb, Lb);
+ Res (Res'Last - I) := Compute_Sum (Carry, Rb, Lb);
Carry := Compute_Carry (Carry, Rb, Lb);
end loop;
return Res;
@@ -86,9 +86,8 @@ package body Synth.Ieee.Numeric_Std is
return Std_Logic_Vector
is
pragma Assert (L'First = 1);
- subtype Res_Type is Std_Logic_Vector (1 .. L'Last);
+ Res : Std_Logic_Vector (1 .. L'Last);
V : Uns64;
- Res : Res_Type;
Lb, Rb, Carry : Sl_X01;
begin
if L'Last < 1 then
@@ -96,7 +95,7 @@ package body Synth.Ieee.Numeric_Std is
end if;
V := To_Uns64 (R);
Carry := '0';
- for I in Res'Range loop
+ for I in reverse Res'Range loop
Lb := Sl_To_X01 (L (I));
Rb := Uns_To_01 (V and 1);
if Lb = 'X' then
@@ -117,9 +116,8 @@ package body Synth.Ieee.Numeric_Std is
return Std_Logic_Vector
is
pragma Assert (L'First = 1);
- subtype Res_Type is Std_Logic_Vector (1 .. L'Last);
+ Res : Std_Logic_Vector (1 .. L'Last);
V : Uns64;
- Res : Res_Type;
Lb, Rb, Carry : Sl_X01;
begin
if L'Last < 1 then
@@ -127,7 +125,7 @@ package body Synth.Ieee.Numeric_Std is
end if;
V := R;
Carry := '0';
- for I in Res'Range loop
+ for I in reverse Res'Range loop
Lb := Sl_To_X01 (L (I));
Rb := Uns_To_01 (V and 1);
if Lb = 'X' then
@@ -143,4 +141,46 @@ package body Synth.Ieee.Numeric_Std is
end loop;
return Res;
end Add_Uns_Nat;
+
+ function Mul_Uns_Uns (L, R : Std_Logic_Vector) return Std_Logic_Vector
+ is
+ pragma Assert (L'First = 1);
+ pragma Assert (R'First = 1);
+ Len : constant Integer := L'Last + R'Last;
+ Res : Std_Logic_Vector (1 .. Len);
+ Lb, Rb, Vb, Carry : Sl_X01;
+ begin
+ if L'Last < 1 or R'Last < 1 then
+ return Null_Vec;
+ end if;
+ Res := (others => '0');
+ -- Shift and add L.
+ for I in 0 .. R'Last - 1 loop
+ Rb := Sl_To_X01 (R (R'Last - I));
+ if Rb = '1' then
+ -- Compute res := res + shift_left (l, i).
+ Carry := '0';
+ for J in 0 .. L'Last - 1 loop
+ Lb := L (L'Last - J);
+ Vb := Res (Len - (I + J));
+ Res (Len - (I + J)) := Compute_Sum (Carry, Vb, Lb);
+ Carry := Compute_Carry (Carry, Vb, Lb);
+ end loop;
+ -- Propagate carry.
+ for J in I + L'Last .. Res'Last loop
+ exit when Carry = '0';
+ Vb := Res (Len - J);
+ Res (Len - J) := Xor_Table (Carry, Vb);
+ Carry := And_Table (Carry, Vb);
+ end loop;
+ elsif Rb = 'X' then
+ null;
+ -- assert NO_WARNING
+ -- report "NUMERIC_STD.""*"": non logical value detected"
+ -- severity warning;
+ end if;
+ end loop;
+ return Res;
+ end Mul_Uns_Uns;
+
end Synth.Ieee.Numeric_Std;
diff --git a/src/synth/synth-ieee-numeric_std.ads b/src/synth/synth-ieee-numeric_std.ads
index 340dac3d6..3d9b8be0b 100644
--- a/src/synth/synth-ieee-numeric_std.ads
+++ b/src/synth/synth-ieee-numeric_std.ads
@@ -23,10 +23,14 @@ with Types; use Types;
with Synth.Ieee.Std_Logic_1164; use Synth.Ieee.Std_Logic_1164;
package Synth.Ieee.Numeric_Std is
+ -- Reminder: vectors elements are from left to right.
+
function Add_Uns_Uns (L, R : Std_Logic_Vector) return Std_Logic_Vector;
function Add_Sgn_Int (L : Std_Logic_Vector; R : Int64)
return Std_Logic_Vector;
function Add_Uns_Nat (L : Std_Logic_Vector; R : Uns64)
return Std_Logic_Vector;
+
+ function Mul_Uns_Uns (L, R : Std_Logic_Vector) return Std_Logic_Vector;
end Synth.Ieee.Numeric_Std;
diff --git a/src/synth/synth-ieee-std_logic_1164.ads b/src/synth/synth-ieee-std_logic_1164.ads
index c90e4e5ca..242a417fb 100644
--- a/src/synth/synth-ieee-std_logic_1164.ads
+++ b/src/synth/synth-ieee-std_logic_1164.ads
@@ -67,4 +67,16 @@ package Synth.Ieee.Std_Logic_1164 is
"UXX1XXX1X" -- -
);
+ Xor_Table : constant Table_2d :=
+ -- UX01ZWLH-
+ ("UUUUUUUUU", -- U
+ "UXXXXXXXX", -- X
+ "UX01XX01X", -- 0
+ "UX10XX10X", -- 1
+ "UXXXXXXXX", -- Z
+ "UXXXXXXXX", -- W
+ "UX01XX01X", -- L
+ "UX10XX10X", -- H
+ "UXXXXXXXX" -- -
+ );
end Synth.Ieee.Std_Logic_1164;
diff --git a/src/synth/synth-static_oper.adb b/src/synth/synth-static_oper.adb
index 645456db0..76c653329 100644
--- a/src/synth/synth-static_oper.adb
+++ b/src/synth/synth-static_oper.adb
@@ -138,6 +138,22 @@ package body Synth.Static_Oper is
end;
end Synth_Add_Uns_Nat;
+ function Synth_Mul_Uns_Uns (L, R : Value_Acc; Loc : Syn_Src)
+ return Value_Acc
+ is
+ pragma Unreferenced (Loc);
+ L_Arr : Std_Logic_Vector (1 .. Natural (L.Arr.Len));
+ R_Arr : Std_Logic_Vector (1 .. Natural (R.Arr.Len));
+ begin
+ To_Std_Logic_Vector (L, L_Arr);
+ To_Std_Logic_Vector (R, R_Arr);
+ declare
+ Res_Arr : constant Std_Logic_Vector := Mul_Uns_Uns (L_Arr, R_Arr);
+ begin
+ return To_Value_Acc (Res_Arr, L.Typ.Vec_El);
+ end;
+ end Synth_Mul_Uns_Uns;
+
function Synth_Static_Dyadic_Predefined (Syn_Inst : Synth_Instance_Acc;
Imp : Node;
Left : Value_Acc;
@@ -242,6 +258,9 @@ package body Synth.Static_Oper is
when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Nat =>
return Synth_Add_Uns_Nat (Left, Right, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Mul_Uns_Uns =>
+ return Synth_Mul_Uns_Uns (Left, Right, Expr);
+
when others =>
Error_Msg_Synth
(+Expr, "synth_static_dyadic_predefined: unhandled "