1 /****************************************************************************
2     Copyright (C) 1987-2015 by Jeffery P. Hansen
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 along
15     with this program; if not, write to the Free Software Foundation, Inc.,
16     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 ****************************************************************************/
18 #ifndef __module_h
19 #define __module_h
20 
21 #define SDF_LOCAL_ONLY		0x1	/* Lookup variable only in the local scope */
22 
23 /*****************************************************************************
24  *
25  * ScopeDecl - Scope in which variables can be declared
26  *
27  *****************************************************************************/
28 struct ScopeDecl_str {
29   ScopeDecl		*sd_parent;	/* Parent scope */
30   SHash/*NetDecl*/	sd_nets;	/* Net declarations */
31 };
32 
33 
34 /*****************************************************************************
35  *
36  * Scope - Scope in which instantiated variables are declared
37  *
38  *****************************************************************************/
39 struct Scope_str {
40   char			*s_path;	/* Path name of scope */
41   ModuleInst		*s_instance;	/* Module instance this scope is in */
42   Scope			*s_parent;	/* Parent scope */
43   Scope			*s_peer;	/* "Peer" scope */
44   SHash/*Net*/		s_nets;		/* Local scope table of nets/parameters */
45   SHash/*UserTask*/	s_tasks;	/* User tasks */
46 };
47 
48 /*****************************************************************************
49  *
50  * FaninNode - Used to build a fanin tree for a path-delay module.  Fanin nodes
51  * are only used if a module contains a "specify" block with a path delay.
52  *
53  *****************************************************************************/
54 typedef struct FaninNode_str {
55   ModuleItem	*fn_item;	/* Module item represented */
56   char		**fn_out;	/* Names of fanouts */
57   char		**fn_in;	/* Names of fanins */
58   Net		**fn_outNets;	/* Nets associated with outputs */
59   Net		**fn_inNets;	/* Nets associated with inputs */
60   int		fn_flag;	/* Flag used in module generation */
61 } FaninNode;
62 
63 
64 /*****************************************************************************
65  *
66  * ModuleDecl - Declaration of a module
67  *
68  *****************************************************************************/
69 struct ModuleDecl_str {
70   char			*m_name;	/* Module name */
71   Place			m_place;	/* Place of declarations */
72   List/*char**/		m_ports;	/* Port names */
73   List/*char**/		m_parmPorts;	/* Parameter ports */
74   ScopeDecl		m_scope;	/* Variable declaration scope */
75   SHash/*UserTaskDecl*/	m_tasks;	/* User tasks */
76   List			m_items;	/* Module "items" */
77   unsigned		m_errorsDone;	/* We are done doing error reporting */
78   Specify		*m_specify;	/* Specify block of module */
79   SHash/*FaninNode*/	*m_faninnodes;	/* Fanin nodes (only used for path-delay modules) */
80   Timescale		m_timescale;	/* Timescale of this module */
81 };
82 
83 /*****************************************************************************
84  *
85  * ModuleInst - Context information for current module being expanded
86  *
87  *****************************************************************************/
88 struct ModuleInst_str {
89   char			*mc_path;	/* Path for this context */
90   ModuleInst		*mc_peer;	/* Peer module (used for simulation scripts) */
91   ModuleDecl		*mc_mod;	/* Module definition */
92   Circuit		*mc_circuit;	/* Circuit we are building */
93   ModuleInst		*mc_parent;	/* Parent instance */
94   List/*VGThread*/	mc_threads;	/* Threads in the module instance */
95   Scope			mc_scope;	/* Scope in which varaibles/tasks are defined */
96   CodeBlock		*mc_codeBlock;	/* Code block for this module instance */
97 };
98 
99 /*****************************************************************************
100  *
101  * Dynamic modules are used to keep track of mitems that are loaded as part
102  * of a script or breakpoint so that it can be dynamically unloaded on request.
103  *
104  *****************************************************************************/
105 struct DynamicModule_str {
106   char			*dm_name;		/* tag name of dynamic module */
107   List			dm_mitems;		/* MItems in the dynamc module */
108 
109   ModuleInst		*dm_moduleInst;		/* Module instance */
110   List			dm_threads;		/* Threads corresponding to module */
111   int			dm_aliveThreads;	/* Number of threads currently alive */
112 };
113 
114 /*****************************************************************************
115  * ScopeDecl methods
116  *****************************************************************************/
117 void ScopeDecl_init(ScopeDecl *s,ScopeDecl *parent);
118 void ScopeDecl_uninit(ScopeDecl *s);
119 NetDecl *ScopeDecl_findNet(ScopeDecl *s,const char *name,unsigned flags);
120 void ScopeDecl_defNet(ScopeDecl *s,NetDecl*n);
121 
122 
123 /*****************************************************************************
124  * Scope methods
125  *****************************************************************************/
126 Scope *new_Scope(const char *path,Scope *parent,ModuleInst *mi);
127 void delete_Scope(Scope *s);
128 void Scope_init(Scope *s,const char *path,Scope *parent,ModuleInst *mi);
129 void Scope_uninit(Scope *s);
130 void Scope_setPeer(Scope *s,Scope *peer);
131 Net *Scope_findNet(Scope *s,const char *name,unsigned flags);
132 void Scope_defNet(Scope *s,const char *name,Net *n);
133 void Scope_replaceLocalNet(Scope *s,const char *name,Net *n);
134 UserTask *Scope_findTask(Scope *mi,const char *name);
135 int Scope_defineTask(Scope *mi,const char *name,UserTask *ut);
136 Value *Scope_findParm(Scope *scope,const char *name);
137 #define Scope_getModuleInst(s) (s)->s_instance
138 #define Scope_getPath(s) (s)->s_path
139 #define Scope_getParent(s) (s)->s_parent
140 
141 /*****************************************************************************
142  * ModuleDecl methods
143  *****************************************************************************/
144 ModuleDecl *new_ModuleDecl(const char *);
145 void delete_ModuleDecl(ModuleDecl*);
146 void ModuleDecl_addPort(ModuleDecl*,const char*);
147 void ModuleDecl_defineParm(ModuleDecl *m,const char *name,Expr *e,int isPort);
148 int ModuleDecl_isParm(ModuleDecl *m,const char *name);
149 void ModuleDecl_print(ModuleDecl*,FILE*);
150 NetDecl *ModuleDecl_findNet(ModuleDecl *m,const char *name);
151 void ModuleDecl_defNet(ModuleDecl *m,NetDecl*n);
152 #define ModuleDecl_getName(m) (m)->m_name
153 void ModuleDecl_printData(ModuleDecl*);
154 #define ModuleDecl_getSpecify(m) (m)->m_specify
155 #define ModuleDecl_getPlace(m) (&(m)->m_place)
156 void ModuleDecl_startSpecify(ModuleDecl*m);
157 int ModuleDecl_numPorts(ModuleDecl *m,nettype_t ptype);
158 UserTaskDecl *ModuleDecl_findTask(ModuleDecl *m,const char *name);
159 int ModuleDecl_defineTask(ModuleDecl *m,const char *name,UserTaskDecl *utd);
160 #define ModuleDecl_getNets(m) (&(m)->m_scope.sd_nets)
161 #define ModuleDecl_getScope(m) (&(m)->m_scope)
162 int ModuleDecl_makeFaninTree(ModuleDecl *m);
163 void ModuleDecl_clearFaninFlags(ModuleDecl *m);
164 #define ModuleDecl_findFanin(m,name) ((FaninNode*)SHash_find((m)->m_faninnodes, name))
165 #define ModuleDecl_isPathDelayMod(m) ((m)->m_specify && Specify_numStats((m)->m_specify) > 0)
166 void ModuleDecl_makeSpecify(ModuleDecl *m);
167 #define ModuleDecl_getTimescale(m) (&(m)->m_timescale)
168 
169 /*****************************************************************************
170  * ModuleInst member functions
171  *****************************************************************************/
172 ModuleInst *new_ModuleInst(ModuleDecl *md,Circuit *c,ModuleInst *parent,const char *path);
173 void delete_ModuleInst(ModuleInst*);
174 void ModuleInst_init(ModuleInst *mc,ModuleDecl *md,Circuit *c,ModuleInst *parent,const char *path);
175 void ModuleInst_uninit(ModuleInst *mc);
176 Value *ModuleInst_findParm(ModuleInst *mc,const char *name);
177 Net *ModuleInst_findNet(ModuleInst *mc,const char *name);
178 void ModuleInst_defParm(ModuleInst *mc,const char *name,Value *value);
179 void ModuleInst_defNet(ModuleInst *mc,const char *name,Net *n);
180 const char *ModuleInst_findLocalNetName(ModuleInst *mc,Net *n);
181 #define ModuleInst_getPath(mc) (mc)->mc_path
182 #define ModuleInst_getCircuit(mc) (mc)->mc_circuit
183 #define ModuleInst_setCodeBlock(mc,cb) ((mc)->mc_codeBlock = (cb))
184 #define ModuleInst_getModDecl(mc) (mc)->mc_mod
185 UserTask *ModuleInst_findTask(ModuleInst *m,const char *name);
186 int ModuleInst_defineTask(ModuleInst *m,const char *name,UserTask *ut);
187 #define ModuleInst_getScope(mc) (&(mc)->mc_scope)
188 #define ModuleInst_isPathDelayMod(mi) ModuleDecl_isPathDelayMod((mi)->mc_mod)
189 #define ModuleInst_addThread(mi, t) List_addToTail(&(mi)->mc_threads,(t))
190 #define ModuleInst_getTimescale(mi) ModuleDecl_getTimescale((mi)->mc_mod)
191 
192 FaninNode *new_FaninNode(ModuleItem *item);
193 
194 #endif
195