From 1464851e0e8747a4d6f23f1993129ae4ab1f9795 Mon Sep 17 00:00:00 2001 From: steve Date: Wed, 9 Jun 1999 03:00:05 +0000 Subject: [PATCH] Add support for procedural concatenation expression. --- PExpr.h | 6 ++++- README.txt | 71 +++++++++++++++++++++++++++++++++++++++++++++++--- design_dump.cc | 13 ++++++++- elaborate.cc | 25 +++++++++++++++--- emit.cc | 10 ++++++- netlist.cc | 39 ++++++++++++++++++++++++++- netlist.h | 35 ++++++++++++++++++++++++- parse.y | 20 +++++++------- t-vvm.cc | 31 +++++++++++++++++++++- target.cc | 17 +++++++++--- target.h | 6 ++++- 11 files changed, 245 insertions(+), 28 deletions(-) diff --git a/PExpr.h b/PExpr.h index 3d051992c..9ea985bf6 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: PExpr.h,v 1.9 1999/05/16 05:08:42 steve Exp $" +#ident "$Id: PExpr.h,v 1.10 1999/06/09 03:00:05 steve Exp $" #endif # include @@ -75,6 +75,7 @@ class PEConcat : public PExpr { virtual void dump(ostream&) const; virtual NetNet* elaborate_net(Design*des, const string&path) const; + virtual NetExpr*elaborate_expr(Design*des, const string&path) const; private: svectorparms_; @@ -196,6 +197,9 @@ class PEBinary : public PExpr { /* * $Log: PExpr.h,v $ + * Revision 1.10 1999/06/09 03:00:05 steve + * Add support for procedural concatenation expression. + * * Revision 1.9 1999/05/16 05:08:42 steve * Redo constant expression detection to happen * after parsing. diff --git a/README.txt b/README.txt index 6be60f174..74e24ada4 100644 --- a/README.txt +++ b/README.txt @@ -223,10 +223,73 @@ IVL is in development - as such it still only supports a (growing) subset of verilog. Below is a description of some of the currently unsupported verilog features. - - Lvalue bit ranges - Example: regvalue [7:3] = 5'b0; + - Lvalue bit ranges, i.e. values being assigned to. Examples: - - Complex delay expressions, specifically min,typ,max expressions. + regval [3:1] = 3'b0; + regval [7:0] = 8'b0; - - Tasks/functions + - Task Enabling isn't implemented: + Example: always @(value) // This isn't available yet. + begin + $display("value changed"); + end + + - The "?" operator. Example: count = val ? 1 : 0; + + - Ranges within parameter definitions: + Example: parameter [15:0] seed = 16'ha3; + + - The "&&" operator: + Example: if (a && 0) do = 1; + + - Concatenation: b = { a , 4'hd }; + + - The "===" operator: Example: if( a === b) do = 1; + + - The ">=" operator: Example: if ( a >= 0) do = 1; + + - The ">" operator: Example: if ( a > 0) do = 1; + + - The "<=" operator: Example: if ( a <= 0) do = 1; + + - The "<<" shift operator: Example: a = 8'b0000_0010 << 1; + + - Min/Typ/Max assignments: Example: a = (1 : 6 : 14); + + - Inversion of a vector with a bit operator: + Example: reg [7:0] a; a = !(8'h01); + + - The "!==" operator: Example: if( a !== b) do = 1; + + - Expansion of a string into a larger variable: + Example: reg [0:15] b; b = "b"; + + - Function declarations/calls. + + - Integer data type. + + - Non-scalar memories, i.e. other than registers. + Example: reg [1:0] b [2:0]; + + - Delay list. Example: sample #(9,99) sample1(a,b); + + - Bit ranges within IF. Example: if (a[2:3]) do = 1; + + - List of targets for case statement: + Example: + case (a) // Not Okay - 1, 2, and 3 must be separate lines. + 1, 2, 3: $write("selected 1, 2, 3 (Not Ok)\n"); + endcase + + - Forever key word. + + - Repeat key word. + + - Assignment timing delay: Example: a = #1 0; #1 a = #2 ~a; + + - Bit Ranges within $write, $display. + + - `timescale directive + + - Task declarations/calls. - - Other things I forgot to mention. diff --git a/design_dump.cc b/design_dump.cc index 45948bd74..c28e8de92 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: design_dump.cc,v 1.27 1999/06/06 20:45:38 steve Exp $" +#ident "$Id: design_dump.cc,v 1.28 1999/06/09 03:00:05 steve Exp $" #endif /* @@ -522,6 +522,14 @@ void NetEBinary::dump(ostream&o) const o << ")"; } +void NetEConcat::dump(ostream&o) const +{ + o << "{" << *parms_[0]; + for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) + o << ", " << *parms_[idx]; + o << "}"; +} + void NetEConst::dump(ostream&o) const { if (value_.is_string()) @@ -622,6 +630,9 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.28 1999/06/09 03:00:05 steve + * Add support for procedural concatenation expression. + * * Revision 1.27 1999/06/06 20:45:38 steve * Add parse and elaboration of non-blocking assignments, * Replace list with an svector version, diff --git a/elaborate.cc b/elaborate.cc index d92ab9d63..68cb4be5b 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: elaborate.cc,v 1.37 1999/06/09 00:58:06 steve Exp $" +#ident "$Id: elaborate.cc,v 1.38 1999/06/09 03:00:06 steve Exp $" #endif /* @@ -564,13 +564,13 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path) const NetNet*lsig = left_->elaborate_net(des, path), *rsig = right_->elaborate_net(des, path); if (lsig == 0) { - cerr << "Cannot elaborate "; + cerr << get_line() << ": Cannot elaborate "; left_->dump(cerr); cerr << endl; return 0; } if (rsig == 0) { - cerr << "Cannot elaborate "; + cerr << get_line() << ": Cannot elaborate "; right_->dump(cerr); cerr << endl; return 0; @@ -822,6 +822,19 @@ NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const return tmp; } +NetExpr* PEConcat::elaborate_expr(Design*des, const string&path) const +{ + NetEConcat*tmp = new NetEConcat(parms_.count()); + tmp->set_line(*this); + + for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { + assert(parms_[idx]); + tmp->set(idx, parms_[idx]->elaborate_expr(des, path)); + } + + return tmp; +} + NetExpr* PENumber::elaborate_expr(Design*des, const string&path) const { assert(value_); @@ -899,7 +912,8 @@ NetExpr*PEIdent::elaborate_expr(Design*des, const string&path) const NetExpr* PExpr::elaborate_expr(Design*des, const string&path) const { - cerr << "Cannot elaborate expression: " << *this << endl; + cerr << get_line() << ": I do not know how to elaborate expression: " + << *this << endl; return 0; } @@ -1382,6 +1396,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.38 1999/06/09 03:00:06 steve + * Add support for procedural concatenation expression. + * * Revision 1.37 1999/06/09 00:58:06 steve * Support for binary | (Stephen Tell) * diff --git a/emit.cc b/emit.cc index 36b6c6ff1..d95979e24 100644 --- a/emit.cc +++ b/emit.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: emit.cc,v 1.12 1999/06/06 20:45:38 steve Exp $" +#ident "$Id: emit.cc,v 1.13 1999/06/09 03:00:06 steve Exp $" #endif /* @@ -219,6 +219,11 @@ void NetEBinary::expr_scan(struct expr_scan_t*tgt) const tgt->expr_binary(this); } +void NetEConcat::expr_scan(struct expr_scan_t*tgt) const +{ + tgt->expr_concat(this); +} + void NetEConst::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_const(this); @@ -268,6 +273,9 @@ void emit(ostream&o, const Design*des, const char*type) /* * $Log: emit.cc,v $ + * Revision 1.13 1999/06/09 03:00:06 steve + * Add support for procedural concatenation expression. + * * Revision 1.12 1999/06/06 20:45:38 steve * Add parse and elaboration of non-blocking assignments, * Replace list with an svector version, diff --git a/netlist.cc b/netlist.cc index 0c50e946f..5d3996b9d 100644 --- a/netlist.cc +++ b/netlist.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: netlist.cc,v 1.33 1999/06/07 02:23:31 steve Exp $" +#ident "$Id: netlist.cc,v 1.34 1999/06/09 03:00:06 steve Exp $" #endif # include @@ -562,6 +562,40 @@ NetExpr* NetEBinary::eval_tree() } } +NetEConcat::NetEConcat(unsigned cnt) +: parms_(cnt) +{ +} + +NetEConcat::~NetEConcat() +{ + for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) + delete parms_[idx]; +} + +void NetEConcat::set(unsigned idx, NetExpr*e) +{ + assert(idx < parms_.count()); + assert(parms_[idx] == 0); + parms_[idx] = e; +} + +bool NetEConcat::set_width(unsigned w) +{ + unsigned sum = 0; + for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) + sum += parms_[idx]->expr_width(); + + if (sum != w) return false; + expr_width(w); + return true; +} + +NetEConcat* NetEConcat::dup_expr() const +{ + assert(0); +} + NetEConst::~NetEConst() { } @@ -1164,6 +1198,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.34 1999/06/09 03:00:06 steve + * Add support for procedural concatenation expression. + * * Revision 1.33 1999/06/07 02:23:31 steve * Support non-blocking assignment down to vvm. * diff --git a/netlist.h b/netlist.h index 316646ddb..93f0481c1 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: netlist.h,v 1.36 1999/06/06 20:45:38 steve Exp $" +#ident "$Id: netlist.h,v 1.37 1999/06/09 03:00:06 steve Exp $" #endif /* @@ -929,6 +929,36 @@ class NetEBinary : public NetExpr { NetExpr* right_; }; +/* + * This expression node supports the concat expression. This is an + * operator that just glues the results of many expressions into a + * single value. + * + * Note that the class stores the parameter expressions in source code + * order. That is, the parm(0) is placed in the most significant + * position of the result. + */ +class NetEConcat : public NetExpr { + + public: + NetEConcat(unsigned cnt); + ~NetEConcat(); + + // Manipulate the parameters. + void set(unsigned idx, NetExpr*e); + + unsigned nparms() const { return parms_.count() ; } + NetExpr* parm(unsigned idx) const { return parms_[idx]; } + + virtual bool set_width(unsigned w); + virtual NetEConcat* dup_expr() const; + virtual void expr_scan(struct expr_scan_t*) const; + virtual void dump(ostream&) const; + + private: + svectorparms_; +}; + class NetEConst : public NetExpr { public: @@ -1207,6 +1237,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.37 1999/06/09 03:00:06 steve + * Add support for procedural concatenation expression. + * * Revision 1.36 1999/06/06 20:45:38 steve * Add parse and elaboration of non-blocking assignments, * Replace list with an svector version, diff --git a/parse.y b/parse.y index 380dfcbe0..2f5f204f6 100644 --- a/parse.y +++ b/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: parse.y,v 1.33 1999/06/06 20:45:39 steve Exp $" +#ident "$Id: parse.y,v 1.34 1999/06/09 03:00:06 steve Exp $" #endif # include "parse_misc.h" @@ -289,10 +289,10 @@ event_expression expression : expr_primary { $$ = $1; } - | '(' expression ')' - { $$ = $2; } | '{' expression_list '}' { PEConcat*tmp = new PEConcat(*$2); + tmp->set_file(@2.text); + tmp->set_lineno(@2.first_line); delete $2; $$ = tmp; } @@ -462,12 +462,6 @@ expression { yyerror(@2, "Sorry, ?: operator not supported."); $$ = 0; } - | '(' expression ':' expression ':' expression ')' - { yyerror(@2, "Sorry, (min:typ:max) not supported."); - $$ = $4; - delete $2; - delete $6; - } | IDENTIFIER '(' expression_list ')' { yyerror(@2, "Sorry, function calls not supported."); $$ = 0; @@ -545,6 +539,14 @@ expr_primary delete $1; $$ = tmp; } + | '(' expression ')' + { $$ = $2; } + | '(' expression ':' expression ':' expression ')' + { yyerror(@2, "Sorry, (min:typ:max) not supported."); + $$ = $4; + delete $2; + delete $6; + } ; diff --git a/t-vvm.cc b/t-vvm.cc index 916769001..764a2ce74 100644 --- a/t-vvm.cc +++ b/t-vvm.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: t-vvm.cc,v 1.22 1999/06/07 02:23:31 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.23 1999/06/09 03:00:06 steve Exp $" #endif # include @@ -93,6 +93,7 @@ class vvm_proc_rval : public expr_scan_t { private: virtual void expr_const(const NetEConst*); + virtual void expr_concat(const NetEConcat*); virtual void expr_ident(const NetEIdent*); virtual void expr_memory(const NetEMemory*mem) { @@ -109,6 +110,31 @@ class vvm_proc_rval : public expr_scan_t { virtual void expr_binary(const NetEBinary*); }; +void vvm_proc_rval::expr_concat(const NetEConcat*expr) +{ + string tname = make_temp(); + os_ << setw(indent_) << "" << "vvm_bitset_t<" << + expr->expr_width() << "> " << tname << ";" << endl; + + unsigned pos = 0; + for (unsigned idx = 0 ; idx < expr->nparms() ; idx += 1) { + + NetExpr*pp = expr->parm(expr->nparms() - idx - 1); + pp->expr_scan(this); + + for (unsigned bit = 0 ; bit < pp->expr_width() ; bit += 1) { + os_ << setw(indent_) << "" << tname << "[" << pos << + "] = " << result << "[" << bit << "];" << + endl; + pos+= 1; + } + assert(pos <= expr->expr_width()); + } + assert(pos == expr->expr_width()); + + result = tname; +} + void vvm_proc_rval::expr_const(const NetEConst*expr) { string tname = make_temp(); @@ -1121,6 +1147,9 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.23 1999/06/09 03:00:06 steve + * Add support for procedural concatenation expression. + * * Revision 1.22 1999/06/07 02:23:31 steve * Support non-blocking assignment down to vvm. * diff --git a/target.cc b/target.cc index a8c72d307..105dcfb4d 100644 --- a/target.cc +++ b/target.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: target.cc,v 1.10 1999/06/06 20:45:39 steve Exp $" +#ident "$Id: target.cc,v 1.11 1999/06/09 03:00:06 steve Exp $" #endif # include "target.h" @@ -164,10 +164,16 @@ void expr_scan_t::expr_const(const NetEConst*) "unhandled expr_const." << endl; } -void expr_scan_t::expr_ident(const NetEIdent*) +void expr_scan_t::expr_concat(const NetEConcat*that) { - cerr << "expr_scan_t (" << typeid(*this).name() << "): " - "unhandled expr_ident." << endl; + cerr << that->get_line() << ": expr_scan_t (" << + typeid(*this).name() << "): unhandled expr_concat." << endl; +} + +void expr_scan_t::expr_ident(const NetEIdent*that) +{ + cerr << that->get_line() << ": expr_scan_t (" << + typeid(*this).name() << "): unhandled expr_ident." << endl; } void expr_scan_t::expr_memory(const NetEMemory*) @@ -202,6 +208,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex) /* * $Log: target.cc,v $ + * Revision 1.11 1999/06/09 03:00:06 steve + * Add support for procedural concatenation expression. + * * Revision 1.10 1999/06/06 20:45:39 steve * Add parse and elaboration of non-blocking assignments, * Replace list with an svector version, diff --git a/target.h b/target.h index ca635336d..fcab2c550 100644 --- a/target.h +++ b/target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: target.h,v 1.10 1999/06/06 20:45:39 steve Exp $" +#ident "$Id: target.h,v 1.11 1999/06/09 03:00:06 steve Exp $" #endif # include "netlist.h" @@ -99,6 +99,7 @@ struct target_t { struct expr_scan_t { virtual ~expr_scan_t(); virtual void expr_const(const NetEConst*); + virtual void expr_concat(const NetEConcat*); virtual void expr_ident(const NetEIdent*); virtual void expr_memory(const NetEMemory*); virtual void expr_signal(const NetESignal*); @@ -124,6 +125,9 @@ extern const struct target *target_table[]; /* * $Log: target.h,v $ + * Revision 1.11 1999/06/09 03:00:06 steve + * Add support for procedural concatenation expression. + * * Revision 1.10 1999/06/06 20:45:39 steve * Add parse and elaboration of non-blocking assignments, * Replace list with an svector version,