Add support for full_case attribute.

This commit is contained in:
steve 2006-07-10 00:21:49 +00:00
parent 62da6aca28
commit 22884f2e64
10 changed files with 171 additions and 41 deletions

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Statement.h,v 1.40 2004/02/20 18:53:33 steve Exp $"
#ident "$Id: Statement.h,v 1.40.2.1 2006/07/10 00:21:49 steve Exp $"
#endif
# include <string>
@ -71,12 +71,15 @@ class PProcess : public LineInfo {
* fact, the Statement class is abstract and represents all the
* possible kinds of statements that exist in Verilog.
*/
class Statement : public LineInfo {
class Statement : public LineInfo, public Attrib {
public:
Statement() { }
virtual ~Statement() =0;
map<perm_string,PExpr*> attributes;
void dump_attributes(ostream&out, unsigned ind) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
@ -456,6 +459,9 @@ class PWhile : public Statement {
/*
* $Log: Statement.h,v $
* Revision 1.40.2.1 2006/07/10 00:21:49 steve
* Add support for full_case attribute.
*
* Revision 1.40 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*

View File

@ -70,6 +70,14 @@ warning.)
* Other Attributes
(* ivl_full_case *)
This attribute only has meaning when attached to case statements,
and only when doing synthesis. The statement means to ignore the
possibility that some cases are not defined. Presume that the
device really is fully specified and do not emit any warnings
about missing guards.
[ none defined yet ]

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: design_dump.cc,v 1.149.2.5 2006/04/16 19:26:37 steve Exp $"
#ident "$Id: design_dump.cc,v 1.149.2.6 2006/07/10 00:21:50 steve Exp $"
#endif
# include "config.h"
@ -567,6 +567,8 @@ void NetCase::dump(ostream&o, unsigned ind) const
break;
}
dump_proc_attr(o, ind+2);
for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
o << setw(ind+2) << "";
if (items_[idx].guard)
@ -872,6 +874,15 @@ void NetProc::dump(ostream&o, unsigned ind) const
o << setw(ind) << "" << "// " << typeid(*this).name() << endl;
}
void NetProc::dump_proc_attr(ostream&o, unsigned ind) const
{
unsigned idx;
for (idx = 0 ; idx < attr_cnt() ; idx += 1) {
o << setw(ind) << "" << "(* " << attr_key(idx) << " = "
<< attr_value(idx) << " *)" << endl;
}
}
/* Dump an expression that no one wrote a dump method for. */
void NetExpr::dump(ostream&o) const
{
@ -1119,6 +1130,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.149.2.6 2006/07/10 00:21:50 steve
* Add support for full_case attribute.
*
* Revision 1.149.2.5 2006/04/16 19:26:37 steve
* Fix handling of exploded memories with partial or missing resets.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elaborate.cc,v 1.308.2.3 2006/06/12 00:16:51 steve Exp $"
#ident "$Id: elaborate.cc,v 1.308.2.4 2006/07/10 00:21:50 steve Exp $"
#endif
# include "config.h"
@ -67,6 +67,21 @@ void PGate::elaborate(Design*des, NetScope*scope) const
typeid(*this).name() << endl;
}
void process_attributes(Design*des, NetScope*scope,
Attrib*dest, const map<perm_string,PExpr*>&table)
{
struct attrib_list_t*attrib_list = 0;
unsigned attrib_list_n = 0;
attrib_list = evaluate_attributes(table, attrib_list_n,
des, scope);
for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1)
dest->attribute(attrib_list[adx].key,
attrib_list[adx].val);
delete[]attrib_list;
}
/*
* Elaborate the continuous assign. (This is *not* the procedural
* assign.) Elaborate the lvalue and rvalue, and do the assignment.
@ -1391,6 +1406,7 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
NetCase*res = new NetCase(type_, expr, icount);
res->set_line(*this);
process_attributes(des, scope, res, attributes);
/* Iterate over all the case items (guard/statement pairs)
elaborating them. If the guard has no expression, then this
@ -2785,6 +2801,9 @@ Design* elaborate(list<perm_string>roots)
/*
* $Log: elaborate.cc,v $
* Revision 1.308.2.4 2006/07/10 00:21:50 steve
* Add support for full_case attribute.
*
* Revision 1.308.2.3 2006/06/12 00:16:51 steve
* Add support for -Wunused warnings.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.h,v 1.321.2.19 2006/06/23 03:49:46 steve Exp $"
#ident "$Id: netlist.h,v 1.321.2.20 2006/07/10 00:21:51 steve Exp $"
#endif
/*
@ -1438,7 +1438,7 @@ class NetUDP : public NetNode {
* linked into the netlist. However, elaborating a process may cause
* special nodes to be created to handle things like events.
*/
class NetProc : public virtual LineInfo {
class NetProc : public virtual LineInfo, public Attrib {
public:
explicit NetProc();
@ -1495,6 +1495,7 @@ class NetProc : public virtual LineInfo {
const svector<NetEvProbe*>&events);
virtual void dump(ostream&, unsigned ind) const;
void dump_proc_attr(ostream&, unsigned ind) const;
private:
friend class NetBlock;
@ -3536,6 +3537,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.321.2.20 2006/07/10 00:21:51 steve
* Add support for full_case attribute.
*
* Revision 1.321.2.19 2006/06/23 03:49:46 steve
* synthesis of NetCondit handles partial resets.
*

63
parse.y
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: parse.y,v 1.201.2.3 2006/02/07 22:45:54 steve Exp $"
#ident "$Id: parse.y,v 1.201.2.4 2006/07/10 00:21:52 steve Exp $"
#endif
# include "config.h"
@ -308,17 +308,14 @@ attribute
integers. This rule matches those declarations. The containing
rule has presumably set up the scope. */
block_item_decl
: attribute_list_opt K_reg signed_opt range register_variable_list ';'
{ pform_set_net_range($5, $4, $3);
if ($1) delete $1;
: K_reg signed_opt range register_variable_list ';'
{ pform_set_net_range($4, $3, $2);
}
| attribute_list_opt K_reg signed_opt register_variable_list ';'
{ pform_set_net_range($4, 0, $3);
if ($1) delete $1;
| K_reg signed_opt register_variable_list ';'
{ pform_set_net_range($3, 0, $2);
}
| attribute_list_opt K_integer register_variable_list ';'
{ pform_set_reg_integer($3);
if ($1) delete $1;
| K_integer register_variable_list ';'
{ pform_set_reg_integer($2);
}
| K_time register_variable_list ';'
{ pform_set_reg_time($2);
@ -335,15 +332,13 @@ block_item_decl
/* Recover from errors that happen within variable lists. Use the
trailing semi-colon to resync the parser. */
| attribute_list_opt K_reg error ';'
{ yyerror(@2, "error: syntax error in reg variable list.");
| K_reg error ';'
{ yyerror(@1, "error: syntax error in reg variable list.");
yyerrok;
if ($1) delete $1;
}
| attribute_list_opt K_integer error ';'
{ yyerror(@2, "error: syntax error in integer variable list.");
| K_integer error ';'
{ yyerror(@1, "error: syntax error in integer variable list.");
yyerrok;
if ($1) delete $1;
}
| K_time error ';'
{ yyerror(@1, "error: syntax error in time variable list.");
@ -2548,9 +2543,9 @@ statement
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| K_begin error K_end
/* | K_begin error K_end
{ yyerrok; }
*/
/* fork-join blocks are very similar to begin-end blocks. In fact,
from the parser's perspective there is no real difference. All we
need to do is remember that this is a parallel block so that the
@ -2697,28 +2692,34 @@ statement
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| event_control statement_opt
| event_control attribute_list_opt statement_opt
{ PEventStatement*tmp = $1;
if (tmp == 0) {
yyerror(@1, "error: Invalid event control.");
$$ = 0;
} else {
tmp->set_statement($2);
pform_attach_attributes($3, $2);
tmp->set_statement($3);
$$ = tmp;
}
if ($2) delete $2;
}
| '@' '*' statement_opt
| '@' '*' attribute_list_opt statement_opt
{ PEventStatement*tmp = new PEventStatement;
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
tmp->set_statement($3);
pform_attach_attributes($4, $3);
tmp->set_statement($4);
if ($3) delete $3;
$$ = tmp;
}
| '@' '(' '*' ')' statement_opt
| '@' '(' '*' ')' attribute_list_opt statement_opt
{ PEventStatement*tmp = new PEventStatement;
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
tmp->set_statement($5);
pform_attach_attributes($6, $5);
tmp->set_statement($6);
if ($5) delete $5;
$$ = tmp;
}
| lpvalue '=' expression ';'
@ -2827,14 +2828,18 @@ statement
;
statement_list
: statement_list statement
{ svector<Statement*>*tmp = new svector<Statement*>(*$1, $2);
: statement_list attribute_list_opt statement
{ pform_attach_attributes($3, $2);
svector<Statement*>*tmp = new svector<Statement*>(*$1, $3);
delete $1;
if ($2) delete $2;
$$ = tmp;
}
| statement
{ svector<Statement*>*tmp = new svector<Statement*>(1);
(*tmp)[0] = $1;
| attribute_list_opt statement
{ pform_attach_attributes($2, $1);
svector<Statement*>*tmp = new svector<Statement*>(1);
(*tmp)[0] = $2;
if ($1) delete $1;
$$ = tmp;
}
;

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: pform.cc,v 1.129 2004/10/04 01:10:55 steve Exp $"
#ident "$Id: pform.cc,v 1.129.2.1 2006/07/10 00:21:53 steve Exp $"
#endif
# include "config.h"
@ -203,6 +203,19 @@ verinum* pform_verinum_with_size(verinum*siz, verinum*val,
return res;
}
void pform_attach_attributes(Statement*obj, svector<named_pexpr_t*>*attr)
{
if (obj == 0)
return;
if (attr == 0)
return;
for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) {
named_pexpr_t*tmp = (*attr)[idx];
obj->attributes[tmp->name] = tmp->parm;
}
}
void pform_startmodule(const char*name, const char*file, unsigned lineno,
svector<named_pexpr_t*>*attr)
{
@ -1597,6 +1610,9 @@ int pform_parse(const char*path, FILE*file)
/*
* $Log: pform.cc,v $
* Revision 1.129.2.1 2006/07/10 00:21:53 steve
* Add support for full_case attribute.
*
* Revision 1.129 2004/10/04 01:10:55 steve
* Clean up spurious trailing white space.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: pform.h,v 1.81 2004/08/26 04:02:04 steve Exp $"
#ident "$Id: pform.h,v 1.81.2.1 2006/07/10 00:21:53 steve Exp $"
#endif
# include "netlist.h"
@ -219,6 +219,8 @@ extern void pform_set_attrib(perm_string name, perm_string key,
extern void pform_set_type_attrib(perm_string name, const string&key,
char*value);
extern void pform_attach_attributes(Statement*obj, svector<named_pexpr_t*>*attr);
extern void pform_set_parameter(perm_string name,
bool signed_flag,
svector<PExpr*>*range,
@ -298,6 +300,9 @@ extern void pform_dump(ostream&out, Module*mod);
/*
* $Log: pform.h,v $
* Revision 1.81.2.1 2006/07/10 00:21:53 steve
* Add support for full_case attribute.
*
* Revision 1.81 2004/08/26 04:02:04 steve
* Add support for localparam ranges.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: pform_dump.cc,v 1.88 2004/10/04 01:10:55 steve Exp $"
#ident "$Id: pform_dump.cc,v 1.88.2.1 2006/07/10 00:21:54 steve Exp $"
#endif
# include "config.h"
@ -418,6 +418,19 @@ void Statement::dump(ostream&out, unsigned ind) const
out << setw(ind) << "";
out << "/* " << get_line() << ": " << typeid(*this).name()
<< " */ ;" << endl;
dump_attributes(out, ind+2);
}
void Statement::dump_attributes(ostream&out, unsigned ind) const
{
for (map<perm_string,PExpr*>::const_iterator idx = attributes.begin()
; idx != attributes.end()
; idx ++) {
out << setw(ind) << "" << "(* " << (*idx).first;
if ((*idx).second)
out << " = " << *(*idx).second;
out << " *)" << endl;
}
}
void PAssign::dump(ostream&out, unsigned ind) const
@ -487,6 +500,8 @@ void PCase::dump(ostream&out, unsigned ind) const
}
out << " (" << *expr_ << ") /* " << get_line() << " */" << endl;
dump_attributes(out, ind+2);
for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) {
PCase::Item*cur = (*items_)[idx];
@ -909,6 +924,9 @@ void PUdp::dump(ostream&out) const
/*
* $Log: pform_dump.cc,v $
* Revision 1.88.2.1 2006/07/10 00:21:54 steve
* Add support for full_case attribute.
*
* Revision 1.88 2004/10/04 01:10:55 steve
* Clean up spurious trailing white space.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: synth2.cc,v 1.39.2.38 2006/07/02 00:50:15 steve Exp $"
#ident "$Id: synth2.cc,v 1.39.2.39 2006/07/10 00:21:54 steve Exp $"
#endif
# include "config.h"
@ -444,6 +444,10 @@ bool NetCase::synth_async(Design*des, NetScope*scope, bool sync_flag,
NetNet*esig = expr_->synthesize(des);
bool full_case_flag = false;
if (attribute(perm_string::literal("ivl_full_case")).len() > 0)
full_case_flag = true;
/* Scan the select vector looking for constant bits. The
constant bits will be elided from the select input connect,
but we still need to keep track of them. */
@ -632,7 +636,7 @@ bool NetCase::synth_async(Design*des, NetScope*scope, bool sync_flag,
default_sig = sig;
}
if (statement_map[item] == 0 && !sync_flag) {
if (statement_map[item] == 0 && !sync_flag && !full_case_flag) {
/* Missing case and no default; this could still be
* synthesizable with synchronous logic, but not here. */
cerr << get_line()
@ -645,7 +649,35 @@ bool NetCase::synth_async(Design*des, NetScope*scope, bool sync_flag,
continue;
}
if (statement_map[item] == 0) {
if (statement_map[item] == 0 && !sync_flag) {
assert(full_case_flag);
/* Cases that should never happen, we connect to
0 bits. Hopefully, the target (or constant
propagation) will know how to optimize this
away. */
NetConst*zero = new NetConst(scope, scope->local_symbol(),
verinum::V0);
zero->set_line(*this);
des->add_node(zero);
NetNet*zsig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, 1);
zsig->local_flag(true);
zsig->set_line(*this);
connect(zsig->pin(0), zero->pin(0));
for (unsigned idx=0; idx < mux->width(); idx += 1)
connect(mux->pin_Data(idx,item), zsig->pin(0));
if (debug_synth) {
cerr << get_line()
<< ": debug: Case item " << item << " is set to"
<< " zero in combinational process." << endl;
}
} else if (statement_map[item] == 0) {
/* If this is an unspecified case, then get the
input from the synchronous output. Note that we
@ -2179,6 +2211,9 @@ void synth2(Design*des)
/*
* $Log: synth2.cc,v $
* Revision 1.39.2.39 2006/07/10 00:21:54 steve
* Add support for full_case attribute.
*
* Revision 1.39.2.38 2006/07/02 00:50:15 steve
* Properly synthesize casex statements.
*