4 * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
6 * This source code is free software; you can redistribute it
7 * and/or modify it in source code form under the terms of the GNU
8 * General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 #ident "$Id: Statement.h,v 1.44 2007/05/24 04:07:11 steve Exp $"
27 # include "StringHeap.h"
31 # include "LineInfo.h"
34 class PEventStatement
;
43 * The PProcess is the root of a behavioral process. Each process gets
44 * one of these, which contains its type (initial or always) and a
45 * pointer to the single statement that is the process. A module may
46 * have several concurrent processes.
48 class PProcess
: public LineInfo
{
51 enum Type
{ PR_INITIAL
, PR_ALWAYS
};
53 PProcess(Type t
, Statement
*st
)
54 : type_(t
), statement_(st
) { }
58 bool elaborate(Design
*des
, NetScope
*scope
) const;
60 Type
type() const { return type_
; }
61 Statement
*statement() { return statement_
; }
63 map
<perm_string
,PExpr
*> attributes
;
65 virtual void dump(ostream
&out
, unsigned ind
) const;
73 * The PProcess is a process, the Statement is the actual action. In
74 * fact, the Statement class is abstract and represents all the
75 * possible kinds of statements that exist in Verilog.
77 class Statement
: public LineInfo
{
81 virtual ~Statement() =0;
83 virtual void dump(ostream
&out
, unsigned ind
) const;
84 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
85 virtual void elaborate_scope(Design
*des
, NetScope
*scope
) const;
89 * Assignment statements of the various forms are handled by this
90 * type. The rvalue is an expression. The lvalue needs to be figured
91 * out by the parser as much as possible.
93 class PAssign_
: public Statement
{
95 explicit PAssign_(PExpr
*lval
, PExpr
*ex
);
96 explicit PAssign_(PExpr
*lval
, PExpr
*de
, PExpr
*ex
);
97 explicit PAssign_(PExpr
*lval
, PEventStatement
*de
, PExpr
*ex
);
98 virtual ~PAssign_() =0;
100 const PExpr
* lval() const { return lval_
; }
101 const PExpr
* rval() const { return rval_
; }
104 NetAssign_
* elaborate_lval(Design
*, NetScope
*scope
) const;
107 PEventStatement
*event_
;
114 class PAssign
: public PAssign_
{
117 explicit PAssign(PExpr
*lval
, PExpr
*ex
);
118 explicit PAssign(PExpr
*lval
, PExpr
*de
, PExpr
*ex
);
119 explicit PAssign(PExpr
*lval
, PEventStatement
*de
, PExpr
*ex
);
122 virtual void dump(ostream
&out
, unsigned ind
) const;
123 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
128 class PAssignNB
: public PAssign_
{
131 explicit PAssignNB(PExpr
*lval
, PExpr
*ex
);
132 explicit PAssignNB(PExpr
*lval
, PExpr
*de
, PExpr
*ex
);
135 virtual void dump(ostream
&out
, unsigned ind
) const;
136 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
139 NetProc
*assign_to_memory_(class NetMemory
*, PExpr
*,
140 Design
*des
, NetScope
*scope
) const;
144 * A block statement is an ordered list of statements that make up the
145 * block. The block can be sequential or parallel, which only affects
146 * how the block is interpreted. The parser collects the list of
147 * statements before constructing this object, so it knows a priori
150 class PBlock
: public Statement
{
153 enum BL_TYPE
{ BL_SEQ
, BL_PAR
};
155 explicit PBlock(perm_string n
, BL_TYPE t
, const svector
<Statement
*>&st
);
156 explicit PBlock(BL_TYPE t
, const svector
<Statement
*>&st
);
157 explicit PBlock(BL_TYPE t
);
160 BL_TYPE
bl_type() const { return bl_type_
; }
163 virtual void dump(ostream
&out
, unsigned ind
) const;
164 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
165 virtual void elaborate_scope(Design
*des
, NetScope
*scope
) const;
169 const BL_TYPE bl_type_
;
170 svector
<Statement
*>list_
;
173 class PCallTask
: public Statement
{
176 explicit PCallTask(const pform_name_t
&n
, const svector
<PExpr
*>&parms
);
177 explicit PCallTask(perm_string n
, const svector
<PExpr
*>&parms
);
180 const pform_name_t
& path() const;
182 unsigned nparms() const { return parms_
.count(); }
184 PExpr
*&parm(unsigned idx
)
185 { assert(idx
< parms_
.count());
189 PExpr
* parm(unsigned idx
) const
190 { assert(idx
< parms_
.count());
194 virtual void dump(ostream
&out
, unsigned ind
) const;
195 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
198 NetProc
* elaborate_sys(Design
*des
, NetScope
*scope
) const;
199 NetProc
* elaborate_usr(Design
*des
, NetScope
*scope
) const;
202 svector
<PExpr
*> parms_
;
205 class PCase
: public Statement
{
213 PCase(NetCase::TYPE
, PExpr
*ex
, svector
<Item
*>*);
216 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
217 virtual void elaborate_scope(Design
*des
, NetScope
*scope
) const;
218 virtual void dump(ostream
&out
, unsigned ind
) const;
224 svector
<Item
*>*items_
;
226 private: // not implemented
228 PCase
& operator= (const PCase
&);
231 class PCAssign
: public Statement
{
234 explicit PCAssign(PExpr
*l
, PExpr
*r
);
237 virtual NetCAssign
* elaborate(Design
*des
, NetScope
*scope
) const;
238 virtual void dump(ostream
&out
, unsigned ind
) const;
245 class PCondit
: public Statement
{
248 PCondit(PExpr
*ex
, Statement
*i
, Statement
*e
);
251 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
252 virtual void elaborate_scope(Design
*des
, NetScope
*scope
) const;
253 virtual void dump(ostream
&out
, unsigned ind
) const;
260 private: // not implemented
261 PCondit(const PCondit
&);
262 PCondit
& operator= (const PCondit
&);
265 class PDeassign
: public Statement
{
268 explicit PDeassign(PExpr
*l
);
271 virtual NetDeassign
* elaborate(Design
*des
, NetScope
*scope
) const;
272 virtual void dump(ostream
&out
, unsigned ind
) const;
278 class PDelayStatement
: public Statement
{
281 PDelayStatement(PExpr
*d
, Statement
*st
);
284 virtual void dump(ostream
&out
, unsigned ind
) const;
285 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
286 virtual void elaborate_scope(Design
*des
, NetScope
*scope
) const;
290 Statement
*statement_
;
295 * This represents the parsing of a disable <scope> statement.
297 class PDisable
: public Statement
{
300 explicit PDisable(const pform_name_t
&sc
);
303 virtual void dump(ostream
&out
, unsigned ind
) const;
304 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
311 * The event statement represents the event delay in behavioral
312 * code. It comes from such things as:
315 * @(expr) <statement>;
318 class PEventStatement
: public Statement
{
322 explicit PEventStatement(const svector
<PEEvent
*>&ee
);
323 explicit PEventStatement(PEEvent
*ee
);
324 // Make an @* statement.
325 explicit PEventStatement(void);
329 void set_statement(Statement
*st
);
331 virtual void dump(ostream
&out
, unsigned ind
) const;
332 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
333 virtual void elaborate_scope(Design
*des
, NetScope
*scope
) const;
335 // This method is used to elaborate, but attach a previously
336 // elaborated statement to the event.
337 NetProc
* elaborate_st(Design
*des
, NetScope
*scope
, NetProc
*st
) const;
339 NetProc
* elaborate_wait(Design
*des
, NetScope
*scope
, NetProc
*st
) const;
342 svector
<PEEvent
*>expr_
;
343 Statement
*statement_
;
346 class PForce
: public Statement
{
349 explicit PForce(PExpr
*l
, PExpr
*r
);
352 virtual NetForce
* elaborate(Design
*des
, NetScope
*scope
) const;
353 virtual void dump(ostream
&out
, unsigned ind
) const;
360 class PForever
: public Statement
{
362 explicit PForever(Statement
*s
);
365 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
366 virtual void elaborate_scope(Design
*des
, NetScope
*scope
) const;
367 virtual void dump(ostream
&out
, unsigned ind
) const;
370 Statement
*statement_
;
373 class PForStatement
: public Statement
{
376 PForStatement(PExpr
*n1
, PExpr
*e1
, PExpr
*cond
,
377 PExpr
*n2
, PExpr
*e2
, Statement
*st
);
380 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
381 virtual void elaborate_scope(Design
*des
, NetScope
*scope
) const;
382 virtual void dump(ostream
&out
, unsigned ind
) const;
393 Statement
*statement_
;
396 class PNoop
: public Statement
{
403 class PRepeat
: public Statement
{
405 explicit PRepeat(PExpr
*expr
, Statement
*s
);
408 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
409 virtual void elaborate_scope(Design
*des
, NetScope
*scope
) const;
410 virtual void dump(ostream
&out
, unsigned ind
) const;
414 Statement
*statement_
;
417 class PRelease
: public Statement
{
420 explicit PRelease(PExpr
*l
);
423 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
424 virtual void dump(ostream
&out
, unsigned ind
) const;
431 * The PTrigger statement sends a trigger to a named event. Take the
434 class PTrigger
: public Statement
{
437 explicit PTrigger(const pform_name_t
&ev
);
440 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
441 virtual void dump(ostream
&out
, unsigned ind
) const;
447 class PWhile
: public Statement
{
450 PWhile(PExpr
*e1
, Statement
*st
);
453 virtual NetProc
* elaborate(Design
*des
, NetScope
*scope
) const;
454 virtual void elaborate_scope(Design
*des
, NetScope
*scope
) const;
455 virtual void dump(ostream
&out
, unsigned ind
) const;
459 Statement
*statement_
;
463 * $Log: Statement.h,v $
464 * Revision 1.44 2007/05/24 04:07:11 steve
465 * Rework the heirarchical identifier parse syntax and pform
466 * to handle more general combinations of heirarch and bit selects.
468 * Revision 1.43 2007/03/05 05:59:10 steve
469 * Handle processes within generate loops.
471 * Revision 1.42 2005/12/05 21:21:18 steve
472 * Fixes for stubborn compilers.
474 * Revision 1.41 2004/12/11 02:31:25 steve
475 * Rework of internals to carry vectors through nexus instead
476 * of single bits. Make the ivl, tgt-vvp and vvp initial changes
479 * Revision 1.40 2004/02/20 18:53:33 steve
480 * Addtrbute keys are perm_strings.
482 * Revision 1.39 2004/02/18 17:11:54 steve
483 * Use perm_strings for named langiage items.
485 * Revision 1.38 2003/05/19 02:50:58 steve
486 * Implement the wait statement behaviorally instead of as nets.
488 * Revision 1.37 2003/01/30 16:23:07 steve
491 * Revision 1.36 2002/08/12 01:34:58 steve
492 * conditional ident string using autoconfig.
494 * Revision 1.35 2002/06/04 05:38:44 steve
495 * Add support for memory words in l-value of
496 * blocking assignments, and remove the special
497 * NetAssignMem class.
499 * Revision 1.34 2002/05/26 01:39:02 steve
500 * Carry Verilog 2001 attributes with processes,
501 * all the way through to the ivl_target API.
503 * Divide signal reference counts between rval
504 * and lval references.
506 * Revision 1.33 2002/04/21 22:31:02 steve
507 * Redo handling of assignment internal delays.
508 * Leave it possible for them to be calculated
511 * Revision 1.32 2002/04/21 04:59:07 steve
512 * Add support for conbinational events by finding
513 * the inputs to expressions and some statements.
514 * Get case and assignment statements working.
516 * Revision 1.31 2001/12/03 04:47:14 steve
517 * Parser and pform use hierarchical names as hname_t
518 * objects instead of encoded strings.
520 * Revision 1.30 2001/11/22 06:20:59 steve
521 * Use NetScope instead of string for scope path.
523 * Revision 1.29 2000/09/09 15:21:26 steve
524 * move lval elaboration to PExpr virtual methods.
526 * Revision 1.28 2000/09/03 17:58:35 steve
527 * Change elaborate_lval to return NetAssign_ objects.
529 * Revision 1.27 2000/07/26 05:08:07 steve
530 * Parse disable statements to pform.
532 * Revision 1.26 2000/05/11 23:37:26 steve
533 * Add support for procedural continuous assignment.
535 * Revision 1.25 2000/04/22 04:20:19 steve
536 * Add support for force assignment.
538 * Revision 1.24 2000/04/12 04:23:57 steve
539 * Named events really should be expressed with PEIdent
540 * objects in the pform,
542 * Handle named events within the mix of net events
543 * and edges. As a unified lot they get caught together.
544 * wait statements are broken into more complex statements
545 * that include a conditional.
547 * Do not generate NetPEvent or NetNEvent objects in
548 * elaboration. NetEvent, NetEvWait and NetEvProbe
549 * take over those functions in the netlist.