Infrastructure for elaborating analog statements.

Put together the infrastructure for elaborating analog statements,
including create the NetAnalogTop objects that hold analog statements
and are in turn held by the design.

While doing this, clean up the various unique initial/always enumerations
to use the ivl_process_type_t type.
This commit is contained in:
Stephen Williams 2008-10-21 22:15:49 -07:00
parent 365960df9d
commit 5aa810dde7
21 changed files with 219 additions and 115 deletions

View File

@ -20,11 +20,15 @@
*/
# include <map>
# include "ivl_target.h"
# include "StringHeap.h"
# include "LineInfo.h"
# include "PExpr.h"
class PExpr;
class NetAnalog;
class NetScope;
class Design;
class AStatement : public LineInfo {
@ -33,6 +37,11 @@ class AStatement : public LineInfo {
virtual ~AStatement() =0;
virtual void dump(ostream&out, unsigned ind) const;
virtual NetAnalog* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
map<perm_string,PExpr*> attributes;
private: // not implemented
AStatement(const AStatement&);
@ -65,20 +74,23 @@ class AContrib : public AStatement {
class AProcess : public LineInfo {
public:
enum Type { PR_INITIAL, PR_ALWAYS };
AProcess(Type t, AStatement*st)
AProcess(ivl_process_type_t t, AStatement*st)
: type_(t), statement_(st) { }
~AProcess();
bool elaborate(Design*des, NetScope*scope) const;
ivl_process_type_t type() const { return type_; }
AStatement*statement() { return statement_; }
map<perm_string,PExpr*> attributes;
// Dump the analog process
void dump(ostream&out, unsigned ind) const;
private:
Type type_;
ivl_process_type_t type_;
AStatement*statement_;
private: // not implemented

View File

@ -116,9 +116,10 @@ distclean: clean
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o elab_expr.o \
O = main.o async.o design_dump.o discipline.o dup_expr.o \
elaborate.o elab_expr.o elaborate_analog.o \
elab_lval.o elab_net.o elab_pexpr.o elab_scope.o \
elab_sig.o emit.o eval.o eval_attrib.o \
elab_sig.o elab_sig_analog.o emit.o eval.o eval_attrib.o \
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
load_module.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_expr.o net_func.o \

View File

@ -20,6 +20,7 @@
*/
# include <string>
# include "ivl_target.h"
# include "svector.h"
# include "StringHeap.h"
# include "PDelays.h"
@ -46,16 +47,14 @@ class NetScope;
class PProcess : public LineInfo {
public:
enum Type { PR_INITIAL, PR_ALWAYS };
PProcess(Type t, Statement*st)
PProcess(ivl_process_type_t t, Statement*st)
: type_(t), statement_(st) { }
virtual ~PProcess();
bool elaborate(Design*des, NetScope*scope) const;
Type type() const { return type_; }
ivl_process_type_t type() const { return type_; }
Statement*statement() { return statement_; }
map<perm_string,PExpr*> attributes;
@ -63,7 +62,7 @@ class PProcess : public LineInfo {
virtual void dump(ostream&out, unsigned ind) const;
private:
Type type_;
ivl_process_type_t type_;
Statement*statement_;
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2008 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
@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: async.cc,v 1.7 2004/01/18 23:26:54 steve Exp $"
#endif
# include "config.h"
@ -87,34 +84,8 @@ bool NetProc::is_asynchronous()
bool NetProcTop::is_asynchronous()
{
if (type_ == NetProcTop::KINITIAL)
if (type_ == IVL_PR_INITIAL)
return false;
return statement_->is_asynchronous();
}
/*
* $Log: async.cc,v $
* Revision 1.7 2004/01/18 23:26:54 steve
* The is_combinational function really need not recurse.
*
* Revision 1.6 2003/12/20 00:33:39 steve
* More thorough check that NetEvWait is asynchronous.
*
* Revision 1.5 2003/09/04 20:28:05 steve
* Support time0 resolution of combinational threads.
*
* Revision 1.4 2002/08/18 22:07:16 steve
* Detect temporaries in sequential block synthesis.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/07/04 00:24:16 steve
* initial statements are not asynchronous.
*
* Revision 1.1 2002/06/30 02:21:31 steve
* Add structure for asynchronous logic synthesis.
*
*/

View File

@ -702,11 +702,11 @@ void NetUDP::dump_node(ostream&o, unsigned ind) const
void NetProcTop::dump(ostream&o, unsigned ind) const
{
switch (type_) {
case NetProcTop::KINITIAL:
case IVL_PR_INITIAL:
o << "initial /* " << get_fileline() << " in "
<< scope_path(scope_) << " */" << endl;
break;
case NetProcTop::KALWAYS:
case IVL_PR_ALWAYS:
o << "always /* " << get_fileline() << " in "
<< scope_path(scope_) << " */" << endl;
break;

View File

@ -40,6 +40,7 @@
# include "PTask.h"
# include "PWire.h"
# include "Statement.h"
# include "AStatement.h"
# include "netlist.h"
# include "util.h"
# include <typeinfo>
@ -1242,3 +1243,12 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
if (statement_)
statement_ -> elaborate_scope(des, scope);
}
/*
* The base statement does not have sub-statements and does not
* introduce any scope, so this is a no-op.
*/
void AStatement::elaborate_scope(Design*, NetScope*) const
{
}

30
elab_sig_analog.cc Normal file
View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2008 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include "AStatement.h"
# include <cstdlib>
# include <iostream>
void AStatement::elaborate_sig(Design*des, NetScope*scope) const
{
}

View File

@ -3502,15 +3502,7 @@ bool PProcess::elaborate(Design*des, NetScope*scope) const
return false;
}
NetProcTop*top=0;
switch (type()) {
case PProcess::PR_INITIAL:
top = new NetProcTop(scope, NetProcTop::KINITIAL, cur);
break;
case PProcess::PR_ALWAYS:
top = new NetProcTop(scope, NetProcTop::KALWAYS, cur);
break;
}
NetProcTop*top=new NetProcTop(scope, type(), cur);
ivl_assert(*this, top);
// Evaluate the attributes for this process, if there
@ -3535,7 +3527,7 @@ bool PProcess::elaborate(Design*des, NetScope*scope) const
gets into its wait statement before non-combinational
code is executed. */
do {
if (top->type() != NetProcTop::KALWAYS)
if (top->type() != IVL_PR_ALWAYS)
break;
NetEvWait*st = dynamic_cast<NetEvWait*>(top->statement());
@ -3958,6 +3950,12 @@ bool PScope::elaborate_behaviors_(Design*des, NetScope*scope) const
result_flag &= (*st)->elaborate(des, scope);
}
for (list<AProcess*>::const_iterator st = analog_behaviors.begin()
; st != analog_behaviors.end() ; st ++ ) {
result_flag &= (*st)->elaborate(des, scope);
}
return result_flag;
}
@ -4045,7 +4043,7 @@ bool Design::check_always_delay() const
* a runtime infinite loop will happen. If we possible have some
* delay then print a warning that an infinite loop is possible.
*/
if (pr->type() == NetProcTop::KALWAYS) {
if (pr->type() == IVL_PR_ALWAYS) {
DelayType dly_type = pr->statement()->delay_type();
if (dly_type == NO_DELAY || dly_type == ZERO_DELAY) {

60
elaborate_analog.cc Normal file
View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2008 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include "AStatement.h"
# include "util.h"
# include <typeinfo>
NetAnalog* AStatement::elaborate(Design*des, NetScope*scope) const
{
cerr << get_fileline() << ": sorry: I don't yet know how to elaborate"
<< " his kind of analog statement." << endl;
cerr << get_fileline() << ": : typeid = " << typeid(*this).name() << endl;
return 0;
}
bool AProcess::elaborate(Design*des, NetScope*scope) const
{
NetAnalog*statement = statement_->elaborate(des, scope);
if (statement == 0)
return false;
NetAnalogTop*top = new NetAnalogTop(scope, type_, statement);
// Evaluate the attributes for this process, if there
// are any. These attributes are to be attached to the
// NetProcTop object.
struct attrib_list_t*attrib_list = 0;
unsigned attrib_list_n = 0;
attrib_list = evaluate_attributes(attributes, attrib_list_n, des, scope);
for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1)
top->attribute(attrib_list[adx].key,
attrib_list[adx].val);
delete[]attrib_list;
top->set_line(*this);
des->add_process(top);
return true;
}

View File

@ -36,7 +36,7 @@
# include "ivl_assert.h"
Design:: Design()
: errors(0), nodes_(0), procs_(0), lcounter_(0)
: errors(0), nodes_(0), procs_(0), aprocs_(0), lcounter_(0)
{
procs_idx_ = 0;
des_precision_ = 0;
@ -764,6 +764,11 @@ void Design::add_process(NetProcTop*pro)
procs_ = pro;
}
void Design::add_process(NetAnalogTop*pro)
{
pro->next_ = aprocs_;
aprocs_ = pro;
}
void Design::delete_process(NetProcTop*top)
{
assert(top);

View File

@ -850,7 +850,7 @@ NetProc::~NetProc()
{
}
NetProcTop::NetProcTop(NetScope*s, Type t, NetProc*st)
NetProcTop::NetProcTop(NetScope*s, ivl_process_type_t t, NetProc*st)
: type_(t), statement_(st), scope_(s)
{
}
@ -875,6 +875,16 @@ NetScope* NetProcTop::scope()
return scope_;
}
NetAnalogTop::NetAnalogTop(NetScope*scope, ivl_process_type_t t, NetAnalog*st)
: type_(t), statement_(st), scope_(scope)
{
next_ = 0;
}
NetAnalogTop::~NetAnalogTop()
{
}
const NetScope* NetProcTop::scope() const
{
return scope_;

View File

@ -3044,12 +3044,10 @@ class NetWhile : public NetProc {
class NetProcTop : public LineInfo, public Attrib {
public:
enum Type { KINITIAL, KALWAYS };
NetProcTop(NetScope*s, Type t, class NetProc*st);
NetProcTop(NetScope*s, ivl_process_type_t t, class NetProc*st);
~NetProcTop();
Type type() const { return type_; }
ivl_process_type_t type() const { return type_; }
NetProc*statement();
const NetProc*statement() const;
@ -3074,7 +3072,7 @@ class NetProcTop : public LineInfo, public Attrib {
bool emit(struct target_t*tgt) const;
private:
const Type type_;
const ivl_process_type_t type_;
NetProc*const statement_;
NetScope*scope_;
@ -3082,6 +3080,35 @@ class NetProcTop : public LineInfo, public Attrib {
NetProcTop*next_;
};
class NetAnalog : public LineInfo, public Attrib {
};
class NetAnalogTop : public LineInfo, public Attrib {
public:
NetAnalogTop(NetScope*scope, ivl_process_type_t t, NetAnalog*st);
~NetAnalogTop();
ivl_process_type_t type() const { return type_; }
NetAnalog*statement();
const NetAnalog*statement() const;
NetScope*scope();
const NetScope*scope() const;
void dump(ostream&, unsigned ind) const;
bool emit(struct target_t*tgt) const;
private:
const ivl_process_type_t type_;
NetAnalog* statement_;
NetScope*scope_;
friend class Design;
NetAnalogTop*next_;
};
/*
* This class represents a binary operator, with the left and right
* operands and a single character for the operator. The operator
@ -3822,6 +3849,7 @@ class Design {
// PROCESSES
void add_process(NetProcTop*);
void add_process(NetAnalogTop*);
void delete_process(NetProcTop*);
bool check_always_delay() const;
@ -3853,6 +3881,8 @@ class Design {
NetProcTop*procs_;
NetProcTop*procs_idx_;
NetAnalogTop*aprocs_;
map<string,const char*> flags_;
int des_precision_;

View File

@ -2093,16 +2093,16 @@ module_item
/* Always and initial items are behavioral processes. */
| attribute_list_opt K_always statement
{ PProcess*tmp = pform_make_behavior(PProcess::PR_ALWAYS, $3, $1);
{ PProcess*tmp = pform_make_behavior(IVL_PR_ALWAYS, $3, $1);
FILE_NAME(tmp, @2);
}
| attribute_list_opt K_initial statement
{ PProcess*tmp = pform_make_behavior(PProcess::PR_INITIAL, $3, $1);
{ PProcess*tmp = pform_make_behavior(IVL_PR_INITIAL, $3, $1);
FILE_NAME(tmp, @2);
}
| attribute_list_opt K_analog analog_statement
{ pform_make_analog_behavior(@2, AProcess::PR_ALWAYS, $3); }
{ pform_make_analog_behavior(@2, IVL_PR_ALWAYS, $3); }
/* The task declaration rule matches the task declaration
header, then pushes the function scope. This causes the

View File

@ -1304,7 +1304,7 @@ void pform_make_reginit(const struct vlltype&li,
FILE_NAME(lval, li);
PAssign*ass = new PAssign(lval, expr, true);
FILE_NAME(ass, li);
PProcess*top = new PProcess(PProcess::PR_INITIAL, ass);
PProcess*top = new PProcess(IVL_PR_INITIAL, ass);
FILE_NAME(top, li);
pform_put_behavior_in_scope(top);
@ -1947,7 +1947,7 @@ svector<PWire*>* pform_make_udp_input_ports(list<perm_string>*names)
return out;
}
PProcess* pform_make_behavior(PProcess::Type type, Statement*st,
PProcess* pform_make_behavior(ivl_process_type_t type, Statement*st,
svector<named_pexpr_t*>*attr)
{
PProcess*pp = new PProcess(type, st);

View File

@ -311,7 +311,7 @@ extern void pform_module_specify_path(PSpecPath*obj);
* pform_make_behavior creates processes that are declared with always
* or initial items.
*/
extern PProcess* pform_make_behavior(PProcess::Type, Statement*,
extern PProcess* pform_make_behavior(ivl_process_type_t, Statement*,
svector<named_pexpr_t*>*attr);
extern svector<PWire*>* pform_make_udp_input_ports(list<perm_string>*);
@ -396,7 +396,7 @@ extern void pform_dump(ostream&out, const discipline_t*);
/* ** pform_analog.cc
*/
extern void pform_make_analog_behavior(const struct vlltype&loc,
AProcess::Type type, AStatement*st);
ivl_process_type_t type, AStatement*st);
extern AStatement*pform_contribution_statement(const struct vlltype&loc,
PExpr*lval, PExpr*rval);

View File

@ -31,7 +31,7 @@ AStatement* pform_contribution_statement(const struct vlltype&loc,
return tmp;
}
void pform_make_analog_behavior(const struct vlltype&loc, AProcess::Type pt,
void pform_make_analog_behavior(const struct vlltype&loc, ivl_process_type_t pt,
AStatement*statement)
{
AProcess*proc = new AProcess(pt, statement);

View File

@ -135,6 +135,18 @@ ostream& operator<< (ostream&o, const pform_name_t&that)
return o;
}
std::ostream& operator << (std::ostream&out, ivl_process_type_t pt)
{
switch (pt) {
case IVL_PR_INITIAL:
out << "initial";
break;
case IVL_PR_ALWAYS:
out << "always";
break;
}
return out;
}
std::ostream& operator << (std::ostream&out, ddomain_t dom)
{
@ -900,16 +912,8 @@ void PWhile::dump(ostream&out, unsigned ind) const
void PProcess::dump(ostream&out, unsigned ind) const
{
switch (type_) {
case PProcess::PR_INITIAL:
out << setw(ind) << "" << "initial";
break;
case PProcess::PR_ALWAYS:
out << setw(ind) << "" << "always";
break;
}
out << " /* " << get_fileline() << " */" << endl;
out << setw(ind) << "" << type_
<< " /* " << get_fileline() << " */" << endl;
dump_attributes_map(out, attributes, ind+2);
@ -919,10 +923,10 @@ void PProcess::dump(ostream&out, unsigned ind) const
void AProcess::dump(ostream&out, unsigned ind) const
{
switch (type_) {
case AProcess::PR_INITIAL:
case IVL_PR_INITIAL:
out << setw(ind) << "" << "analog initial";
break;
case AProcess::PR_ALWAYS:
case IVL_PR_ALWAYS:
out << setw(ind) << "" << "analog";
break;
}

View File

@ -335,7 +335,7 @@ static void syn_start_process(NetProcTop*t)
last_ = first_;
ptr_ = first_;
first_->token = (t->type() == NetProcTop::KALWAYS)? S_ALWAYS : S_INITIAL;
first_->token = (t->type() == IVL_PR_ALWAYS)? S_ALWAYS : S_INITIAL;
first_->top = t;
first_->next_ = 0;

22
sync.cc
View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2008 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
@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: sync.cc,v 1.3 2002/09/24 00:58:35 steve Exp $"
#endif
# include "config.h"
@ -59,23 +56,8 @@ bool NetEvWait::is_synchronous()
bool NetProcTop::is_synchronous()
{
if (type_ == NetProcTop::KINITIAL)
if (type_ == IVL_PR_INITIAL)
return false;
return statement_->is_synchronous();
}
/*
* $Log: sync.cc,v $
* Revision 1.3 2002/09/24 00:58:35 steve
* More detailed check of process edge events.
*
* Revision 1.2 2002/09/16 21:55:06 steve
* Reject multiple probes on synchronous logic.
*
* Revision 1.1 2002/09/16 00:30:33 steve
* Add to synth2 support for synthesis of
* synchronous logic. This includes DFF enables
* modeled by if/then/else.
*
*/

View File

@ -131,10 +131,10 @@ void synth_f::process(class Design*des, class NetProcTop*top)
{
top_ = top;
switch (top->type()) {
case NetProcTop::KALWAYS:
case IVL_PR_ALWAYS:
proc_always_(des);
break;
case NetProcTop::KINITIAL:
case IVL_PR_INITIAL:
proc_initial_(des);
break;
}

View File

@ -39,16 +39,8 @@ bool dll_target::process(const NetProcTop*net)
ivl_process_t obj = (struct ivl_process_s*)
calloc(1, sizeof(struct ivl_process_s));
switch (net->type()) {
case NetProcTop::KINITIAL:
obj->type_ = IVL_PR_INITIAL;
break;
case NetProcTop::KALWAYS:
obj->type_ = IVL_PR_ALWAYS;
break;
default:
assert(0);
}
obj->type_ = net->type();
FILE_NAME(obj, net);
/* Save the scope of the process. */