From 03e306c8056594972ef14cb5518eaf0168e5ecd9 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 27 Jul 2008 15:02:09 -0400 Subject: [PATCH] Infrastructure for parsing analog process statements. Organize the parsing infrastructure for parsing analog processes, including holding them in scopes, and collecting analog statements. --- AStatement.cc | 38 +++++++++++++++++++++++++ AStatement.h | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ Makefile.in | 5 ++-- PScope.h | 8 ++++-- parse.y | 6 +++- pform.cc | 11 ++++++++ pform.h | 9 ++++++ pform_analog.cc | 40 ++++++++++++++++++++++++++ pform_dump.cc | 46 ++++++++++++++++++++++++++++++ 9 files changed, 231 insertions(+), 6 deletions(-) create mode 100644 AStatement.cc create mode 100644 AStatement.h create mode 100644 pform_analog.cc diff --git a/AStatement.cc b/AStatement.cc new file mode 100644 index 000000000..4d59dffc2 --- /dev/null +++ b/AStatement.cc @@ -0,0 +1,38 @@ +/* + * 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" + +AStatement::~AStatement() +{ +} + +AContrib::AContrib() +{ +} + +AContrib::~AContrib() +{ +} + +AProcess::~AProcess() +{ +} diff --git a/AStatement.h b/AStatement.h new file mode 100644 index 000000000..fb00fc6ce --- /dev/null +++ b/AStatement.h @@ -0,0 +1,74 @@ +#ifndef __AStatement_H +#define __AStatement_H +/* + * 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 +# include "StringHeap.h" +# include "LineInfo.h" + +class PExpr; + +class AStatement : public LineInfo { + + public: + AStatement() { } + virtual ~AStatement() =0; + + virtual void dump(ostream&out, unsigned ind) const; + + private: // not implemented + AStatement(const AStatement&); + AStatement& operator= (const AStatement&); +}; + +class AContrib : public AStatement { + + public: + AContrib(); + ~AContrib(); + + private: +}; + +class AProcess : public LineInfo { + + public: + enum Type { PR_INITIAL, PR_ALWAYS }; + + AProcess(Type t, AStatement*st) + : type_(t), statement_(st) { } + + ~AProcess(); + + map attributes; + + // Dump the analog process + void dump(ostream&out, unsigned ind) const; + + private: + Type type_; + AStatement*statement_; + + private: // not implemented + AProcess(const AProcess&); + AProcess& operator= (const AProcess&); +}; + +#endif diff --git a/Makefile.in b/Makefile.in index a5be31f9b..a45841892 100644 --- a/Makefile.in +++ b/Makefile.in @@ -107,12 +107,13 @@ load_module.o netlist.o netmisc.o net_assign.o \ net_design.o net_event.o net_expr.o net_force.o net_func.o \ net_link.o net_modulo.o net_nex_input.o net_nex_output.o \ net_proc.o net_scope.o net_tran.o net_udp.o pad_to_width.o \ -parse.o parse_misc.o pform.o pform_disciplines.o pform_dump.o pform_types.o \ +parse.o parse_misc.o pform.o pform_analog.o pform_disciplines.o \ +pform_dump.o pform_types.o \ set_width.o symbol_search.o sync.o sys_funcs.o \ verinum.o verireal.o target.o targets.o \ Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \ PExpr.o PGate.o PGenerate.o PScope.o PSpec.o \ -PTask.o PUdp.o PFunction.o PWire.o Statement.o StringHeap.o \ +PTask.o PUdp.o PFunction.o PWire.o Statement.o AStatement.o StringHeap.o \ $(FF) $(TT) Makefile: Makefile.in config.h.in config.status diff --git a/PScope.h b/PScope.h index d65244a03..545b502f3 100644 --- a/PScope.h +++ b/PScope.h @@ -24,6 +24,7 @@ # include class PEvent; +class AProcess; class PProcess; class PWire; @@ -50,6 +51,10 @@ class LexicalScope { mapwires; PWire* wires_find(perm_string name); + // Behaviors (processes) in this scope + list behaviors; + list analog_behaviors; + private: }; @@ -74,9 +79,6 @@ class PScope : public LexicalScope { // Named events in the scope. mapevents; - // Behaviors (processes) in this scope - list behaviors; - protected: void dump_wires_(ostream&out, unsigned indent) const; diff --git a/parse.y b/parse.y index f63ee1d9b..0bea41113 100644 --- a/parse.y +++ b/parse.y @@ -180,6 +180,7 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2) PEventStatement*event_statement; Statement*statement; svector*statement_list; + AStatement*astatement; PTaskFuncArg function_type; @@ -302,6 +303,8 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2) %type statement statement_or_null %type statement_list +%type analog_statement + %type spec_polarity %type specify_path_identifiers @@ -2078,6 +2081,7 @@ module_item } | attribute_list_opt K_analog analog_statement + { pform_make_analog_behavior(@2, AProcess::PR_ALWAYS, $3); } /* The task declaration rule matches the task declaration header, then pushes the function scope. This causes the @@ -3724,7 +3728,7 @@ statement_or_null analog_statement : branch_probe_expression K_CONTRIBUTE expression ';' - { yyerror(@1, "sorry: Analog contribution statements not supported."); } + { $$ = pform_contribution_statement(@2); } ; /* Task items are, other than the statement, task port items and diff --git a/pform.cc b/pform.cc index 6b3612a06..9e9d84a87 100644 --- a/pform.cc +++ b/pform.cc @@ -192,6 +192,17 @@ static void pform_put_behavior_in_scope(PProcess*pp) lexical_scope->behaviors.push_back(pp); } +void pform_put_behavior_in_scope(AProcess*pp) +{ + if (pform_cur_generate) + if (pform_cur_generate->lexical_scope) + pform_cur_generate->lexical_scope->analog_behaviors.push_back(pp); + else + pform_cur_generate->analog_behaviors.push_back(pp); + else + lexical_scope->analog_behaviors.push_back(pp); +} + void pform_set_default_nettype(NetNet::Type type, const char*file, unsigned lineno) { diff --git a/pform.h b/pform.h index a94be9f96..c3a5f7652 100644 --- a/pform.h +++ b/pform.h @@ -24,6 +24,7 @@ # include "named.h" # include "Module.h" # include "Statement.h" +# include "AStatement.h" # include "PGate.h" # include "PExpr.h" # include "PTask.h" @@ -179,6 +180,7 @@ extern PTask*pform_push_task_scope(char*name); extern PFunction*pform_push_function_scope(char*name); extern PBlock*pform_push_block_scope(char*name, PBlock::BL_TYPE tt); +extern void pform_put_behavior_in_scope(AProcess*proc); extern verinum* pform_verinum_with_size(verinum*s, verinum*val, const char*file, unsigned lineno); @@ -389,4 +391,11 @@ extern void pform_attach_discipline(const struct vlltype&loc, extern void pform_dump(ostream&out, const nature_t*); 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); + +extern AStatement*pform_contribution_statement(const struct vlltype&loc); + #endif diff --git a/pform_analog.cc b/pform_analog.cc new file mode 100644 index 000000000..44c080458 --- /dev/null +++ b/pform_analog.cc @@ -0,0 +1,40 @@ +/* + * 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 "compiler.h" +# include "pform.h" +# include "parse_misc.h" +# include "AStatement.h" + +AStatement* pform_contribution_statement(const struct vlltype&loc) +{ + AContrib*tmp = new AContrib; + FILE_NAME(tmp, loc); + return tmp; +} + +void pform_make_analog_behavior(const struct vlltype&loc, AProcess::Type pt, + AStatement*statement) +{ + AProcess*proc = new AProcess(pt, statement); + FILE_NAME(proc, loc); + + pform_put_behavior_in_scope(proc); +} diff --git a/pform_dump.cc b/pform_dump.cc index ba6e60912..7ea9b37b1 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -531,6 +531,16 @@ void Statement::dump(ostream&out, unsigned ind) const << " */ ;" << endl; } +void AStatement::dump(ostream&out, unsigned ind) const +{ + /* I give up. I don't know what type this statement is, + so just print the C++ typeid and let the user figure + it out. */ + out << setw(ind) << ""; + out << "/* " << get_fileline() << ": " << typeid(*this).name() + << " */ ;" << endl; +} + void PAssign::dump(ostream&out, unsigned ind) const { out << setw(ind) << ""; @@ -840,6 +850,32 @@ void PProcess::dump(ostream&out, unsigned ind) const statement_->dump(out, ind+2); } +void AProcess::dump(ostream&out, unsigned ind) const +{ + switch (type_) { + case AProcess::PR_INITIAL: + out << setw(ind) << "" << "analog initial"; + break; + case AProcess::PR_ALWAYS: + out << setw(ind) << "" << "analog"; + break; + } + + out << " /* " << get_fileline() << " */" << endl; + + for (map::const_iterator idx = attributes.begin() + ; idx != attributes.end() ; idx++ ) { + + out << setw(ind+2) << "" << "(* " << (*idx).first; + if ((*idx).second) { + out << " = " << *(*idx).second; + } + out << " *)" << endl; + } + + statement_->dump(out, ind+2); +} + void PSpecPath::dump(std::ostream&out, unsigned ind) const { out << setw(ind) << "" << "specify path "; @@ -937,6 +973,11 @@ void PGenerate::dump(ostream&out, unsigned indent) const (*idx)->dump(out, indent+2); } + for (list::const_iterator idx = analog_behaviors.begin() + ; idx != analog_behaviors.end() ; idx++) { + (*idx)->dump(out, indent+2); + } + for (list::const_iterator idx = generate_schemes.begin() ; idx != generate_schemes.end() ; idx++) { (*idx)->dump(out, indent+2); @@ -1122,6 +1163,11 @@ void Module::dump(ostream&out) const (*behav)->dump(out, 4); } + for (list::const_iterator idx = analog_behaviors.begin() + ; idx != analog_behaviors.end() ; idx++) { + (*idx)->dump(out, 4); + } + for (list::const_iterator spec = specify_paths.begin() ; spec != specify_paths.end() ; spec ++ ) {