Add support for conditional generate. In the process, fix bugs
[iverilog.git] / synth.cc
blobe92276d3a7c59049cedde13829e4b127d0454df8
1 /*
2 * Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #ifdef HAVE_CVS_IDENT
20 #ident "$Id: synth.cc,v 1.14 2002/08/12 01:35:00 steve Exp $"
21 #endif
23 # include "config.h"
25 # include "functor.h"
26 # include "netlist.h"
29 * This functor scans the behavioral code, looking for expressions to
30 * synthesize. Although it uses the proc_match_t class, it doesn't
31 * actually match anything, but transforms expressions into structural
32 * netlists. The product of this should be a process where all the
33 * expressions have been reduced to a signal ident, which references
34 * the NetNet of the now synthesized expression.
36 class do_expr : public proc_match_t {
38 public:
39 do_expr(Design*d)
40 : des_(d) { }
42 private:
44 Design*des_;
46 virtual int assign(NetAssign*);
47 virtual int assign_nb(NetAssignNB*);
48 virtual int event_wait(NetEvWait*);
49 virtual int condit(NetCondit*);
53 int do_expr::assign(NetAssign*stmt)
55 if (dynamic_cast<NetESignal*>(stmt->rval()))
56 return 0;
58 NetNet*tmp = stmt->rval()->synthesize(des_);
59 if (tmp == 0)
60 return 0;
62 NetESignal*tmpe = new NetESignal(tmp);
63 stmt->set_rval(tmpe);
65 return 0;
68 int do_expr::assign_nb(NetAssignNB*stmt)
70 if (dynamic_cast<NetESignal*>(stmt->rval()))
71 return 0;
73 NetNet*tmp = stmt->rval()->synthesize(des_);
74 if (tmp == 0)
75 return 0;
77 NetESignal*tmpe = new NetESignal(tmp);
78 stmt->set_rval(tmpe);
80 return 0;
83 int do_expr::condit(NetCondit*stmt)
85 /* synthesize the condition expression, if necessary. */
86 if (! dynamic_cast<NetESignal*>(stmt->expr())) {
87 NetNet*tmp = stmt->expr()->synthesize(des_);
89 if (tmp) {
90 NetESignal*tmpe = new NetESignal(tmp);
91 stmt->set_expr(tmpe);
96 /* Now recurse through the if and else clauses. */
97 if (NetProc*tmp = stmt->if_clause())
98 tmp->match_proc(this);
100 if (NetProc*tmp = stmt->else_clause())
101 tmp->match_proc(this);
103 return 0;
106 int do_expr::event_wait(NetEvWait*stmt)
108 NetProc*tmp = stmt->statement();
109 if (tmp)
110 return tmp->match_proc(this);
111 else
112 return 0;
115 class synth_f : public functor_t {
117 public:
118 void process(class Design*, class NetProcTop*);
120 private:
121 void proc_always_(class Design*);
122 void proc_initial_(class Design*);
124 NetProcTop*top_;
129 * Look at a process, and divide the problem into always and initial
130 * threads.
132 void synth_f::process(class Design*des, class NetProcTop*top)
134 top_ = top;
135 switch (top->type()) {
136 case NetProcTop::KALWAYS:
137 proc_always_(des);
138 break;
139 case NetProcTop::KINITIAL:
140 proc_initial_(des);
141 break;
145 void synth_f::proc_always_(class Design*des)
147 do_expr expr_pat(des);
148 top_->statement()->match_proc(&expr_pat);
151 void synth_f::proc_initial_(class Design*des)
153 do_expr expr_pat(des);
154 top_->statement()->match_proc(&expr_pat);
157 void synth(Design*des)
159 synth_f synth_obj;
160 des->functor(&synth_obj);
164 * $Log: synth.cc,v $
165 * Revision 1.14 2002/08/12 01:35:00 steve
166 * conditional ident string using autoconfig.
168 * Revision 1.13 2002/06/05 03:44:25 steve
169 * Add support for memory words in l-value of
170 * non-blocking assignments, and remove the special
171 * NetAssignMem_ and NetAssignMemNB classes.
173 * Revision 1.12 2001/07/25 03:10:49 steve
174 * Create a config.h.in file to hold all the config
175 * junk, and support gcc 3.0. (Stephan Boettcher)
177 * Revision 1.11 2000/11/22 21:18:42 steve
178 * synthesize the rvalue of <= statements.
180 * Revision 1.10 2000/05/13 20:55:47 steve
181 * Use yacc based synthesizer.
183 * Revision 1.9 2000/04/16 22:57:34 steve
184 * Catch expressions that are part of conditionals.