1--  Naive values for interpreted simulation
2--  Copyright (C) 2014 Tristan Gingold
3--
4--  This program is free software: you can redistribute it and/or modify
5--  it under the terms of the GNU General Public License as published by
6--  the Free Software Foundation, either version 2 of the License, or
7--  (at your option) any later version.
8--
9--  This program is distributed in the hope that it will be useful,
10--  but WITHOUT ANY WARRANTY; without even the implied warranty of
11--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12--  GNU General Public License for more details.
13--
14--  You should have received a copy of the GNU General Public License
15--  along with this program.  If not, see <gnu.org/licenses>.
16
17with Ada.Unchecked_Deallocation;
18
19with Types; use Types;
20
21with Vhdl.Nodes; use Vhdl.Nodes;
22with Vhdl.Annotations; use Vhdl.Annotations;
23with Grt.Types; use Grt.Types;
24with Grt.Signals; use Grt.Signals;
25with Grt.Files;
26with Areapools; use Areapools;
27-- with System.Debug_Pools;
28
29package Simul.Environments is
30   -- During simulation, all values are contained into objects of type
31   -- iir_value_literal.  The annotation pass creates such objects for every
32   -- literal of units.  The elaboration pass creates such objects for
33   -- signals, variables, contants...
34   -- The simulator uses iir_value_literal for intermediate results, for
35   -- computed values...
36
37   -- There is several kinds of iir_value_literal, mainly depending on the
38   -- type of the value:
39   --
40   -- iir_value_e32:
41   --  the value is an enumeration literal.  The enum field contains the
42   --  position of the literal (same as 'pos).
43   --
44   -- iir_value_i64:
45   --  the value is an integer.
46   --
47   -- iir_value_f64:
48   --  the value is a floating point.
49   --
50   -- iir_value_range:
51   --  Boundaries and direction.
52   --
53   -- iir_value_array:
54   --  All the values are contained in the array Val_Array.
55   --  Boundaries of the array are contained in the array BOUNDS, one element
56   --  per dimension, from 1 to number of dimensions.
57   --
58   -- iir_value_signal:
59   --  Special case: the iir_value_literal designates a signal.
60   --
61   -- iir_value_record
62   --  For records.
63   --
64   -- iir_value_access
65   --  for accesses.
66   --
67   -- iir_value_file
68   --  for files.
69
70   --  Memory management:
71   --  The values are always allocated on areapool, which uses a mark/release
72   --  management. A release operation frees all the memory of the areapool
73   --  allocated since the mark. This memory management is very efficient.
74   --
75   --  There is one areapool per processes; there is one mark per instances.
76   --  Objects (variables, signals, constants, iterators, ...) are allocated
77   --  on the per-process pool.  When an activation frame is created (due
78   --  to a call to a subprogram), a mark is saved. When the activation frame
79   --  is removed (due to a return from subprogram), the memory is released to
80   --  the mark. That's simple.
81   --
82   --  Objects for the process is allocated in that areapool, but never
83   --  released (could be if the process is waiting forever if the user don't
84   --  need to inspect values).
85   --
86   --  Signals and constants for blocks/entity/architecture are allocated on
87   --  a global pool.
88   --
89   --  In fact this is not so simple because of functions: they return a
90   --  value.  The current solution is to compute every expressions on a
91   --  expression pool (only one is needed as the computation cannot be
92   --  suspended), use the result (copy in case of assignment or return), and
93   --  release that pool.
94   --
95   --  It is highly recommended to share values as much as possible for
96   --  expressions (for example, alias the values of 'others =>'). Do not
97   --  share values for names, but be sure to keep the original nodes.
98   --  ??? In fact sharing is required to pass actual by references.
99   --  When an object is created, be sure to unshare the values.  This is
100   --  usually achieved by Copy.
101   --
102   --  Finally, a pool is also needed during elaboration (as elaboration is
103   --  not done within the context of a process).
104
105   type Iir_Value_Kind is
106     (Iir_Value_B1, Iir_Value_E8, Iir_Value_E32,
107      Iir_Value_I64, Iir_Value_F64,
108      Iir_Value_Access,
109      Iir_Value_File,
110      Iir_Value_Range,
111      Iir_Value_Array, Iir_Value_Record,
112      Iir_Value_Protected,
113      Iir_Value_Signal,
114      Iir_Value_Terminal,
115      Iir_Value_Quantity,
116      Iir_Value_Instance);
117
118   --  Uniq identifier for scalar signal.  First identifier is 'First + 1.
119   type Signal_Index_Type is new Natural;
120   function Get_Last_Signal_Index return Signal_Index_Type;
121
122   type Protected_Index_Type is new Natural;
123   type Quantity_Index_Type is new Natural;
124   type Terminal_Index_Type is new Natural;
125
126   --  Scalar values.  Only these ones can be signals.
127   subtype Iir_Value_Scalars is
128     Iir_Value_Kind range Iir_Value_B1 .. Iir_Value_F64;
129
130   subtype Iir_Value_Discrete is
131     Iir_Value_Kind range Iir_Value_B1 .. Iir_Value_I64;
132
133   subtype Iir_Value_Enums is
134     Iir_Value_Kind range Iir_Value_B1 .. Iir_Value_E32;
135
136   --  Abstrace numeric types.
137   subtype Iir_Value_Numerics is
138     Iir_Value_Kind range Iir_Value_I64 .. Iir_Value_F64;
139
140   subtype Iir_Value_Physicals is
141     Iir_Value_Kind range Iir_Value_I64 .. Iir_Value_I64;
142
143   type Iir_Value_Literal (Kind: Iir_Value_Kind);
144
145   type Iir_Value_Literal_Acc is access Iir_Value_Literal;
146
147   -- Must start at 0.
148   -- Thus, length of the array is val_array'last - 1.
149   type Iir_Value_Literal_Array is array (Iir_Index32 range <>) of
150     Iir_Value_Literal_Acc;
151
152   type Iir_Value_Literal_Array_Acc is access Iir_Value_Literal_Array;
153
154   type Value_Bounds_Array (Nbr_Dims : Iir_Index32) is record
155      D : Iir_Value_Literal_Array (1 .. Nbr_Dims);
156   end record;
157
158   type Value_Bounds_Array_Acc is access Value_Bounds_Array;
159
160   type Value_Array (Len : Iir_Index32) is record
161      V : Iir_Value_Literal_Array (1 .. Len);
162   end record;
163
164   type Value_Array_Acc is access Value_Array;
165
166   -- A block instance with its architecture/entity declaration is an
167   -- instancied entity.
168   type Block_Instance_Type;
169   type Block_Instance_Acc is access Block_Instance_Type;
170
171   type Iir_Value_Literal (Kind: Iir_Value_Kind) is record
172      case Kind is
173         when Iir_Value_B1 =>
174            B1 : Ghdl_B1;
175         when Iir_Value_E8 =>
176            E8 : Ghdl_E8;
177         when Iir_Value_E32 =>
178            E32 : Ghdl_E32;
179         when Iir_Value_I64 =>
180            I64 : Ghdl_I64;
181         when Iir_Value_F64 =>
182            F64 : Ghdl_F64;
183         when Iir_Value_Access =>
184            Val_Access: Iir_Value_Literal_Acc;
185         when Iir_Value_File =>
186            File: Grt.Files.Ghdl_File_Index;
187         when Iir_Value_Array =>
188            Val_Array: Value_Array_Acc; --  range 1 .. N
189            Bounds : Value_Bounds_Array_Acc;   --  range 1 .. Dim
190         when Iir_Value_Record =>
191            Val_Record: Value_Array_Acc; -- range 1 .. N
192         when Iir_Value_Signal =>
193            Sig : Ghdl_Signal_Ptr;
194            --  Each signal has a uniq identifier.
195            Sig_Id : Signal_Index_Type;
196         when Iir_Value_Protected =>
197            Prot : Protected_Index_Type;
198         when Iir_Value_Quantity =>
199            Quantity : Quantity_Index_Type;
200         when Iir_Value_Terminal =>
201            Terminal : Terminal_Index_Type;
202         when Iir_Value_Instance =>
203            Instance : Block_Instance_Acc;
204         when Iir_Value_Range =>
205            Dir: Direction_Type;
206            Length : Iir_Index32;
207            Left: Iir_Value_Literal_Acc;
208            Right: Iir_Value_Literal_Acc;
209      end case;
210   end record;
211
212   type Objects_Array is array (Object_Slot_Type range <>) of
213     Iir_Value_Literal_Acc;
214
215   type Block_Instance_Type (Max_Objs : Object_Slot_Type) is record
216      --  Flag for wait statement: true if not yet executed.
217      In_Wait_Flag : Boolean;
218
219      --  Uniq number for a block instance.
220      Id : Block_Instance_Id;
221
222      -- Useful informations for a dynamic block (ie, a frame).
223      -- The scope level and an access to the block of upper scope level.
224      Block_Scope : Sim_Info_Acc;
225      Uninst_Scope : Sim_Info_Acc;
226      Up_Block : Block_Instance_Acc;
227
228      --  Block, architecture, package, process, component instantiation for
229      --  this instance.
230      Label : Iir;
231
232      --  For subprograms: the body.
233      Bod : Iir;
234
235      --  For blocks: corresponding block (different from label for direct
236      --  component instantiation statement and generate iterator).
237      --  For packages: Null_Iir
238      --  For subprograms and processes: statement being executed.
239      Stmt : Iir;
240
241      --  Instanciation tree.
242
243      --  Parent is always set (but null for top-level block and packages)
244      Parent: Block_Instance_Acc;
245
246      --  Chain of children.  They are in declaration order after elaboration.
247      --  (in reverse order during elaboration).
248      --  Not null only for blocks and processes.
249      Children: Block_Instance_Acc;
250      Brother: Block_Instance_Acc;
251
252      --  Pool marker for the child (only for subprograms and processes).
253      Marker : Areapools.Mark_Type;
254
255      --  Reference to the actuals, for copy-out when returning from a
256      --  procedure.
257      Actuals_Ref : Value_Array_Acc;
258
259      -- Only for function frame; contains the result.
260      Result: Iir_Value_Literal_Acc;
261
262      --  Last object elaborated (or number of objects elaborated).
263      --  Note: this is generally the slot index of the next object to be
264      --  elaborated (this may be wrong for dynamic objects due to execution
265      --  branches).
266      Elab_Objects : Object_Slot_Type := 0;
267
268      --  Values of the objects in that frame.
269      Objects : Objects_Array (1 .. Max_Objs);
270   end record;
271
272   procedure Free is new Ada.Unchecked_Deallocation
273     (Object => Block_Instance_Type, Name => Block_Instance_Acc);
274
275
276   -- What is chosen for time.
277   subtype Iir_Value_Time is Ghdl_I64;
278
279   Global_Pool : aliased Areapool;
280   Expr_Pool : aliased Areapool;
281
282   --  Areapool used by Create_*_Value
283   Current_Pool : Areapool_Acc := Expr_Pool'Access;
284
285   --  Pool for objects allocated in the current instance.
286   Instance_Pool : Areapool_Acc;
287
288   function Create_Signal_Value (Sig : Ghdl_Signal_Ptr)
289                                return Iir_Value_Literal_Acc;
290   function Create_Terminal_Value (Terminal : Terminal_Index_Type)
291                                  return Iir_Value_Literal_Acc;
292   function Create_Quantity_Value (Quantity : Quantity_Index_Type)
293                                  return Iir_Value_Literal_Acc;
294   function Create_Instance_Value (Inst : Block_Instance_Acc)
295                                  return Iir_Value_Literal_Acc;
296
297   function Create_B1_Value (Val : Ghdl_B1) return Iir_Value_Literal_Acc;
298   function Create_E8_Value (Val : Ghdl_E8) return Iir_Value_Literal_Acc;
299   function Create_E32_Value (Val : Ghdl_E32) return Iir_Value_Literal_Acc;
300
301   -- Return an iir_value_literal_acc (iir_value_int64).
302   function Create_I64_Value (Val : Ghdl_I64) return Iir_Value_Literal_Acc;
303
304   --  Return an iir_value_literal_acc (iir_value_fp64)
305   function Create_F64_Value (Val : Ghdl_F64) return Iir_Value_Literal_Acc;
306
307   function Create_Access_Value (Val : Iir_Value_Literal_Acc)
308                                return Iir_Value_Literal_Acc;
309
310   function Create_File_Value (Val : Grt.Files.Ghdl_File_Index)
311                              return Iir_Value_Literal_Acc;
312
313   function Create_Protected_Value (Prot : Protected_Index_Type)
314                                   return Iir_Value_Literal_Acc;
315
316   -- Return an iir_value_literal (iir_value_record) of NBR elements.
317   function Create_Record_Value
318     (Nbr : Iir_Index32; Pool : Areapool_Acc := Current_Pool)
319     return Iir_Value_Literal_Acc;
320
321   --  Allocate array and the dimension vector (but bounds and values aren't
322   --  allocated).
323   function Create_Array_Value (Dim : Iir_Index32;
324                                Pool : Areapool_Acc := Current_Pool)
325                               return Iir_Value_Literal_Acc;
326
327   --  Allocate the Val_Array vector.
328   procedure Create_Array_Data (Arr : Iir_Value_Literal_Acc;
329                                Len : Iir_Index32;
330                                Pool : Areapool_Acc := Current_Pool);
331
332   -- Return an array of length LENGTH and DIM bounds.
333   -- If DIM is 0, then the bounds array is not allocated.
334   function Create_Array_Value (Length: Iir_Index32;
335                                Dim : Iir_Index32;
336                                Pool : Areapool_Acc := Current_Pool)
337                               return Iir_Value_Literal_Acc;
338
339   --  Create a range_value of life LIFE.
340   function Create_Range_Value
341     (Left, Right : Iir_Value_Literal_Acc;
342      Dir : Direction_Type;
343      Length : Iir_Index32)
344     return Iir_Value_Literal_Acc;
345
346   --  Create a range_value (compute the length)
347   function Create_Range_Value
348     (Left, Right : Iir_Value_Literal_Acc;
349      Dir : Direction_Type)
350      return Iir_Value_Literal_Acc;
351
352   -- Return true if the value of LEFT and RIGHT are equal.
353   -- Return false if they are not equal.
354   -- Raise constraint_error if the types differes.
355   -- Value or sub-value must not be indirect.
356   function Is_Equal (Left, Right: Iir_Value_Literal_Acc) return Boolean;
357
358   --  Return TRUE iif ARANGE is a null range.
359   function Is_Null_Range (Arange : Iir_Value_Literal_Acc) return Boolean;
360
361   -- Get order of LEFT with RIGHT.
362   -- Must be discrete kind (enum, int, fp, physical) or array (uni dim).
363   type Order is (Less, Equal, Greater);
364   function Compare_Value (Left, Right : Iir_Value_Literal_Acc)
365                           return Order;
366
367   --  Check that SRC has the same structure as DEST.  Report an error at
368   --  LOC if not.
369   procedure Check_Bounds (Dest : Iir_Value_Literal_Acc;
370                           Src : Iir_Value_Literal_Acc;
371                           Loc : Iir);
372
373   -- Store (by copy) SRC into DEST.
374   -- The type must be equal (otherwise  constraint_error is raised).
375   -- Life of DEST must be Target, otherwise program_error is raised.
376   -- Value or sub-value must not be indirect.
377   procedure Store (Dest : Iir_Value_Literal_Acc; Src : Iir_Value_Literal_Acc);
378
379   --  Create a copy of SRC allocated in POOL.
380   function Unshare (Src : Iir_Value_Literal_Acc; Pool : Areapool_Acc)
381                    return Iir_Value_Literal_Acc;
382
383   --  If SRC is an array, just copy the bounds in POOL and return it.
384   --  Otherwise return SRC.  Values are always kept, so that this could
385   --  be used by alias declarations.
386   function Unshare_Bounds (Src : Iir_Value_Literal_Acc; Pool : Areapool_Acc)
387                           return Iir_Value_Literal_Acc;
388
389   --  Create a copy of SRC on the heap.
390   function Unshare_Heap (Src : Iir_Value_Literal_Acc)
391                         return Iir_Value_Literal_Acc;
392
393   --  Deallocate value accessed by ACC.
394   procedure Free_Heap_Value (Acc : Iir_Value_Literal_Acc);
395
396   --  Increment.
397   --  VAL must be of kind integer or enumeration.
398   --  VAL must be of life temporary.
399   procedure Increment (Val : Iir_Value_Literal_Acc);
400
401   --  Copy BOUNDS of SRC with a specified life.
402   --  Note: val_array is allocated but not filled.
403   function Copy_Array_Bound (Src : Iir_Value_Literal_Acc)
404                             return Iir_Value_Literal_Acc;
405
406   --  Copy the bounds (well the array containing the values) of SRC.
407   --  Val_record is allocated but not filled.
408   function Copy_Record (Src : Iir_Value_Literal_Acc)
409                        return Iir_Value_Literal_Acc;
410
411   --  Return the number of scalars elements in VALS.
412   function Get_Nbr_Of_Scalars (Val : Iir_Value_Literal_Acc) return Natural;
413
414   --  Return the position of an enumerated type value.
415   function Get_Enum_Pos (Val : Iir_Value_Literal_Acc) return Natural;
416
417   -- Well known values.
418   -- Boolean_to_lit can be used to convert a boolean value from Ada to a
419   -- boolean value for vhdl.
420   type Lit_Enum_Type is array (Boolean) of Iir_Value_Literal_Acc;
421   Lit_Enum_0 : constant Iir_Value_Literal_Acc :=
422     new Iir_Value_Literal'(Kind => Iir_Value_B1,
423                            B1 => False);
424   Lit_Enum_1 : constant Iir_Value_Literal_Acc :=
425     new Iir_Value_Literal'(Kind => Iir_Value_B1,
426                            B1 => True);
427   Boolean_To_Lit: constant Lit_Enum_Type :=
428     (False => Lit_Enum_0, True => Lit_Enum_1);
429   Lit_Boolean_False: Iir_Value_Literal_Acc
430     renames Boolean_To_Lit (False);
431   Lit_Boolean_True: Iir_Value_Literal_Acc
432     renames Boolean_To_Lit (True);
433
434   -- Literal NULL.
435   Null_Lit: constant Iir_Value_Literal_Acc :=
436     new Iir_Value_Literal'(Kind => Iir_Value_Access,
437                            Val_Access => null);
438
439   -- Disp a value_literal in raw form.
440   procedure Disp_Value (Value: Iir_Value_Literal_Acc);
441   procedure Disp_Value_Tab (Value: Iir_Value_Literal_Acc;
442                             Indent : Natural);
443
444   -- Disp literal of an enumerated type.
445   procedure Disp_Iir_Value_Enum (Pos : Natural; A_Type : Iir);
446
447   -- Disp a value_literal in readable form.
448   procedure Disp_Iir_Value (Value: Iir_Value_Literal_Acc; A_Type: Iir);
449end Simul.Environments;
450