1--  Synthesis context.
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;
22
23with Netlists; use Netlists;
24with Netlists.Builders; use Netlists.Builders;
25
26with Vhdl.Annotations; use Vhdl.Annotations;
27with Vhdl.Nodes; use Vhdl.Nodes;
28
29with Synth.Environment; use Synth.Environment;
30with Synth.Objtypes; use Synth.Objtypes;
31with Synth.Values; use Synth.Values;
32
33package Synth.Context is
34   --  Values are stored into Synth_Instance, which is parallel to simulation
35   --  Block_Instance_Type.
36
37   type Synth_Instance_Type (<>) is limited private;
38   type Synth_Instance_Acc is access Synth_Instance_Type;
39
40   function Get_Instance_By_Scope
41     (Syn_Inst: Synth_Instance_Acc; Scope: Sim_Info_Acc)
42     return Synth_Instance_Acc;
43
44   --  Create the first instance.
45   function Make_Base_Instance return Synth_Instance_Acc;
46
47   --  Free the first instance.
48   procedure Free_Base_Instance;
49
50   --  Create and free the corresponding synth instance.
51   function Make_Instance (Parent : Synth_Instance_Acc;
52                           Blk : Node;
53                           Name : Sname := No_Sname)
54                          return Synth_Instance_Acc;
55
56   --  Only useful for subprograms: set the base (which can be different from
57   --  the parent).  Ideally it should be part of Make_Instance, but in most
58   --  cases they are the same (except sometimes for subprograms).
59   procedure Set_Instance_Base (Inst : Synth_Instance_Acc;
60                                Base : Synth_Instance_Acc);
61   procedure Free_Instance (Synth_Inst : in out Synth_Instance_Acc);
62
63   function Is_Error (Inst : Synth_Instance_Acc) return Boolean;
64   pragma Inline (Is_Error);
65
66   procedure Set_Error (Inst : Synth_Instance_Acc);
67
68   function Get_Sname (Inst : Synth_Instance_Acc) return Sname;
69   pragma Inline (Get_Sname);
70
71   function Get_Build (Inst : Synth_Instance_Acc) return Context_Acc;
72   pragma Inline (Get_Build);
73
74   function Get_Top_Module (Inst : Synth_Instance_Acc) return Module;
75
76   function Get_Instance_Module (Inst : Synth_Instance_Acc) return Module;
77   pragma Inline (Get_Instance_Module);
78
79   --  Start the definition of module M (using INST).
80   procedure Set_Instance_Module (Inst : Synth_Instance_Acc; M : Module);
81
82   function Get_Instance_Const (Inst : Synth_Instance_Acc) return Boolean;
83   procedure Set_Instance_Const (Inst : Synth_Instance_Acc; Val : Boolean);
84
85   --  Get the corresponding source for the scope of the instance.
86   function Get_Source_Scope (Inst : Synth_Instance_Acc) return Node;
87
88   procedure Create_Object
89     (Syn_Inst : Synth_Instance_Acc; Decl : Node; Vt : Valtyp);
90
91   procedure Create_Package_Object (Syn_Inst : Synth_Instance_Acc;
92                                    Decl : Node;
93                                    Inst : Synth_Instance_Acc;
94                                    Is_Global : Boolean);
95
96   procedure Create_Package_Interface (Syn_Inst : Synth_Instance_Acc;
97                                       Decl     : Node;
98                                       Inst     : Synth_Instance_Acc);
99
100   procedure Create_Subtype_Object
101     (Syn_Inst : Synth_Instance_Acc; Decl : Node; Typ : Type_Acc);
102
103   --  Force the value of DECL, without checking for elaboration order.
104   --  It is for deferred constants.
105   procedure Create_Object_Force
106     (Syn_Inst : Synth_Instance_Acc; Decl : Node; Vt : Valtyp);
107
108   procedure Destroy_Object
109     (Syn_Inst : Synth_Instance_Acc; Decl : Node);
110
111   --  Build the value for object OBJ.
112   --  KIND must be Wire_Variable or Wire_Signal.
113   procedure Create_Wire_Object (Syn_Inst : Synth_Instance_Acc;
114                                 Kind : Wire_Kind;
115                                 Obj : Node);
116
117   --  Get the value of OBJ.
118   function Get_Value (Syn_Inst : Synth_Instance_Acc; Obj : Node)
119                      return Valtyp;
120
121   --  Get a net from a scalar/vector value.  This will automatically create
122   --  a net for literals.
123   function Get_Net (Ctxt : Context_Acc; Val : Valtyp) return Net;
124   function Get_Partial_Memtyp_Net
125     (Ctxt : Context_Acc; Val : Memtyp; Off : Uns32; Wd : Width) return Net;
126   function Get_Memtyp_Net (Ctxt : Context_Acc; Val : Memtyp) return Net;
127
128   function Get_Package_Object
129     (Syn_Inst : Synth_Instance_Acc; Pkg : Node) return Synth_Instance_Acc;
130
131   --  Return the type for DECL (a subtype indication).
132   function Get_Subtype_Object
133     (Syn_Inst : Synth_Instance_Acc; Decl : Node) return Type_Acc;
134
135   --  Return the scope of the parent of BLK.  Deals with architecture bodies.
136   function Get_Parent_Scope (Blk : Node) return Sim_Info_Acc;
137
138   procedure Set_Uninstantiated_Scope
139     (Syn_Inst : Synth_Instance_Acc; Bod : Node);
140private
141   type Obj_Kind is
142     (
143      Obj_None,
144      Obj_Object,
145      Obj_Subtype,
146      Obj_Instance
147     );
148
149   type Obj_Type (Kind : Obj_Kind := Obj_None) is record
150      case Kind is
151         when Obj_None =>
152            null;
153         when Obj_Object =>
154            Obj : Valtyp;
155         when Obj_Subtype =>
156            T_Typ : Type_Acc;
157         when Obj_Instance =>
158            I_Inst : Synth_Instance_Acc;
159      end case;
160   end record;
161
162   type Objects_Array is array (Object_Slot_Type range <>) of Obj_Type;
163
164   type Base_Instance_Type is limited record
165      Builder : Context_Acc;
166      Top_Module : Module;
167
168      Cur_Module : Module;
169   end record;
170
171   type Base_Instance_Acc is access Base_Instance_Type;
172
173   type Synth_Instance_Type (Max_Objs : Object_Slot_Type) is limited record
174      Is_Const : Boolean;
175
176      --  True if a fatal error has been detected that aborts the synthesis
177      --  of this instance.
178      Is_Error : Boolean;
179
180      Base : Base_Instance_Acc;
181
182      --  Name prefix for declarations.
183      Name : Sname;
184
185      --  The corresponding info for this instance.
186      --  This is used for lookup.
187      Block_Scope : Sim_Info_Acc;
188
189      --  The corresponding info the the uninstantiated specification of
190      --  an instantiated package.  When an object is looked for from the
191      --  uninstantiated body, the scope of the uninstantiated specification
192      --  is used.  And it is different from Block_Scope.
193      --  This is used for lookup of uninstantiated specification.
194      Uninst_Scope : Sim_Info_Acc;
195
196      --  Instance of the parent scope.
197      Up_Block : Synth_Instance_Acc;
198
199      --  Source construct corresponding to this instance/
200      Source_Scope : Node;
201
202      Elab_Objects : Object_Slot_Type;
203
204      --  Instance for synthesis.
205      Objects : Objects_Array (1 .. Max_Objs);
206   end record;
207end Synth.Context;
208