Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

171 lines (137 sloc) 4.125 kB
/*
* Copyright (c) 1999-2012 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form 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.
*/
# include "config.h"
# include "functor.h"
# include "netlist.h"
/*
* This functor scans the behavioral code, looking for expressions to
* synthesize. Although it uses the proc_match_t class, it doesn't
* actually match anything, but transforms expressions into structural
* netlists. The product of this should be a process where all the
* expressions have been reduced to a signal ident, which references
* the NetNet of the now synthesized expression.
*/
class do_expr : public proc_match_t {
public:
do_expr(Design*d, NetScope*s)
: des_(d), scope_(s) { }
private:
Design*des_;
NetScope*scope_;
virtual int assign(NetAssign*);
virtual int assign_nb(NetAssignNB*);
virtual int event_wait(NetEvWait*);
virtual int condit(NetCondit*);
};
int do_expr::assign(NetAssign*stmt)
{
if (dynamic_cast<NetESignal*>(stmt->rval()))
return 0;
NetNet*tmp = stmt->rval()->synthesize(des_, scope_, stmt->rval());
if (tmp == 0)
return 0;
NetESignal*tmpe = new NetESignal(tmp);
stmt->set_rval(tmpe);
return 0;
}
int do_expr::assign_nb(NetAssignNB*stmt)
{
if (dynamic_cast<NetESignal*>(stmt->rval()))
return 0;
NetNet*tmp = stmt->rval()->synthesize(des_, scope_, stmt->rval());
if (tmp == 0)
return 0;
NetESignal*tmpe = new NetESignal(tmp);
stmt->set_rval(tmpe);
return 0;
}
int do_expr::condit(NetCondit*stmt)
{
/* synthesize the condition expression, if necessary. */
if (! dynamic_cast<NetESignal*>(stmt->expr())) {
NetNet*tmp = stmt->expr()->synthesize(des_, scope_, stmt->expr());
if (tmp) {
NetESignal*tmpe = new NetESignal(tmp);
stmt->set_expr(tmpe);
}
}
/* Now recurse through the if and else clauses. */
if (NetProc*tmp = stmt->if_clause())
tmp->match_proc(this);
if (NetProc*tmp = stmt->else_clause())
tmp->match_proc(this);
return 0;
}
int do_expr::event_wait(NetEvWait*stmt)
{
NetProc*tmp = stmt->statement();
if (tmp)
return tmp->match_proc(this);
else
return 0;
}
class synth_f : public functor_t {
public:
synth_f() { top_ = NULL; }
void process(Design*, NetProcTop*);
private:
void proc_always_(Design*);
void proc_initial_(Design*);
void proc_final_(Design*);
NetProcTop*top_;
};
/*
* Look at a process, and divide the problem into always and initial
* threads.
*/
void synth_f::process(Design*des, NetProcTop*top)
{
top_ = top;
switch (top->type()) {
case IVL_PR_ALWAYS:
proc_always_(des);
break;
case IVL_PR_INITIAL:
proc_initial_(des);
break;
case IVL_PR_FINAL:
proc_final_(des);
break;
}
}
void synth_f::proc_always_(Design*des)
{
do_expr expr_pat(des, top_->scope());
top_->statement()->match_proc(&expr_pat);
}
void synth_f::proc_initial_(Design*des)
{
do_expr expr_pat(des, top_->scope());
top_->statement()->match_proc(&expr_pat);
}
void synth_f::proc_final_(Design*des)
{
do_expr expr_pat(des, top_->scope());
top_->statement()->match_proc(&expr_pat);
}
void synth(Design*des)
{
synth_f synth_obj;
des->functor(&synth_obj);
}
Jump to Line
Something went wrong with that request. Please try again.