diff --git a/ivl_target.h b/ivl_target.h index 76a58a4be..a9c96f594 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: ivl_target.h,v 1.59 2001/05/08 04:13:12 steve Exp $" +#ident "$Id: ivl_target.h,v 1.60 2001/05/08 23:59:33 steve Exp $" #endif #ifdef __cplusplus @@ -410,8 +410,10 @@ extern unsigned ivl_expr_width(ivl_expr_t net); * */ -extern char*ivl_memory_name(ivl_memory_t net); -extern unsigned ivl_memory_root(ivl_memory_t net); +extern const char*ivl_memory_name(ivl_memory_t net); +extern const char*ivl_memory_basename(ivl_memory_t net); +extern int ivl_memory_root(ivl_memory_t net); +extern unsigned ivl_memory_size(ivl_memory_t net); extern unsigned ivl_memory_width(ivl_memory_t net); extern ivl_memory_t ivl_expr_memory(ivl_expr_t net); @@ -514,16 +516,27 @@ extern unsigned ivl_lpm_size(ivl_lpm_t net); * ivl_lval_mux * If the l-value includes a bit select expression, this method * returns an ivl_expr_t that represents that - * expression. Otherwise, it returns 0. + * expression. Otherwise, it returns 0. + * + * ivl_lval_mem + * If the l-value is a memory, this method returns an + * ivl_memory_t that represents that memory. Otherwise, it + * returns 0. + * + * ivl_lval_idx + * If the l-value is a memory, this method returns an + * ivl_expr_t that represents the index expression. Otherwise, it + * returns 0. * * ivl_lval_pin * Return an ivl_nexus_t for the connection of the ivl_lval_t. * * ivl_lval_pins - * Return the number of pins for this object. - */ + * Return the number of pins for this object. */ extern ivl_expr_t ivl_lval_mux(ivl_lval_t net); +extern ivl_expr_t ivl_lval_idx(ivl_lval_t net); +extern ivl_memory_t ivl_lval_mem(ivl_lval_t net); extern unsigned ivl_lval_pins(ivl_lval_t net); extern ivl_nexus_t ivl_lval_pin(ivl_lval_t net, unsigned idx); @@ -661,6 +674,8 @@ extern unsigned ivl_scope_logs(ivl_scope_t net); extern ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx); extern unsigned ivl_scope_lpms(ivl_scope_t net); extern ivl_lpm_t ivl_scope_lpm(ivl_scope_t, unsigned idx); +extern unsigned ivl_scope_mems(ivl_scope_t net); +extern ivl_memory_t ivl_scope_mem(ivl_scope_t net, unsigned idx); extern const char* ivl_scope_name(ivl_scope_t net); extern unsigned ivl_scope_ports(ivl_scope_t net); extern const char* ivl_scope_port(ivl_scope_t net, unsigned idx); @@ -824,6 +839,10 @@ _END_DECL /* * $Log: ivl_target.h,v $ + * Revision 1.60 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.59 2001/05/08 04:13:12 steve * sort enumeration values. * diff --git a/netlist.h b/netlist.h index 627339438..c39f6843c 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) && !defined(macintosh) -#ident "$Id: netlist.h,v 1.205 2001/04/29 20:19:10 steve Exp $" +#ident "$Id: netlist.h,v 1.206 2001/05/08 23:59:33 steve Exp $" #endif /* @@ -636,8 +636,8 @@ class NetMemory { // This is the width (in bits) of a single memory position. unsigned width() const { return width_; } - NetScope*scope(); - const NetScope*scope() const; + // NetScope*scope(); + const NetScope*scope() const { return scope_; }; // This is the number of memory positions. unsigned count() const; @@ -2434,6 +2434,8 @@ class NetEMemory : public NetExpr { virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(ostream&) const; + const NetMemory*memory() const { return mem_; }; + private: NetMemory*mem_; NetExpr* idx_; @@ -2807,6 +2809,10 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.206 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.205 2001/04/29 20:19:10 steve * Add pullup and pulldown devices. * diff --git a/t-dll-api.cc b/t-dll-api.cc index 62a7c4c48..8bfac30cd 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll-api.cc,v 1.43 2001/05/06 17:48:20 steve Exp $" +#ident "$Id: t-dll-api.cc,v 1.44 2001/05/08 23:59:33 steve Exp $" #endif # include "t-dll.h" @@ -55,16 +55,33 @@ extern "C" ivl_expr_type_t ivl_expr_type(ivl_expr_t net) } -extern "C" char*ivl_memory_name(ivl_memory_t net) +inline static const char *basename(ivl_scope_t scope, const char *inst) +{ + inst += strlen(ivl_scope_name(scope)); + assert(*inst == '.'); + return inst+1; +} + +extern "C" const char*ivl_memory_name(ivl_memory_t net) { return net->name_; } -extern "C" unsigned ivl_memory_root(ivl_memory_t net) +extern "C" const char* ivl_memory_basename(ivl_memory_t net) +{ + return basename(net->scope_, net->name_); +} + +extern "C" int ivl_memory_root(ivl_memory_t net) { return net->root_; } +extern "C" unsigned ivl_memory_size(ivl_memory_t net) +{ + return net->size_; +} + extern "C" unsigned ivl_memory_width(ivl_memory_t net) { return net->width_; @@ -109,11 +126,7 @@ extern "C" const char* ivl_event_name(ivl_event_t net) extern "C" const char* ivl_event_basename(ivl_event_t net) { - const char*nam = net->name; - nam += strlen(ivl_scope_name(net->scope)); - assert(*nam == '.'); - nam += 1; - return nam; + return basename(net->scope, net->name); } @@ -341,11 +354,7 @@ extern "C" const char* ivl_logic_name(ivl_net_logic_t net) extern "C" const char* ivl_logic_basename(ivl_net_logic_t net) { - const char*nam = net->name_; - nam += strlen(ivl_scope_name(net->scope_)); - assert(*nam == '.'); - nam += 1; - return nam; + return basename(net->scope_, net->name_); } extern "C" ivl_logic_t ivl_logic_type(ivl_net_logic_t net) @@ -541,7 +550,25 @@ extern "C" unsigned ivl_lpm_width(ivl_lpm_t net) extern "C" ivl_expr_t ivl_lval_mux(ivl_lval_t net) { assert(net); - return net->mux; + if (net->type_ == IVL_LVAL_MUX) + return net->idx; + return 0x0; +} + +extern "C" ivl_expr_t ivl_lval_idx(ivl_lval_t net) +{ + assert(net); + if (net->type_ == IVL_LVAL_MEM) + return net->idx; + return 0x0; +} + +extern "C" ivl_memory_t ivl_lval_mem(ivl_lval_t net) +{ + assert(net); + if (net->type_ == IVL_LVAL_MEM) + return net->n.mem_; + return 0x0; } extern "C" unsigned ivl_lval_pins(ivl_lval_t net) @@ -554,6 +581,7 @@ extern "C" ivl_nexus_t ivl_lval_pin(ivl_lval_t net, unsigned idx) { assert(net); assert(idx < net->width_); + assert(net->type_ != IVL_LVAL_MEM); if (net->width_ == 1) return net->n.pin_; else @@ -706,6 +734,19 @@ extern "C" ivl_lpm_t ivl_scope_lpm(ivl_scope_t net, unsigned idx) return net->lpm_[idx]; } +extern "C" unsigned ivl_scope_mems(ivl_scope_t net) +{ + assert(net); + return net->nmem_; +} + +extern "C" ivl_memory_t ivl_scope_mem(ivl_scope_t net, unsigned idx) +{ + assert(net); + assert(idx < net->nmem_); + return net->mem_[idx]; +} + extern "C" const char* ivl_scope_name(ivl_scope_t net) { return net->name_; @@ -769,11 +810,7 @@ extern "C" const char* ivl_signal_attr(ivl_signal_t net, const char*key) extern "C" const char* ivl_signal_basename(ivl_signal_t net) { - const char*nam = net->name_; - nam += strlen(ivl_scope_name(net->scope_)); - assert(*nam == '.'); - nam += 1; - return nam; + return basename(net->scope_, net->name_); } extern "C" const char* ivl_signal_name(ivl_signal_t net) @@ -1004,10 +1041,19 @@ extern "C" unsigned ivl_stmt_lwidth(ivl_statement_t net) unsigned sum = 0; for (unsigned idx = 0 ; idx < net->u_.assign_.lvals_ ; idx += 1) { ivl_lval_t cur = net->u_.assign_.lval_ + idx; - if (cur->mux) + switch(cur->type_) { + case IVL_LVAL_MUX: sum += 1; - else - sum += cur->width_; + break; + case IVL_LVAL_REG: + sum += ivl_lval_pins(cur); + break; + case IVL_LVAL_MEM: + sum += ivl_memory_width(ivl_lval_mem(cur)); + break; + default: + assert(0); + } } return sum; @@ -1083,6 +1129,10 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net) /* * $Log: t-dll-api.cc,v $ + * Revision 1.44 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.43 2001/05/06 17:48:20 steve * Support memory objects. (Stephan Boettcher) * diff --git a/t-dll-expr.cc b/t-dll-expr.cc index 8a44fdeba..8b87ce600 100644 --- a/t-dll-expr.cc +++ b/t-dll-expr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) & !defined(macintosh) -#ident "$Id: t-dll-expr.cc,v 1.11 2001/04/06 02:28:02 steve Exp $" +#ident "$Id: t-dll-expr.cc,v 1.12 2001/05/08 23:59:33 steve Exp $" #endif # include "t-dll.h" @@ -80,10 +80,32 @@ void dll_target::expr_concat(const NetEConcat*net) expr_ = cur; } +void dll_target::expr_memory(const NetEMemory*net) +{ + assert(expr_ == 0); + if (net->index()) { + net->index()->expr_scan(this); + assert(expr_); + } + + ivl_expr_t cur = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); + assert(cur); + + cur->type_ = IVL_EX_MEMORY; + cur->width_= net->expr_width(); + cur->signed_ = net->has_sign()? 1 : 0; + cur->u_.memory_.mem_ = lookup_memory_(net->memory()); + cur->u_.memory_.idx_ = expr_; + + expr_ = cur; +} + void dll_target::expr_const(const NetEConst*net) { assert(expr_ == 0); + ivl_expr_t idx = 0; + expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); assert(expr_); @@ -204,6 +226,10 @@ void dll_target::expr_unary(const NetEUnary*net) /* * $Log: t-dll-expr.cc,v $ + * Revision 1.12 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.11 2001/04/06 02:28:02 steve * Generate vvp code for functions with ports. * diff --git a/t-dll-proc.cc b/t-dll-proc.cc index 1627bae80..c4aed5395 100644 --- a/t-dll-proc.cc +++ b/t-dll-proc.cc @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll-proc.cc,v 1.28 2001/04/15 03:19:44 steve Exp $" +#ident "$Id: t-dll-proc.cc,v 1.29 2001/05/08 23:59:33 steve Exp $" #endif # include "target.h" @@ -132,6 +132,7 @@ void dll_target::proc_assign(const NetAssign*net) const NetAssign_*asn = net->l_val(idx); cur->width_ = asn->pin_count(); + cur->type_ = IVL_LVAL_REG; if (cur->width_ > 1) { cur->n.pins_ = new ivl_nexus_t[cur->width_]; @@ -147,11 +148,12 @@ void dll_target::proc_assign(const NetAssign*net) cur->n.pin_ = (ivl_nexus_t)nex->t_cookie(); } - cur->mux = 0; + cur->idx = 0; if (asn->bmux()) { assert(expr_ == 0); asn->bmux()->expr_scan(this); - cur->mux = expr_; + cur->type_ = IVL_LVAL_MUX; + cur->idx = expr_; expr_ = 0; } } @@ -184,6 +186,7 @@ void dll_target::proc_assign_nb(const NetAssignNB*net) assert(asn->rise_time() == delay_val); + cur->type_ = IVL_LVAL_REG; cur->width_ = asn->pin_count(); if (cur->width_ > 1) { @@ -200,11 +203,12 @@ void dll_target::proc_assign_nb(const NetAssignNB*net) cur->n.pin_ = (ivl_nexus_t)nex->t_cookie(); } - cur->mux = 0; + cur->idx = 0; if (asn->bmux()) { assert(expr_ == 0); asn->bmux()->expr_scan(this); - cur->mux = expr_; + cur->type_ = IVL_LVAL_MUX; + cur->idx = expr_; expr_ = 0; } } @@ -224,6 +228,73 @@ void dll_target::proc_assign_nb(const NetAssignNB*net) } } +void dll_target::proc_assign_mem(const NetAssignMem*net) +{ + assert(stmt_cur_); + assert(stmt_cur_->type_ == IVL_ST_NONE); + + stmt_cur_->type_ = IVL_ST_ASSIGN; + + stmt_cur_->u_.assign_.lvals_ = 1; + stmt_cur_->u_.assign_.lval_ = new struct ivl_lval_s[1]; + stmt_cur_->u_.assign_.delay = 0; + struct ivl_lval_s*cur = stmt_cur_->u_.assign_.lval_; + + cur->type_ = IVL_LVAL_MEM; + cur->n.mem_ = lookup_memory_(net->memory()); + assert(cur->n.mem_); + cur->width_ = ivl_memory_width(cur->n.mem_); + + assert(expr_ == 0); + + net->index()->expr_scan(this); + cur->type_ = IVL_LVAL_MEM; + cur->idx = expr_; + expr_ = 0; + + net->rval()->expr_scan(this); + stmt_cur_->u_.assign_.rval_ = expr_; + expr_ = 0; +} + +void dll_target::proc_assign_mem_nb(const NetAssignMemNB*net) +{ + assert(stmt_cur_); + assert(stmt_cur_->type_ == IVL_ST_NONE); + + stmt_cur_->type_ = IVL_ST_ASSIGN_NB; + + stmt_cur_->u_.assign_.lvals_ = 1; + stmt_cur_->u_.assign_.lval_ = new struct ivl_lval_s[1]; + stmt_cur_->u_.assign_.delay = 0; + struct ivl_lval_s*cur = stmt_cur_->u_.assign_.lval_; + + cur->type_ = IVL_LVAL_MEM; + cur->n.mem_ = lookup_memory_(net->memory()); + cur->width_ = ivl_memory_width(cur->n.mem_); + + assert(expr_ == 0); + + net->index()->expr_scan(this); + cur->type_ = IVL_LVAL_MEM; + cur->idx = expr_; + expr_ = 0; + + net->rval()->expr_scan(this); + stmt_cur_->u_.assign_.rval_ = expr_; + expr_ = 0; + + unsigned long delay_val = 0; + + if (delay_val > 0) { + ivl_expr_t de = new struct ivl_expr_s; + de->type_ = IVL_EX_ULONG; + de->width_ = 8 * sizeof(unsigned long); + de->signed_ = 0; + de->u_.ulong_.value = delay_val; + stmt_cur_->u_.assign_.delay = de; + } +} bool dll_target::proc_block(const NetBlock*net) { @@ -607,6 +678,10 @@ void dll_target::proc_while(const NetWhile*net) /* * $Log: t-dll-proc.cc,v $ + * Revision 1.29 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.28 2001/04/15 03:19:44 steve * Oops, excessive test assert neets to be removed. * diff --git a/t-dll.cc b/t-dll.cc index d817ba2c7..020ce9082 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll.cc,v 1.39 2001/05/03 01:52:45 steve Exp $" +#ident "$Id: t-dll.cc,v 1.40 2001/05/08 23:59:33 steve Exp $" #endif # include "compiler.h" @@ -83,6 +83,41 @@ ivl_scope_t dll_target::lookup_scope_(const NetScope*cur) return find_scope(des_.root_, cur); } +/* + * This function locates an ivl_memory_t object that matches the + * NetMemory object. The search works by looking for the parent scope, + * then scanning the parent scope for the NetMemory object. + */ +static ivl_memory_t find_memory(ivl_scope_t root, const NetMemory*cur) +{ + ivl_scope_t tmp; + ivl_memory_t mem ; + + if (!root) + return 0; + + for (unsigned i = 0; i < ivl_scope_mems(root); i++) { + mem = ivl_scope_mem(root, i); + if (!strcmp(ivl_memory_name(mem), cur->name().c_str())) + return mem; + } + + mem = find_memory(root->child_, cur); + if (mem) + return mem; + + mem = find_memory(root->sibling_, cur); + if (mem) + return mem; + + return 0; +} + +ivl_memory_t dll_target::lookup_memory_(const NetMemory*cur) +{ + return find_memory(des_.root_, cur); +} + static ivl_nexus_t nexus_sig_make(ivl_signal_t net, unsigned pin) { ivl_nexus_t tmp = new struct ivl_nexus_s; @@ -202,6 +237,14 @@ static void scope_add_lpm(ivl_scope_t scope, ivl_lpm_t net) } } +static void scope_add_mem(ivl_scope_t scope, ivl_memory_t net) +{ + scope->nmem_ += 1; + scope->mem_ = (ivl_memory_t*) + realloc(scope->mem_, scope->nmem_*sizeof(ivl_memory_t)); + scope->mem_[scope->nmem_-1] = net; +} + bool dll_target::start_design(const Design*des) { dll_path_ = des->get_flag("DLL"); @@ -227,6 +270,8 @@ bool dll_target::start_design(const Design*des) des_.root_->event_ = 0; des_.root_->nlpm_ = 0; des_.root_->lpm_ = 0; + des_.root_->nmem_ = 0; + des_.root_->mem_ = 0; des_.root_->type_ = IVL_SCT_MODULE; des_.root_->tname_ = des_.root_->name_; @@ -488,6 +533,19 @@ void dll_target::udp(const NetUDP*net) scope_add_logic(scope, obj); } +void dll_target::memory(const NetMemory*net) +{ + ivl_memory_t obj = new struct ivl_memory_s; + obj->name_ = strdup(net->name().c_str()); + obj->scope_ = find_scope(des_.root_, net->scope()); + obj->width_ = net->width(); + obj->signed_ = 0; + obj->size_ = net->count(); + obj->root_ = -net->index_to_address(0); + + scope_add_mem(obj->scope_, obj); +} + void dll_target::lpm_ff(const NetFF*net) { ivl_lpm_t obj = new struct ivl_lpm_s; @@ -693,6 +751,8 @@ void dll_target::scope(const NetScope*net) scope->event_ = 0; scope->nlpm_ = 0; scope->lpm_ = 0; + scope->nmem_ = 0; + scope->mem_ = 0; switch (net->type()) { case NetScope::MODULE: @@ -893,6 +953,10 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj }; /* * $Log: t-dll.cc,v $ + * Revision 1.40 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.39 2001/05/03 01:52:45 steve * dll build of many probes forgot to index the probe. * diff --git a/t-dll.h b/t-dll.h index 43a22ab6a..2b5bd5c2c 100644 --- a/t-dll.h +++ b/t-dll.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll.h,v 1.42 2001/05/06 17:48:20 steve Exp $" +#ident "$Id: t-dll.h,v 1.43 2001/05/08 23:59:33 steve Exp $" #endif # include "target.h" @@ -67,6 +67,7 @@ struct dll_target : public target_t, public expr_scan_t { bool process(const NetProcTop*); void scope(const NetScope*); void signal(const NetNet*); + void memory(const NetMemory*); ivl_dll_t dll_; string dll_path_; @@ -80,7 +81,9 @@ struct dll_target : public target_t, public expr_scan_t { statements of a thread. */ struct ivl_statement_s*stmt_cur_; void proc_assign(const NetAssign*); + void proc_assign_mem(const NetAssignMem*); void proc_assign_nb(const NetAssignNB*); + void proc_assign_mem_nb(const NetAssignMemNB*net); bool proc_block(const NetBlock*); void proc_case(const NetCase*); void proc_condit(const NetCondit*); @@ -100,6 +103,7 @@ struct dll_target : public target_t, public expr_scan_t { struct ivl_expr_s*expr_; void expr_binary(const NetEBinary*); void expr_concat(const NetEConcat*); + void expr_memory(const NetEMemory*); void expr_const(const NetEConst*); void expr_scope(const NetEScope*); void expr_sfunc(const NetESFunc*); @@ -108,6 +112,7 @@ struct dll_target : public target_t, public expr_scan_t { void expr_signal(const NetESignal*); ivl_scope_t lookup_scope_(const NetScope*scope); + ivl_memory_t lookup_memory_(const NetMemory*mem); }; /* @@ -240,12 +245,21 @@ struct ivl_lpm_s { * are reg nets. This is used by the assignment to represent the * l-value expressions. */ + +enum ivl_lval_type_t { + IVL_LVAL_REG = 0, + IVL_LVAL_MUX = 1, + IVL_LVAL_MEM = 2, +}; + struct ivl_lval_s { unsigned width_ :24; - ivl_expr_t mux; + unsigned type_ : 8; + ivl_expr_t idx; union { ivl_nexus_t*pins_; ivl_nexus_t pin_; + ivl_memory_t mem_; } n; }; @@ -383,6 +397,9 @@ struct ivl_scope_s { unsigned nlpm_; ivl_lpm_t* lpm_; + unsigned nmem_; + ivl_memory_t* mem_; + /* Scopes that are tasks/functions have a definition. */ ivl_statement_t def; @@ -496,6 +513,10 @@ struct ivl_statement_s { /* * $Log: t-dll.h,v $ + * Revision 1.43 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.42 2001/05/06 17:48:20 steve * Support memory objects. (Stephan Boettcher) * diff --git a/tgt-verilog/verilog.c b/tgt-verilog/verilog.c index 3d7199e9c..8d1efac29 100644 --- a/tgt-verilog/verilog.c +++ b/tgt-verilog/verilog.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: verilog.c,v 1.20 2001/02/07 22:22:00 steve Exp $" +#ident "$Id: verilog.c,v 1.21 2001/05/08 23:59:33 steve Exp $" #endif /* @@ -240,6 +240,7 @@ static void show_assign_lval(ivl_lval_t lval) unsigned lsb; assert(ivl_lval_mux(lval) == 0); + assert(ivl_lval_mem(lval) == 0); nex = ivl_lval_pin(lval, 0); @@ -440,6 +441,10 @@ DECLARE_CYGWIN_DLL(DllMain); /* * $Log: verilog.c,v $ + * Revision 1.21 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.20 2001/02/07 22:22:00 steve * ivl_target header search path fixes. * diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index ed23e7785..7ac06c6a2 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvp_process.c,v 1.31 2001/05/03 04:55:28 steve Exp $" +#ident "$Id: vvp_process.c,v 1.32 2001/05/08 23:59:33 steve Exp $" #endif # include "vvp_priv.h" @@ -82,6 +82,14 @@ static void set_to_nexus(ivl_nexus_t nex, unsigned bit) } } +static void set_to_memory(ivl_memory_t mem, unsigned idx, unsigned bit) +{ + if (idx) + fprintf(vvp_out, " %%ix/add 3, 1;\n"); + fprintf(vvp_out, " %%set/m M_%s, %u;\n", + ivl_memory_name(mem), bit); +} + static void assign_to_nexus(ivl_nexus_t nex, unsigned bit, unsigned delay) { unsigned idx; @@ -99,10 +107,20 @@ static void assign_to_nexus(ivl_nexus_t nex, unsigned bit, unsigned delay) } } +static void assign_to_memory(ivl_memory_t mem, unsigned idx, + unsigned bit, unsigned delay) +{ + if (idx) + fprintf(vvp_out, " %%ix/add 3, 1;\n"); + fprintf(vvp_out, " %%assign/m M_%s, %u, %u;\n", + ivl_memory_name(mem), delay, bit); +} + static int show_stmt_assign(ivl_statement_t net) { ivl_lval_t lval; ivl_expr_t rval = ivl_stmt_rval(net); + ivl_memory_t mem; /* Handle the special case that the r-value is a constant. We @@ -119,10 +137,17 @@ static int show_stmt_assign(ivl_statement_t net) lval = ivl_stmt_lval(net, 0); /* XXXX No mux support yet. */ assert(ivl_lval_mux(lval) == 0); + mem = ivl_lval_mem(lval); + + if (mem) + draw_memory_index_expr(mem, ivl_lval_idx(lval)); for (idx = 0 ; idx < ivl_lval_pins(lval) ; idx += 1) - set_to_nexus(ivl_lval_pin(lval, idx), - bitchar_to_idx(bits[idx])); + if (mem) + set_to_memory(mem, idx, bitchar_to_idx(bits[idx])); + else + set_to_nexus(ivl_lval_pin(lval, idx), + bitchar_to_idx(bits[idx])); return 0; } @@ -137,18 +162,28 @@ static int show_stmt_assign(ivl_statement_t net) lval = ivl_stmt_lval(net, 0); /* XXXX No mux support yet. */ assert(ivl_lval_mux(lval) == 0); + mem = ivl_lval_mem(lval); if (ivl_lval_pins(lval) < wid) wid = ivl_lval_pins(lval); + if (mem) + draw_memory_index_expr(mem, ivl_lval_idx(lval)); + for (idx = 0 ; idx < wid ; idx += 1) { - unsigned bidx = res.base < 4? res.base : (res.base+idx); - set_to_nexus(ivl_lval_pin(lval, idx), bidx); + unsigned bidx = res.base < 4 ? res.base : (res.base+idx); + if (mem) + set_to_memory(mem, idx, bidx); + else + set_to_nexus(ivl_lval_pin(lval, idx), bidx); } for (idx = wid ; idx < ivl_lval_pins(lval) ; idx += 1) - set_to_nexus(ivl_lval_pin(lval, idx), 0); - + if (mem) + set_to_memory(mem, idx, 0); + else + set_to_nexus(ivl_lval_pin(lval, idx), 0); + clr_vector(res); } @@ -160,6 +195,7 @@ static int show_stmt_assign_nb(ivl_statement_t net) ivl_lval_t lval; ivl_expr_t rval = ivl_stmt_rval(net); ivl_expr_t del = ivl_stmt_delay_expr(net); + ivl_memory_t mem; unsigned long delay = 0; if (del != 0) { @@ -168,7 +204,6 @@ static int show_stmt_assign_nb(ivl_statement_t net) delay = ivl_expr_uvalue(del); } - /* Handle the special case that the r-value is a constant. We can generate the %set statement directly, without any worry about generating code to evaluate the r-value expressions. */ @@ -183,11 +218,19 @@ static int show_stmt_assign_nb(ivl_statement_t net) lval = ivl_stmt_lval(net, 0); /* XXXX No mux support yet. */ assert(ivl_lval_mux(lval) == 0); + mem = ivl_lval_mem(lval); + + if (mem) + draw_memory_index_expr(mem, ivl_lval_idx(lval)); for (idx = 0 ; idx < ivl_lval_pins(lval) ; idx += 1) - assign_to_nexus(ivl_lval_pin(lval, idx), - bitchar_to_idx(bits[idx]), delay); - + if (mem) + assign_to_memory(mem, idx, + bitchar_to_idx(bits[idx]), delay); + else + assign_to_nexus(ivl_lval_pin(lval, idx), + bitchar_to_idx(bits[idx]), delay); + return 0; } @@ -201,15 +244,27 @@ static int show_stmt_assign_nb(ivl_statement_t net) lval = ivl_stmt_lval(net, 0); /* XXXX No mux support yet. */ assert(ivl_lval_mux(lval) == 0); + mem = ivl_lval_mem(lval); if (ivl_lval_pins(lval) < wid) wid = ivl_lval_pins(lval); - for (idx = 0 ; idx < wid ; idx += 1) - assign_to_nexus(ivl_lval_pin(lval, idx), res.base+idx, delay); - + if (mem) + draw_memory_index_expr(mem, ivl_lval_idx(lval)); + + for (idx = 0 ; idx < wid ; idx += 1) { + unsigned bidx = res.base < 4 ? res.base : (res.base+idx); + if (mem) + assign_to_memory(mem, idx, bidx, delay); + else + assign_to_nexus(ivl_lval_pin(lval, idx), bidx, delay); + } + for (idx = wid ; idx < ivl_lval_pins(lval) ; idx += 1) - assign_to_nexus(ivl_lval_pin(lval, idx), 0, delay); + if (mem) + assign_to_memory(mem, idx, 0, delay); + else + assign_to_nexus(ivl_lval_pin(lval, idx), 0, delay); clr_vector(res); } @@ -556,6 +611,13 @@ static int show_system_task_call(ivl_statement_t net) fprintf(vvp_out, ", V_%s", ivl_expr_name(expr)); break; + case IVL_EX_MEMORY: + if (!ivl_expr_oper1(expr)) + fprintf(vvp_out, ", M_%s", ivl_expr_name(expr)); + else + fprintf(vvp_out, ", M_%s[?]", ivl_expr_name(expr)); + break; + case IVL_EX_STRING: fprintf(vvp_out, ", \"%s\"", ivl_expr_string(expr)); break; @@ -751,6 +813,10 @@ int draw_func_definition(ivl_scope_t scope) /* * $Log: vvp_process.c,v $ + * Revision 1.32 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.31 2001/05/03 04:55:28 steve * Generate null statements for conditional labels. * diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index 162498b3f..2039d0664 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvp_scope.c,v 1.25 2001/05/06 00:01:02 steve Exp $" +#ident "$Id: vvp_scope.c,v 1.26 2001/05/08 23:59:33 steve Exp $" #endif # include "vvp_priv.h" @@ -607,6 +607,19 @@ static void draw_lpm_in_scope(ivl_lpm_t net) } } + +static void draw_mem_in_scope(ivl_memory_t net) +{ + int root = ivl_memory_root(net); + int last = root + ivl_memory_size(net) - 1; + int msb = ivl_memory_width(net) - 1; + int lsb = 0; + fprintf(vvp_out, "M_%s .mem \"%s\", %u,%u, %u,%u;\n", + ivl_memory_name(net), ivl_memory_basename(net), + msb, lsb, root, last); +} + + int draw_scope(ivl_scope_t net, ivl_scope_t parent) { unsigned idx; @@ -656,6 +669,11 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) draw_lpm_in_scope(lpm); } + for (idx = 0 ; idx < ivl_scope_mems(net) ; idx += 1) { + ivl_memory_t mem = ivl_scope_mem(net, idx); + draw_mem_in_scope(mem); + } + if (ivl_scope_type(net) == IVL_SCT_TASK) draw_task_definition(net); @@ -668,6 +686,10 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) /* * $Log: vvp_scope.c,v $ + * Revision 1.26 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.25 2001/05/06 00:01:02 steve * Generate code that causes the value of a net to be passed * passed through all nets of a nexus. diff --git a/vvp/Makefile.in b/vvp/Makefile.in index 6f4c4cb80..20073eeb4 100644 --- a/vvp/Makefile.in +++ b/vvp/Makefile.in @@ -16,7 +16,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.16 2001/05/05 23:55:46 steve Exp $" +#ident "$Id: Makefile.in,v 1.17 2001/05/08 23:59:33 steve Exp $" # # SHELL = /bin/sh @@ -59,7 +59,7 @@ check: all ./vvp -M../vpi $(srcdir)/examples/hello.vvp | grep 'Hello, World.' V = vpi_modules.o vpi_const.o vpi_iter.o vpi_mcd.o vpi_priv.o \ -vpi_scope.o vpi_signal.o vpi_tasks.o vpi_time.o +vpi_scope.o vpi_signal.o vpi_tasks.o vpi_time.o vpi_memory.o O = main.o parse.o parse_misc.o lexor.o compile.o debug.o functor.o \ symbols.o codes.o vthread.o schedule.o tables.o udp.o memory.o $V diff --git a/vvp/compile.cc b/vvp/compile.cc index f292715e3..f2988637f 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: compile.cc,v 1.58 2001/05/08 23:32:26 steve Exp $" +#ident "$Id: compile.cc,v 1.59 2001/05/08 23:59:33 steve Exp $" #endif # include "compile.h" @@ -433,8 +433,12 @@ void compile_memory(char *label, char *name, int msb, int lsb, unsigned idxs, long *idx) { vvp_memory_t mem = memory_create(label); - free(label); memory_new(mem, name, lsb, msb, idxs, idx); + + vpiHandle obj = vpip_make_memory(mem); + compile_vpi_symbol(label, obj); + + free(label); } void compile_memory_port(char *label, char *memid, @@ -1096,6 +1100,10 @@ vvp_ipoint_t debug_lookup_functor(const char*name) /* * $Log: compile.cc,v $ + * Revision 1.59 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.58 2001/05/08 23:32:26 steve * Add to the debugger the ability to view and * break on functors. diff --git a/vvp/examples/memory.vvp b/vvp/examples/memory.vvp index 25ed6f678..6e88a742d 100644 --- a/vvp/examples/memory.vvp +++ b/vvp/examples/memory.vvp @@ -127,7 +127,9 @@ initial ; %set a[3], 0; %set a[4], 0; - %delay 320; + %delay 220; + %vpi_call "$readmemh", "memory.hex", memory; + %delay 100; ;;; Memories are indexed by index register 3. The index register ;;; points to the bit position in the memory. Each memory word diff --git a/vvp/memory.cc b/vvp/memory.cc index 8666f4a6d..30fe8f4cb 100644 --- a/vvp/memory.cc +++ b/vvp/memory.cc @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: memory.cc,v 1.2 2001/05/06 03:51:37 steve Exp $" +#ident "$Id: memory.cc,v 1.3 2001/05/08 23:59:33 steve Exp $" #endif #include "memory.h" @@ -83,6 +83,24 @@ struct vvp_memory_port_s : public vvp_fobj_s int nbits; }; + +unsigned memory_size(vvp_memory_t mem) +{ + return mem->size; +} + +unsigned memory_root(vvp_memory_t mem, unsigned ix) +{ + if (ix >= mem->a_idxs) + return 0; + return mem->a_idx[ix].first; +} + +char *memory_name(vvp_memory_t mem) +{ + return mem->name; +} + // Compilation static symbol_table_t memory_table; @@ -130,8 +148,14 @@ void memory_new(vvp_memory_t mem, char *name, int msb, int lsb, vvp_memory_index_t x = mem->a_idx + i; int msw = *(idx++); int lsw = *(idx++); - x->size = msw - lsw + 1; - x->first = lsw; + if (msw > lsw) { + x->size = msw - lsw + 1; + x->first = lsw; + } + else { + x->size = lsw - msw + 1; + x->first = msw; + } int m = lsw ^ msw; x->awidth = 0; if (m < 0) diff --git a/vvp/memory.h b/vvp/memory.h index ddf872efa..664f540ac 100644 --- a/vvp/memory.h +++ b/vvp/memory.h @@ -20,12 +20,17 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: memory.h,v 1.1 2001/05/01 01:09:39 steve Exp $" +#ident "$Id: memory.h,v 1.2 2001/05/08 23:59:33 steve Exp $" #endif #include "pointers.h" #include "functor.h" +/* +** vvp_memory_t is a memory +** vvp_memory_bits_t are bits in a memory +** vvp_memory_index_t is a memory index range definition +*/ typedef struct vvp_memory_s *vvp_memory_t; typedef unsigned char *vvp_memory_bits_t; typedef struct vvp_memory_index_s *vvp_memory_index_t; @@ -42,13 +47,23 @@ void schedule_memory(vvp_memory_t mem, unsigned idx, unsigned char val, unsigned delay); unsigned memory_addr_width(vvp_memory_t mem); +unsigned memory_size(vvp_memory_t mem); +char *memory_name(vvp_memory_t mem); unsigned memory_data_width(vvp_memory_t mem); +unsigned memory_root(vvp_memory_t mem, unsigned ix = 0); +/* +** Access to the memory symbol table. +*/ vvp_memory_t memory_find(char *label); vvp_memory_t memory_create(char *label); /* * $Log: memory.h,v $ + * Revision 1.2 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.1 2001/05/01 01:09:39 steve * Add support for memory objects. (Stephan Boettcher) * diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index e23225841..b9c724484 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -1,7 +1,7 @@ /* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * - * $Id: opcodes.txt,v 1.19 2001/05/06 17:42:22 steve Exp $ + * $Id: opcodes.txt,v 1.20 2001/05/08 23:59:33 steve Exp $ */ @@ -149,7 +149,7 @@ thread bit space, and is the width of the vector. The function converts the 4-value bits into a binary number, without sign extension. If any of the bits of the vector is x or z, then the -index register gets the value 0. +index register gets the value (-1). * %ix/load , diff --git a/vvp/vpi_iter.cc b/vvp/vpi_iter.cc index 4f950c5dc..6e09c311f 100644 --- a/vvp/vpi_iter.cc +++ b/vvp/vpi_iter.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vpi_iter.cc,v 1.1 2001/03/16 01:44:34 steve Exp $" +#ident "$Id: vpi_iter.cc,v 1.2 2001/05/08 23:59:33 steve Exp $" #endif /* @@ -59,6 +59,9 @@ vpiHandle vpi_scan(vpiHandle ref) struct __vpiIterator*hp = (struct __vpiIterator*)ref; assert(ref->vpi_type->type_code == vpiIterator); + if (ref->vpi_type->index_) + return (ref->vpi_type->index_(ref, 0)); + if (hp->next == hp->nargs) { vpi_free_object(ref); return 0; @@ -69,6 +72,10 @@ vpiHandle vpi_scan(vpiHandle ref) /* * $Log: vpi_iter.cc,v $ + * Revision 1.2 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.1 2001/03/16 01:44:34 steve * Add structures for VPI support, and all the %vpi_call * instruction. Get linking of VPI modules to work. diff --git a/vvp/vpi_memory.cc b/vvp/vpi_memory.cc new file mode 100644 index 000000000..afa8fdfb9 --- /dev/null +++ b/vvp/vpi_memory.cc @@ -0,0 +1,229 @@ +/* + * Copyright (c) 1999-2000 Picture Elements, Inc. + * Stephen Williams (steve@picturel.com) + * Copyright (c) 2001 Stephan Boettcher + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. In order to redistribute the software in + * binary form, you will need a Picture Elements Binary Software + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * --- + * You should also have recieved a copy of the Picture Elements + * Binary Software License offer along with the source. This offer + * allows you to obtain the right to redistribute the software in + * binary (compiled) form. If you have not received it, contact + * Picture Elements, Inc., 777 Panoramic Way, Berkeley, CA 94704. + */ +#if !defined(WINNT) && !defined(macintosh) +#ident "$Id: vpi_memory.cc,v 1.1 2001/05/08 23:59:33 steve Exp $" +#endif + +# include "vpi_priv.h" +# include "memory.h" +# include +# include + + +struct __vpiMemoryWord { + struct __vpiHandle base; + struct __vpiMemory*mem; + int index; +}; + +struct __vpiMemory { + struct __vpiHandle base; + /* The signal has a name (this points to static memory.) */ + struct __vpiMemoryWord word; + vvp_memory_t mem; +}; + +static int vpi_memory_get(int code, vpiHandle ref) +{ + struct __vpiMemory*rfp = (struct __vpiMemory*)ref; + + assert(ref->vpi_type->type_code==vpiMemory); + + switch (code) { + case vpiSize: + return (int)memory_size(rfp->mem); + + default: + return 0; + } +} + +static char* memory_get_str(int code, vpiHandle ref) +{ + struct __vpiMemory*rfp = (struct __vpiMemory*)ref; + assert(ref->vpi_type->type_code==vpiMemory); + + switch (code) { + case vpiFullName: + return memory_name(rfp->mem); + } + + return 0; +} + + +static vpiHandle memory_scan(vpiHandle ref, int) +{ + struct __vpiIterator*hp = (struct __vpiIterator*)ref; + assert(ref->vpi_type->type_code == vpiIterator); + + struct __vpiMemory*rfp = (struct __vpiMemory*)hp->args; + assert(rfp->base.vpi_type->type_code==vpiMemory); + + if (hp->next >= hp->nargs) { + vpi_free_object(ref); + return 0; + } + + rfp->word.index = hp->next++; + return &rfp->word.base; +} + +static const struct __vpirt vpip_mem_iter_rt = { + vpiIterator, + 0, + 0, + 0, + 0, + 0, + 0, + memory_scan, +}; + +static vpiHandle memory_iterate(int code, vpiHandle ref) +{ + struct __vpiMemory*rfp = (struct __vpiMemory*)ref; + assert(ref->vpi_type->type_code==vpiMemory); + + switch (code) { + case vpiMemoryWord: { + struct __vpiIterator*res = (struct __vpiIterator*) + calloc(1, sizeof(struct __vpiIterator)); + assert(res); + res->base.vpi_type = &vpip_mem_iter_rt; + res->args = (vpiHandle *)&rfp->base; + res->nargs = memory_size(rfp->mem); + res->next = 0; + return &(res->base); + } + } + + return 0; +} + +static vpiHandle memory_index(vpiHandle ref, int index) +{ + struct __vpiMemory*rfp = (struct __vpiMemory*)ref; + assert(ref->vpi_type->type_code==vpiMemory); + + index -= memory_root(rfp->mem); + if (index >= (int)memory_size(rfp->mem)) return 0; + if (index < 0) return 0; + rfp->word.index = index; + return &rfp->word.base; +} + +static int memory_word_get(int code, vpiHandle ref) +{ + struct __vpiMemoryWord*rfp = (struct __vpiMemoryWord*)ref; + assert(ref->vpi_type->type_code==vpiMemoryWord); + + switch (code) { + case vpiSize: + return memory_data_width(rfp->mem->mem); + + default: + return 0; + } +} + +static vpiHandle memory_word_put(vpiHandle ref, p_vpi_value val, + p_vpi_time tim, int flags) +{ + struct __vpiMemoryWord*rfp = (struct __vpiMemoryWord*)ref; + assert(ref->vpi_type->type_code==vpiMemoryWord); + + assert(val->format == vpiVectorVal); + + unsigned width = memory_data_width(rfp->mem->mem); + unsigned bidx = rfp->index * ((width+3)&~3); + + for (unsigned widx = 0; widx < width; widx += 32) { + p_vpi_vecval cur = val->value.vector + (widx/32); + for (unsigned idx = widx; idx < width && idx < widx+32; idx++) { + int aval = (cur->aval >> (idx%32)) & 1; + int bval = (cur->bval >> (idx%32)) & 1; + unsigned char val = (bval<<1) | (aval^bval); + memory_set(rfp->mem->mem, bidx+idx, val); + } + } + return 0; +} + +static void memory_word_get_value(vpiHandle ref, s_vpi_value*vp) +{ + struct __vpiMemoryWord*rfp = (struct __vpiMemoryWord*)ref; + assert(rfp->base.vpi_type->type_code==vpiMemoryWord); + + assert(0 && "sorry, not yet"); +} + +static const struct __vpirt vpip_memory_rt = { + vpiMemory, + vpi_memory_get, + memory_get_str, + 0, + 0, + 0, + memory_iterate, + memory_index, +}; + +static const struct __vpirt vpip_memory_word_rt = { + vpiMemoryWord, + memory_word_get, + 0, + memory_word_get_value, + memory_word_put, + 0, + 0, + 0, +}; + +vpiHandle vpip_make_memory(vvp_memory_t mem) +{ + struct __vpiMemory*obj = (struct __vpiMemory*) + malloc(sizeof(struct __vpiMemory)); + + obj->base.vpi_type = &vpip_memory_rt; + obj->word.base.vpi_type = &vpip_memory_word_rt; + obj->mem = mem; + obj->word.mem = obj; + + return &(obj->base); +} + +/* + * $Log: vpi_memory.cc,v $ + * Revision 1.1 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * + */ + diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index a8676a282..b04f276cd 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -19,11 +19,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vpi_priv.h,v 1.13 2001/04/18 04:21:23 steve Exp $" +#ident "$Id: vpi_priv.h,v 1.14 2001/05/08 23:59:33 steve Exp $" #endif # include "vpi_user.h" # include "pointers.h" +# include "memory.h" /* * This header file contains the internal definitions that the vvp @@ -114,6 +115,15 @@ extern vpiHandle vpip_make_reg(char*name, int msb, int lsb, bool signed_flag, extern vpiHandle vpip_make_net(char*name, int msb, int lsb, bool signed_flag, vvp_ipoint_t base); +/* + * Memory is an array of bits that is accessible in N-bit chunks, with + * N being the width of a word. The memory word handle just points + * back to the memory and uses an index to identify its position in + * the memory. + */ + +extern vpiHandle vpip_make_memory(vvp_memory_t mem); + /* * When a loaded VPI module announces a system task/function, one * __vpiUserSystf object is created to hold the definition of that @@ -196,6 +206,10 @@ vpiHandle vpip_sim_time(void); /* * $Log: vpi_priv.h,v $ + * Revision 1.14 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.13 2001/04/18 04:21:23 steve * Put threads into scopes. * diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 63c05396e..a7e9150f7 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vthread.cc,v 1.37 2001/05/08 23:32:26 steve Exp $" +#ident "$Id: vthread.cc,v 1.38 2001/05/08 23:59:33 steve Exp $" #endif # include "vthread.h" @@ -666,7 +666,7 @@ bool of_IX_LOAD(vthread_t thr, vvp_code_t cp) bool of_IX_GET(vthread_t thr, vvp_code_t cp) { unsigned long v = 0; - for (int i = 0; inumber; i++) { + for (unsigned i = 0; inumber; i++) { unsigned char vv = thr_get_bit(thr, cp->bit_idx2 + i); if (vv&2) { v = ~0UL; @@ -993,6 +993,10 @@ bool of_ZOMBIE(vthread_t thr, vvp_code_t) /* * $Log: vthread.cc,v $ + * Revision 1.38 2001/05/08 23:59:33 steve + * Add ivl and vvp.tgt support for memories in + * expressions and l-values. (Stephan Boettcher) + * * Revision 1.37 2001/05/08 23:32:26 steve * Add to the debugger the ability to view and * break on functors.