-
Notifications
You must be signed in to change notification settings - Fork 7
/
chpsim.h
294 lines (233 loc) · 8.35 KB
/
chpsim.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
/*************************************************************************
*
* Copyright (c) 2020 Rajit Manohar
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
**************************************************************************
*/
#ifndef __ACT_CHP_SIM_H__
#define __ACT_CHP_SIM_H__
#include <common/simdes.h>
#include "actsim.h"
#include <common/hash.h>
/*--- CHP simulation data structures ---*/
struct chpsimcond {
Expr *g;
struct chpsimcond *next;
};
#define CHPSIM_COND 0
#define CHPSIM_ASSIGN 1
#define CHPSIM_SEND 2
#define CHPSIM_RECV 3
#define CHPSIM_FUNC 4 /* built-in functions */
#define CHPSIM_FORK 5
#define CHPSIM_LOOP 6
#define CHPSIM_NOP 7 /* dummy needed for turning off simulator opt */
#define CHPSIM_CONDARB 8
struct chpsimderef {
Array *range; // if NULL, then offset is the id
Expr **chp_idx;
int *idx; // for structures, we use this
// array. Length is 3x the # of items
// in the struct. Format: offset,
// width, type
Data *d; // used for structures
int offset; // offset / offseti for struct
int stride; // stride for struct arrays
unsigned int isbool:1; // is this a bool type?
unsigned int isenum:1; // is this an enumeration?
int enum_sz; // used for enumerations
int width;
act_connection *cx;
};
struct chpsimstmt {
int type;
int delay_cost;
int bw_cost; // can be used for channels
int energy_cost;
union {
int fork; /* # of forks */
struct {
chpsimcond c; /* conditional */
unsigned int is_shared:1; // shared variable in guards for CHPSIM_COND
unsigned int is_probe:1; // probe in guards for CHPSIM_COND
int stats;
} cond;
struct {
const char *name; /* function name */
list_t *l; /* arguments */
} fn;
struct {
short isint; /* 0 = bool, otherwise bitwidth of int
*/
unsigned int is_struct:1; // 1 if structure, 0 otherwise
Expr *e;
struct chpsimderef d; /* variable deref */
} assign; /* var := e */
struct {
int chvar;
act_connection *vc;
unsigned int d_type:3; // data type (0, 1, 2)
unsigned int flavor:2; // flavor: 0, 1 (+), 2 (-)
unsigned int is_struct:1; // 1 if structure, 0 otherwise
unsigned int is_structx:2; // 0 if not bidir, 1 if bidir, no
// 2 if bidir and struct
int width; // channel width
Expr *e; // outgoing expression, if any
struct chpsimderef *d; // variable, if any
} sendrecv;
} u;
};
/* --- Each unique process has a CHP sim graph associated with it --- */
/**
* The overall information about the chpsim graph
* - g : the entry point into the graph
* - e : ?
* - max_count : number of slots needed to keep track of internal joins
* - max_stats : number of slots needed to keep track of any run-time
* - labels : map from label to chpsimgraph pointer
* statistics.
*/
class ChpSimGraph;
struct chpsimgraph_info {
chpsimgraph_info() {
g = NULL; labels = NULL; e = NULL; max_count = 0; max_stats = 0;
}
~chpsimgraph_info() { }
ChpSimGraph *g;
Expr *e; /* for probes, if needed */
int max_count;
int max_stats;
struct Hashtable *labels;
};
class ChpSimGraph {
public:
ChpSimGraph (ActSimCore *);
~ChpSimGraph ();
ActSimCore *state;
chpsimstmt *stmt; /* object to simulate */
int wait; /* for concurrency */
int totidx; /* index into pending count */
ChpSimGraph *next;
ChpSimGraph **all; /* successors, if multiple.
used by comma and selections
*/
ChpSimGraph *completed (int pc, int *tot, int *done);
void printStmt (FILE *fp, Process *p);
static chpsimgraph_info *buildChpSimGraph (ActSimCore *, act_chp_lang_t *);
static int max_pending_count;
static int max_stats;
static struct Hashtable *labels;
static void checkFragmentation (ActSimCore *, ChpSim *, act_chp_lang_t *);
static void checkFragmentation (ActSimCore *, ChpSim *, Expr *);
static void checkFragmentation (ActSimCore *, ChpSim *, ActId *, int);
static void recordChannel (ActSimCore *, ChpSim *, ActId *);
static void recordChannel (ActSimCore *, ChpSim *, act_chp_lang_t *);
private:
static ChpSimGraph *_buildChpSimGraph (ActSimCore *,
act_chp_lang_t *, ChpSimGraph **stop);
static int cur_pending_count;
};
/* --- each unique instance has a ChpSim object associated with it --- */
class ChpSim : public ActSimObj {
public:
ChpSim (chpsimgraph_info *, act_chp_lang_t *, ActSimCore *sim, Process *p);
/* initialize simulation, and create initial event */
~ChpSim ();
int Step (Event *ev); /* run a step of the simulation */
void reStart (ChpSimGraph *g, int maxcnt);
int jumpTo (const char *s);
void computeFanout ();
int computeOffset (const struct chpsimderef *d);
virtual void propagate (void *cause);
void zeroInit ();
void dumpState (FILE *fp);
unsigned long getEnergy (void);
double getLeakage (void);
unsigned long getArea (void);
void dumpStats (FILE *fp);
int getBool (int glob_off) { return _sc->getBool (glob_off); }
bool setBool (int glob_off, int val) { return _sc->setBool (glob_off, val); }
void boolProp (int glob_off);
void intProp (int glob_off);
void setFrag (act_channel_state *f) { _frag_ch = f; }
void awakenDeadlockedGC ();
void skipChannelAction (int is_send, int offset);
BigInt exprEval (Expr *e);
void setHseMode() { _hse_mode = 1; }
int isHseMode() { return _hse_mode; }
void sPrintCause (char *buf, int sz) {
if (_npc == 0) {
snprintf (buf, sz, "chan-method");
}
else {
ActSimObj::sPrintCause (buf, sz);
}
}
private:
int _npc; /* # of program counters */
int _pcused; /* # of _pc[] slots currently being
used */
struct Hashtable *_labels; /* label map */
ChpSimGraph **_pc; /* current PC state of simulation */
int *_holes; /* available slots in the _pc array */
int *_tot; /* current pending concurrent count */
list_t *_deadlock_pc;
list_t *_stalled_pc;
act_chp_lang_t *_savedc;
unsigned long _energy_cost;
double _leakage_cost;
unsigned long _area_cost;
WaitForOne *_probe;
int _max_program_counters (act_chp_lang_t *c);
void _compute_used_variables (act_chp_lang_t *c);
void _compute_used_variables_helper (act_chp_lang_t *c);
void _compute_used_variables_helper (Expr *e);
struct iHashtable *_tmpused;
list_t *_statestk;
Scope *_cureval;
act_channel_state *_frag_ch; // fragmented channel
unsigned long *_stats;
int _maxstats;
int _hse_mode; // is this a HSE?
BigInt funcEval (Function *, int, void **);
BigInt varEval (int id, int type);
expr_multires varChanEvalStruct (int id, int type);
expr_multires exprStruct (Expr *e);
expr_multires funcStruct (Function *, int, void **);
expr_multires varStruct (struct chpsimderef *);
int _structure_assign (struct chpsimderef *, expr_multires *, void *cause,
bool skip_check = false);
void _run_chp (Function *fn, act_chp_lang_t *);
/* type == 3 : probe */
int varSend (int pc, int wakeup, int id, int off, int flavor,
expr_multires &v, int bidir, expr_multires *xchg, int *frag,
int *skipwrite);
int varRecv (int pc, int wakeup, int id, int off, int flavor,
expr_multires *v, int bidir, expr_multires &xchg, int *frag,
int *skipwrite);
int chkWatchBreakPt (int type, int loff, int goff, const BigInt &v, void *cause, int flag = 0);
int _updatepc (int pc);
int _add_waitcond (chpsimcond *gc, int pc, int undo = 0);
int _collect_sharedvars (Expr *e, int pc, int undo);
void _remove_me (int pc);
int _nextEvent (int pc, int bw_delay);
void _initEvent ();
void _zeroAllIntsChans (ChpSimGraph *g);
void _zeroStructure (struct chpsimderef *d);
};
#endif /* __ACT_CHP_SIM_H__ */