aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-04-16 19:03:15 +0200
committerTristan Gingold <tgingold@free.fr>2019-04-16 19:03:15 +0200
commit2ce8781f76e0c1695165196aaebf2fe50307d8d1 (patch)
tree3d60bae5ce8670ff48fb720f8a91b25b6ffbd9ba /src/synth
parentc7f21ce2263a90520c0b592ebaec56cd15239866 (diff)
downloadghdl-2ce8781f76e0c1695165196aaebf2fe50307d8d1.tar.gz
ghdl-2ce8781f76e0c1695165196aaebf2fe50307d8d1.tar.bz2
ghdl-2ce8781f76e0c1695165196aaebf2fe50307d8d1.zip
synth: minimal support of slices.
Diffstat (limited to 'src/synth')
-rw-r--r--src/synth/netlists-dump.adb1
-rw-r--r--src/synth/synth-expr.adb87
2 files changed, 88 insertions, 0 deletions
diff --git a/src/synth/netlists-dump.adb b/src/synth/netlists-dump.adb
index 76438a6e1..ad13b1ee8 100644
--- a/src/synth/netlists-dump.adb
+++ b/src/synth/netlists-dump.adb
@@ -465,6 +465,7 @@ package body Netlists.Dump is
procedure Disp_Module (M : Module; Indent : Natural := 0) is
begin
+ -- Name and ports.
Dump_Module_Header (M, Indent);
-- Submodules.
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb
index c585f0d81..e04ccae05 100644
--- a/src/synth/synth-expr.adb
+++ b/src/synth/synth-expr.adb
@@ -119,6 +119,23 @@ package body Synth.Expr is
end case;
end Bit_Extract;
+ function Vec_Extract (Val : Value_Acc; Off : Uns32; Rng : Value_Range_Acc)
+ return Value_Acc is
+ begin
+ case Val.Kind is
+ when Value_Lit =>
+ -- TODO.
+ raise Internal_Error;
+ when Value_Net
+ | Value_Wire =>
+ return Create_Value_Net
+ (Build_Slice (Build_Context, Get_Net (Val), Off, Rng.Len),
+ Rng);
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Vec_Extract;
+
function Synth_Uresize (Val : Value_Acc; W : Width) return Net
is
N : constant Net := Get_Net (Val);
@@ -502,6 +519,7 @@ package body Synth.Expr is
return null;
end if;
+ -- The offset is from the LSB (bit 0). Bit 0 is the rightmost one.
case Rng.Dir is
when Iir_To =>
return Bit_Extract (Pfx, Uns32 (Rng.Right - Idx));
@@ -510,6 +528,73 @@ package body Synth.Expr is
end case;
end Synth_Indexed_Name;
+ function Synth_Slice_Name (Syn_Inst : Synth_Instance_Acc; Name : Iir)
+ return Value_Acc
+ is
+ Pfx : constant Value_Acc :=
+ Synth_Expression (Syn_Inst, Get_Prefix (Name));
+ Expr : constant Iir := Get_Suffix (Name);
+ Res_Rng : Value_Range_Acc;
+ Left, Right : Value_Acc;
+ Dir : Iir_Direction;
+ Rng : Value_Range_Acc;
+ begin
+ case Get_Kind (Expr) is
+ when Iir_Kind_Range_Expression =>
+ Left := Synth_Expression (Syn_Inst, Get_Left_Limit (Expr));
+ Right := Synth_Expression (Syn_Inst, Get_Right_Limit (Expr));
+ Dir := Get_Direction (Expr);
+ when others =>
+ Error_Msg_Synth (+Expr, "only range supported for slices");
+ end case;
+
+ if Left.Kind /= Value_Lit
+ or else Left.Lit.Kind /= Iir_Value_I64
+ then
+ Error_Msg_Synth (+Name, "non constant integer left not supported");
+ return null;
+ end if;
+
+ if Right.Kind /= Value_Lit
+ or else Right.Lit.Kind /= Iir_Value_I64
+ then
+ Error_Msg_Synth (+Name, "non constant integer right not supported");
+ return null;
+ end if;
+
+ Rng := Extract_Range (Pfx);
+ if Rng.Dir /= Dir then
+ Error_Msg_Synth (+Name, "direction mismatch in slice");
+ return null;
+ end if;
+
+ if not In_Range (Rng, Int32 (Left.Lit.I64))
+ or else not In_Range (Rng, Int32 (Right.Lit.I64))
+ then
+ Error_Msg_Synth (+Name, "index not within bounds");
+ return null;
+ end if;
+
+ case Rng.Dir is
+ when Iir_To =>
+ Res_Rng := Create_Range_Value
+ (Value_Range'(Dir => Iir_To,
+ Len => Width (Right.Lit.I64 - Left.Lit.I64 + 1),
+ Left => Int32 (Left.Lit.I64),
+ Right => Int32 (Right.Lit.I64)));
+ return Vec_Extract
+ (Pfx, Uns32 (Rng.Right - Res_Rng.Right), Res_Rng);
+ when Iir_Downto =>
+ Res_Rng := Create_Range_Value
+ (Value_Range'(Dir => Iir_Downto,
+ Len => Width (Left.Lit.I64 - Right.Lit.I64 + 1),
+ Left => Int32 (Left.Lit.I64),
+ Right => Int32 (Right.Lit.I64)));
+ return Vec_Extract
+ (Pfx, Uns32 (Res_Rng.Right - Rng.Right), Res_Rng);
+ end case;
+ end Synth_Slice_Name;
+
-- Match: clk_signal_name'event
-- and return clk_signal_name.
function Extract_Event_Expr_Prefix (Expr : Iir) return Iir is
@@ -700,6 +785,8 @@ package body Synth.Expr is
return Synth_Name (Syn_Inst, Expr);
when Iir_Kind_Indexed_Name =>
return Synth_Indexed_Name (Syn_Inst, Expr);
+ when Iir_Kind_Slice_Name =>
+ return Synth_Slice_Name (Syn_Inst, Expr);
when Iir_Kind_Character_Literal
| Iir_Kind_Integer_Literal
| Iir_Kind_String_Literal8 =>