diff --git a/AStatement.h b/AStatement.h index 0b1b60396..b386b3398 100644 --- a/AStatement.h +++ b/AStatement.h @@ -20,11 +20,15 @@ */ # include +# 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 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 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 diff --git a/Makefile.in b/Makefile.in index b5fc3d3d2..47c1ad1f4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 \ diff --git a/Statement.h b/Statement.h index 8890f938e..e99833131 100644 --- a/Statement.h +++ b/Statement.h @@ -20,6 +20,7 @@ */ # include +# 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 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_; }; diff --git a/async.cc b/async.cc index 3d283b9c6..0db7d7bec 100644 --- a/async.cc +++ b/async.cc @@ -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. - * - */ - diff --git a/design_dump.cc b/design_dump.cc index 3aabb3fdd..1ffcd10d7 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -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; diff --git a/elab_scope.cc b/elab_scope.cc index d4040375c..0e2820261 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -40,6 +40,7 @@ # include "PTask.h" # include "PWire.h" # include "Statement.h" +# include "AStatement.h" # include "netlist.h" # include "util.h" # include @@ -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 +{ +} + diff --git a/elab_sig_analog.cc b/elab_sig_analog.cc new file mode 100644 index 000000000..d7da16fcf --- /dev/null +++ b/elab_sig_analog.cc @@ -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 +# include + +void AStatement::elaborate_sig(Design*des, NetScope*scope) const +{ +} + diff --git a/elaborate.cc b/elaborate.cc index 503b04b54..1adb217d7 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -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(top->statement()); @@ -3958,6 +3950,12 @@ bool PScope::elaborate_behaviors_(Design*des, NetScope*scope) const result_flag &= (*st)->elaborate(des, scope); } + for (list::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) { diff --git a/elaborate_analog.cc b/elaborate_analog.cc new file mode 100644 index 000000000..0688aa2b2 --- /dev/null +++ b/elaborate_analog.cc @@ -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 + +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; +} diff --git a/net_design.cc b/net_design.cc index a8434128e..1ee8a4e1f 100644 --- a/net_design.cc +++ b/net_design.cc @@ -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); diff --git a/netlist.cc b/netlist.cc index 9cd711a8c..f23fbbe23 100644 --- a/netlist.cc +++ b/netlist.cc @@ -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_; diff --git a/netlist.h b/netlist.h index 9eaf5cce8..63f9f032a 100644 --- a/netlist.h +++ b/netlist.h @@ -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 flags_; int des_precision_; diff --git a/parse.y b/parse.y index 99475d19c..d6c05e830 100644 --- a/parse.y +++ b/parse.y @@ -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 diff --git a/pform.cc b/pform.cc index 7c0427631..0cd16c451 100644 --- a/pform.cc +++ b/pform.cc @@ -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* pform_make_udp_input_ports(list*names) return out; } -PProcess* pform_make_behavior(PProcess::Type type, Statement*st, +PProcess* pform_make_behavior(ivl_process_type_t type, Statement*st, svector*attr) { PProcess*pp = new PProcess(type, st); diff --git a/pform.h b/pform.h index 5422e74a2..16ef2f9f9 100644 --- a/pform.h +++ b/pform.h @@ -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*attr); extern svector* pform_make_udp_input_ports(list*); @@ -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); diff --git a/pform_analog.cc b/pform_analog.cc index 55408452b..fe5489b44 100644 --- a/pform_analog.cc +++ b/pform_analog.cc @@ -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); diff --git a/pform_dump.cc b/pform_dump.cc index a41b835d3..4283620e0 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -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; } diff --git a/syn-rules.y b/syn-rules.y index 78c4b4588..1a3f66ee3 100644 --- a/syn-rules.y +++ b/syn-rules.y @@ -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; diff --git a/sync.cc b/sync.cc index 50454a787..b720dc6d5 100644 --- a/sync.cc +++ b/sync.cc @@ -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. - * - */ diff --git a/synth.cc b/synth.cc index ac2aaeb87..6f2012290 100644 --- a/synth.cc +++ b/synth.cc @@ -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; } diff --git a/t-dll-proc.cc b/t-dll-proc.cc index f2031fb0b..13ac6240f 100644 --- a/t-dll-proc.cc +++ b/t-dll-proc.cc @@ -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. */