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:
steve 1998-11-23 00:20:22 +00:00
parent 338240c37b
commit af8d6fbf01
14 changed files with 494 additions and 43 deletions

13
PWire.h
View File

@ -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.
* *

View File

@ -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

View File

@ -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,

View File

@ -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.
* *

View File

@ -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 },

View File

@ -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.
* *

View File

@ -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
View File

@ -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."); }
;

View File

@ -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
View File

@ -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.
* *

View File

@ -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.
* *

View File

@ -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.
* *

View File

@ -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
View File

@ -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.
* *