1--  Values in synthesis.
2--  Copyright (C) 2017 Tristan Gingold
3--
4--  This file is part of GHDL.
5--
6--  This program is free software; you can redistribute it and/or modify
7--  it under the terms of the GNU General Public License as published by
8--  the Free Software Foundation; either version 2 of the License, or
9--  (at your option) any later version.
10--
11--  This program is distributed in the hope that it will be useful,
12--  but WITHOUT ANY WARRANTY; without even the implied warranty of
13--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14--  GNU General Public License for more details.
15--
16--  You should have received a copy of the GNU General Public License
17--  along with this program; if not, write to the Free Software
18--  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19--  MA 02110-1301, USA.
20
21with Types; use Types;
22with Areapools; use Areapools;
23
24with Netlists; use Netlists;
25
26with Grt.Types; use Grt.Types;
27
28with Vhdl.Nodes; use Vhdl.Nodes;
29
30package Synth.Objtypes is
31   type Discrete_Range_Type is record
32      --  An integer range.
33      Dir : Direction_Type;
34
35      --  Netlist representation: signed or unsigned, width of vector.
36      Is_Signed : Boolean;
37
38      Left : Int64;
39      Right : Int64;
40   end record;
41
42   --  Return the width of RNG.
43   function Discrete_Range_Width (Rng : Discrete_Range_Type) return Width;
44
45   type Float_Range_Type is record
46      Dir : Direction_Type;
47      Left : Fp64;
48      Right : Fp64;
49   end record;
50
51   type Bound_Type is record
52      Dir : Direction_Type;
53      Left : Int32;
54      Right : Int32;
55      Len : Width;
56   end record;
57
58   type Bound_Array_Type is array (Dim_Type range <>) of Bound_Type;
59
60   type Bound_Array (Ndim : Dim_Type) is record
61      D : Bound_Array_Type (1 .. Ndim);
62   end record;
63
64   type Bound_Array_Acc is access Bound_Array;
65
66   type Type_Kind is
67     (
68      Type_Bit,
69      Type_Logic,
70      Type_Discrete,
71      Type_Float,
72      Type_Vector,
73      Type_Unbounded_Vector,
74
75      --  A slice is for a slice of vector with dynamic bounds.  So the bounds
76      --  of the result aren't known, but its width is.
77      Type_Slice,
78      Type_Array,
79      Type_Unbounded_Array,
80      Type_Unbounded_Record,
81      Type_Record,
82
83      Type_Access,
84      Type_File,
85      Type_Protected
86     );
87
88   subtype Type_Nets is Type_Kind range Type_Bit .. Type_Logic;
89   subtype Type_All_Discrete is Type_Kind range Type_Bit .. Type_Discrete;
90   subtype Type_Records is
91     Type_Kind range Type_Unbounded_Record .. Type_Record;
92
93   type Type_Type (Kind : Type_Kind);
94   type Type_Acc is access Type_Type;
95
96   type Rec_El_Type is record
97      --  Bit offset: offset of the element in a net.
98      Boff : Uns32;
99
100      --  Memory offset: offset of the element in memory.
101      Moff : Size_Type;
102
103      --  Type of the element.
104      Typ : Type_Acc;
105   end record;
106
107   type Rec_El_Array_Type is array (Iir_Index32 range <>) of Rec_El_Type;
108   type Rec_El_Array (Len : Iir_Index32) is record
109      E : Rec_El_Array_Type (1 .. Len);
110   end record;
111
112   type Rec_El_Array_Acc is access Rec_El_Array;
113
114   --  Power of 2 alignment.
115   type Palign_Type is range 0 .. 3;
116
117   type Type_Type (Kind : Type_Kind) is record
118      --  False if the type is not synthesisable: is or contains access/file.
119      Is_Synth : Boolean;
120
121      --  Alignment (in bytes) for this type.
122      Al : Palign_Type;
123
124      --  Number of bytes (when in memory) for this type.
125      Sz : Size_Type;
126
127      --  Number of bits (when in a net) for this type.
128      --  Can be zero only if the type has only 0 or 1 value (like a discrete
129      --  type with 1 element, a null vector, or a null array).
130      --  For non synthesizable types (like files or protected type), just
131      --  use 32.
132      W : Width;
133
134      case Kind is
135         when Type_Bit
136           | Type_Logic =>
137            null;
138         when Type_Discrete =>
139            Drange : Discrete_Range_Type;
140         when Type_Float =>
141            Frange : Float_Range_Type;
142         when Type_Vector =>
143            Vbound : Bound_Type;
144            Vec_El : Type_Acc;
145         when Type_Unbounded_Vector =>
146            Uvec_El : Type_Acc;
147         when Type_Slice =>
148            Slice_El : Type_Acc;
149         when Type_Array =>
150            Abounds : Bound_Array_Acc;
151            Arr_El : Type_Acc;
152         when Type_Unbounded_Array =>
153            Uarr_Ndim : Dim_Type;
154            Uarr_El : Type_Acc;
155         when Type_Record
156           | Type_Unbounded_Record =>
157            Rec : Rec_El_Array_Acc;
158         when Type_Access =>
159            Acc_Acc : Type_Acc;
160         when Type_File =>
161            File_Typ  : Type_Acc;
162            File_Signature : String_Acc;
163         when Type_Protected =>
164            null;
165      end case;
166   end record;
167
168   type Memory_Element is mod 2**8;
169   type Memory_Array is array (Size_Type range <>) of Memory_Element;
170
171   --  Thin pointer for a generic pointer.
172   type Memory_Ptr is access all Memory_Array (Size_Type);
173   pragma No_Strict_Aliasing (Memory_Ptr);
174
175   type Memtyp is record
176      Typ : Type_Acc;
177      Mem : Memory_Ptr;
178   end record;
179
180   Null_Memtyp : constant Memtyp := (null, null);
181
182   --  Offsets for a value.
183   type Value_Offsets is record
184      Net_Off : Uns32;
185      Mem_Off : Size_Type;
186   end record;
187
188   No_Value_Offsets : constant Value_Offsets := (0, 0);
189
190   function "+" (L, R : Value_Offsets) return Value_Offsets;
191
192   Global_Pool : aliased Areapool;
193   Expr_Pool : aliased Areapool;
194
195   --  Areapool used by Create_*_Value
196   Current_Pool : Areapool_Acc := Expr_Pool'Access;
197
198   --  Pool for objects allocated in the current instance.
199   Instance_Pool : Areapool_Acc;
200
201   --  Types.
202   function Create_Discrete_Type (Rng : Discrete_Range_Type;
203                                  Sz : Size_Type;
204                                  W : Width)
205                                 return Type_Acc;
206
207   function Create_Float_Type (Rng : Float_Range_Type) return Type_Acc;
208   function Create_Vec_Type_By_Length (Len : Width; El : Type_Acc)
209                                      return Type_Acc;
210   function Create_Vector_Type (Bnd : Bound_Type; El_Type : Type_Acc)
211                               return Type_Acc;
212   function Create_Unbounded_Vector (El_Type : Type_Acc) return Type_Acc;
213   function Create_Slice_Type (Len : Uns32; El_Type : Type_Acc)
214                              return Type_Acc;
215   function Create_Bound_Array (Ndims : Dim_Type) return Bound_Array_Acc;
216   function Create_Array_Type (Bnd : Bound_Array_Acc; El_Type : Type_Acc)
217                              return Type_Acc;
218   function Create_Unbounded_Array (Ndim : Dim_Type; El_Type : Type_Acc)
219                                   return Type_Acc;
220   function Create_Rec_El_Array (Nels : Iir_Index32) return Rec_El_Array_Acc;
221
222   function Create_Record_Type (Els : Rec_El_Array_Acc) return Type_Acc;
223   function Create_Unbounded_Record (Els : Rec_El_Array_Acc) return Type_Acc;
224
225   function Create_Access_Type (Acc_Type : Type_Acc) return Type_Acc;
226
227   function Create_File_Type (File_Type : Type_Acc) return Type_Acc;
228
229   function Create_Protected_Type return Type_Acc;
230
231   function In_Bounds (Bnd : Bound_Type; V : Int32) return Boolean;
232   function In_Range (Rng : Discrete_Range_Type; V : Int64) return Boolean;
233
234   --  Return the bounds of dimension DIM of a vector/array.  For a vector,
235   --  DIM must be 1.
236   function Get_Array_Bound (Typ : Type_Acc; Dim : Dim_Type)
237                            return Bound_Type;
238
239   --  Return the length of RNG.
240   function Get_Range_Length (Rng : Discrete_Range_Type) return Uns32;
241
242   --  Return the element of a vector/array/unbounded_array.
243   function Get_Array_Element (Arr_Type : Type_Acc) return Type_Acc;
244
245   function Is_Bounded_Type (Typ : Type_Acc) return Boolean;
246
247   function Are_Types_Equal (L, R : Type_Acc) return Boolean;
248
249   --  Return the length of a vector type.
250   function Vec_Length (Typ : Type_Acc) return Iir_Index32;
251
252   --  Get the number of indexes in array type TYP without counting
253   --  sub-elements.
254   function Get_Array_Flat_Length (Typ : Type_Acc) return Iir_Index32;
255
256   --  Return length of dimension DIM of type T.
257   function Get_Bound_Length (T : Type_Acc; Dim : Dim_Type) return Width;
258
259   function Is_Matching_Bounds (L, R : Type_Acc) return Boolean;
260
261   function Get_Type_Width (Atype : Type_Acc) return Width;
262
263   --  Low-level functions.
264
265   function "+" (Base : Memory_Ptr; Off : Size_Type) return Memory_Ptr;
266
267   procedure Write_U8 (Mem : Memory_Ptr; Val : Ghdl_U8);
268   function Read_U8 (Mem : Memory_Ptr) return Ghdl_U8;
269   function Read_U8 (Mt : Memtyp) return Ghdl_U8;
270
271   procedure Write_U32 (Mem : Memory_Ptr; Val : Ghdl_U32);
272   function Read_U32 (Mem : Memory_Ptr) return Ghdl_U32;
273
274   procedure Write_I32 (Mem : Memory_Ptr; Val : Ghdl_I32);
275   function Read_I32 (Mem : Memory_Ptr) return Ghdl_I32;
276
277   procedure Write_I64 (Mem : Memory_Ptr; Val : Ghdl_I64);
278   function Read_I64 (Mem : Memory_Ptr) return Ghdl_I64;
279
280   procedure Write_Fp64 (Mem : Memory_Ptr; Val : Fp64);
281   function Read_Fp64 (Mem : Memory_Ptr) return Fp64;
282   function Read_Fp64 (Mt : Memtyp) return Fp64;
283
284   procedure Write_Discrete (Mem : Memory_Ptr; Typ : Type_Acc; Val : Int64);
285   function Read_Discrete (Mt : Memtyp) return Int64;
286
287   --  Memory allocation.
288
289   function Create_Memory_U8 (Val : Ghdl_U8; Vtype : Type_Acc)
290                             return Memtyp;
291   function Create_Memory_Fp64 (Val : Fp64; Vtype : Type_Acc)
292                               return Memtyp;
293   function Create_Memory_Discrete (Val : Int64; Vtype : Type_Acc)
294                                   return Memtyp;
295
296   function Alloc_Memory (Vtype : Type_Acc) return Memory_Ptr;
297   function Create_Memory (Vtype : Type_Acc) return Memtyp;
298
299   --  Like Create_Memory but initialize to 0.  To be used only for types
300   --  of width 0.
301   function Create_Memory_Zero (Vtype : Type_Acc) return Memtyp;
302
303   function Is_Equal (L, R : Memtyp) return Boolean;
304
305   procedure Copy_Memory (Dest : Memory_Ptr; Src : Memory_Ptr; Sz : Size_Type);
306
307   function Unshare (Src : Memtyp) return Memtyp;
308
309   procedure Init;
310
311   --  Set by Init.
312   Boolean_Type : Type_Acc := null;
313   Logic_Type : Type_Acc := null;
314   Bit_Type : Type_Acc := null;
315
316   --  Also set by init.
317   Bit0 : Memtyp;
318   Bit1 : Memtyp;
319end Synth.Objtypes;
320