Parse disciplines and contribution statements

Parse discipline declarations, net discipline declarations, and
analog contribution statements. Don't yet do anything useful with
these, just give a sorry message where they are encountered.
This commit is contained in:
Stephen Williams 2008-05-11 12:00:11 -07:00
parent cde87ed4a3
commit 5b273178f5
10 changed files with 257 additions and 27 deletions

View File

@ -99,7 +99,7 @@ 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 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 \
elab_lval.o elab_net.o elab_pexpr.o elab_scope.o \
elab_sig.o emit.o eval.o eval_attrib.o \
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
@ -107,7 +107,7 @@ 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_udp.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o pform_types.o \
parse.o parse_misc.o pform.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 \

29
discipline.cc Normal file
View File

@ -0,0 +1,29 @@
/*
* 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 "discipline.h"
discipline_t::discipline_t(perm_string name, ddomain_t domain)
: name_(name), domain_(domain)
{
}
discipline_t::~discipline_t()
{
}

51
discipline.h Normal file
View File

@ -0,0 +1,51 @@
#ifndef __discipline_H
#define __discipline_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
*/
/*
* The discipline types include the discipline, nature and other
* related types for managing declared and used disciplines in a
* Verilog-AMS program.
*/
# include "StringHeap.h"
# include <iostream>
# include <map>
# include "LineInfo.h"
typedef enum { DD_NONE, DD_DISCRETE, DD_CONTINUOUS } ddomain_t;
extern std::ostream& operator << (std::ostream&, ddomain_t);
class discipline_t : public LineInfo {
public:
explicit discipline_t (perm_string name, ddomain_t dom);
~discipline_t();
perm_string name() const { return name_; }
ddomain_t domain() const { return domain_; }
private:
perm_string name_;
ddomain_t domain_;
};
extern map<perm_string,discipline_t*> disciplines;
#endif

View File

@ -34,6 +34,7 @@
# include <ctype.h>
# include <string.h>
# include "lexor_keyword.h"
# include "discipline.h"
# include <list>
# define YY_USER_INIT reset_lexor();
@ -152,6 +153,7 @@ S [afpnumkKMGT]
"->" { return K_TRIGGER; }
"+:" { return K_PO_POS; }
"-:" { return K_PO_NEG; }
"<+" { return K_CONTRIBUTE; }
/* Watch out for the tricky case of (*). Cannot parse this as "(*"
and ")", but since I know that this is really ( * ), replace it
@ -230,6 +232,18 @@ S [afpnumkKMGT]
break;
}
/* If this identifier names a discipline, then return this as
a DISCIPLINE_IDENTIFIER and return the discipline as the
value instead. */
if (rc == IDENTIFIER && gn_verilog_ams_flag) {
perm_string tmp = lex_strings.make(yylval.text);
map<perm_string,discipline_t*>::iterator cur = disciplines.find(tmp);
if (cur != disciplines.end()) {
yylval.discipline = (*cur).second;
rc = DISCIPLINE_IDENTIFIER;
}
}
return rc;
}

View File

@ -57,6 +57,7 @@ const char NOTICE[] =
# include "netlist.h"
# include "target.h"
# include "compiler.h"
# include "discipline.h"
#if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
extern "C" int getopt(int argc, char*argv[], const char*fmt);
@ -683,6 +684,11 @@ int main(int argc, char*argv[])
if (pf_path) {
ofstream out (pf_path);
out << "PFORM DUMP DISCIPLINES:" << endl;
for (map<perm_string,discipline_t*>::iterator cur = disciplines.begin()
; cur != disciplines.end() ; cur ++ ) {
pform_dump(out, (*cur).second);
}
out << "PFORM DUMP MODULES:" << endl;
for (map<perm_string,Module*>::iterator mod = pform_modules.begin()
; mod != pform_modules.end()

58
parse.y
View File

@ -94,12 +94,6 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
return tmp;
}
static inline void FILE_NAME(LineInfo*tmp, const struct vlltype&where)
{
tmp->set_lineno(where.first_line);
tmp->set_file(filename_strings.make(where.text));
}
static svector<PExpr*>* copy_range(svector<PExpr*>* orig)
{
svector<PExpr*>*copy = 0;
@ -147,6 +141,8 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
list<perm_string>*perm_strings;
pform_name_t*pform_name;
discipline_t*discipline;
hname_t*hier;
list<string>*strings;
@ -196,10 +192,13 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
};
%token <text> IDENTIFIER SYSTEM_IDENTIFIER STRING
%token <discipline> DISCIPLINE_IDENTIFIER
%token <text> PATHPULSE_IDENTIFIER
%token <number> BASED_NUMBER DEC_NUMBER
%token <realtime> REALTIME
%token K_LE K_GE K_EG K_EQ K_NE K_CEQ K_CNE K_LS K_RS K_RSS K_SG
/* K_CONTRIBUTE is <+, the contribution assign. */
%token K_CONTRIBUTE
%token K_PO_POS K_PO_NEG K_POW
%token K_PSTAR K_STARP
%token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER
@ -674,8 +673,10 @@ description
;
discipline_declaration
: K_discipline IDENTIFIER discipline_items K_enddiscipline
{ delete[]$2; }
: K_discipline IDENTIFIER
{ pform_start_discipline($2); }
discipline_items K_enddiscipline
{ pform_end_discipline(@1); delete[] $2; }
;
discipline_items
@ -822,6 +823,15 @@ event_expression
}
;
/* A branch probe expression applies a probe function (potential or
flow) to a branch. The branch may be implicit as a pair of nets
or explicit as a named branch. Elaboration will check that the
function name really is a nature attribute identifier. */
branch_probe_expression
: IDENTIFIER '(' IDENTIFIER ',' IDENTIFIER ')'
| IDENTIFIER '(' IDENTIFIER ')'
;
expression
: expr_primary
{ $$ = $1; }
@ -1951,6 +1961,12 @@ module_item
yyerrok;
}
/* Maybe this is a discipline declaration? If so, then the lexor
will see the discipline name as an identifier. We match it to the
discipline or type name semantically. */
| DISCIPLINE_IDENTIFIER list_of_identifiers ';'
{ pform_attach_discipline(@1, $1, $2); }
/* block_item_decl rule is shared with task blocks and named
begin/end. */
@ -2030,16 +2046,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);
FILE_NAME(tmp, @2);
}
| attribute_list_opt K_initial statement
{ PProcess*tmp = pform_make_behavior(PProcess::PR_INITIAL,
$3, $1);
FILE_NAME(tmp, @2);
}
| attribute_list_opt K_always statement
{ PProcess*tmp = pform_make_behavior(PProcess::PR_ALWAYS, $3, $1);
FILE_NAME(tmp, @2);
}
| attribute_list_opt K_initial statement
{ PProcess*tmp = pform_make_behavior(PProcess::PR_INITIAL, $3, $1);
FILE_NAME(tmp, @2);
}
| attribute_list_opt K_analog analog_statement
/* The task declaration rule matches the task declaration
header, then pushes the function scope. This causes the
@ -3541,6 +3557,12 @@ statement_or_null
| ';' { $$ = 0; }
;
analog_statement
: branch_probe_expression K_CONTRIBUTE expression ';'
{ yyerror(@1, "sorry: Analog contribution statements not supported."); }
;
/* Task items are, other than the statement, task port items and
other block items. */
task_item

View File

@ -23,6 +23,7 @@
#endif
# include <list>
# include "compiler.h"
# include "pform.h"
/*
@ -39,6 +40,13 @@ struct vlltype {
};
# define YYLTYPE struct vlltype
class LineInfo;
inline void FILE_NAME(LineInfo*tmp, const struct vlltype&where)
{
tmp->set_lineno(where.first_line);
tmp->set_file(filename_strings.make(where.text));
}
/* This for compatibility with new and older bison versions. */
#ifndef yylloc
# define yylloc VLlloc

View File

@ -27,6 +27,7 @@
# include "PUdp.h"
# include "PGenerate.h"
# include "PSpec.h"
# include "discipline.h"
# include <list>
# include <map>
# include <assert.h>
@ -38,7 +39,6 @@
# include "ivl_assert.h"
map<perm_string,Module*> pform_modules;
map<perm_string,PUdp*> pform_primitives;
@ -82,12 +82,6 @@ static inline void FILE_NAME(LineInfo*obj, const char*file, unsigned lineno)
obj->set_file(filename_strings.make(file));
}
static inline void FILE_NAME(LineInfo*tmp, const struct vlltype&where)
{
tmp->set_lineno(where.first_line);
tmp->set_file(filename_strings.make(where.text));
}
/*
* The lexical_scope keeps track of the current lexical scope that is
* being parsed. The lexical scope may stack, so the current scope may

15
pform.h
View File

@ -115,6 +115,7 @@ struct lgate {
unsigned lineno;
};
/* The lexor calls this function to change the default nettype. */
extern void pform_set_default_nettype(NetNet::Type net,
const char*file,
@ -350,4 +351,18 @@ extern void pform_dump(ostream&out, Module*mod);
*/
extern void pform_error_nested_modules();
/* ** pform_discipline.cc
* Functions for handling the parse of natures and disciplines. These
* functions are in pform_disciplines.cc
*/
class discipline_t;
extern void pform_start_discipline(const char*name);
extern void pform_end_discipline(const struct vlltype&loc);
extern void pform_attach_discipline(const struct vlltype&loc,
discipline_t*discipline, list<perm_string>*names);
extern void pform_dump(ostream&out, discipline_t*);
#endif

91
pform_disciplines.cc Normal file
View File

@ -0,0 +1,91 @@
/*
* 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 "discipline.h"
map<perm_string,discipline_t*> disciplines;
static perm_string discipline_name;
static ddomain_t discipline_domain = DD_NONE;
void pform_start_discipline(const char*name)
{
discipline_name = lex_strings.make(name);
discipline_domain = DD_NONE;
}
void pform_end_discipline(const struct vlltype&loc)
{
discipline_t*tmp = new discipline_t(discipline_name, discipline_domain);
disciplines[discipline_name] = tmp;
FILE_NAME(tmp, loc);
/* Clear the static variables for the next item. */
discipline_name = perm_string::perm_string();
discipline_domain = DD_NONE;
}
/*
* The parser uses this function to attach a discipline to a declared wire.
*/
void pform_attach_discipline(const struct vlltype&loc,
discipline_t*discipline, list<perm_string>*names)
{
error_count += 1;
cerr << yylloc.text << ";" << yylloc.first_line << ": sorry: "
<< "Net discipline declarations not supported." << endl;
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; cur ++ ) {
cerr << yylloc.text << ";" << yylloc.first_line << ": : "
<< "discipline=" << discipline->name()
<< ", net=" << *cur << endl;
}
}
void pform_dump(std::ostream&out, discipline_t*dis)
{
out << "discipline " << dis->name() << endl;
out << " domain " << dis->domain() << ";" << endl;
out << "enddiscipline" << endl;
}
std::ostream& operator << (std::ostream&out, ddomain_t dom)
{
switch (dom) {
case DD_NONE:
out << "no-domain";
break;
case DD_DISCRETE:
out << "discrete";
break;
case DD_CONTINUOUS:
out << "continuous";
break;
default:
assert(0);
break;
}
return out;
}