aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/synth/synth-expr.adb63
-rw-r--r--src/synth/synth-expr.ads5
-rw-r--r--src/synth/synth-stmts.adb21
-rw-r--r--src/synth/synth-values.adb12
-rw-r--r--src/synth/synth-values.ads1
5 files changed, 71 insertions, 31 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb
index 78285cc09..04830971a 100644
--- a/src/synth/synth-expr.adb
+++ b/src/synth/synth-expr.adb
@@ -512,18 +512,6 @@ package body Synth.Expr is
end if;
end Synth_Bit_Eq_Const;
- function Extract_Bound (Val : Value_Acc) return Value_Bound_Acc is
- begin
- case Val.Kind is
- when Value_Net =>
- return Val.N_Bound;
- when Value_Wire =>
- return Val.W_Bound;
- when others =>
- raise Internal_Error;
- end case;
- end Extract_Bound;
-
-- Create the result range of an operator. According to the ieee standard,
-- the range is LEN-1 downto 0.
function Create_Res_Bound (Prev : Value_Acc; N : Net) return Value_Bound_Acc
@@ -907,17 +895,19 @@ package body Synth.Expr is
return Bit_Extract (Pfx, Off);
end Synth_Indexed_Name;
- function Synth_Slice_Name (Syn_Inst : Synth_Instance_Acc; Name : Node)
- return Value_Acc
+ procedure Synth_Slice_Suffix (Syn_Inst : Synth_Instance_Acc;
+ Name : Node;
+ Pfx_Bnd : Value_Bound_Acc;
+ Res_Bnd : out Value_Bound_Acc;
+ Off : out Uns32)
is
- Pfx : constant Value_Acc :=
- Synth_Expression (Syn_Inst, Get_Prefix (Name));
Expr : constant Node := Get_Suffix (Name);
- Res_Bnd : Value_Bound_Acc;
Left, Right : Value_Acc;
Dir : Iir_Direction;
- Bnd : Value_Bound_Acc;
begin
+ Res_Bnd := null;
+ Off := 0;
+
case Get_Kind (Expr) is
when Iir_Kind_Range_Expression =>
Left := Synth_Expression (Syn_Inst, Get_Left_Limit (Expr));
@@ -929,28 +919,27 @@ package body Synth.Expr is
if Left.Kind /= Value_Discrete then
Error_Msg_Synth (+Name, "non constant integer left not supported");
- return null;
+ return;
end if;
if Right.Kind /= Value_Discrete then
Error_Msg_Synth (+Name, "non constant integer right not supported");
- return null;
+ return;
end if;
- Bnd := Extract_Bound (Pfx);
- if Bnd.Dir /= Dir then
+ if Pfx_Bnd.Dir /= Dir then
Error_Msg_Synth (+Name, "direction mismatch in slice");
- return null;
+ return;
end if;
- if not In_Bounds (Bnd, Int32 (Left.Scal))
- or else not In_Bounds (Bnd, Int32 (Right.Scal))
+ if not In_Bounds (Pfx_Bnd, Int32 (Left.Scal))
+ or else not In_Bounds (Pfx_Bnd, Int32 (Right.Scal))
then
Error_Msg_Synth (+Name, "index not within bounds");
- return null;
+ return;
end if;
- case Bnd.Dir is
+ case Pfx_Bnd.Dir is
when Iir_To =>
Res_Bnd := Create_Value_Bound
(Value_Bound_Type'
@@ -958,8 +947,7 @@ package body Synth.Expr is
Len => Width (Right.Scal - Left.Scal + 1),
Left => Int32 (Left.Scal),
Right => Int32 (Right.Scal)));
- return Vec_Extract
- (Pfx, Uns32 (Bnd.Right - Res_Bnd.Right), Res_Bnd);
+ Off := Uns32 (Pfx_Bnd.Right - Res_Bnd.Right);
when Iir_Downto =>
Res_Bnd := Create_Value_Bound
(Value_Bound_Type'
@@ -967,9 +955,22 @@ package body Synth.Expr is
Len => Width (Left.Scal - Right.Scal + 1),
Left => Int32 (Left.Scal),
Right => Int32 (Right.Scal)));
- return Vec_Extract
- (Pfx, Uns32 (Res_Bnd.Right - Bnd.Right), Res_Bnd);
+ Off := Uns32 (Res_Bnd.Right - Pfx_Bnd.Right);
end case;
+ end Synth_Slice_Suffix;
+
+ function Synth_Slice_Name (Syn_Inst : Synth_Instance_Acc; Name : Node)
+ return Value_Acc
+ is
+ Pfx : constant Value_Acc :=
+ Synth_Expression (Syn_Inst, Get_Prefix (Name));
+ Bnd : Value_Bound_Acc;
+ Res_Bnd : Value_Bound_Acc;
+ Off : Uns32;
+ begin
+ Bnd := Extract_Bound (Pfx);
+ Synth_Slice_Suffix (Syn_Inst, Name, Bnd, Res_Bnd, Off);
+ return Vec_Extract (Pfx, Off, Res_Bnd);
end Synth_Slice_Name;
-- Match: clk_signal_name'event
diff --git a/src/synth/synth-expr.ads b/src/synth/synth-expr.ads
index 1f4cf3ee2..21758b797 100644
--- a/src/synth/synth-expr.ads
+++ b/src/synth/synth-expr.ads
@@ -55,4 +55,9 @@ package Synth.Expr is
function Index_To_Offset (Pfx : Value_Acc; Idx : Int64; Loc : Node)
return Uns32;
+ procedure Synth_Slice_Suffix (Syn_Inst : Synth_Instance_Acc;
+ Name : Node;
+ Pfx_Bnd : Value_Bound_Acc;
+ Res_Bnd : out Value_Bound_Acc;
+ Off : out Uns32);
end Synth.Expr;
diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb
index 92384c42c..c05568261 100644
--- a/src/synth/synth-stmts.adb
+++ b/src/synth/synth-stmts.adb
@@ -149,6 +149,27 @@ package body Synth.Stmts is
end if;
Synth_Assign (Targ, Create_Value_Net (V, null), Get_Type (Pfx));
end;
+ when Iir_Kind_Slice_Name =>
+ declare
+ Pfx : constant Node := Get_Prefix (Target);
+ Targ : constant Value_Acc :=
+ Get_Value (Syn_Inst, Get_Base_Name (Pfx));
+ V : Net;
+ Res_Bnd : Value_Bound_Acc;
+ Off : Uns32;
+ begin
+ if Targ.Kind /= Value_Wire then
+ -- Only support assignment of vector.
+ raise Internal_Error;
+ end if;
+ Synth_Slice_Suffix (Syn_Inst, Target, Extract_Bound (Targ),
+ Res_Bnd, Off);
+ V := Build_Insert (Build_Context,
+ Get_Net (Targ, Get_Type (Pfx)),
+ Get_Net (Val, Get_Type (Target)), Off);
+ Synth_Assign
+ (Targ, Create_Value_Net (V, Res_Bnd), Get_Type (Pfx));
+ end;
when others =>
Error_Kind ("synth_assignment", Target);
end case;
diff --git a/src/synth/synth-values.adb b/src/synth/synth-values.adb
index 45e9cf4e6..b71373b16 100644
--- a/src/synth/synth-values.adb
+++ b/src/synth/synth-values.adb
@@ -279,4 +279,16 @@ package body Synth.Values is
Current_Pool := Prev_Pool;
return Res;
end Unshare;
+
+ function Extract_Bound (Val : Value_Acc) return Value_Bound_Acc is
+ begin
+ case Val.Kind is
+ when Value_Net =>
+ return Val.N_Bound;
+ when Value_Wire =>
+ return Val.W_Bound;
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Extract_Bound;
end Synth.Values;
diff --git a/src/synth/synth-values.ads b/src/synth/synth-values.ads
index 01b522440..48d51e0f8 100644
--- a/src/synth/synth-values.ads
+++ b/src/synth/synth-values.ads
@@ -201,4 +201,5 @@ package Synth.Values is
function Unshare (Src : Value_Acc; Pool : Areapool_Acc)
return Value_Acc;
+ function Extract_Bound (Val : Value_Acc) return Value_Bound_Acc;
end Synth.Values;