NetAssign handles lvalues as pin links
instead of a signal pointer, Wire attributes added, Ability to parse UDP descriptions added, XNF generates EXT records for signals with the PAD attribute.
This commit is contained in:
parent
338240c37b
commit
af8d6fbf01
13
PWire.h
13
PWire.h
|
|
@ -19,10 +19,11 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: PWire.h,v 1.1 1998/11/03 23:28:55 steve Exp $"
|
#ident "$Id: PWire.h,v 1.2 1998/11/23 00:20:22 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
# include <map>
|
||||||
class ostream;
|
class ostream;
|
||||||
class PExpr;
|
class PExpr;
|
||||||
class Design;
|
class Design;
|
||||||
|
|
@ -46,6 +47,8 @@ class PWire {
|
||||||
PExpr*msb;
|
PExpr*msb;
|
||||||
PExpr*lsb;
|
PExpr*lsb;
|
||||||
|
|
||||||
|
map<string,string> attributes;
|
||||||
|
|
||||||
// Write myself to the specified stream.
|
// Write myself to the specified stream.
|
||||||
void dump(ostream&out) const;
|
void dump(ostream&out) const;
|
||||||
|
|
||||||
|
|
@ -58,6 +61,14 @@ class PWire {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PWire.h,v $
|
* $Log: PWire.h,v $
|
||||||
|
* Revision 1.2 1998/11/23 00:20:22 steve
|
||||||
|
* NetAssign handles lvalues as pin links
|
||||||
|
* instead of a signal pointer,
|
||||||
|
* Wire attributes added,
|
||||||
|
* Ability to parse UDP descriptions added,
|
||||||
|
* XNF generates EXT records for signals with
|
||||||
|
* the PAD attribute.
|
||||||
|
*
|
||||||
* Revision 1.1 1998/11/03 23:28:55 steve
|
* Revision 1.1 1998/11/03 23:28:55 steve
|
||||||
* Introduce verilog to CVS.
|
* Introduce verilog to CVS.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
26
README.txt
26
README.txt
|
|
@ -1,4 +1,13 @@
|
||||||
|
|
||||||
|
THE ICARUS VERILOG COMPILATION SYSTEM
|
||||||
|
|
||||||
|
This tool includes a parser that parses Verilog (plus extensions) and
|
||||||
|
generates an internal netlist. The netlist is passed to various
|
||||||
|
processing steps that transform the design to more optimal/practical
|
||||||
|
forms, then passed to a code generator for final output. The
|
||||||
|
processing steps and the code generator are selected by command line
|
||||||
|
switches.
|
||||||
|
|
||||||
INVOKING
|
INVOKING
|
||||||
|
|
||||||
The vl command is the compiler driver, that invokes the parser,
|
The vl command is the compiler driver, that invokes the parser,
|
||||||
|
|
@ -42,6 +51,23 @@ Usage: vl [-s <module>] [-o <file>] [-D] [-F <name>] [-t <name>] file
|
||||||
Select the output format for the compiled result. Use the
|
Select the output format for the compiled result. Use the
|
||||||
"vl -h" command to get a list of configured targets.
|
"vl -h" command to get a list of configured targets.
|
||||||
|
|
||||||
|
ATTRIBUTES
|
||||||
|
|
||||||
|
The parser accepts as an extension to Verilog the $attribute module
|
||||||
|
item. The syntax of the $attribute item is:
|
||||||
|
|
||||||
|
$attribute (<identifier>, <key>, <value>);
|
||||||
|
|
||||||
|
The $attribute keyword looks like a system task invocation. The
|
||||||
|
difference here is that the parameters are more restricted then those
|
||||||
|
of a system task. The <identifier> must be an identifier. This will be
|
||||||
|
the item to get an attribute. The <key> and <value> are strings, not
|
||||||
|
expressions, that give the key and the value of the attribute to be
|
||||||
|
attached to the identified object.
|
||||||
|
|
||||||
|
Attributes are [<key> <value>] pairs and are used to communicate with
|
||||||
|
the various processing steps. See the documentation for the processing
|
||||||
|
step for a list of the pertinent attributes.
|
||||||
|
|
||||||
HOW IT WORKS -- STAGES OF PROCESSING
|
HOW IT WORKS -- STAGES OF PROCESSING
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: design_dump.cc,v 1.3 1998/11/09 18:55:34 steve Exp $"
|
#ident "$Id: design_dump.cc,v 1.4 1998/11/23 00:20:22 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -66,6 +66,7 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||||
o << " (local)";
|
o << " (local)";
|
||||||
o << " #(" << delay1() << "," << delay2() << "," << delay3() <<
|
o << " #(" << delay1() << "," << delay2() << "," << delay3() <<
|
||||||
")" << endl;
|
")" << endl;
|
||||||
|
dump_obj_attr(o, ind+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -80,6 +81,7 @@ void NetNode::dump_node(ostream&o, unsigned ind) const
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
dump_node_pins(o, ind+4);
|
dump_node_pins(o, ind+4);
|
||||||
|
dump_obj_attr(o, ind+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the generic dumping of all the signals connected to each
|
/* This is the generic dumping of all the signals connected to each
|
||||||
|
|
@ -103,6 +105,16 @@ void NetObj::dump_node_pins(ostream&o, unsigned ind) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetObj::dump_obj_attr(ostream&o, unsigned ind) const
|
||||||
|
{
|
||||||
|
for (map<string,string>::const_iterator idx = attributes_.begin()
|
||||||
|
; idx != attributes_.end()
|
||||||
|
; idx ++) {
|
||||||
|
o << setw(ind) << "" << (*idx).first << " = \"" <<
|
||||||
|
(*idx).second << "\"" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NetAssign::dump_node(ostream&o, unsigned ind) const
|
void NetAssign::dump_node(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
o << setw(ind) << "" << "Procedural assign: " << *rval_ << endl;
|
o << setw(ind) << "" << "Procedural assign: " << *rval_ << endl;
|
||||||
|
|
@ -193,7 +205,16 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
|
||||||
/* Dump an assignment statement */
|
/* Dump an assignment statement */
|
||||||
void NetAssign::dump(ostream&o, unsigned ind) const
|
void NetAssign::dump(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
o << setw(ind) << "" << lval_->name() << " = ";
|
o << setw(ind) << "";
|
||||||
|
|
||||||
|
NetNet*sig;
|
||||||
|
unsigned msb, lsb;
|
||||||
|
find_lval_range(sig, msb, lsb);
|
||||||
|
o << sig->name() << "[" << msb;
|
||||||
|
if (pin_count() > 1)
|
||||||
|
o << ":" << lsb;
|
||||||
|
o << "] = ";
|
||||||
|
|
||||||
rval_->dump(o);
|
rval_->dump(o);
|
||||||
o << ";" << endl;
|
o << ";" << endl;
|
||||||
}
|
}
|
||||||
|
|
@ -375,6 +396,14 @@ void Design::dump(ostream&o) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: design_dump.cc,v $
|
* $Log: design_dump.cc,v $
|
||||||
|
* Revision 1.4 1998/11/23 00:20:22 steve
|
||||||
|
* NetAssign handles lvalues as pin links
|
||||||
|
* instead of a signal pointer,
|
||||||
|
* Wire attributes added,
|
||||||
|
* Ability to parse UDP descriptions added,
|
||||||
|
* XNF generates EXT records for signals with
|
||||||
|
* the PAD attribute.
|
||||||
|
*
|
||||||
* Revision 1.3 1998/11/09 18:55:34 steve
|
* Revision 1.3 1998/11/09 18:55:34 steve
|
||||||
* Add procedural while loops,
|
* Add procedural while loops,
|
||||||
* Parse procedural for loops,
|
* Parse procedural for loops,
|
||||||
|
|
|
||||||
11
elaborate.cc
11
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: elaborate.cc,v 1.5 1998/11/21 19:19:44 steve Exp $"
|
#ident "$Id: elaborate.cc,v 1.6 1998/11/23 00:20:22 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -125,6 +125,7 @@ void PWire::elaborate(Design*des, const string&path) const
|
||||||
|
|
||||||
NetNet*sig = new NetNet(path + "." + name, wtype, wid);
|
NetNet*sig = new NetNet(path + "." + name, wtype, wid);
|
||||||
sig->port_type(port_type);
|
sig->port_type(port_type);
|
||||||
|
sig->set_attributes(attributes);
|
||||||
des->add_signal(sig);
|
des->add_signal(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -706,6 +707,14 @@ Design* elaborate(const list<Module*>&modules, const string&root)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elaborate.cc,v $
|
* $Log: elaborate.cc,v $
|
||||||
|
* Revision 1.6 1998/11/23 00:20:22 steve
|
||||||
|
* NetAssign handles lvalues as pin links
|
||||||
|
* instead of a signal pointer,
|
||||||
|
* Wire attributes added,
|
||||||
|
* Ability to parse UDP descriptions added,
|
||||||
|
* XNF generates EXT records for signals with
|
||||||
|
* the PAD attribute.
|
||||||
|
*
|
||||||
* Revision 1.5 1998/11/21 19:19:44 steve
|
* Revision 1.5 1998/11/21 19:19:44 steve
|
||||||
* Give anonymous modules a name when elaborated.
|
* Give anonymous modules a name when elaborated.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
22
lexor.lex
22
lexor.lex
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: lexor.lex,v 1.3 1998/11/09 18:55:34 steve Exp $"
|
#ident "$Id: lexor.lex,v 1.4 1998/11/23 00:20:23 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//# define YYSTYPE lexval
|
//# define YYSTYPE lexval
|
||||||
|
|
@ -48,6 +48,7 @@ static verinum*make_sized_hex(const char*txt);
|
||||||
|
|
||||||
%x CCOMMENT
|
%x CCOMMENT
|
||||||
%x CSTRING
|
%x CSTRING
|
||||||
|
%s UDPTABLE
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
|
@ -81,6 +82,8 @@ static verinum*make_sized_hex(const char*txt);
|
||||||
return STRING; }
|
return STRING; }
|
||||||
<CSTRING>. { yymore(); }
|
<CSTRING>. { yymore(); }
|
||||||
|
|
||||||
|
<UDPTABLE>[xXbB01\?] { return yytext[0]; }
|
||||||
|
|
||||||
[a-zA-Z_][a-zA-Z0-9$_]* {
|
[a-zA-Z_][a-zA-Z0-9$_]* {
|
||||||
int rc = check_identifier(yytext);
|
int rc = check_identifier(yytext);
|
||||||
if (rc == IDENTIFIER)
|
if (rc == IDENTIFIER)
|
||||||
|
|
@ -95,6 +98,8 @@ static verinum*make_sized_hex(const char*txt);
|
||||||
return IDENTIFIER; }
|
return IDENTIFIER; }
|
||||||
|
|
||||||
\$([a-zA-Z0-9$_]+) {
|
\$([a-zA-Z0-9$_]+) {
|
||||||
|
if (strcmp(yytext,"$attribute") == 0)
|
||||||
|
return KK_attribute;
|
||||||
yylval.text = new string(yytext);
|
yylval.text = new string(yytext);
|
||||||
return SYSTEM_IDENTIFIER; }
|
return SYSTEM_IDENTIFIER; }
|
||||||
|
|
||||||
|
|
@ -136,6 +141,21 @@ static verinum*make_sized_hex(const char*txt);
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The UDP state table needs some slightly different treatment by the
|
||||||
|
* lexor. The level characters are normally accepted as other things,
|
||||||
|
* so the parser needs to switch my mode when it believes in needs to.
|
||||||
|
*/
|
||||||
|
void lex_start_table()
|
||||||
|
{
|
||||||
|
BEGIN(UDPTABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lex_end_table()
|
||||||
|
{
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct { const char*name; int code; } key_table[] = {
|
static const struct { const char*name; int code; } key_table[] = {
|
||||||
{ "always", K_always },
|
{ "always", K_always },
|
||||||
{ "and", K_and },
|
{ "and", K_and },
|
||||||
|
|
|
||||||
96
netlist.cc
96
netlist.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: netlist.cc,v 1.7 1998/11/18 04:25:22 steve Exp $"
|
#ident "$Id: netlist.cc,v 1.8 1998/11/23 00:20:23 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
|
@ -44,6 +44,33 @@ void connect(NetObj::Link&l, NetObj::Link&r)
|
||||||
} while (cur != &l);
|
} while (cur != &l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NetObj::Link::is_linked(const NetObj&that) const
|
||||||
|
{
|
||||||
|
for (const Link*idx = next_ ; this != idx ; idx = idx->next_)
|
||||||
|
if (idx->node_ == &that)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetObj::Link::is_linked(const NetObj::Link&that) const
|
||||||
|
{
|
||||||
|
for (const Link*idx = next_ ; this != idx ; idx = idx->next_)
|
||||||
|
if (idx == &that)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool connected(const NetObj&l, const NetObj&r)
|
||||||
|
{
|
||||||
|
for (unsigned idx = 0 ; idx < l.pin_count() ; idx += 1)
|
||||||
|
if (! l.pin(idx).is_linked(r))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const NetNet* find_link_signal(const NetObj*net, unsigned pin, unsigned&bidx)
|
const NetNet* find_link_signal(const NetObj*net, unsigned pin, unsigned&bidx)
|
||||||
{
|
{
|
||||||
const NetObj*cur;
|
const NetObj*cur;
|
||||||
|
|
@ -77,6 +104,21 @@ NetObj::~NetObj()
|
||||||
delete[]pins_;
|
delete[]pins_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetObj::set_attributes(const map<string,string>&attr)
|
||||||
|
{
|
||||||
|
assert(attributes_.size() == 0);
|
||||||
|
attributes_ = attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
string NetObj::attribute(const string&key) const
|
||||||
|
{
|
||||||
|
map<string,string>::const_iterator idx = attributes_.find(key);
|
||||||
|
if (idx == attributes_.end())
|
||||||
|
return "";
|
||||||
|
|
||||||
|
return (*idx).second;
|
||||||
|
}
|
||||||
|
|
||||||
NetNode::~NetNode()
|
NetNode::~NetNode()
|
||||||
{
|
{
|
||||||
if (design_)
|
if (design_)
|
||||||
|
|
@ -94,19 +136,59 @@ NetProc::~NetProc()
|
||||||
}
|
}
|
||||||
|
|
||||||
NetAssign::NetAssign(NetNet*lv, NetExpr*rv)
|
NetAssign::NetAssign(NetNet*lv, NetExpr*rv)
|
||||||
: NetNode("@assign", lv->pin_count()), lval_(lv), rval_(rv)
|
: NetNode("@assign", lv->pin_count()), rval_(rv)
|
||||||
{
|
{
|
||||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
||||||
connect(pin(idx), lv->pin(idx));
|
connect(pin(idx), lv->pin(idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
rval_->set_width(lval_->pin_count());
|
rval_->set_width(lv->pin_count());
|
||||||
}
|
}
|
||||||
|
|
||||||
NetAssign::~NetAssign()
|
NetAssign::~NetAssign()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This method looks at the objects connected to me, and searches for
|
||||||
|
* a signal that I am fully connected to. Return that signal, and the
|
||||||
|
* range of bits that I use.
|
||||||
|
*/
|
||||||
|
void NetAssign::find_lval_range(const NetNet*&net, unsigned&msb,
|
||||||
|
unsigned&lsb) const
|
||||||
|
{
|
||||||
|
const NetObj*cur;
|
||||||
|
unsigned cpin;
|
||||||
|
|
||||||
|
for (pin(0).next_link(cur,cpin) ; pin(0) != cur->pin(cpin)
|
||||||
|
; cur->pin(cpin).next_link(cur, cpin)) {
|
||||||
|
const NetNet*s = dynamic_cast<const NetNet*>(cur);
|
||||||
|
if (s == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!connected(*this, *s))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
unsigned idx;
|
||||||
|
for (idx = 1 ; idx < pin_count() ; idx += 1) {
|
||||||
|
if (idx+cpin > s->pin_count())
|
||||||
|
break;
|
||||||
|
if (! connected(pin(idx), s->pin(idx+cpin)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < pin_count())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
net = s;
|
||||||
|
lsb = cpin;
|
||||||
|
msb = cpin+pin_count()-1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(0); // No suitable signals??
|
||||||
|
}
|
||||||
|
|
||||||
NetBlock::~NetBlock()
|
NetBlock::~NetBlock()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -370,6 +452,14 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.cc,v $
|
* $Log: netlist.cc,v $
|
||||||
|
* Revision 1.8 1998/11/23 00:20:23 steve
|
||||||
|
* NetAssign handles lvalues as pin links
|
||||||
|
* instead of a signal pointer,
|
||||||
|
* Wire attributes added,
|
||||||
|
* Ability to parse UDP descriptions added,
|
||||||
|
* XNF generates EXT records for signals with
|
||||||
|
* the PAD attribute.
|
||||||
|
*
|
||||||
* Revision 1.7 1998/11/18 04:25:22 steve
|
* Revision 1.7 1998/11/18 04:25:22 steve
|
||||||
* Add -f flags for generic flag key/values.
|
* Add -f flags for generic flag key/values.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
44
netlist.h
44
netlist.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: netlist.h,v 1.7 1998/11/18 04:25:22 steve Exp $"
|
#ident "$Id: netlist.h,v 1.8 1998/11/23 00:20:23 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -87,6 +87,15 @@ class NetObj {
|
||||||
// Return true if this link is connected to anything else.
|
// Return true if this link is connected to anything else.
|
||||||
bool is_linked() const { return next_ != this; }
|
bool is_linked() const { return next_ != this; }
|
||||||
|
|
||||||
|
// Return true if these pins are connected.
|
||||||
|
bool is_linked(const NetObj::Link&that) const;
|
||||||
|
|
||||||
|
// Return true if this link is connected to any pin of r.
|
||||||
|
bool is_linked(const NetObj&r) const;
|
||||||
|
|
||||||
|
bool is_equal(const NetObj::Link&that) const
|
||||||
|
{ return (node_ == that.node_) && (pin_ == that.pin_); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The NetNode manages these. They point back to the
|
// The NetNode manages these. They point back to the
|
||||||
// NetNode so that following the links can get me here.
|
// NetNode so that following the links can get me here.
|
||||||
|
|
@ -118,6 +127,9 @@ class NetObj {
|
||||||
void delay2(unsigned d) { delay2_ = d; }
|
void delay2(unsigned d) { delay2_ = d; }
|
||||||
void delay3(unsigned d) { delay3_ = d; }
|
void delay3(unsigned d) { delay3_ = d; }
|
||||||
|
|
||||||
|
void set_attributes(const map<string,string>&);
|
||||||
|
string attribute(const string&key) const;
|
||||||
|
|
||||||
bool test_mark() const { return mark_; }
|
bool test_mark() const { return mark_; }
|
||||||
void set_mark(bool flag=true) { mark_ = flag; }
|
void set_mark(bool flag=true) { mark_ = flag; }
|
||||||
|
|
||||||
|
|
@ -125,7 +137,7 @@ class NetObj {
|
||||||
const Link&pin(unsigned idx) const { return pins_[idx]; }
|
const Link&pin(unsigned idx) const { return pins_[idx]; }
|
||||||
|
|
||||||
void dump_node_pins(ostream&, unsigned) const;
|
void dump_node_pins(ostream&, unsigned) const;
|
||||||
|
void dump_obj_attr(ostream&, unsigned) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
string name_;
|
string name_;
|
||||||
|
|
@ -135,6 +147,8 @@ class NetObj {
|
||||||
unsigned delay2_;
|
unsigned delay2_;
|
||||||
unsigned delay3_;
|
unsigned delay3_;
|
||||||
|
|
||||||
|
map<string,string> attributes_;
|
||||||
|
|
||||||
bool mark_;
|
bool mark_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -323,16 +337,17 @@ class NetAssign : public NetProc, public NetNode {
|
||||||
explicit NetAssign(NetNet*lv, NetExpr*rv);
|
explicit NetAssign(NetNet*lv, NetExpr*rv);
|
||||||
~NetAssign();
|
~NetAssign();
|
||||||
|
|
||||||
const NetNet* lval() const { return lval_; }
|
|
||||||
const NetExpr*rval() const { return rval_; }
|
const NetExpr*rval() const { return rval_; }
|
||||||
|
|
||||||
|
void find_lval_range(const NetNet*&net, unsigned&msb,
|
||||||
|
unsigned&lsb) const;
|
||||||
|
|
||||||
virtual void emit_proc(ostream&, struct target_t*) const;
|
virtual void emit_proc(ostream&, struct target_t*) const;
|
||||||
virtual void emit_node(ostream&, struct target_t*) const;
|
virtual void emit_node(ostream&, struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
virtual void dump_node(ostream&, unsigned ind) const;
|
virtual void dump_node(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetNet*const lval_;
|
|
||||||
NetExpr*const rval_;
|
NetExpr*const rval_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -711,11 +726,24 @@ class Design {
|
||||||
/* =======
|
/* =======
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
inline bool operator == (const NetObj::Link&l, const NetObj::Link&r)
|
||||||
|
{ return l.is_equal(r); }
|
||||||
|
|
||||||
|
inline bool operator != (const NetObj::Link&l, const NetObj::Link&r)
|
||||||
|
{ return ! l.is_equal(r); }
|
||||||
|
|
||||||
/* Connect the pins of two nodes together. Either may already be
|
/* Connect the pins of two nodes together. Either may already be
|
||||||
connected to other things, connect is transitive. */
|
connected to other things, connect is transitive. */
|
||||||
extern void connect(NetObj::Link&, NetObj::Link&);
|
extern void connect(NetObj::Link&, NetObj::Link&);
|
||||||
|
|
||||||
|
inline bool connected(const NetObj::Link&l, const NetObj::Link&r)
|
||||||
|
{ return l.is_linked(r); }
|
||||||
|
|
||||||
|
/* Return true if l is fully connected to r. This means, every pin in
|
||||||
|
l is connected to a pin in r. This is expecially useful for
|
||||||
|
checking signal vectors. */
|
||||||
|
extern bool connected(const NetObj&l, const NetObj&r);
|
||||||
|
|
||||||
/* Find the signal connected to the given node pin. There should
|
/* Find the signal connected to the given node pin. There should
|
||||||
always be exactly one signal. The bidx parameter get filled with
|
always be exactly one signal. The bidx parameter get filled with
|
||||||
the signal index of the Net, in case it is a vector. */
|
the signal index of the Net, in case it is a vector. */
|
||||||
|
|
@ -727,6 +755,14 @@ inline ostream& operator << (ostream&o, const NetExpr&exp)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $Log: netlist.h,v $
|
||||||
|
* Revision 1.8 1998/11/23 00:20:23 steve
|
||||||
|
* NetAssign handles lvalues as pin links
|
||||||
|
* instead of a signal pointer,
|
||||||
|
* Wire attributes added,
|
||||||
|
* Ability to parse UDP descriptions added,
|
||||||
|
* XNF generates EXT records for signals with
|
||||||
|
* the PAD attribute.
|
||||||
|
*
|
||||||
* Revision 1.7 1998/11/18 04:25:22 steve
|
* Revision 1.7 1998/11/18 04:25:22 steve
|
||||||
* Add -f flags for generic flag key/values.
|
* Add -f flags for generic flag key/values.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
67
parse.y
67
parse.y
|
|
@ -19,12 +19,14 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: parse.y,v 1.5 1998/11/11 03:13:04 steve Exp $"
|
#ident "$Id: parse.y,v 1.6 1998/11/23 00:20:23 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "parse_misc.h"
|
# include "parse_misc.h"
|
||||||
# include "pform.h"
|
# include "pform.h"
|
||||||
|
|
||||||
|
extern void lex_start_table();
|
||||||
|
extern void lex_end_table();
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
|
|
@ -70,6 +72,8 @@
|
||||||
%token K_trior K_vectored K_wait K_wand K_weak0 K_weak1 K_while K_wire
|
%token K_trior K_vectored K_wait K_wand K_weak0 K_weak1 K_while K_wire
|
||||||
%token K_wor K_xnor K_xor
|
%token K_wor K_xnor K_xor
|
||||||
|
|
||||||
|
%token KK_attribute
|
||||||
|
|
||||||
%type <text> identifier lvalue register_variable
|
%type <text> identifier lvalue register_variable
|
||||||
%type <strings> list_of_register_variables
|
%type <strings> list_of_register_variables
|
||||||
%type <strings> list_of_variables
|
%type <strings> list_of_variables
|
||||||
|
|
@ -138,7 +142,7 @@ delay_opt
|
||||||
|
|
||||||
description
|
description
|
||||||
: module
|
: module
|
||||||
| primitive
|
| udp_primitive
|
||||||
;
|
;
|
||||||
|
|
||||||
event_control
|
event_control
|
||||||
|
|
@ -433,6 +437,14 @@ module_item
|
||||||
| K_initial statement
|
| K_initial statement
|
||||||
{ pform_make_behavior(PProcess::PR_INITIAL, $2);
|
{ pform_make_behavior(PProcess::PR_INITIAL, $2);
|
||||||
}
|
}
|
||||||
|
| KK_attribute '(' IDENTIFIER ',' STRING ',' STRING ')' ';'
|
||||||
|
{ pform_set_attrib(*$3, *$5, *$7);
|
||||||
|
delete $3;
|
||||||
|
delete $5;
|
||||||
|
delete $7;
|
||||||
|
}
|
||||||
|
| KK_attribute '(' error ')' ';'
|
||||||
|
{ yyerror(@1, "Misformed $attribute parameter list."); }
|
||||||
;
|
;
|
||||||
|
|
||||||
module_item_list
|
module_item_list
|
||||||
|
|
@ -480,11 +492,6 @@ port_type
|
||||||
| K_inout { $$ = NetNet::PINOUT; }
|
| K_inout { $$ = NetNet::PINOUT; }
|
||||||
;
|
;
|
||||||
|
|
||||||
primitive
|
|
||||||
: K_primitive IDENTIFIER '(' error ')' ';' K_endprimitive
|
|
||||||
{ yyerror(@1, "Sorry, primitives not supported."); }
|
|
||||||
;
|
|
||||||
|
|
||||||
range
|
range
|
||||||
: '[' const_expression ':' const_expression ']'
|
: '[' const_expression ':' const_expression ']'
|
||||||
{ list<PExpr*>*tmp = new list<PExpr*>;
|
{ list<PExpr*>*tmp = new list<PExpr*>;
|
||||||
|
|
@ -612,3 +619,49 @@ statement_opt
|
||||||
: statement
|
: statement
|
||||||
| ';' { $$ = 0; }
|
| ';' { $$ = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
udp_body
|
||||||
|
: K_table { lex_start_table(); }
|
||||||
|
udp_comb_entry_list
|
||||||
|
K_endtable { lex_end_table(); }
|
||||||
|
;
|
||||||
|
|
||||||
|
udp_comb_entry
|
||||||
|
: udp_input_list ':' udp_output_sym ';'
|
||||||
|
;
|
||||||
|
|
||||||
|
udp_comb_entry_list
|
||||||
|
: udp_comb_entry
|
||||||
|
| udp_comb_entry_list udp_comb_entry
|
||||||
|
;
|
||||||
|
|
||||||
|
udp_input_list
|
||||||
|
: udp_input_sym
|
||||||
|
| udp_input_list udp_input_sym
|
||||||
|
;
|
||||||
|
|
||||||
|
udp_input_sym : '0' | '1' | 'x' | 'X' | '?' | 'b' | 'B' ;
|
||||||
|
udp_output_sym : '0' | '1' | 'x' | 'X' ;
|
||||||
|
|
||||||
|
udp_port_decl
|
||||||
|
: K_input list_of_variables ';'
|
||||||
|
| K_output IDENTIFIER ';'
|
||||||
|
;
|
||||||
|
|
||||||
|
udp_port_decls
|
||||||
|
: udp_port_decl
|
||||||
|
| udp_port_decls udp_port_decl
|
||||||
|
;
|
||||||
|
|
||||||
|
udp_port_list
|
||||||
|
: IDENTIFIER { ; }
|
||||||
|
| udp_port_list ',' IDENTIFIER { ; }
|
||||||
|
;
|
||||||
|
|
||||||
|
udp_primitive
|
||||||
|
: K_primitive IDENTIFIER '(' udp_port_list ')' ';'
|
||||||
|
udp_port_decls
|
||||||
|
udp_body
|
||||||
|
K_endprimitive
|
||||||
|
{ yyerror(@1, "Sorry, UDP primitives not supported."); }
|
||||||
|
;
|
||||||
|
|
|
||||||
17
pform.cc
17
pform.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: pform.cc,v 1.3 1998/11/11 00:01:51 steve Exp $"
|
#ident "$Id: pform.cc,v 1.4 1998/11/23 00:20:23 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "pform.h"
|
# include "pform.h"
|
||||||
|
|
@ -195,6 +195,13 @@ void pform_set_port_type(const string&name, NetNet::PortType pt)
|
||||||
cur->port_type = pt;
|
cur->port_type = pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pform_set_attrib(const string&name, const string&key, const string&value)
|
||||||
|
{
|
||||||
|
PWire*cur = cur_module->get_wire(name);
|
||||||
|
assert(cur);
|
||||||
|
cur->attributes[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
static void pform_set_net_range(const string&name, list<PExpr*>*range)
|
static void pform_set_net_range(const string&name, list<PExpr*>*range)
|
||||||
{
|
{
|
||||||
assert(range->size() == 2);
|
assert(range->size() == 2);
|
||||||
|
|
@ -293,6 +300,14 @@ int pform_parse(FILE*input, list<Module*>&modules)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform.cc,v $
|
* $Log: pform.cc,v $
|
||||||
|
* Revision 1.4 1998/11/23 00:20:23 steve
|
||||||
|
* NetAssign handles lvalues as pin links
|
||||||
|
* instead of a signal pointer,
|
||||||
|
* Wire attributes added,
|
||||||
|
* Ability to parse UDP descriptions added,
|
||||||
|
* XNF generates EXT records for signals with
|
||||||
|
* the PAD attribute.
|
||||||
|
*
|
||||||
* Revision 1.3 1998/11/11 00:01:51 steve
|
* Revision 1.3 1998/11/11 00:01:51 steve
|
||||||
* Check net ranges in declarations.
|
* Check net ranges in declarations.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
12
pform.h
12
pform.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: pform.h,v 1.1 1998/11/03 23:29:04 steve Exp $"
|
#ident "$Id: pform.h,v 1.2 1998/11/23 00:20:23 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -85,6 +85,8 @@ extern void pform_makewire(const string&name, NetNet::Type type);
|
||||||
extern void pform_makewire(const list<string>*names, NetNet::Type type);
|
extern void pform_makewire(const list<string>*names, NetNet::Type type);
|
||||||
extern void pform_set_port_type(list<string>*names, NetNet::PortType);
|
extern void pform_set_port_type(list<string>*names, NetNet::PortType);
|
||||||
extern void pform_set_net_range(list<string>*names, list<PExpr*>*);
|
extern void pform_set_net_range(list<string>*names, list<PExpr*>*);
|
||||||
|
extern void pform_set_attrib(const string&name, const string&key,
|
||||||
|
const string&value);
|
||||||
extern void pform_make_behavior(PProcess::Type, Statement*);
|
extern void pform_make_behavior(PProcess::Type, Statement*);
|
||||||
extern Statement* pform_make_block(PBlock::BL_TYPE, list<Statement*>*);
|
extern Statement* pform_make_block(PBlock::BL_TYPE, list<Statement*>*);
|
||||||
extern Statement* pform_make_assignment(string*t, PExpr*e);
|
extern Statement* pform_make_assignment(string*t, PExpr*e);
|
||||||
|
|
@ -120,6 +122,14 @@ extern void pform_dump(ostream&out, Module*mod);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform.h,v $
|
* $Log: pform.h,v $
|
||||||
|
* Revision 1.2 1998/11/23 00:20:23 steve
|
||||||
|
* NetAssign handles lvalues as pin links
|
||||||
|
* instead of a signal pointer,
|
||||||
|
* Wire attributes added,
|
||||||
|
* Ability to parse UDP descriptions added,
|
||||||
|
* XNF generates EXT records for signals with
|
||||||
|
* the PAD attribute.
|
||||||
|
*
|
||||||
* Revision 1.1 1998/11/03 23:29:04 steve
|
* Revision 1.1 1998/11/03 23:29:04 steve
|
||||||
* Introduce verilog to CVS.
|
* Introduce verilog to CVS.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: pform_dump.cc,v 1.4 1998/11/11 03:13:04 steve Exp $"
|
#ident "$Id: pform_dump.cc,v 1.5 1998/11/23 00:20:23 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -130,6 +130,12 @@ void PWire::dump(ostream&out) const
|
||||||
}
|
}
|
||||||
|
|
||||||
out << name << ";" << endl;
|
out << name << ";" << endl;
|
||||||
|
for (map<string,string>::const_iterator idx = attributes.begin()
|
||||||
|
; idx != attributes.end()
|
||||||
|
; idx ++) {
|
||||||
|
out << " " << (*idx).first << " = \"" <<
|
||||||
|
(*idx).second << "\"" << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PGate::dump_pins(ostream&out) const
|
void PGate::dump_pins(ostream&out) const
|
||||||
|
|
@ -329,6 +335,14 @@ void pform_dump(ostream&out, Module*mod)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform_dump.cc,v $
|
* $Log: pform_dump.cc,v $
|
||||||
|
* Revision 1.5 1998/11/23 00:20:23 steve
|
||||||
|
* NetAssign handles lvalues as pin links
|
||||||
|
* instead of a signal pointer,
|
||||||
|
* Wire attributes added,
|
||||||
|
* Ability to parse UDP descriptions added,
|
||||||
|
* XNF generates EXT records for signals with
|
||||||
|
* the PAD attribute.
|
||||||
|
*
|
||||||
* Revision 1.4 1998/11/11 03:13:04 steve
|
* Revision 1.4 1998/11/11 03:13:04 steve
|
||||||
* Handle while loops.
|
* Handle while loops.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
30
t-verilog.cc
30
t-verilog.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: t-verilog.cc,v 1.1 1998/11/03 23:29:05 steve Exp $"
|
#ident "$Id: t-verilog.cc,v 1.2 1998/11/23 00:20:23 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -117,6 +117,9 @@ void target_verilog::logic(ostream&os, const NetLogic*net)
|
||||||
case NetLogic::OR:
|
case NetLogic::OR:
|
||||||
os << " or";
|
os << " or";
|
||||||
break;
|
break;
|
||||||
|
case NetLogic::XNOR:
|
||||||
|
os << " xnor";
|
||||||
|
break;
|
||||||
case NetLogic::XOR:
|
case NetLogic::XOR:
|
||||||
os << " xor";
|
os << " xor";
|
||||||
break;
|
break;
|
||||||
|
|
@ -166,9 +169,22 @@ void target_verilog::proc_assign(ostream&os, const NetAssign*net)
|
||||||
{
|
{
|
||||||
os << setw(indent_) << "";
|
os << setw(indent_) << "";
|
||||||
|
|
||||||
const NetNet*lval = net->lval();
|
const NetNet*lval;
|
||||||
|
unsigned msb, lsb;
|
||||||
|
net->find_lval_range(lval, msb, lsb);
|
||||||
|
|
||||||
os << mangle(lval->name()) << " = ";
|
if ((lsb == 0) && (msb == (lval->pin_count()-1))) {
|
||||||
|
os << mangle(lval->name());
|
||||||
|
|
||||||
|
} else if (msb == lsb) {
|
||||||
|
os << mangle(lval->name()) << "[" << msb << "]";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
os << mangle(lval->name()) << "[" << msb << ":" << lsb <<
|
||||||
|
"]";
|
||||||
|
}
|
||||||
|
|
||||||
|
os << " = ";
|
||||||
|
|
||||||
emit_expr_(os, net->rval());
|
emit_expr_(os, net->rval());
|
||||||
|
|
||||||
|
|
@ -291,6 +307,14 @@ const struct target tgt_verilog = {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: t-verilog.cc,v $
|
* $Log: t-verilog.cc,v $
|
||||||
|
* Revision 1.2 1998/11/23 00:20:23 steve
|
||||||
|
* NetAssign handles lvalues as pin links
|
||||||
|
* instead of a signal pointer,
|
||||||
|
* Wire attributes added,
|
||||||
|
* Ability to parse UDP descriptions added,
|
||||||
|
* XNF generates EXT records for signals with
|
||||||
|
* the PAD attribute.
|
||||||
|
*
|
||||||
* Revision 1.1 1998/11/03 23:29:05 steve
|
* Revision 1.1 1998/11/03 23:29:05 steve
|
||||||
* Introduce verilog to CVS.
|
* Introduce verilog to CVS.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
35
t-vvm.cc
35
t-vvm.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: t-vvm.cc,v 1.5 1998/11/10 00:48:31 steve Exp $"
|
#ident "$Id: t-vvm.cc,v 1.6 1998/11/23 00:20:23 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
|
|
@ -462,14 +462,23 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
|
||||||
{
|
{
|
||||||
string rval = emit_proc_rval(os, indent_, net->rval());
|
string rval = emit_proc_rval(os, indent_, net->rval());
|
||||||
|
|
||||||
os << setw(indent_) << "" << "// " << net->lval()->name() << " = ";
|
const NetNet*lval;
|
||||||
net->rval()->dump(os);
|
unsigned msb, lsb;
|
||||||
os << endl;
|
net->find_lval_range(lval, msb, lsb);
|
||||||
|
|
||||||
os << setw(indent_) << "" << mangle(net->lval()->name()) << " = "
|
if ((lsb == 0) && (msb == (lval->pin_count()-1))) {
|
||||||
<< rval << ";" << endl;
|
os << setw(indent_) << "" << "// " << lval->name()
|
||||||
|
<< " = ";
|
||||||
|
net->rval()->dump(os);
|
||||||
|
os << endl;
|
||||||
|
|
||||||
os << setw(indent_) << "" << mangle(net->lval()->name()) <<
|
os << setw(indent_) << "" << mangle(lval->name())
|
||||||
|
<< " = " << rval << ";" << endl;
|
||||||
|
} else {
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
os << setw(indent_) << "" << mangle(lval->name()) <<
|
||||||
"_mon.trigger(sim_);" << endl;
|
"_mon.trigger(sim_);" << endl;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -479,8 +488,8 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
|
||||||
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
|
||||||
const NetObj*cur;
|
const NetObj*cur;
|
||||||
unsigned pin;
|
unsigned pin;
|
||||||
for (net->lval()->pin(idx).next_link(cur, pin)
|
for (net->pin(idx).next_link(cur, pin)
|
||||||
; cur != net->lval()
|
; net->pin(idx) != cur->pin(pin)
|
||||||
; cur->pin(pin).next_link(cur, pin)) {
|
; cur->pin(pin).next_link(cur, pin)) {
|
||||||
|
|
||||||
// Skip NetAssign nodes. They are output-only.
|
// Skip NetAssign nodes. They are output-only.
|
||||||
|
|
@ -662,6 +671,14 @@ extern const struct target tgt_vvm = {
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
* $Log: t-vvm.cc,v $
|
* $Log: t-vvm.cc,v $
|
||||||
|
* Revision 1.6 1998/11/23 00:20:23 steve
|
||||||
|
* NetAssign handles lvalues as pin links
|
||||||
|
* instead of a signal pointer,
|
||||||
|
* Wire attributes added,
|
||||||
|
* Ability to parse UDP descriptions added,
|
||||||
|
* XNF generates EXT records for signals with
|
||||||
|
* the PAD attribute.
|
||||||
|
*
|
||||||
* Revision 1.5 1998/11/10 00:48:31 steve
|
* Revision 1.5 1998/11/10 00:48:31 steve
|
||||||
* Add support it vvm target for level-sensitive
|
* Add support it vvm target for level-sensitive
|
||||||
* triggers (i.e. the Verilog wait).
|
* triggers (i.e. the Verilog wait).
|
||||||
|
|
|
||||||
115
t-xnf.cc
115
t-xnf.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: t-xnf.cc,v 1.2 1998/11/18 04:25:22 steve Exp $"
|
#ident "$Id: t-xnf.cc,v 1.3 1998/11/23 00:20:24 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* XNF BACKEND
|
/* XNF BACKEND
|
||||||
|
|
@ -42,6 +42,7 @@ class target_xnf : public target_t {
|
||||||
public:
|
public:
|
||||||
void start_design(ostream&os, const Design*);
|
void start_design(ostream&os, const Design*);
|
||||||
void end_design(ostream&os, const Design*);
|
void end_design(ostream&os, const Design*);
|
||||||
|
void signal(ostream&os, const NetNet*);
|
||||||
void logic(ostream&os, const NetLogic*);
|
void logic(ostream&os, const NetLogic*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -81,9 +82,90 @@ void target_xnf::end_design(ostream&os, const Design*)
|
||||||
os << "EOF" << endl;
|
os << "EOF" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scrape_pad_info(string&str, char&dir, unsigned&num)
|
||||||
|
{
|
||||||
|
while (str[0] == ' ')
|
||||||
|
str = str.substr(1);
|
||||||
|
|
||||||
|
switch (str[0]) {
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
dir = 'B';
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
case 'O':
|
||||||
|
dir = 'O';
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
case 'I':
|
||||||
|
dir = 'I';
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
case 'T':
|
||||||
|
dir = 'T';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dir = '?';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = str.substr(1);
|
||||||
|
unsigned val = 0;
|
||||||
|
while (str.size() && isdigit(str[0])) {
|
||||||
|
val = val * 10 + (str[0]-'0');
|
||||||
|
str = str.substr(1);
|
||||||
|
}
|
||||||
|
num = val;
|
||||||
|
|
||||||
|
while (str.size() && str[0] == ' ')
|
||||||
|
str = str.substr(1);
|
||||||
|
|
||||||
|
if (str.size() && str[0] == ',')
|
||||||
|
str = str.substr(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look for signals that have attributes that are pertinent to XNF
|
||||||
|
* files. The most obvious are those that have the PAD attribute.
|
||||||
|
*
|
||||||
|
* Individual signals are easy, the pad description is a letter
|
||||||
|
* followed by a decimal number that is the pin.
|
||||||
|
*
|
||||||
|
* The PAD attribute for a vector is a comma separated pin
|
||||||
|
* descriptions, that enumerate the pins from most significant to
|
||||||
|
* least significant.
|
||||||
|
*/
|
||||||
|
void target_xnf::signal(ostream&os, const NetNet*net)
|
||||||
|
{
|
||||||
|
string pad = net->attribute("PAD");
|
||||||
|
if (pad != "") {
|
||||||
|
|
||||||
|
if (net->pin_count() == 1) {
|
||||||
|
char dir;
|
||||||
|
unsigned num;
|
||||||
|
scrape_pad_info(pad, dir, num);
|
||||||
|
os << "EXT, " << mangle(net->name()) << ", " << dir
|
||||||
|
<< ", " << num << endl;
|
||||||
|
|
||||||
|
} else for (unsigned idx = net->pin_count(); idx > 0; idx -= 1) {
|
||||||
|
|
||||||
|
char dir;
|
||||||
|
unsigned num;
|
||||||
|
scrape_pad_info(pad, dir, num);
|
||||||
|
os << "EXT, " << mangle(net->name()) << "<" << (idx-1)
|
||||||
|
<< ">, " << dir << ", " << num << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The logic gates I know so far can be translated directly into XNF
|
||||||
|
* standard symbol types. This is a fairly obvious transformation.
|
||||||
|
*/
|
||||||
void target_xnf::logic(ostream&os, const NetLogic*net)
|
void target_xnf::logic(ostream&os, const NetLogic*net)
|
||||||
{
|
{
|
||||||
os << "SYM," << net->name() << ", ";
|
os << "SYM, " << mangle(net->name()) << ", ";
|
||||||
switch (net->type()) {
|
switch (net->type()) {
|
||||||
case NetLogic::AND:
|
case NetLogic::AND:
|
||||||
os << "AND";
|
os << "AND";
|
||||||
|
|
@ -94,6 +176,9 @@ void target_xnf::logic(ostream&os, const NetLogic*net)
|
||||||
case NetLogic::NOR:
|
case NetLogic::NOR:
|
||||||
os << "NOR";
|
os << "NOR";
|
||||||
break;
|
break;
|
||||||
|
case NetLogic::NOT:
|
||||||
|
os << "INV";
|
||||||
|
break;
|
||||||
case NetLogic::OR:
|
case NetLogic::OR:
|
||||||
os << "OR";
|
os << "OR";
|
||||||
break;
|
break;
|
||||||
|
|
@ -104,7 +189,7 @@ void target_xnf::logic(ostream&os, const NetLogic*net)
|
||||||
os << "XOR";
|
os << "XOR";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
os << endl;
|
os << ", LIBVER=2.0.0" << endl;
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
|
||||||
unsigned cpin;
|
unsigned cpin;
|
||||||
|
|
@ -115,16 +200,20 @@ void target_xnf::logic(ostream&os, const NetLogic*net)
|
||||||
|
|
||||||
const NetNet*sig = dynamic_cast<const NetNet*>(cur);
|
const NetNet*sig = dynamic_cast<const NetNet*>(cur);
|
||||||
if (sig) {
|
if (sig) {
|
||||||
os << "PIN,";
|
os << " PIN, ";
|
||||||
if (idx == 0)
|
if (idx == 0) {
|
||||||
os << "O,O,";
|
os << "O, O, ";
|
||||||
else
|
} else {
|
||||||
os << "I" << idx-1 << ",I,";
|
os << "I";
|
||||||
|
if (net->pin_count() > 2)
|
||||||
|
os << idx-1;
|
||||||
|
os << ", I, ";
|
||||||
|
}
|
||||||
os << mangle(sig->name());
|
os << mangle(sig->name());
|
||||||
if (sig->pin_count() > 1)
|
if (sig->pin_count() > 1)
|
||||||
os << "<" << cpin << ">";
|
os << "<" << cpin << ">";
|
||||||
|
|
||||||
os << ",," << endl;
|
os << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -138,6 +227,14 @@ extern const struct target tgt_xnf = { "xnf", &target_xnf_obj };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: t-xnf.cc,v $
|
* $Log: t-xnf.cc,v $
|
||||||
|
* Revision 1.3 1998/11/23 00:20:24 steve
|
||||||
|
* NetAssign handles lvalues as pin links
|
||||||
|
* instead of a signal pointer,
|
||||||
|
* Wire attributes added,
|
||||||
|
* Ability to parse UDP descriptions added,
|
||||||
|
* XNF generates EXT records for signals with
|
||||||
|
* the PAD attribute.
|
||||||
|
*
|
||||||
* Revision 1.2 1998/11/18 04:25:22 steve
|
* Revision 1.2 1998/11/18 04:25:22 steve
|
||||||
* Add -f flags for generic flag key/values.
|
* Add -f flags for generic flag key/values.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue