From 2075f8cf5995bc83a8edc07456331b5b0f5b6be1 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Fri, 26 Jul 2019 04:32:07 +0200 Subject: synth: preliminary support of integer subtypes. --- src/synth/synth-context.adb | 17 +++++++++++-- src/synth/synth-decls.adb | 2 +- src/synth/synth-insts.adb | 10 +++----- src/synth/synth-stmts.adb | 4 ++- src/synth/synth-types.adb | 59 ++++++++++++++++++++++++--------------------- src/synth/synth-types.ads | 7 +++--- src/synth/synth-values.adb | 9 +++++++ src/synth/synth-values.ads | 2 ++ 8 files changed, 68 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/synth/synth-context.adb b/src/synth/synth-context.adb index 1d87df365..e4c0436e8 100644 --- a/src/synth/synth-context.adb +++ b/src/synth/synth-context.adb @@ -110,16 +110,29 @@ package body Synth.Context is end; when Iir_Kind_Array_Subtype_Definition => declare - El_Type : constant Node := Get_Element_Subtype (Obj_Type); Bounds : Value_Bound_Acc; begin Bounds := Synth_Array_Bounds (Syn_Inst, Obj_Type, 0); - if Is_Bit_Type (El_Type) then + if Is_Vector_Type (Obj_Type) then return Alloc_Wire (Kind, Obj, Bounds); else raise Internal_Error; end if; end; + when Iir_Kind_Integer_Subtype_Definition => + declare + Rng : Value_Acc; + W : Width; + Bnd : Value_Bound_Acc; + begin + Rng := Get_Value (Syn_Inst, Obj_Type); + W := Get_Range_Width (Rng.Rng); + Bnd := Create_Value_Bound ((Dir => Iir_Downto, + Left => Int32 (W - 1), + Right => 0, + Len => W)); + return Alloc_Wire (Kind, Obj, Bnd); + end; when others => Error_Kind ("alloc_object", Obj_Type); end case; diff --git a/src/synth/synth-decls.adb b/src/synth/synth-decls.adb index d7a0699d9..48952ef5a 100644 --- a/src/synth/synth-decls.adb +++ b/src/synth/synth-decls.adb @@ -46,7 +46,7 @@ package body Synth.Decls is case Val.Kind is when Value_Wire => -- FIXME: get the width directly from the wire ? - W := Get_Width (Syn_Inst, Get_Type (Decl)); + W := Get_Bound_Width (Val.W_Bound); Name := New_Sname (Syn_Inst.Name, Get_Identifier (Decl)); if Init /= null then Ival := Get_Net (Init, Get_Type (Decl)); diff --git a/src/synth/synth-insts.adb b/src/synth/synth-insts.adb index 6aa0e78ad..0bc361d5c 100644 --- a/src/synth/synth-insts.adb +++ b/src/synth/synth-insts.adb @@ -36,7 +36,6 @@ with Synth.Values; use Synth.Values; with Synth.Environment; use Synth.Environment; with Synth.Stmts; use Synth.Stmts; with Synth.Decls; use Synth.Decls; -with Synth.Types; use Synth.Types; with Synth.Expr; use Synth.Expr; package body Synth.Insts is @@ -67,17 +66,15 @@ package body Synth.Insts is procedure Make_Port_Desc (Val : Value_Acc; Name : Sname; - Wd : Width; Ports : in out Port_Desc_Array; Idx : in out Port_Nbr; - Dir : Port_Kind) - is + Dir : Port_Kind) is begin case Val.Kind is when Value_Wire => Idx := Idx + 1; Ports (Idx) := (Name => Name, - W => Wd, + W => Get_Bound_Width (Val.W_Bound), Dir => Dir); when others => raise Internal_Error; -- TODO @@ -91,11 +88,10 @@ package body Synth.Insts is Dir : Port_Kind) is Val : constant Value_Acc := Get_Value (Syn_Inst, Inter); - Wd : constant Width := Get_Width (Syn_Inst, Get_Type (Inter)); Name : Sname; begin Name := New_Sname_User (Get_Identifier (Inter)); - Make_Port_Desc (Val, Name, Wd, Ports, Idx, Dir); + Make_Port_Desc (Val, Name, Ports, Idx, Dir); end Make_Port_Desc; -- Parameters that define an instance. diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index 5aad73c76..158fd60df 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -84,13 +84,15 @@ package body Synth.Stmts is Val : Value_Acc) is Targ_Type : constant Node := Get_Type (Target); + Bnd : Value_Bound_Acc; Choice : Node; Assoc : Node; Pos : Uns32; begin if Is_Vector_Type (Targ_Type) then + Bnd := Expr.Synth_Array_Bounds (Syn_Inst, Targ_Type, 0); Choice := Get_Association_Choices_Chain (Target); - Pos := Get_Width (Syn_Inst, Targ_Type); + Pos := Bnd.Len; while Is_Valid (Choice) loop Assoc := Get_Associated_Expr (Choice); case Get_Kind (Choice) is diff --git a/src/synth/synth-types.adb b/src/synth/synth-types.adb index b197ca570..cbccbb628 100644 --- a/src/synth/synth-types.adb +++ b/src/synth/synth-types.adb @@ -19,14 +19,10 @@ -- MA 02110-1301, USA. with Types; use Types; +with Mutils; use Mutils; with Vhdl.Std_Package; with Vhdl.Ieee.Std_Logic_1164; with Vhdl.Utils; use Vhdl.Utils; -with Vhdl.Errors; use Vhdl.Errors; - -with Synth.Values; use Synth.Values; -with Synth.Expr; -with Vhdl.Annotations; use Vhdl.Annotations; package body Synth.Types is function Is_Bit_Type (Atype : Node) return Boolean @@ -54,31 +50,38 @@ package body Synth.Types is and then Get_Nbr_Dimensions (Atype) = 1; end Is_Vector_Type; - function Get_Width (Syn_Inst : Synth_Instance_Acc; Atype : Node) - return Width + function Get_Range_Width (Rng : Value_Range_Type) return Width is - Btype : constant Node := Get_Base_Type (Atype); + Low : Int64; + High : Int64; begin - case Get_Kind (Atype) is - when Iir_Kind_Enumeration_Type_Definition => - return Width (Get_Info (Atype).Width); - when Iir_Kind_Enumeration_Subtype_Definition => - -- Tail call - return Get_Width (Syn_Inst, Btype); - when Iir_Kind_Array_Subtype_Definition => - if Is_Vector_Type (Btype) then - declare - Bnd : Value_Bound_Acc; - begin - Bnd := Expr.Synth_Array_Bounds (Syn_Inst, Atype, 0); - return Bnd.Len; - end; - else - raise Internal_Error; - end if; - when others => - Error_Kind ("get_width", Atype); + case Rng.Dir is + when Iir_To => + Low := Rng.Left; + High := Rng.Right; + when Iir_Downto => + Low := Rng.Right; + High := Rng.Left; end case; - end Get_Width; + if Low > High then + return 0; + end if; + if Low >= 0 then + -- Positive. + return Width (Clog2 (Uns64 (High))); + elsif High < 0 then + -- Negative only. + -- FIXME: overflow. + return Width (Clog2 (Uns64 (-Low))) + 1; + else + declare + -- FIXME: overflow. + L : constant Width := Width (Clog2 (Uns64 (-Low))); + H : constant Width := Width (Clog2 (Uns64 (-High))); + begin + return Width'Max (L, H) + 1; + end; + end if; + end Get_Range_Width; end Synth.Types; diff --git a/src/synth/synth-types.ads b/src/synth/synth-types.ads index 15b12767d..e82ece9bd 100644 --- a/src/synth/synth-types.ads +++ b/src/synth/synth-types.ads @@ -19,7 +19,7 @@ -- MA 02110-1301, USA. with Netlists; use Netlists; -with Synth.Context; use Synth.Context; +with Synth.Values; use Synth.Values; with Vhdl.Nodes; use Vhdl.Nodes; package Synth.Types is @@ -28,6 +28,7 @@ package Synth.Types is function Is_Vector_Type (Atype : Node) return Boolean; - function Get_Width (Syn_Inst : Synth_Instance_Acc; Atype : Node) - return Width; + -- Number of bits for RNG. + function Get_Range_Width (Rng : Value_Range_Type) return Width; + end Synth.Types; diff --git a/src/synth/synth-values.adb b/src/synth/synth-values.adb index 47c47e279..92587fd55 100644 --- a/src/synth/synth-values.adb +++ b/src/synth/synth-values.adb @@ -304,4 +304,13 @@ package body Synth.Values is raise Internal_Error; end case; end Extract_Bound; + + function Get_Bound_Width (Bnd : Value_Bound_Acc) return Width is + begin + if Bnd = null then + return 1; + else + return Bnd.Len; + end if; + end Get_Bound_Width; end Synth.Values; diff --git a/src/synth/synth-values.ads b/src/synth/synth-values.ads index 9b23d834c..357bd1006 100644 --- a/src/synth/synth-values.ads +++ b/src/synth/synth-values.ads @@ -205,4 +205,6 @@ package Synth.Values is return Value_Acc; function Extract_Bound (Val : Value_Acc) return Value_Bound_Acc; + + function Get_Bound_Width (Bnd : Value_Bound_Acc) return Width; end Synth.Values; -- cgit v1.2.3