From 6257d31582295be39e20e0d72c32bb45539b716c Mon Sep 17 00:00:00 2001 From: Cary R Date: Sat, 14 Aug 2010 09:18:07 -0700 Subject: [PATCH 01/19] Add another missing probe_expr_width() call. The indexed select width argument was missing a call to probe_expr_width() and was crashing the compiler. --- elab_expr.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/elab_expr.cc b/elab_expr.cc index 8091c585e..f0ed6ffc9 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -1902,6 +1902,7 @@ bool PEIdent::calculate_up_do_width_(Design*des, NetScope*scope, /* Calculate the width expression (in the lsb_ position) first. If the expression is not constant, error but guess 1 so we can keep going and find more errors. */ + probe_expr_width(des, scope, index_tail.lsb); need_constant_expr = true; NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1); need_constant_expr = false; From c9f28902eb77f422498a903473d73dc55fc0f742 Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 3 Sep 2010 17:12:49 -0700 Subject: [PATCH 02/19] Warn the user that synthesis is no longer maintained. Add code to print a warning if the user tries to use the -S flag. We need this warning since synthesis is not currently being actively maintained or supported in any branch after V0.8. --- driver/main.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/driver/main.c b/driver/main.c index 9d0abfb89..51a7c5e74 100644 --- a/driver/main.c +++ b/driver/main.c @@ -661,10 +661,10 @@ int process_generation(const char*name) else if (strcmp(name,"no-std-include") == 0) gen_std_include = 0; - + else if (strcmp(name,"relative-include") == 0) gen_relative_include = 1; - + else if (strcmp(name,"no-relative-include") == 0) gen_relative_include = 0; @@ -685,7 +685,7 @@ int process_generation(const char*name) else if (strcmp(name,"no-verilog-ams") == 0) gen_verilog_ams = "no-verilog-ams"; - + else { fprintf(stderr, "Unknown/Unsupported Language generation " "%s\n\n", name); @@ -988,10 +988,19 @@ int main(int argc, char **argv) if (version_flag || verbose_flag) { printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n"); - printf("Copyright 1998-2009 Stephen Williams\n\n"); + printf("Copyright 1998-2010 Stephen Williams\n\n"); puts(NOTICE); } + if (synth_flag) { + fprintf(stderr, "Warning: Synthesis is not currently being " + "maintained and may not\n"); + fprintf(stderr, " function correctly. V0.8 was the " + "last release branch to\n"); + fprintf(stderr, " have active synthesis development " + "and support!\n"); + } + /* Make a common conf file path to reflect the target. */ snprintf(iconfig_common_path, sizeof iconfig_common_path, "%s%c%s%s.conf", base, sep, targ, synth_flag? "-s" : ""); From c87186a15c6fa6c01c746850b18586404e5fa023 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Tue, 24 Aug 2010 22:51:19 +0100 Subject: [PATCH 03/19] Add uwire support to VHDL backend Implemented as std_ulogic which behaves almost identically. --- tgt-vhdl/cast.cc | 28 ++++++++++++++++++++++++---- tgt-vhdl/scope.cc | 11 ++++++++--- tgt-vhdl/vhdl_syntax.hh | 2 ++ tgt-vhdl/vhdl_type.cc | 19 +++++++++++++++---- tgt-vhdl/vhdl_type.hh | 5 ++++- 5 files changed, 53 insertions(+), 12 deletions(-) diff --git a/tgt-vhdl/cast.cc b/tgt-vhdl/cast.cc index 22f6b89f4..9f54270a1 100644 --- a/tgt-vhdl/cast.cc +++ b/tgt-vhdl/cast.cc @@ -28,10 +28,12 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to) { - //std::cout << "Cast: from=" << type_->get_string() - // << " (" << type_->get_width() << ") " - // << " to=" << to->get_string() << " (" - // << to->get_width() << ")" << std::endl; +#if 0 + std::cout << "Cast: from=" << type_->get_string() + << " (" << type_->get_width() << ") " + << " to=" << to->get_string() << " (" + << to->get_width() << ")" << std::endl; +#endif // If this expression hasn't been given a type then // we can't generate any type conversion code @@ -56,6 +58,8 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to) return to_vector(to->get_name(), to->get_width()); case VHDL_TYPE_STD_LOGIC: return to_std_logic(); + case VHDL_TYPE_STD_ULOGIC: + return to_std_ulogic(); default: assert(false); } @@ -185,6 +189,17 @@ vhdl_expr *vhdl_expr::to_std_logic() return NULL; } +vhdl_expr *vhdl_expr::to_std_ulogic() +{ + if (type_->get_name() == VHDL_TYPE_STD_LOGIC) { + vhdl_fcall *f = new vhdl_fcall("std_logic", vhdl_type::std_logic()); + f->add_expr(this); + return f; + } + else + assert(false); +} + /* * Change the width of a signed/unsigned type. */ @@ -304,6 +319,11 @@ vhdl_expr *vhdl_const_bit::to_boolean() return new vhdl_const_bool(bit_ == '1'); } +vhdl_expr *vhdl_const_bit::to_std_ulogic() +{ + return this; +} + vhdl_expr *vhdl_const_bit::to_vector(vhdl_type_name_t name, int w) { // Zero-extend this bit to the correct width diff --git a/tgt-vhdl/scope.cc b/tgt-vhdl/scope.cc index 35b5d3b76..6097b41e5 100644 --- a/tgt-vhdl/scope.cc +++ b/tgt-vhdl/scope.cc @@ -277,6 +277,7 @@ void draw_nexus(ivl_nexus_t nexus) switch (signal_type_of_nexus(nexus, width)) { case IVL_SIT_TRI: + case IVL_SIT_UWIRE: def = 'Z'; break; case IVL_SIT_TRI0: @@ -556,9 +557,13 @@ static void declare_one_signal(vhdl_entity *ent, ivl_signal_t sig, sig_type = new vhdl_type(*array_type); } - else - sig_type = - vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig) != 0); + else { + sig_type = vhdl_type::type_for(ivl_signal_width(sig), + ivl_signal_signed(sig) != 0, + 0, ivl_signal_type(sig) == IVL_SIT_UWIRE); + + + } ivl_signal_port_t mode = ivl_signal_port(sig); switch (mode) { diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index de3e11313..961542d99 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -46,6 +46,7 @@ public: virtual vhdl_expr *to_boolean(); virtual vhdl_expr *to_integer(); virtual vhdl_expr *to_std_logic(); + virtual vhdl_expr *to_std_ulogic(); virtual vhdl_expr *to_vector(vhdl_type_name_t name, int w); protected: const vhdl_type *type_; @@ -198,6 +199,7 @@ public: vhdl_expr *to_boolean(); vhdl_expr *to_integer(); vhdl_expr *to_vector(vhdl_type_name_t name, int w); + vhdl_expr *to_std_ulogic(); private: char bit_; }; diff --git a/tgt-vhdl/vhdl_type.cc b/tgt-vhdl/vhdl_type.cc index 9442826c3..c448f6a5e 100644 --- a/tgt-vhdl/vhdl_type.cc +++ b/tgt-vhdl/vhdl_type.cc @@ -24,12 +24,16 @@ #include #include - vhdl_type *vhdl_type::std_logic() { return new vhdl_type(VHDL_TYPE_STD_LOGIC); } +vhdl_type *vhdl_type::std_ulogic() +{ + return new vhdl_type(VHDL_TYPE_STD_ULOGIC); +} + vhdl_type *vhdl_type::string() { return new vhdl_type(VHDL_TYPE_STRING); @@ -79,6 +83,8 @@ std::string vhdl_type::get_string() const switch (name_) { case VHDL_TYPE_STD_LOGIC: return std::string("std_logic"); + case VHDL_TYPE_STD_ULOGIC: + return std::string("std_ulogic"); case VHDL_TYPE_STD_LOGIC_VECTOR: return std::string("std_logic_vector"); case VHDL_TYPE_STRING: @@ -167,10 +173,15 @@ vhdl_type *vhdl_type::std_logic_vector(int msb, int lsb) return new vhdl_type(VHDL_TYPE_STD_LOGIC_VECTOR, msb, lsb); } -vhdl_type *vhdl_type::type_for(int width, bool issigned, int lsb) +vhdl_type *vhdl_type::type_for(int width, bool issigned, + int lsb, bool unresolved) { - if (width == 1) - return vhdl_type::std_logic(); + if (width == 1) { + if (unresolved) + return vhdl_type::std_ulogic(); + else + return vhdl_type::std_logic(); + } else if (issigned) return vhdl_type::nsigned(width, lsb); else diff --git a/tgt-vhdl/vhdl_type.hh b/tgt-vhdl/vhdl_type.hh index 3d551a3f2..9786ab9ad 100644 --- a/tgt-vhdl/vhdl_type.hh +++ b/tgt-vhdl/vhdl_type.hh @@ -25,6 +25,7 @@ enum vhdl_type_name_t { VHDL_TYPE_STD_LOGIC, + VHDL_TYPE_STD_ULOGIC, VHDL_TYPE_STD_LOGIC_VECTOR, VHDL_TYPE_STRING, VHDL_TYPE_LINE, @@ -71,6 +72,7 @@ public: // Common types static vhdl_type *std_logic(); + static vhdl_type *std_ulogic(); static vhdl_type *string(); static vhdl_type *line(); static vhdl_type *std_logic_vector(int msb, int lsb); @@ -80,7 +82,8 @@ public: static vhdl_type *boolean(); static vhdl_type *time(); - static vhdl_type *type_for(int width, bool issigned, int lsb=0); + static vhdl_type *type_for(int width, bool issigned, + int lsb=0, bool unresolved=false); static vhdl_type *array_of(vhdl_type *b, std::string &n, int m, int l); protected: vhdl_type_name_t name_; From 5e1546faaf9567f14776bf5d3a6933c551ca9219 Mon Sep 17 00:00:00 2001 From: Cary R Date: Sun, 5 Sep 2010 12:30:03 -0700 Subject: [PATCH 04/19] Don't elide a BUFZ that represents a continuous assignment. To prevent a force from back propagating we need to keep a BUFZ that represents a continuous assignment between two nets. This only effects continuous assignments of the form assign out = in. In general these are fairly rare so keeping them has minimal impact on the simulation speed. --- tgt-vvp/vvp_scope.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index aed28c035..da38e9647 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -260,9 +260,43 @@ const char*drive_string(ivl_drive_t drive) * on. The last net is selected as the output of the nexus. */ +/* + * When checking if we can elide a buffer we need to keep the buffer + * if both the input and output for the buffer are connected only + * to netlist signals. This routine performs this check on the + * given nexus. + */ +static unsigned is_netlist_signal(ivl_net_logic_t net, ivl_nexus_t nex) +{ + unsigned idx, rtn; + + /* Assume that this is a netlist signal. */ + rtn = 1; + + for (idx = 0; idx < ivl_nexus_ptrs(nex); idx += 1) { + ivl_nexus_ptr_t nptr; + ivl_signal_t sptr; + + nptr = ivl_nexus_ptr(nex, idx); + + /* Skip a pointer to the buffer we're checking. */ + if (ivl_nexus_ptr_log(nptr) == net) continue; + + /* Check to see if this is a netlist signal. */ + sptr = ivl_nexus_ptr_sig(nptr); + if (sptr && !ivl_signal_local(sptr)) continue; + + /* If we get here then this is not just a netlist signal. */ + rtn = 0; + break; + } + + return rtn; +} + /* * This tests a bufz device against an output receiver, and determines - * if the device can be skipped. If this function returns true, then a + * if the device can be skipped. If this function returns false, then a * gate will be generated for this node. Otherwise, the code generator * will connect its input to its output and skip the gate. */ @@ -311,6 +345,14 @@ int can_elide_bufz(ivl_net_logic_t net, ivl_nexus_ptr_t nptr) if (drive_count != 1) return 0; + /* If both the input and output are netlist signal then we cannot + elide a BUFZ since it represents a continuous assignment. */ + if (is_netlist_signal(net, ivl_logic_pin(net, 0)) && + is_netlist_signal(net, ivl_logic_pin(net, 1)) && + (ivl_logic_type(net) == IVL_LO_BUFZ)) { + return 0; + } + return 1; } From 4b98a50dce99b2834d8f52d38965690b1a46d375 Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 7 Sep 2010 16:18:06 -0700 Subject: [PATCH 05/19] Report and fail gracefully for recursive parameter definitions. If someone accidentally makes a parameter depend on itself we need to report this not crash. This patch fixes the crash and prints an appropriate string of messages to figure out the loop. Icarus currently supports forward references of parameters so more complicated loops can be created. These are also caught. --- eval_tree.cc | 28 +++++++++++++++++----------- net_design.cc | 49 ++++++++++++++++++++++++++++++++----------------- net_expr.cc | 16 +++++++++++++++- netlist.h | 3 +++ 4 files changed, 67 insertions(+), 29 deletions(-) diff --git a/eval_tree.cc b/eval_tree.cc index 6f744f452..993025568 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -858,7 +858,7 @@ NetExpr* NetEBDiv::eval_tree(int prune_to_width) eval_expr(right_); if (expr_type() == IVL_VT_REAL) return eval_tree_real_(); - + assert(expr_type() == IVL_VT_LOGIC); NetEConst*lc = dynamic_cast(left_); @@ -1228,6 +1228,12 @@ NetExpr* NetEParam::eval_tree(int prune_to_width) << *this << endl; } + if (solving()) { + cerr << get_fileline() << ": warning: Recursive parameter " + "reference found involving " << *this << "." << endl; + return 0; + } + assert(scope_); perm_string name = (*reference_).first; const NetExpr*expr = (*reference_).second.expr; @@ -1239,35 +1245,35 @@ NetExpr* NetEParam::eval_tree(int prune_to_width) << *this << " cannot be evaluated." << endl; return 0; } -// ivl_assert(*this, expr); - - NetExpr*nexpr = expr->dup_expr(); - assert(nexpr); // If the parameter that I refer to is already evaluated, then // return the constant value. - if (NetEConst*tmp = dynamic_cast(nexpr)) { + if (const NetEConst*tmp = dynamic_cast(expr)) { verinum val = tmp->value(); NetEConstParam*ptmp = new NetEConstParam(scope_, name, val); ptmp->set_line(*this); - delete nexpr; return ptmp; } - if (NetECReal*tmp = dynamic_cast(nexpr)) { + if (const NetECReal*tmp = dynamic_cast(expr)) { verireal val = tmp->value(); NetECRealParam*ptmp = new NetECRealParam(scope_, name, val); ptmp->set_line(*this); - delete nexpr; return ptmp; } // Try to evaluate the expression. If I cannot, then the // expression is not a constant expression and I fail here. + + solving(true); + NetExpr*nexpr = expr->dup_expr(); + assert(nexpr); NetExpr*res = nexpr->eval_tree(); + solving(false); if (res == 0) { - cerr << get_fileline() << ": internal error: Unable to evaluate " - << "parameter " << name << " expression: " + cerr << get_fileline() << ": internal error: Unable to evaluate "; + if (expr_type() == IVL_VT_REAL) cerr << "real "; + cerr << "parameter " << name << " expression: " << *nexpr << endl; delete nexpr; return 0; diff --git a/net_design.cc b/net_design.cc index 84c4a55a1..055e620ed 100644 --- a/net_design.cc +++ b/net_design.cc @@ -341,8 +341,7 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur) eval_expr((*cur).second.msb); if (! eval_as_long(msb, (*cur).second.msb)) { cerr << (*cur).second.expr->get_fileline() - << ": internal error: " - << "unable to evaluate msb expression " + << ": error: Unable to evaluate msb expression " << "for parameter " << (*cur).first << ": " << *(*cur).second.msb << endl; des->errors += 1; @@ -357,8 +356,7 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur) eval_expr((*cur).second.lsb); if (! eval_as_long(lsb, (*cur).second.lsb)) { cerr << (*cur).second.expr->get_fileline() - << ": internal error: " - << "unable to evaluate lsb expression " + << ": error: Unable to evaluate lsb expression " << "for parameter " << (*cur).first << ": " << *(*cur).second.lsb << endl; des->errors += 1; @@ -384,10 +382,10 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur) case IVL_VT_REAL: if (! dynamic_cast(expr)) { cerr << expr->get_fileline() - << ": internal error: " - << "unable to evaluate real parameter value: " - << *expr << endl; + << ": error: Unable to evaluate real parameter " + << (*cur).first << " value: " << *expr << endl; des->errors += 1; + (*cur).second.expr = NULL; return; } break; @@ -396,11 +394,10 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur) case IVL_VT_BOOL: if (! dynamic_cast(expr)) { cerr << expr->get_fileline() - << ": internal error: " - << "unable to evaluate parameter " - << (*cur).first - << " value: " << *expr << endl; + << ": error: Unable to evaluate parameter " + << (*cur).first << " value: " << *expr << endl; des->errors += 1; + (*cur).second.expr = NULL; return; } break; @@ -408,8 +405,9 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur) default: cerr << expr->get_fileline() << ": internal error: " - << "unhandled expression type?" << endl; + << "Unhandled expression type?" << endl; des->errors += 1; + (*cur).second.expr = NULL; return; } @@ -522,7 +520,13 @@ void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur) if (NetECReal*tmp = dynamic_cast(expr)) { res = tmp; } else { - ivl_assert(*expr, 0); + cerr << expr->get_fileline() + << ": error: " + << "Unable to evaluate real parameter " + << (*cur).first << " value: " << *expr << endl; + des->errors += 1; + (*cur).second.expr = NULL; + return; } break; @@ -533,12 +537,23 @@ void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur) res = new NetECReal(val); res->set_line(*tmp); } else { - ivl_assert(*expr, 0); + cerr << expr->get_fileline() + << ": error: " + << "Unable to evaluate parameter " + << (*cur).first << " value: " << *expr << endl; + des->errors += 1; + (*cur).second.expr = NULL; + return; } break; default: - ivl_assert(*expr, 0); + cerr << expr->get_fileline() + << ": internal error: " + << "Unhandled expression type?" << endl; + des->errors += 1; + (*cur).second.expr = NULL; + return; break; } @@ -586,7 +601,7 @@ void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur) if (! from_flag) { cerr << res->get_fileline() << ": error: " << "Parameter value " << value - << " is out of range for parameter " << (*cur).first + << " is out of range for real parameter " << (*cur).first << "." << endl; des->errors += 1; } @@ -612,7 +627,7 @@ void NetScope::evaluate_parameters(Design*des) // Resolve the expression type (signed/unsigned) if the // expression is present. It is possible to not be - // present if there are earlier errors en elaboration. + // present if there are earlier errors in elaboration. if (cur->second.expr) cur->second.expr->resolve_pexpr_type(); diff --git a/net_expr.cc b/net_expr.cc index 3b5890caa..1dc1c3cb1 100644 --- a/net_expr.cc +++ b/net_expr.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -488,18 +488,21 @@ const NetScope* NetECRealParam::scope() const NetEParam::NetEParam() : des_(0), scope_(0) { + solving_ = false; } NetEParam::NetEParam(Design*d, NetScope*s, perm_string n) : des_(d), scope_(s), reference_(scope_->find_parameter(n)) { cast_signed_base_(reference_->second.signed_flag); + solving_ = false; } NetEParam::NetEParam(Design*d, NetScope*s, ref_t ref) : des_(d), scope_(s), reference_(ref) { cast_signed_base_(reference_->second.signed_flag); + solving_ = false; } NetEParam::~NetEParam() @@ -519,10 +522,21 @@ ivl_variable_type_t NetEParam::expr_type() const NetEParam* NetEParam::dup_expr() const { NetEParam*tmp = new NetEParam(des_, scope_, reference_); + tmp->solving(solving_); tmp->set_line(*this); return tmp; } +void NetEParam::solving(bool arg) +{ + solving_ = arg; +} + +bool NetEParam::solving() const +{ + return solving_; +} + NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid) : expr_(exp), base_(base) { diff --git a/netlist.h b/netlist.h index 04ef95a06..6c25220eb 100644 --- a/netlist.h +++ b/netlist.h @@ -3574,6 +3574,8 @@ class NetEParam : public NetExpr { virtual ivl_variable_type_t expr_type() const; virtual NetExpr* eval_tree(int prune_to_width = -1); virtual NetEParam* dup_expr() const; + void solving(bool arg); + bool solving() const; virtual void dump(ostream&) const; @@ -3582,6 +3584,7 @@ class NetEParam : public NetExpr { NetScope*scope_; typedef map::iterator ref_t; ref_t reference_; + bool solving_; NetEParam(class Design*des, NetScope*scope, ref_t ref); }; From b252dc0192f0a70103787eaf0ea26b8da5a71003 Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 7 Sep 2010 18:01:50 -0700 Subject: [PATCH 06/19] Don't elide unconnected module ports. When performing a translation we do not want to elide any module ports. Dropping ports can result in port mismatch issues. --- nodangle.cc | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/nodangle.cc b/nodangle.cc index 5ce442dac..68c2118ee 100644 --- a/nodangle.cc +++ b/nodangle.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -131,14 +131,12 @@ void nodangle_f::signal(Design*des, NetNet*sig) if (sig->get_refs() > 0) return; - /* Cannot delete the ports of tasks or functions. There are - too many places where they are referenced. */ - if ((sig->port_type() != NetNet::NOT_A_PORT) - && (sig->scope()->type() == NetScope::TASK)) - return; - - if ((sig->port_type() != NetNet::NOT_A_PORT) - && (sig->scope()->type() == NetScope::FUNC)) + /* Cannot delete the ports of tasks, functions or modules. There + are too many places where they are referenced. */ + if ((sig->port_type() != NetNet::NOT_A_PORT) && + ((sig->scope()->type() == NetScope::TASK) || + (sig->scope()->type() == NetScope::FUNC) || + (sig->scope()->type() == NetScope::MODULE))) return; /* Can't delete ports of cells. */ From 4001c7a27f5862952f59d06c7fd21b37138d95cd Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 13 Sep 2010 09:08:40 -0700 Subject: [PATCH 07/19] An if statement is optional and results in no delay. While checking for an infinite loop in an always block I missed the case where an if statement does not have a statement. This was resulting in a segmentation fault. --- netlist.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/netlist.cc b/netlist.cc index 215aedac8..bce287665 100644 --- a/netlist.cc +++ b/netlist.cc @@ -227,7 +227,7 @@ bool NetPins::is_linked(void) NetObj::NetObj(NetScope*s, perm_string n, unsigned np) : NetPins(np), scope_(s), name_(n), delay1_(0), delay2_(0), delay3_(0) { - /* Don't + /* Don't ivl_assert(*this, np > 0); * because it would happen before we get to print a useful * message in the NetNet constructor @@ -2697,7 +2697,11 @@ DelayType NetCondit::delay_type() const } else { /* Because of the indeterminate conditional value the * best we can have for this case is a possible delay. */ - result = combine_delays(if_->delay_type(), NO_DELAY); + if (if_) { + result = combine_delays(if_->delay_type(), NO_DELAY); + } else { + result = NO_DELAY; + } } return result; From acb55916dad1cfe7ede5fc18852bf3572a3944d2 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 13 Sep 2010 15:45:19 -0700 Subject: [PATCH 08/19] Resize constants in eval_expr when needed. If we are given an unsized constant that is smaller then the requested width then resize the constant to fit. --- netmisc.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/netmisc.cc b/netmisc.cc index f2644cc56..8bde89a53 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -289,8 +289,15 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, void eval_expr(NetExpr*&expr, int prune_width) { assert(expr); - if (dynamic_cast(expr)) return; if (dynamic_cast(expr)) return; + /* Resize a constant if allowed and needed. */ + if (NetEConst *tmp = dynamic_cast(expr)) { + if (prune_width <= 0) return; + if (tmp->has_width()) return; + if ((unsigned)prune_width <= tmp->expr_width()) return; + expr = pad_to_width(expr, (unsigned)prune_width, *expr); + return; + } NetExpr*tmp = expr->eval_tree(prune_width); if (tmp != 0) { From 5ae3e48cdba0a464b2710dcc8908d96be4002a63 Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 14 Sep 2010 16:35:27 -0700 Subject: [PATCH 09/19] Fix generation of PS files and hence PDF files on cygwin. The Cygwin man command requires that you have a / in the path if you want to avoid looking at the normal search path. This patch addes ./ before the manual page file name. Which should work on any system. It also makes the vvp generation create a PS file like is done in the other Makefiles. By default we generate normal manual pages. You can then create PostScript version and from these you can generate a PDF version. --- Makefile.in | 2 +- driver/Makefile.in | 2 +- vvp/Makefile.in | 9 ++++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Makefile.in b/Makefile.in index 2614e374c..7a9f120cc 100644 --- a/Makefile.in +++ b/Makefile.in @@ -240,7 +240,7 @@ iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in version.exe tail -n +2 $(srcdir)/iverilog-vpi.man.in >> $@ iverilog-vpi.ps: iverilog-vpi.man - $(MAN) -t iverilog-vpi.man > iverilog-vpi.ps + $(MAN) -t ./iverilog-vpi.man > iverilog-vpi.ps iverilog-vpi.pdf: iverilog-vpi.ps $(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf diff --git a/driver/Makefile.in b/driver/Makefile.in index 054c0b1ac..26d6346b7 100644 --- a/driver/Makefile.in +++ b/driver/Makefile.in @@ -89,7 +89,7 @@ iverilog.man: $(srcdir)/iverilog.man.in ../version.exe tail -n +2 $(srcdir)/iverilog.man.in >> $@ iverilog.ps: iverilog.man - $(MAN) -t iverilog.man > iverilog.ps + $(MAN) -t ./iverilog.man > iverilog.ps iverilog.pdf: iverilog.ps $(PS2PDF) iverilog.ps iverilog.pdf diff --git a/vvp/Makefile.in b/vvp/Makefile.in index bf55273c1..b68832fdb 100644 --- a/vvp/Makefile.in +++ b/vvp/Makefile.in @@ -59,7 +59,7 @@ all: dep vvp@EXEEXT@ libvpi.a vvp.man clean: rm -f *.o *~ parse.cc parse.h lexor.cc tables.cc - rm -rf dep vvp@EXEEXT@ libvpi.a parse.output vvp.man vvp.pdf vvp.exp + rm -rf dep vvp@EXEEXT@ libvpi.a parse.output vvp.man vvp.ps vvp.pdf vvp.exp distclean: clean rm -f Makefile config.log @@ -152,8 +152,11 @@ vvp.man: $(srcdir)/vvp.man.in ../version.exe ../version.exe `head -1 $(srcdir)/vvp.man.in`'\n' > $@ tail -n +2 $(srcdir)/vvp.man.in >> $@ -vvp.pdf: vvp.man - $(MAN) -t $(srcdir)/vvp.man | $(PS2PDF) - vvp.pdf +vvp.ps: vvp.man + $(MAN) -t ./vvp.man > vvp.ps + +vvp.pdf: vvp.ps + $(PS2PDF) vvp.ps vvp.pdf ifeq (@MINGW32@,yes) ifeq ($(MAN),none) From dd4fb9b4ef1a62574c9f0e378c374d97a1bd046d Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 14 Sep 2010 16:10:41 -0700 Subject: [PATCH 10/19] Fix spacing issues. This patch removes space before a tab and space or tab before end of line. --- driver/globals.h | 4 +- driver/iverilog.man.in | 2 +- elab_net.cc | 8 +- elaborate.cc | 2 +- examples/des.v | 126 ++++++++++---------- examples/pal_reg.v | 8 +- examples/sqrt-virtex.v | 4 +- expr_synth.cc | 2 +- ivlpp/lexor.lex | 10 +- main.cc | 2 +- mingw.txt | 2 +- net_link.cc | 2 +- net_scope.cc | 4 +- parse.y | 2 +- pform.cc | 18 +-- pform.h | 2 +- symbol_search.cc | 2 +- tgt-vhdl/Makefile.in | 2 +- tgt-vhdl/cast.cc | 38 +++--- tgt-vhdl/display.cc | 26 ++--- tgt-vhdl/expr.cc | 50 ++++---- tgt-vhdl/logic.cc | 30 ++--- tgt-vhdl/lpm.cc | 56 ++++----- tgt-vhdl/process.cc | 16 +-- tgt-vhdl/scope.cc | 244 +++++++++++++++++++-------------------- tgt-vhdl/state.cc | 12 +- tgt-vhdl/stmt.cc | 126 ++++++++++---------- tgt-vhdl/support.cc | 6 +- tgt-vhdl/support.hh | 2 +- tgt-vhdl/vhdl.cc | 6 +- tgt-vhdl/vhdl_element.cc | 6 +- tgt-vhdl/vhdl_element.hh | 2 +- tgt-vhdl/vhdl_helper.hh | 4 +- tgt-vhdl/vhdl_syntax.cc | 128 ++++++++++---------- tgt-vhdl/vhdl_syntax.hh | 46 ++++---- tgt-vhdl/vhdl_target.h | 5 +- tgt-vhdl/vhdl_type.cc | 2 +- tgt-vhdl/vhdl_type.hh | 4 +- tgt-vvp/eval_expr.c | 2 +- vvp/array.cc | 3 +- vvp/concat.cc | 2 +- vvp/event.cc | 2 +- vvp/examples/vector.vvp | 2 +- vvp/schedule.h | 4 +- vvp/vpi_mcd.cc | 2 +- vvp/vpi_vthr_vector.cc | 2 +- vvp/vvp_net.cc | 4 +- vvp/vvp_net.h | 1 - vvp/words.cc | 2 +- 49 files changed, 517 insertions(+), 520 deletions(-) diff --git a/driver/globals.h b/driver/globals.h index 22be7a12e..810787f93 100644 --- a/driver/globals.h +++ b/driver/globals.h @@ -40,10 +40,10 @@ extern void process_include_dir(const char*name); /* Add a new -D define. */ extern void process_define(const char*name); - + /* Add a new parameter definition */ extern void process_parameter(const char*name); - + /* Set the default timescale for the simulator. */ extern void process_timescale(const char*ts_string); diff --git a/driver/iverilog.man.in b/driver/iverilog.man.in index a42a89b23..2cb0bc488 100644 --- a/driver/iverilog.man.in +++ b/driver/iverilog.man.in @@ -64,7 +64,7 @@ Verilog source for use by other compilers. .B -g1995\fI|\fP-g2001\fI|\fP-g2001-noconfig\fI|\fP-g2005\fI|\fP-g2009 Select the Verilog language \fIgeneration\fP to support in the compiler. This selects between \fIIEEE1364\-1995\fP, -\fIIEEE1364\-2001\fP, \fIIEEE1364\-2005\fP, or \fIIEEE1800-2009\fP. +\fIIEEE1364\-2001\fP, \fIIEEE1364\-2005\fP, or \fIIEEE1800-2009\fP. Normally, Icarus Verilog defaults to the latest known generation of the language. This flag is most useful to restrict the language to a set supported by tools of specific generations, for compatibility with diff --git a/elab_net.cc b/elab_net.cc index 6cccd5205..06ef24b51 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -497,7 +497,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope, /* The array has a part/bit select at the end. */ if (name_tail.index.size() > sig->array_dimensions()) { if (sig->get_scalar()) { - cerr << get_fileline() << ": error: " + cerr << get_fileline() << ": error: " << "can not select part of "; if (sig->data_type() == IVL_VT_REAL) cerr << "real"; else cerr << "scalar"; @@ -512,7 +512,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope, return 0; if (lidx_tmp < 0) { - cerr << get_fileline() << ": sorry: part selects " + cerr << get_fileline() << ": sorry: part selects " "straddling the start of signal (" << path_ << ") are not currently supported." << endl; des->errors += 1; @@ -523,7 +523,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope, } } else if (!name_tail.index.empty()) { if (sig->get_scalar()) { - cerr << get_fileline() << ": error: " + cerr << get_fileline() << ": error: " << "can not select part of "; if (sig->data_type() == IVL_VT_REAL) cerr << "real: "; else cerr << "scalar: "; @@ -537,7 +537,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope, return 0; if (lidx_tmp < 0) { - cerr << get_fileline() << ": sorry: part selects " + cerr << get_fileline() << ": sorry: part selects " "straddling the start of signal (" << path_ << ") are not currently supported." << endl; des->errors += 1; diff --git a/elaborate.cc b/elaborate.cc index a53d46733..70fe2a0b5 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -1422,7 +1422,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const des->errors += 1; continue; } - + // We do not support real inout ports at all. if (!prts.empty() && (prts[0]->data_type() == IVL_VT_REAL )) { cerr << pins[idx]->get_fileline() << ": error: " diff --git a/examples/des.v b/examples/des.v index a0eeff187..59cd0d370 100644 --- a/examples/des.v +++ b/examples/des.v @@ -162,11 +162,11 @@ end endmodule module des(pt, key, ct, clk); -input [1:64] pt; -input [1:64] key; -output [1:64] ct; -input clk; -wire [1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x; +input [1:64] pt; +input [1:64] key; +output [1:64] ct; +input clk; +wire [1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x; wire [1:32] l0x,l1x,l2x,l3x,l4x,l5x,l6x,l7x,l8x,l9x,l10x,l11x,l12x,l13x,l14x,l15x,l16x; wire [1:32] r0x,r1x,r2x,r3x,r4x,r5x,r6x,r7x,r8x,r9x,r10x,r11x,r12x,r13x,r14x,r15x,r16x; @@ -194,9 +194,9 @@ endmodule module pc1(key, c0x, d0x); -input [1:64] key; -output [1:28] c0x, d0x; -wire [1:56] XX; +input [1:64] key; +output [1:28] c0x, d0x; +wire [1:56] XX; assign XX[1]=key[57]; assign XX[2]=key[49]; assign XX[3]=key[41]; assign XX[4]=key[33]; assign XX[5]=key[25]; assign XX[6]=key[17]; assign XX[7]=key[9]; assign XX[8]=key[1]; assign XX[9]=key[58]; assign XX[10]=key[50]; assign XX[11]=key[42]; assign XX[12]=key[34]; assign XX[13]=key[26]; assign XX[14]=key[18]; @@ -213,9 +213,9 @@ endmodule module pc2(c,d,k); -input [1:28] c,d; -output [1:48] k; -wire [1:56] YY; +input [1:28] c,d; +output [1:48] k; +wire [1:56] YY; assign YY[1:28]=c; assign YY[29:56]=d; @@ -231,7 +231,7 @@ endmodule module rol1(o, i); -output [1:28] o; +output [1:28] o; input [1:28] i; assign o={i[2:28],i[1]}; @@ -240,7 +240,7 @@ endmodule module rol2(o, i); -output [1:28] o; +output [1:28] o; input [1:28] i; assign o={i[3:28],i[1:2]}; @@ -248,10 +248,10 @@ endmodule module keysched(key,k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x); -input [1:64] key; -output [1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x; -wire [1:28] c0x,c1x,c2x,c3x,c4x,c5x,c6x,c7x,c8x,c9x,c10x,c11x,c12x,c13x,c14x,c15x,c16x; -wire [1:28] d0x,d1x,d2x,d3x,d4x,d5x,d6x,d7x,d8x,d9x,d10x,d11x,d12x,d13x,d14x,d15x,d16x; +input [1:64] key; +output [1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x; +wire [1:28] c0x,c1x,c2x,c3x,c4x,c5x,c6x,c7x,c8x,c9x,c10x,c11x,c12x,c13x,c14x,c15x,c16x; +wire [1:28] d0x,d1x,d2x,d3x,d4x,d5x,d6x,d7x,d8x,d9x,d10x,d11x,d12x,d13x,d14x,d15x,d16x; pc1 pc1(key, c0x, d0x); @@ -294,10 +294,10 @@ endmodule module s1(clk, b, so); -input clk; -input [1:6] b; -output [1:4] so; -reg [1:4] so; +input clk; +input [1:6] b; +output [1:4] so; +reg [1:4] so; always @(posedge clk) casex(b) @@ -370,10 +370,10 @@ endmodule module s2(clk, b, so); -input clk; -input [1:6] b; -output [1:4] so; -reg [1:4] so; +input clk; +input [1:6] b; +output [1:4] so; +reg [1:4] so; always @(posedge clk) casex(b) @@ -446,10 +446,10 @@ endmodule module s3(clk, b, so); -input clk; -input [1:6] b; -output [1:4] so; -reg [1:4] so; +input clk; +input [1:6] b; +output [1:4] so; +reg [1:4] so; always @(posedge clk) casex(b) @@ -522,10 +522,10 @@ endmodule module s4(clk, b, so); -input clk; -input [1:6] b; -output [1:4] so; -reg [1:4] so; +input clk; +input [1:6] b; +output [1:4] so; +reg [1:4] so; always @(posedge clk) casex(b) @@ -598,10 +598,10 @@ endmodule module s5(clk, b, so); -input clk; -input [1:6] b; -output [1:4] so; -reg [1:4] so; +input clk; +input [1:6] b; +output [1:4] so; +reg [1:4] so; always @(posedge clk) casex(b) @@ -674,10 +674,10 @@ endmodule module s6(clk, b, so); -input clk; -input [1:6] b; -output [1:4] so; -reg [1:4] so; +input clk; +input [1:6] b; +output [1:4] so; +reg [1:4] so; always @(posedge clk) casex(b) @@ -750,10 +750,10 @@ endmodule module s7(clk, b, so); -input clk; -input [1:6] b; -output [1:4] so; -reg [1:4] so; +input clk; +input [1:6] b; +output [1:4] so; +reg [1:4] so; always @(posedge clk) casex(b) @@ -826,10 +826,10 @@ endmodule module s8(clk, b, so); -input clk; -input [1:6] b; -output [1:4] so; -reg [1:4] so; +input clk; +input [1:6] b; +output [1:4] so; +reg [1:4] so; always @(posedge clk) casex(b) @@ -902,8 +902,8 @@ endmodule module ip(pt, l0x, r0x); -input [1:64] pt; -output [1:32] l0x, r0x; +input [1:64] pt; +output [1:32] l0x, r0x; assign l0x[1]=pt[58]; assign l0x[2]=pt[50]; assign l0x[3]=pt[42]; assign l0x[4]=pt[34]; assign l0x[5]=pt[26]; assign l0x[6]=pt[18]; assign l0x[7]=pt[10]; assign l0x[8]=pt[2]; @@ -941,10 +941,10 @@ endmodule module desxor1(e,b1x,b2x,b3x,b4x,b5x,b6x,b7x,b8x,k); -input [1:48] e; -output [1:6] b1x,b2x,b3x,b4x,b5x,b6x,b7x,b8x; -input [1:48] k; -wire [1:48] XX; +input [1:48] e; +output [1:6] b1x,b2x,b3x,b4x,b5x,b6x,b7x,b8x; +input [1:48] k; +wire [1:48] XX; assign XX = k ^ e; assign b1x = XX[1:6]; @@ -960,9 +960,9 @@ endmodule module pp(so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x,ppo); -input [1:4] so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x; -output [1:32] ppo; -wire [1:32] XX; +input [1:4] so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x; +output [1:32] ppo; +wire [1:32] XX; assign XX[1:4]=so1x; assign XX[5:8]=so2x; assign XX[9:12]=so3x; assign XX[13:16]=so4x; assign XX[17:20]=so5x; assign XX[21:24]=so6x; assign XX[25:28]=so7x; assign XX[29:32]=so8x; @@ -980,8 +980,8 @@ endmodule module desxor2(d,l,q); -input [1:32] d,l; -output [1:32] q; +input [1:32] d,l; +output [1:32] q; assign q = d ^ l; @@ -994,10 +994,10 @@ input [1:32] li, ri; input [1:48] k; output [1:32] lo, ro; -wire [1:48] e; +wire [1:48] e; wire [1:6] b1x,b2x,b3x,b4x,b5x,b6x,b7x,b8x; wire [1:4] so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x; -wire [1:32] ppo; +wire [1:32] ppo; xp xp(ri, e); desxor1 desxor1(e, b1x, b2x, b3x, b4x, b5x, b6x, b7x, b8x, k); @@ -1018,7 +1018,7 @@ endmodule module fp(l,r,ct); -input [1:32] l,r; +input [1:32] l,r; output [1:64] ct; assign ct[1]=r[8]; assign ct[2]=l[8]; assign ct[3]=r[16]; assign ct[4]=l[16]; assign ct[5]=r[24]; assign ct[6]=l[24]; assign ct[7]=r[32]; assign ct[8]=l[32]; diff --git a/examples/pal_reg.v b/examples/pal_reg.v index f959a6e1b..2207c88a1 100644 --- a/examples/pal_reg.v +++ b/examples/pal_reg.v @@ -55,12 +55,12 @@ module register (out, val, clk, oe); output [7:0] out; - input [7:0] val; - input clk, oe; + input [7:0] val; + input clk, oe; - reg [7:0] Q; + reg [7:0] Q; - wire [7:0] out; + wire [7:0] out; bufif0 drv[7:0](out, Q, oe); diff --git a/examples/sqrt-virtex.v b/examples/sqrt-virtex.v index bc95d4939..ad532eab3 100644 --- a/examples/sqrt-virtex.v +++ b/examples/sqrt-virtex.v @@ -252,7 +252,7 @@ endmodule // sqrt32 module main; reg [31:0] x; - reg clk, reset; + reg clk, reset; wire [15:0] y; wire rdy; @@ -354,7 +354,7 @@ module chip_root(clk, rdy, reset, x, y); input [31:0] x; output [15:0] y; - wire clk_int; + wire clk_int; (* cellref="BUFG:O,I" *) buf gbuf (clk_int, clk); diff --git a/expr_synth.cc b/expr_synth.cc index e58c2b30d..c279364ae 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -1328,7 +1328,7 @@ static NetEvWait* make_func_trigger(Design*des, NetScope*scope, NetExpr*root) delete nset; return trigger; -} +} NetNet* NetESFunc::synthesize(Design*des, NetScope*scope, NetExpr*root) { diff --git a/ivlpp/lexor.lex b/ivlpp/lexor.lex index b63fa377d..4f3577e89 100644 --- a/ivlpp/lexor.lex +++ b/ivlpp/lexor.lex @@ -1394,19 +1394,19 @@ static void do_expand(int use_args) str_buf[idx+1] = '0'; str_buf[idx+2] = '4'; str_buf[idx+3] = '2'; - idx += 4; - continue; + idx += 4; + continue; } if (*cp == '\\') { str_buf[idx] = '\\'; str_buf[idx+1] = '1'; str_buf[idx+2] = '3'; str_buf[idx+3] = '4'; - idx += 4; - continue; + idx += 4; + continue; } str_buf[idx] = *cp; - idx += 1; + idx += 1; } str_buf[idx] = 0; idx += 1; diff --git a/main.cc b/main.cc index 51cccfb1d..1370d2cb6 100644 --- a/main.cc +++ b/main.cc @@ -872,7 +872,7 @@ int main(int argc, char*argv[]) if (gn_cadence_types_flag) lexor_keyword_mask |= GN_KEYWORDS_ICARUS; - + if (gn_verilog_ams_flag) lexor_keyword_mask |= GN_KEYWORDS_VAMS_2_3; diff --git a/mingw.txt b/mingw.txt index c8a2ee063..af1c61489 100644 --- a/mingw.txt +++ b/mingw.txt @@ -84,7 +84,7 @@ Download the msys-1.x.x.exe and msysdtc-1.x.x.exe binaries. These are self-installing packages. Install msys first, and then msysDTC. Most likely, you want to install them in c:/msys. (The msysDTK is installed in the same location, as it is an add-on.) - + This install should be easy and reliable. The installation will leave an "msys" icon on your desktop and in the diff --git a/net_link.cc b/net_link.cc index 2bf71302c..e53f9da6a 100644 --- a/net_link.cc +++ b/net_link.cc @@ -382,7 +382,7 @@ void Nexus::unlink(Link*that) } // If the link I'm removing was a driver for this nexus, then - // cancel my guess of the driven value. + // cancel my guess of the driven value. if (that->get_dir() != Link::INPUT) driven_ = NO_GUESS; diff --git a/net_scope.cc b/net_scope.cc index c9760cd0c..ae84b6e39 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -251,14 +251,14 @@ void NetScope::print_type(ostream&stream) const break; case FORK_JOIN: stream << "parallel block"; - break; + break; case FUNC: stream << "function"; break; case MODULE: stream << "module <" << (module_name_ ? module_name_.str() : "") << "> instance"; - break; + break; case TASK: stream << "task"; break; diff --git a/parse.y b/parse.y index a9a5bfc3f..fe87b00e7 100644 --- a/parse.y +++ b/parse.y @@ -2052,7 +2052,7 @@ local_timeunit_prec_decl module : attribute_list_opt module_start IDENTIFIER { pform_startmodule($3, @2.text, @2.first_line, $1); } module_parameter_port_list_opt - module_port_list_opt + module_port_list_opt module_attribute_foreign ';' { pform_module_set_ports($6); } local_timeunit_prec_decl_opt diff --git a/pform.cc b/pform.cc index 973f52c70..230843bd2 100644 --- a/pform.cc +++ b/pform.cc @@ -62,7 +62,7 @@ void parm_to_defparam_list(const string¶m) key = strdup(param.substr(0, off).c_str()); value = strdup(param.substr(off+1).c_str()); } - + // Resolve hierarchical name for defparam. Remember // to deal with bit select for generate scopes. Bit // select expression should be constant interger. @@ -109,7 +109,7 @@ void parm_to_defparam_list(const string¶m) ptr = strchr(nkey, '.'); } name.push_back(name_component_t(lex_strings.make(nkey))); - + // Resolve value to PExpr class. Should support all kind of constant // format including based number, dec number, real number and string. if (*value == '"') { // string type @@ -127,13 +127,13 @@ void parm_to_defparam_list(const string¶m) cerr << ": error: missing close quote of string for defparam: " << name << endl; else if (*(buf_ptr+1) != 0) { // '"' appears within string with no escape cerr << buf_ptr << endl; - cerr << ": error: \'\"\' appears within string value for defparam: " << name + cerr << ": error: \'\"\' appears within string value for defparam: " << name << ". Ignore characters after \'\"\'" << endl; } - + *buf_ptr = '\0'; buf_ptr = buf+1; - // Remember to use 'new' to allocate string for PEString + // Remember to use 'new' to allocate string for PEString // because 'delete' is used by its destructor. char *nchar = strcpy(new char [strlen(buf_ptr)+1], buf_ptr); PExpr* ndec = new PEString(nchar); @@ -165,17 +165,17 @@ void parm_to_defparam_list(const string¶m) free(value); return; } - + // BASED_NUMBER with size, something like - scope.parameter=2'b11 if (num != value) { *num = 0; verinum *siz = make_unsized_dec(value); val = pform_verinum_with_size(siz, val, "", 0); } - + PExpr* ndec = new PENumber(val); Module::user_defparms.push_back( make_pair(name, ndec) ); - + } else { // REALTIME, something like - scope.parameter=1.22 or scope.parameter=1e2 @@ -799,7 +799,7 @@ void pform_endmodule(const char*name, bool inside_celldefine, tp_local_flag = false; } -static void pform_add_genvar(const struct vlltype&li, const perm_string&name, +static void pform_add_genvar(const struct vlltype&li, const perm_string&name, map&genvars) { LineInfo*lni = new LineInfo(); diff --git a/pform.h b/pform.h index 4d611ad8d..ea50b318a 100644 --- a/pform.h +++ b/pform.h @@ -418,7 +418,7 @@ extern PExpr* pform_make_branch_probe_expression(const struct vlltype&loc, extern PExpr* pform_make_branch_probe_expression(const struct vlltype&loc, char*name, char*branch); -/* +/* * Parse configuration file with format =, where key * is the hierarchical name of a valid parameter name and value * is the value user wants to assign to. The value should be constant. diff --git a/symbol_search.cc b/symbol_search.cc index f6ed3f527..8b8cadbfa 100644 --- a/symbol_search.cc +++ b/symbol_search.cc @@ -61,7 +61,7 @@ NetScope*symbol_search(const LineInfo*li, Design*des, NetScope*scope, cerr << li->get_fileline() << ": error: Hierarchical " "reference to automatically allocated item " "`" << key << "' in path `" << path << "'" << endl; - des->errors += 1; + des->errors += 1; } hier_path = true; diff --git a/tgt-vhdl/Makefile.in b/tgt-vhdl/Makefile.in index 533013cc9..ea04ee9a1 100644 --- a/tgt-vhdl/Makefile.in +++ b/tgt-vhdl/Makefile.in @@ -72,7 +72,7 @@ stamp-vhdl_config-h: $(srcdir)/vhdl_config.h.in ../config.status vhdl_config.h: stamp-vhdl_config-h clean: - rm -rf $(O) dep vhdl.tgt + rm -rf $(O) dep vhdl.tgt distclean: clean rm -f Makefile config.log diff --git a/tgt-vhdl/cast.cc b/tgt-vhdl/cast.cc index 9f54270a1..07540f71d 100644 --- a/tgt-vhdl/cast.cc +++ b/tgt-vhdl/cast.cc @@ -39,7 +39,7 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to) // we can't generate any type conversion code if (NULL == type_) return this; - + if (to->get_name() == type_->get_name()) { if (to->get_width() == type_->get_width()) return this; // Identical @@ -79,7 +79,7 @@ vhdl_expr *vhdl_expr::to_vector(vhdl_type_name_t name, int w) vhdl_bit_spec_expr *bs = new vhdl_bit_spec_expr(new vhdl_type(name, w - 1, 0), others); bs->add_bit(0, this); - + return bs; } else { @@ -89,11 +89,11 @@ vhdl_expr *vhdl_expr::to_vector(vhdl_type_name_t name, int w) vhdl_type *t = new vhdl_type(name, w - 1, 0); vhdl_fcall *conv = new vhdl_fcall(t->get_string().c_str(), t); conv->add_expr(this); - + if (w != type_->get_width()) return conv->resize(w); else - return conv; + return conv; } } @@ -110,9 +110,9 @@ vhdl_expr *vhdl_expr::to_integer() } else conv = new vhdl_fcall("To_Integer", vhdl_type::integer()); - + conv->add_expr(this); - + return conv; } @@ -130,7 +130,7 @@ vhdl_expr *vhdl_expr::to_boolean() else if (type_->get_name() == VHDL_TYPE_UNSIGNED) { // Need to use a support function for this conversion require_support_function(SF_UNSIGNED_TO_BOOLEAN); - + vhdl_fcall *conv = new vhdl_fcall(support_function::function_name(SF_UNSIGNED_TO_BOOLEAN), vhdl_type::boolean()); @@ -139,7 +139,7 @@ vhdl_expr *vhdl_expr::to_boolean() } else if (type_->get_name() == VHDL_TYPE_SIGNED) { require_support_function(SF_SIGNED_TO_BOOLEAN); - + vhdl_fcall *conv = new vhdl_fcall(support_function::function_name(SF_SIGNED_TO_BOOLEAN), vhdl_type::boolean()); @@ -157,12 +157,12 @@ vhdl_expr *vhdl_expr::to_std_logic() { if (type_->get_name() == VHDL_TYPE_BOOLEAN) { require_support_function(SF_BOOLEAN_TO_LOGIC); - + vhdl_fcall *ah = new vhdl_fcall(support_function::function_name(SF_BOOLEAN_TO_LOGIC), vhdl_type::std_logic()); ah->add_expr(this); - + return ah; } else if (type_->get_name() == VHDL_TYPE_SIGNED) { @@ -196,7 +196,7 @@ vhdl_expr *vhdl_expr::to_std_ulogic() f->add_expr(this); return f; } - else + else assert(false); } @@ -219,11 +219,11 @@ vhdl_expr *vhdl_expr::resize(int newwidth) vhdl_binop_expr* concat = new vhdl_binop_expr(zeros, VHDL_BINOP_CONCAT, this, vhdl_type::nunsigned(newwidth)); - return concat; + return concat; } else return this; // Doesn't make sense to resize non-vector type - + vhdl_fcall *resizef = new vhdl_fcall("Resize", rtype); resizef->add_expr(this); resizef->add_expr(new vhdl_const_int(newwidth)); @@ -267,10 +267,10 @@ vhdl_expr *vhdl_const_bits::to_std_logic() // VHDL won't let us cast directly between a vector and // a scalar type // But we don't need to here as we have the bits available - + // Take the least significant bit char lsb = value_[0]; - + return new vhdl_const_bit(lsb); } @@ -280,14 +280,14 @@ char vhdl_const_bits::sign_bit() const } vhdl_expr *vhdl_const_bits::to_vector(vhdl_type_name_t name, int w) -{ +{ if (name == VHDL_TYPE_STD_LOGIC_VECTOR) { // Don't need to do anything return this; } else if (name == VHDL_TYPE_SIGNED || name == VHDL_TYPE_UNSIGNED) { // Extend with sign bit - value_.resize(w, sign_bit()); + value_.resize(w, sign_bit()); return this; } assert(false); @@ -304,8 +304,8 @@ vhdl_expr *vhdl_const_bits::resize(int w) // Rather than generating a call to Resize, when can just sign-extend // the bits here. As well as looking better, this avoids any ambiguity // between which of the signed/unsigned versions of Resize to use. - - value_.resize(w, sign_bit()); + + value_.resize(w, sign_bit()); return this; } diff --git a/tgt-vhdl/display.cc b/tgt-vhdl/display.cc index 75eca6110..1f95365ec 100644 --- a/tgt-vhdl/display.cc +++ b/tgt-vhdl/display.cc @@ -48,16 +48,16 @@ static void display_write(stmt_container *container, vhdl_expr *expr) // supported by std.textio std::string name(expr->get_type()->get_string()); name += "'Image"; - + vhdl_fcall *cast = new vhdl_fcall(name.c_str(), vhdl_type::string()); cast->add_expr(expr); - + write->add_expr(cast); } - else + else write->add_expr(expr); - + container->add_stmt(write); } @@ -125,7 +125,7 @@ int draw_stask_display(vhdl_procedural *proc, stmt_container *container, line_var->set_comment("For generating $display output"); proc->get_scope()->add_decl(line_var); } - + // Write the data into the line int count = ivl_stmt_parm_count(stmt), i = 0; while (i < count) { @@ -137,7 +137,7 @@ int draw_stask_display(vhdl_procedural *proc, stmt_container *container, display_write(container, new vhdl_const_string(" ")); continue; } - + if (ivl_expr_type(net) == IVL_EX_STRING) { ostringstream ss; for (const char *p = ivl_expr_string(net); *p; p++) { @@ -154,7 +154,7 @@ int draw_stask_display(vhdl_procedural *proc, stmt_container *container, } else if (*p == '%' && *(++p) != '%') { flush_string(ss, container); - + // Skip over width for now while (isdigit(*p)) ++p; @@ -167,11 +167,11 @@ int draw_stask_display(vhdl_procedural *proc, stmt_container *container, assert(i < count); ivl_expr_t netp = ivl_stmt_parm(stmt, i++); assert(netp); - + vhdl_expr *base = translate_expr(netp); if (NULL == base) return 1; - + display_write(container, base); } } @@ -181,20 +181,20 @@ int draw_stask_display(vhdl_procedural *proc, stmt_container *container, } // Call Write on any non-empty string data left in the buffer - if (!ss.str().empty()) + if (!ss.str().empty()) display_write(container, new vhdl_const_string(ss.str().c_str())); } else { vhdl_expr *base = translate_expr(net); - if (NULL == base) + if (NULL == base) return 1; - + display_write(container, base); } } if (newline) display_line(container); - + return 0; } diff --git a/tgt-vhdl/expr.cc b/tgt-vhdl/expr.cc index 78ce66882..11dd41683 100644 --- a/tgt-vhdl/expr.cc +++ b/tgt-vhdl/expr.cc @@ -35,7 +35,7 @@ static vhdl_expr *change_signedness(vhdl_expr *e, bool issigned) int msb = e->get_type()->get_msb(); int lsb = e->get_type()->get_lsb(); vhdl_type u(issigned ? VHDL_TYPE_SIGNED : VHDL_TYPE_UNSIGNED, msb, lsb); - + return e->cast(&u); } @@ -44,9 +44,9 @@ static vhdl_expr *change_signedness(vhdl_expr *e, bool issigned) * same signedness as the Verilog expression vl_e. */ static vhdl_expr *correct_signedness(vhdl_expr *vhd_e, ivl_expr_t vl_e) -{ +{ bool should_be_signed = ivl_expr_signed(vl_e) != 0; - + if (vhd_e->get_type()->get_name() == VHDL_TYPE_UNSIGNED && should_be_signed) { //operand->print(); @@ -69,7 +69,7 @@ static vhdl_expr *correct_signedness(vhdl_expr *vhd_e, ivl_expr_t vl_e) * Convert a constant Verilog string to a constant VHDL string. */ static vhdl_expr *translate_string(ivl_expr_t e) -{ +{ // TODO: May need to inspect or escape parts of this const char *str = ivl_expr_string(e); return new vhdl_const_string(str); @@ -82,12 +82,12 @@ static vhdl_expr *translate_string(ivl_expr_t e) static vhdl_var_ref *translate_signal(ivl_expr_t e) { ivl_signal_t sig = ivl_expr_signal(e); - + const vhdl_scope *scope = find_scope_for_signal(sig); assert(scope); const char *renamed = get_renamed_signal(sig).c_str(); - + vhdl_decl *decl = scope->get_decl(renamed); assert(decl); @@ -102,7 +102,7 @@ static vhdl_var_ref *translate_signal(ivl_expr_t e) vhdl_var_ref *ref = new vhdl_var_ref(renamed, new vhdl_type(*decl->get_type())); - + ivl_expr_t off; if (ivl_signal_array_count(sig) > 0 && (off = ivl_expr_oper1(e))) { // Select from an array @@ -152,7 +152,7 @@ static vhdl_expr *translate_reduction(support_function_t f, bool neg, vhdl_fcall *fcall = new vhdl_fcall(support_function::function_name(f), vhdl_type::std_logic()); - + vhdl_type std_logic_vector(VHDL_TYPE_STD_LOGIC_VECTOR); fcall->add_expr(operand->cast(&std_logic_vector)); @@ -173,7 +173,7 @@ static vhdl_expr *translate_unary(ivl_expr_t e) return NULL; operand = correct_signedness(operand, e); - + char opcode = ivl_expr_opcode(e); switch (opcode) { case '!': @@ -234,7 +234,7 @@ static vhdl_expr *translate_relation(vhdl_expr *lhs, vhdl_expr *rhs, // Generate any necessary casts // Arbitrarily, the RHS is casted to the type of the LHS vhdl_expr *r_cast = rhs->cast(lhs->get_type()); - + return new vhdl_binop_expr(lhs, op, r_cast, vhdl_type::boolean()); } @@ -311,7 +311,7 @@ static vhdl_expr *translate_binary(ivl_expr_t e) vhdl_expr *lhs = translate_expr(ivl_expr_oper1(e)); if (NULL == lhs) return NULL; - + vhdl_expr *rhs = translate_expr(ivl_expr_oper2(e)); if (NULL == rhs) return NULL; @@ -319,7 +319,7 @@ static vhdl_expr *translate_binary(ivl_expr_t e) int lwidth = lhs->get_type()->get_width(); int rwidth = rhs->get_type()->get_width(); int result_width = ivl_expr_width(e); - + // For === and !== we need to compare std_logic_vectors // rather than signeds vhdl_type std_logic_vector(VHDL_TYPE_STD_LOGIC_VECTOR, result_width-1, 0); @@ -328,7 +328,7 @@ static vhdl_expr *translate_binary(ivl_expr_t e) bool vectorop = (ltype == VHDL_TYPE_SIGNED || ltype == VHDL_TYPE_UNSIGNED) && (rtype == VHDL_TYPE_SIGNED || rtype == VHDL_TYPE_UNSIGNED); - + // May need to resize the left or right hand side or change the // signedness if (vectorop) { @@ -425,7 +425,7 @@ static vhdl_expr *translate_binary(ivl_expr_t e) result = translate_shift(lhs, rhs, VHDL_BINOP_SRA); else result = translate_shift(lhs, rhs, VHDL_BINOP_SR); - break; + break; case '^': result = translate_numeric(lhs, rhs, VHDL_BINOP_XOR); break; @@ -463,7 +463,7 @@ static vhdl_expr *translate_select(ivl_expr_t e) return NULL; ivl_expr_t o2 = ivl_expr_oper2(e); - if (o2) { + if (o2) { vhdl_expr *base = translate_expr(ivl_expr_oper2(e)); if (NULL == base) return NULL; @@ -528,7 +528,7 @@ static vhdl_expr *translate_ufunc(ivl_expr_t e) const char *funcname = ivl_scope_tname(defscope); - vhdl_type *rettype = + vhdl_type *rettype = vhdl_type::type_for(ivl_expr_width(e), ivl_expr_signed(e) != 0); vhdl_fcall *fcall = new vhdl_fcall(funcname, rettype); @@ -539,18 +539,18 @@ static vhdl_expr *translate_ufunc(ivl_expr_t e) delete fcall; return NULL; } - + // Ensure the parameter has the correct VHDL type // Parameter number is i + 1 since 0th parameter is return value ivl_signal_t param_sig = ivl_scope_port(defscope, i + 1); vhdl_type *param_type = vhdl_type::type_for(ivl_signal_width(param_sig), ivl_signal_signed(param_sig) != 0); - + fcall->add_expr(param->cast(param_type)); delete param_type; } - + return fcall; } @@ -565,7 +565,7 @@ static vhdl_expr *translate_ternary(ivl_expr_t e) sf = SF_TERNARY_SIGNED; else sf = SF_TERNARY_UNSIGNED; - + require_support_function(sf); vhdl_expr *test = translate_expr(ivl_expr_oper1(e)); @@ -576,20 +576,20 @@ static vhdl_expr *translate_ternary(ivl_expr_t e) vhdl_type boolean(VHDL_TYPE_BOOLEAN); test = test->cast(&boolean); - + vhdl_fcall *fcall = new vhdl_fcall(support_function::function_name(sf), vhdl_type::type_for(width, issigned)); fcall->add_expr(test); fcall->add_expr(true_part); fcall->add_expr(false_part); - + return fcall; } static vhdl_expr *translate_concat(ivl_expr_t e) { - vhdl_type *rtype = + vhdl_type *rtype = vhdl_type::type_for(ivl_expr_width(e), ivl_expr_signed(e) != 0); vhdl_binop_expr *concat = new vhdl_binop_expr(VHDL_BINOP_CONCAT, rtype); @@ -716,11 +716,11 @@ vhdl_expr *translate_time_expr(ivl_expr_t e) if (time->get_type()->get_name() != VHDL_TYPE_TIME) { vhdl_type integer(VHDL_TYPE_INTEGER); time = time->cast(&integer); - + vhdl_expr *ns1 = scale_time(get_active_entity(), 1); return new vhdl_binop_expr(time, VHDL_BINOP_MULT, ns1, vhdl_type::time()); } else // Translating IVL_EX_DELAY will always return a time type - return time; + return time; } diff --git a/tgt-vhdl/logic.cc b/tgt-vhdl/logic.cc index b27f69ce2..4efe3cc33 100644 --- a/tgt-vhdl/logic.cc +++ b/tgt-vhdl/logic.cc @@ -36,11 +36,11 @@ static vhdl_expr *inputs_to_expr(vhdl_scope *scope, vhdl_binop_t op, // the program has already been type checked vhdl_binop_expr *gate = new vhdl_binop_expr(op, vhdl_type::std_logic()); - + int npins = ivl_logic_pins(log); for (int i = 1; i < npins; i++) { ivl_nexus_t input = ivl_logic_pin(log, i); - + gate->add_expr(readable_ref(scope, input)); } @@ -57,7 +57,7 @@ static vhdl_expr *input_to_expr(vhdl_scope *scope, vhdl_unaryop_t op, assert(input); vhdl_expr *operand = readable_ref(scope, input); - return new vhdl_unaryop_expr(op, operand, vhdl_type::std_logic()); + return new vhdl_unaryop_expr(op, operand, vhdl_type::std_logic()); } static void bufif_logic(vhdl_arch *arch, ivl_net_logic_t log, bool if0) @@ -65,7 +65,7 @@ static void bufif_logic(vhdl_arch *arch, ivl_net_logic_t log, bool if0) ivl_nexus_t output = ivl_logic_pin(log, 0); vhdl_var_ref *lhs = nexus_to_var_ref(arch->get_scope(), output); assert(lhs); - + vhdl_expr *val = readable_ref(arch->get_scope(), ivl_logic_pin(log, 1)); vhdl_expr *sel = readable_ref(arch->get_scope(), ivl_logic_pin(log, 2)); @@ -80,7 +80,7 @@ static void bufif_logic(vhdl_arch *arch, ivl_net_logic_t log, bool if0) vhdl_binop_t op = if0 ? VHDL_BINOP_EQ : VHDL_BINOP_NEQ; cmp = new vhdl_binop_expr(sel, op, zero, NULL); } - + ivl_signal_t sig = find_signal_named(lhs->get_name(), arch->get_scope()); char zbit; switch (ivl_signal_type(sig)) { @@ -107,12 +107,12 @@ static void bufif_logic(vhdl_arch *arch, ivl_net_logic_t log, bool if0) static void comb_udp_logic(vhdl_arch *arch, ivl_net_logic_t log) { ivl_udp_t udp = ivl_logic_udp(log); - + // As with regular case statements, the expression in a // `with .. select' statement must be "locally static". // This is achieved by first combining the inputs into // a temporary - + ostringstream ss; ss << ivl_logic_basename(log) << "_Tmp"; int msb = ivl_udp_nin(udp) - 1; @@ -149,11 +149,11 @@ static void comb_udp_logic(vhdl_arch *arch, ivl_net_logic_t log) // Ensure the select statement completely covers the input space // or some strict VHDL compilers will complain ws->add_default(new vhdl_const_bit('X')); - + int nrows = ivl_udp_rows(udp); for (int i = 0; i < nrows; i++) { const char *row = ivl_udp_row(udp, i); - + vhdl_expr *value = new vhdl_const_bit(row[nin]); vhdl_expr *cond = new vhdl_const_bits(row, nin, false); @@ -189,11 +189,11 @@ static void seq_udp_logic(vhdl_arch *arch, ivl_net_logic_t log) int msb = ivl_udp_nin(udp) - 1; vhdl_type *tmp_type = vhdl_type::std_logic_vector(msb, 0); proc->get_scope()->add_decl(new vhdl_var_decl("UDP_Inputs", tmp_type)); - + // Concatenate the inputs into a single expression that can be // used as the test in a case statement (this can't be inserted // directly into the case statement due to the requirement that - // the test expression be "locally static") + // the test expression be "locally static") int nin = ivl_udp_nin(udp); vhdl_expr *tmp_rhs = NULL; if (nin == 1) { @@ -217,7 +217,7 @@ static void seq_udp_logic(vhdl_arch *arch, ivl_net_logic_t log) proc->get_container()->add_stmt (new vhdl_assign_stmt(new vhdl_var_ref("UDP_Inputs", NULL), tmp_rhs)); - + arch->add_stmt(proc); } @@ -273,18 +273,18 @@ void draw_logic(vhdl_arch *arch, ivl_net_logic_t log) udp_logic(arch, log); break; default: - { + { // The output is always pin zero ivl_nexus_t output = ivl_logic_pin(log, 0); vhdl_var_ref *lhs = nexus_to_var_ref(arch->get_scope(), output); vhdl_expr *rhs = translate_logic_inputs(arch->get_scope(), log); vhdl_cassign_stmt *ass = new vhdl_cassign_stmt(lhs, rhs); - + ivl_expr_t delay = ivl_logic_delay(log, 1); if (delay) ass->set_after(translate_time_expr(delay)); - + arch->add_stmt(ass); } } diff --git a/tgt-vhdl/lpm.cc b/tgt-vhdl/lpm.cc index 67c09d569..c68d6bebe 100644 --- a/tgt-vhdl/lpm.cc +++ b/tgt-vhdl/lpm.cc @@ -47,7 +47,7 @@ static vhdl_expr *concat_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm) vhdl_type::type_for(ivl_lpm_width(lpm), ivl_lpm_signed(lpm) != 0); vhdl_binop_expr *expr = new vhdl_binop_expr(VHDL_BINOP_CONCAT, result_type); - + for (int i = ivl_lpm_size(lpm) - 1; i >= 0; i--) { vhdl_expr *e = readable_ref(scope, ivl_lpm_data(lpm, i)); if (NULL == e) { @@ -67,7 +67,7 @@ static vhdl_expr *binop_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm, vhdl_binop vhdl_type *result_type = vhdl_type::type_for(out_width, ivl_lpm_signed(lpm) != 0); vhdl_binop_expr *expr = new vhdl_binop_expr(op, result_type); - + for (int i = 0; i < 2; i++) { vhdl_expr *e = readable_ref(scope, ivl_lpm_data(lpm, i)); if (NULL == e) { @@ -77,16 +77,16 @@ static vhdl_expr *binop_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm, vhdl_binop expr->add_expr(e->cast(result_type)); } - + if (op == VHDL_BINOP_MULT) { // Need to resize the output to the desired size, // as this does not happen automatically in VHDL - + vhdl_fcall *resize = new vhdl_fcall("Resize", vhdl_type::nsigned(out_width)); resize->add_expr(expr); resize->add_expr(new vhdl_const_int(out_width)); - + return resize; } else @@ -106,7 +106,7 @@ static vhdl_expr *rel_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm, vhdl_binop_t delete lhs; return NULL; } - + // Ensure LHS and RHS are the same type if (lhs->get_type() != rhs->get_type()) rhs = rhs->cast(lhs->get_type()); @@ -122,20 +122,20 @@ static vhdl_expr *part_select_vp_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm) vhdl_var_ref *selfrom = readable_ref(scope, ivl_lpm_data(lpm, 0)); if (NULL == selfrom) return NULL; - + vhdl_expr *off = part_select_base(scope, lpm);; if (NULL == off) return NULL; if (selfrom->get_type()->get_width() > 1) selfrom->set_slice(off, ivl_lpm_width(lpm) - 1); - + return selfrom; } static vhdl_expr *part_select_pv_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm) -{ +{ return readable_ref(scope, ivl_lpm_data(lpm, 0)); } @@ -171,13 +171,13 @@ static vhdl_expr *reduction_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm, require_support_function(f); vhdl_fcall *fcall = new vhdl_fcall(support_function::function_name(f), vhdl_type::std_logic()); - - vhdl_type std_logic_vector(VHDL_TYPE_STD_LOGIC_VECTOR); + + vhdl_type std_logic_vector(VHDL_TYPE_STD_LOGIC_VECTOR); fcall->add_expr(ref->cast(&std_logic_vector)); - + result = fcall; - } - + } + if (invert) return new vhdl_unaryop_expr (VHDL_UNARYOP_NOT, result, vhdl_type::std_logic()); @@ -199,12 +199,12 @@ static vhdl_expr *array_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm) ivl_signal_t array = ivl_lpm_array(lpm); if (!seen_signal_before(array)) return NULL; - + const char *renamed = get_renamed_signal(array).c_str(); - + vhdl_decl *adecl = scope->get_decl(renamed); assert(adecl); - + vhdl_type *atype = new vhdl_type(*adecl->get_type()); vhdl_expr *select = readable_ref(scope, ivl_lpm_select(lpm)); @@ -212,11 +212,11 @@ static vhdl_expr *array_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm) delete atype; return NULL; } - + vhdl_var_ref *ref = new vhdl_var_ref(renamed, atype); vhdl_type integer(VHDL_TYPE_INTEGER); ref->set_slice(select->cast(&integer)); - + return ref; } @@ -226,8 +226,8 @@ static vhdl_expr *shift_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm, vhdl_expr *lhs = readable_ref(scope, ivl_lpm_data(lpm, 0)); vhdl_expr *rhs = readable_ref(scope, ivl_lpm_data(lpm, 1)); if (!lhs || !rhs) - return NULL; - + return NULL; + // The RHS must be an integer vhdl_type integer(VHDL_TYPE_INTEGER); vhdl_expr *r_cast = rhs->cast(&integer); @@ -311,7 +311,7 @@ static int draw_mux_lpm(vhdl_arch *arch, ivl_lpm_t lpm) } vhdl_scope *scope = arch->get_scope(); - + vhdl_expr *s0 = readable_ref(scope, ivl_lpm_data(lpm, 0)); vhdl_expr *s1 = readable_ref(scope, ivl_lpm_data(lpm, 1)); @@ -319,7 +319,7 @@ static int draw_mux_lpm(vhdl_arch *arch, ivl_lpm_t lpm) vhdl_expr *b1 = new vhdl_const_bit('1'); vhdl_expr *t1 = new vhdl_binop_expr(sel, VHDL_BINOP_EQ, b1, vhdl_type::boolean()); - + vhdl_var_ref *out = nexus_to_var_ref(scope, ivl_lpm_q(lpm)); // Make sure s0 and s1 have the same type as the output @@ -337,11 +337,11 @@ int draw_lpm(vhdl_arch *arch, ivl_lpm_t lpm) { if (ivl_lpm_type(lpm) == IVL_LPM_MUX) return draw_mux_lpm(arch, lpm); - + vhdl_expr *f = lpm_to_expr(arch->get_scope(), lpm); if (NULL == f) return 1; - + vhdl_var_ref *out = nexus_to_var_ref(arch->get_scope(), ivl_lpm_q(lpm)); if (ivl_lpm_type(lpm) == IVL_LPM_PART_PV) { vhdl_expr *off = part_select_base(arch->get_scope(), lpm); @@ -357,16 +357,16 @@ int draw_lpm(vhdl_arch *arch, ivl_lpm_t lpm) bool bool_to_logic = out->get_type()->get_name() == VHDL_TYPE_STD_LOGIC && f->get_type()->get_name() == VHDL_TYPE_BOOLEAN; - + if (bool_to_logic) { vhdl_cassign_stmt* s = new vhdl_cassign_stmt(out, new vhdl_const_bit('0')); s->add_condition(new vhdl_const_bit('1'), f); arch->add_stmt(s); } - else + else arch->add_stmt(new vhdl_cassign_stmt(out, f->cast(out->get_type()))); - + return 0; } diff --git a/tgt-vhdl/process.cc b/tgt-vhdl/process.cc index 9440b25cf..4660ea98b 100644 --- a/tgt-vhdl/process.cc +++ b/tgt-vhdl/process.cc @@ -33,7 +33,7 @@ static int generate_vhdl_process(vhdl_entity *ent, ivl_process_t proc) { set_active_entity(ent); - + // Create a new process and store it in the entity's // architecture. This needs to be done first or the // parent link won't be valid (and draw_stmt needs this @@ -45,7 +45,7 @@ static int generate_vhdl_process(vhdl_entity *ent, ivl_process_t proc) // into the declarations vhdl_proc->get_scope()->set_initializing (ivl_process_type(proc) == IVL_PR_INITIAL); - + ivl_statement_t stmt = ivl_process_stmt(proc); int rc = draw_stmt(vhdl_proc, vhdl_proc->get_container(), stmt); if (rc != 0) @@ -61,13 +61,13 @@ static int generate_vhdl_process(vhdl_entity *ent, ivl_process_t proc) // Get rid of any useless `wait for 0 ns's at the end of the process prune_wait_for_0(vhdl_proc->get_container()); - // The above pruning might have removed all logic from the process + // The above pruning might have removed all logic from the process if (!vhdl_proc->get_container()->empty()) { vhdl_wait_stmt *wait = new vhdl_wait_stmt(); vhdl_proc->get_container()->add_stmt(wait); } } - + // Add a comment indicating where it came from ivl_scope_t scope = ivl_process_scope(proc); const char *type = ivl_process_type(proc) == IVL_PR_INITIAL @@ -90,21 +90,21 @@ extern "C" int draw_process(ivl_process_t proc, void *cd) if (!is_default_scope_instance(scope)) return 0; // Ignore this process at it's not in a scope that // we're using to generate code - + debug_msg("Translating process in scope type %s (%s:%d)", ivl_scope_tname(scope), ivl_process_file(proc), ivl_process_lineno(proc)); - + // Skip over any generate and begin scopes until we find // the module that contains them - this is where we will // generate the process while (ivl_scope_type(scope) == IVL_SCT_GENERATE || ivl_scope_type(scope) == IVL_SCT_BEGIN) scope = ivl_scope_parent(scope); - + assert(ivl_scope_type(scope) == IVL_SCT_MODULE); vhdl_entity *ent = find_entity(scope); assert(ent != NULL); - + return generate_vhdl_process(ent, proc); } diff --git a/tgt-vhdl/scope.cc b/tgt-vhdl/scope.cc index 6097b41e5..1cd47f91e 100644 --- a/tgt-vhdl/scope.cc +++ b/tgt-vhdl/scope.cc @@ -42,7 +42,7 @@ struct scope_nexus_t { string tmpname; // A new temporary signal list connect; // Other signals to wire together }; - + /* * This structure is stored in the private part of each nexus. * It stores a scope_nexus_t for each VHDL scope which is @@ -76,11 +76,11 @@ static scope_nexus_t *visible_nexus(nexus_private_t *priv, vhdl_scope *scope) */ static void link_scope_to_nexus_signal(nexus_private_t *priv, vhdl_scope *scope, ivl_signal_t sig, unsigned pin) -{ +{ scope_nexus_t *sn; if ((sn = visible_nexus(priv, scope))) { assert(sn->tmpname == ""); - + // Remember to connect this signal up later // If one of the signals is a input, make sure the input is not being driven if (ivl_signal_port(sn->sig) == IVL_SIP_INPUT) @@ -126,16 +126,16 @@ static ivl_signal_type_t signal_type_of_nexus(ivl_nexus_t nex, int &width) { ivl_signal_type_t out = IVL_SIT_TRI; width = 0; - + for (unsigned idx = 0; idx < ivl_nexus_ptrs(nex); idx += 1) { ivl_signal_type_t stype; ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig == 0) continue; - + width = ivl_signal_width(sig); - + stype = ivl_signal_type(sig); if (stype == IVL_SIT_TRI) continue; @@ -143,7 +143,7 @@ static ivl_signal_type_t signal_type_of_nexus(ivl_nexus_t nex, int &width) continue; out = stype; } - + return out; } @@ -151,11 +151,11 @@ static ivl_signal_type_t signal_type_of_nexus(ivl_nexus_t nex, int &width) * Generates VHDL code to fully represent a nexus. */ void draw_nexus(ivl_nexus_t nexus) -{ +{ nexus_private_t *priv = new nexus_private_t; int nexus_signal_width = -1; priv->const_driver = NULL; - + int nptrs = ivl_nexus_ptrs(nexus); // Number of drivers for this nexus @@ -164,9 +164,9 @@ void draw_nexus(ivl_nexus_t nexus) // First pass through connect all the signals up for (int i = 0; i < nptrs; i++) { ivl_nexus_ptr_t nexus_ptr = ivl_nexus_ptr(nexus, i); - + ivl_signal_t sig; - if ((sig = ivl_nexus_ptr_sig(nexus_ptr))) { + if ((sig = ivl_nexus_ptr_sig(nexus_ptr))) { vhdl_scope *scope = find_scope_for_signal(sig); if (scope) { unsigned pin = ivl_nexus_ptr_pin(nexus_ptr); @@ -181,7 +181,7 @@ void draw_nexus(ivl_nexus_t nexus) // inputs and outputs for (int i = 0; i < nptrs; i++) { ivl_nexus_ptr_t nexus_ptr = ivl_nexus_ptr(nexus, i); - + ivl_net_logic_t log; ivl_lpm_t lpm; ivl_net_const_t con; @@ -189,10 +189,10 @@ void draw_nexus(ivl_nexus_t nexus) ivl_scope_t log_scope = ivl_logic_scope(log); if (!is_default_scope_instance(log_scope)) continue; - + vhdl_entity *ent = find_entity(log_scope); assert(ent); - + vhdl_scope *vhdl_scope = ent->get_arch()->get_scope(); if (visible_nexus(priv, vhdl_scope)) { // Already seen this signal in vhdl_scope @@ -201,7 +201,7 @@ void draw_nexus(ivl_nexus_t nexus) // Create a temporary signal to connect it to the nexus vhdl_type *type = vhdl_type::type_for(ivl_logic_width(log), false); - + ostringstream ss; ss << "LO" << ivl_logic_basename(log); vhdl_scope->add_decl(new vhdl_signal_decl(ss.str().c_str(), type)); @@ -218,7 +218,7 @@ void draw_nexus(ivl_nexus_t nexus) ivl_scope_t lpm_scope = ivl_lpm_scope(lpm); vhdl_entity *ent = find_entity(lpm_scope); assert(ent); - + vhdl_scope *vhdl_scope = ent->get_arch()->get_scope(); if (visible_nexus(priv, vhdl_scope)) { // Already seen this signal in vhdl_scope @@ -235,7 +235,7 @@ void draw_nexus(ivl_nexus_t nexus) lpm_temp_width = nexus_signal_width; else lpm_temp_width = ivl_lpm_width(lpm); - + vhdl_type *type = vhdl_type::type_for(lpm_temp_width, ivl_lpm_signed(lpm) != 0); ostringstream ss; @@ -243,7 +243,7 @@ void draw_nexus(ivl_nexus_t nexus) if (!vhdl_scope->have_declared(ss.str())) vhdl_scope->add_decl(new vhdl_signal_decl(ss.str().c_str(), type)); - + link_scope_to_nexus_tmp(priv, vhdl_scope, ss.str()); } @@ -274,7 +274,7 @@ void draw_nexus(ivl_nexus_t nexus) if (ndrivers == 0) { char def = 0; int width; - + switch (signal_type_of_nexus(nexus, width)) { case IVL_SIT_TRI: case IVL_SIT_UWIRE: @@ -305,7 +305,7 @@ void draw_nexus(ivl_nexus_t nexus) priv->const_driver = new vhdl_const_bit(def); } } - + // Save the private data in the nexus ivl_nexus_set_private(nexus, priv); } @@ -316,10 +316,10 @@ void draw_nexus(ivl_nexus_t nexus) */ static void seen_nexus(ivl_nexus_t nexus) { - if (ivl_nexus_get_private(nexus) == NULL) + if (ivl_nexus_get_private(nexus) == NULL) draw_nexus(nexus); } - + /* * Translate a nexus to a variable reference. Given a nexus and a * scope, this function returns a reference to a signal that is @@ -332,18 +332,18 @@ static void seen_nexus(ivl_nexus_t nexus) vhdl_var_ref *nexus_to_var_ref(vhdl_scope *scope, ivl_nexus_t nexus) { seen_nexus(nexus); - + nexus_private_t *priv = static_cast(ivl_nexus_get_private(nexus)); unsigned pin; string renamed(visible_nexus_signal_name(priv, scope, &pin)); - + vhdl_decl *decl = scope->get_decl(renamed); assert(decl); vhdl_type *type = new vhdl_type(*(decl->get_type())); vhdl_var_ref *ref = new vhdl_var_ref(renamed.c_str(), type); - + if (decl->get_type()->get_name() == VHDL_TYPE_ARRAY) ref->set_slice(new vhdl_const_int(pin), 0); @@ -355,7 +355,7 @@ vhdl_var_ref *nexus_to_var_ref(vhdl_scope *scope, ivl_nexus_t nexus) vhdl_var_ref* readable_ref(vhdl_scope* scope, ivl_nexus_t nex) { vhdl_var_ref* ref = nexus_to_var_ref(scope, nex); - + vhdl_decl* decl = scope->get_decl(ref->get_name()); decl->ensure_readable(); @@ -369,10 +369,10 @@ vhdl_var_ref* readable_ref(vhdl_scope* scope, ivl_nexus_t nex) static void declare_logic(vhdl_arch *arch, ivl_scope_t scope) { debug_msg("Declaring logic in scope type %s", ivl_scope_tname(scope)); - + int nlogs = ivl_scope_logs(scope); for (int i = 0; i < nlogs; i++) - draw_logic(arch, ivl_scope_log(scope, i)); + draw_logic(arch, ivl_scope_log(scope, i)); } // Replace consecutive underscores with a single underscore @@ -422,7 +422,7 @@ static string valid_entity_name(const string& module_name) name = "module" + name; if (*name.rbegin() == '_') name += "module"; - + if (is_vhdl_reserved_word(name)) name += "_module"; @@ -434,7 +434,7 @@ static string valid_entity_name(const string& module_name) ss.str(""); ss << name << i++; } - + return ss.str(); } @@ -445,7 +445,7 @@ string make_safe_name(ivl_signal_t sig) if (ivl_signal_local(sig)) base = "tmp" + base; - + if (base[0] == '_') base = "sig" + base; @@ -454,14 +454,14 @@ string make_safe_name(ivl_signal_t sig) // Can't have two consecutive underscores replace_consecutive_underscores(base); - + // A signal name may not be the same as a component name if (find_entity(base) != NULL) base += "_sig"; if (is_vhdl_reserved_word(base)) base += "_sig"; - + return base; } @@ -478,7 +478,7 @@ static void avoid_name_collision(string& name, vhdl_scope* scope) ss.str(""); ss << name << i++; } while (scope->name_collides(ss.str())); - + name = ss.str(); } } @@ -495,24 +495,24 @@ static string genvar_unique_suffix(ivl_scope_t scope) for (unsigned i = 0; i < ivl_scope_params(scope); i++) { ivl_parameter_t param = ivl_scope_param(scope, i); ivl_expr_t e = ivl_parameter_expr(param); - + if (ivl_expr_type(e) == IVL_EX_NUMBER) { vhdl_expr* value = translate_expr(e); assert(value); - + value = value->cast(vhdl_type::integer()); - + suffix << "_" << ivl_parameter_basename(param); value->emit(suffix, 0); - + delete value; } else { error("Only numeric genvars supported at the moment"); return "_ERROR"; // Never used - } + } } - + scope = ivl_scope_parent(scope); } @@ -528,33 +528,33 @@ static void declare_one_signal(vhdl_entity *ent, ivl_signal_t sig, string name(make_safe_name(sig)); name += genvar_unique_suffix(scope); avoid_name_collision(name, ent->get_arch()->get_scope()); - + rename_signal(sig, name); - + vhdl_type *sig_type; unsigned dimensions = ivl_signal_dimensions(sig); if (dimensions > 0) { // Arrays are implemented by generating a separate type // declaration for each array, and then declaring a // signal of that type - + if (dimensions > 1) { error("> 1 dimension arrays not implemented yet"); return; } - + string type_name = name + "_Type"; vhdl_type *base_type = vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig) != 0); - + int lsb = ivl_signal_array_base(sig); int msb = lsb + ivl_signal_array_count(sig) - 1; - + vhdl_type *array_type = vhdl_type::array_of(base_type, type_name, msb, lsb); vhdl_decl *array_decl = new vhdl_type_decl(type_name.c_str(), array_type); ent->get_arch()->get_scope()->add_decl(array_decl); - + sig_type = new vhdl_type(*array_type); } else { @@ -562,15 +562,15 @@ static void declare_one_signal(vhdl_entity *ent, ivl_signal_t sig, ivl_signal_signed(sig) != 0, 0, ivl_signal_type(sig) == IVL_SIT_UWIRE); - + } - + ivl_signal_port_t mode = ivl_signal_port(sig); switch (mode) { case IVL_SIP_NONE: { vhdl_decl *decl = new vhdl_signal_decl(name.c_str(), sig_type); - + ostringstream ss; if (ivl_signal_local(sig)) { ss << "Temporary created at " << ivl_signal_file(sig) << ":" @@ -580,7 +580,7 @@ static void declare_one_signal(vhdl_entity *ent, ivl_signal_t sig, << ivl_signal_lineno(sig); } decl->set_comment(ss.str().c_str()); - + ent->get_arch()->get_scope()->add_decl(decl); } break; @@ -591,10 +591,10 @@ static void declare_one_signal(vhdl_entity *ent, ivl_signal_t sig, case IVL_SIP_OUTPUT: { vhdl_port_decl *decl = - new vhdl_port_decl(name.c_str(), sig_type, VHDL_PORT_OUT); + new vhdl_port_decl(name.c_str(), sig_type, VHDL_PORT_OUT); ent->get_scope()->add_decl(decl); } - + if (ivl_signal_type(sig) == IVL_SIT_REG) { // A registered output // In Verilog the output and reg can have the @@ -604,11 +604,11 @@ static void declare_one_signal(vhdl_entity *ent, ivl_signal_t sig, std::string newname(name); newname += "_Reg"; rename_signal(sig, newname.c_str()); - + vhdl_type *reg_type = new vhdl_type(*sig_type); ent->get_arch()->get_scope()->add_decl (new vhdl_signal_decl(newname.c_str(), reg_type)); - + // Create a concurrent assignment statement to // connect the register to the output ent->get_arch()->add_stmt @@ -633,17 +633,17 @@ static void declare_one_signal(vhdl_entity *ent, ivl_signal_t sig, static void declare_signals(vhdl_entity *ent, ivl_scope_t scope) { debug_msg("Declaring signals in scope type %s", ivl_scope_tname(scope)); - + int nsigs = ivl_scope_sigs(scope); for (int i = 0; i < nsigs; i++) { - ivl_signal_t sig = ivl_scope_sig(scope, i); + ivl_signal_t sig = ivl_scope_sig(scope, i); if (ivl_signal_port(sig) != IVL_SIP_NONE) declare_one_signal(ent, sig, scope); } - + for (int i = 0; i < nsigs; i++) { - ivl_signal_t sig = ivl_scope_sig(scope, i); + ivl_signal_t sig = ivl_scope_sig(scope, i); if (ivl_signal_port(sig) == IVL_SIP_NONE) declare_one_signal(ent, sig, scope); @@ -669,7 +669,7 @@ static void declare_lpm(vhdl_arch *arch, ivl_scope_t scope) */ static void map_signal(ivl_signal_t to, vhdl_entity *parent, vhdl_comp_inst *inst) -{ +{ // TODO: Work for multiple words ivl_nexus_t nexus = ivl_signal_nex(to, 0); seen_nexus(nexus); @@ -699,14 +699,14 @@ static void map_signal(ivl_signal_t to, vhdl_entity *parent, && !arch_scope->have_declared(name + "_Readable")) { vhdl_decl* tmp_decl = new vhdl_signal_decl(name + "_Readable", ref->get_type()); - + // Add a comment to explain what this is for tmp_decl->set_comment("Needed to connect outputs"); - + arch_scope->add_decl(tmp_decl); parent->get_arch()->add_stmt (new vhdl_cassign_stmt(from_decl->make_ref(), tmp_decl->make_ref())); - + map_to = tmp_decl->make_ref(); } else @@ -719,7 +719,7 @@ static void map_signal(ivl_signal_t to, vhdl_entity *parent, else { // This nexus isn't attached to anything in the parent return; - } + } inst->map_port(name, map_to); } @@ -734,7 +734,7 @@ static void port_map(ivl_scope_t scope, vhdl_entity *parent, int nsigs = ivl_scope_sigs(scope); for (int i = 0; i < nsigs; i++) { ivl_signal_t sig = ivl_scope_sig(scope, i); - + ivl_signal_port_t mode = ivl_signal_port(sig); switch (mode) { case IVL_SIP_NONE: @@ -744,10 +744,10 @@ static void port_map(ivl_scope_t scope, vhdl_entity *parent, case IVL_SIP_OUTPUT: case IVL_SIP_INOUT: map_signal(sig, parent, inst); - break; + break; default: assert(false); - } + } } } @@ -788,9 +788,9 @@ static int draw_function(ivl_scope_t scope, ivl_scope_t parent) vhdl_type *sigtype = vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig) != 0); - + string signame(make_safe_name(sig)); - + switch (ivl_signal_port(sig)) { case IVL_SIP_INPUT: func->add_param(new vhdl_param_decl(signame.c_str(), sigtype)); @@ -807,30 +807,30 @@ static int draw_function(ivl_scope_t scope, ivl_scope_t parent) // Only expecting inputs and outputs assert(false); } - + remember_signal(sig, func->get_scope()); rename_signal(sig, signame); } - + int nsigs = ivl_scope_sigs(scope); for (int i = 0; i < nsigs; i++) { - ivl_signal_t sig = ivl_scope_sig(scope, i); + ivl_signal_t sig = ivl_scope_sig(scope, i); if (ivl_signal_port(sig) == IVL_SIP_NONE) { vhdl_type *sigtype = vhdl_type::type_for( ivl_signal_width(sig), ivl_signal_signed(sig) != 0); - + string signame(make_safe_name(sig)); func->get_scope()->add_decl( new vhdl_var_decl(signame, sigtype)); - + remember_signal(sig, func->get_scope()); rename_signal(sig, signame); } } - + // Non-blocking assignment not allowed in functions func->get_scope()->set_allow_signal_assignment(false); @@ -849,8 +849,8 @@ static int draw_function(ivl_scope_t scope, ivl_scope_t parent) ss << "Generated from function " << funcname << " at " << ivl_scope_def_file(scope) << ":" << ivl_scope_def_lineno(scope); func->set_comment(ss.str().c_str()); - - ent->get_arch()->get_scope()->add_decl(func); + + ent->get_arch()->get_scope()->add_decl(func); return 0; } @@ -867,14 +867,14 @@ static int draw_task(ivl_scope_t scope, ivl_scope_t parent) assert(ent); const char *taskname = ivl_scope_tname(scope); - + int nsigs = ivl_scope_sigs(scope); for (int i = 0; i < nsigs; i++) { - ivl_signal_t sig = ivl_scope_sig(scope, i); + ivl_signal_t sig = ivl_scope_sig(scope, i); vhdl_type *sigtype = vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig) != 0); - + string signame(make_safe_name(sig)); // Check this signal isn't declared in the outer scope @@ -889,13 +889,13 @@ static int draw_task(ivl_scope_t scope, ivl_scope_t parent) ss << "Declared at " << ivl_signal_file(sig) << ":" << ivl_signal_lineno(sig) << " (in task " << taskname << ")"; decl->set_comment(ss.str().c_str()); - - ent->get_arch()->get_scope()->add_decl(decl); - + + ent->get_arch()->get_scope()->add_decl(decl); + remember_signal(sig, ent->get_arch()->get_scope()); rename_signal(sig, signame); } - + return 0; } @@ -908,7 +908,7 @@ static void create_skeleton_entity_for(ivl_scope_t scope, int depth) // The type name will become the entity name const string tname = valid_entity_name(ivl_scope_tname(scope)); - + // Verilog does not have the entity/architecture distinction // so we always create a pair and associate the architecture // with the entity for convenience (this also means that we @@ -925,10 +925,10 @@ static void create_skeleton_entity_for(ivl_scope_t scope, int depth) ss << "Generated from Verilog module " << ivl_scope_tname(scope) << " (" << ivl_scope_def_file(scope) << ":" << ivl_scope_def_lineno(scope) << ")"; - + arch->set_comment(ss.str()); ent->set_comment(ss.str()); - + remember_entity(ent, scope); } @@ -939,13 +939,13 @@ static void create_skeleton_entity_for(ivl_scope_t scope, int depth) extern "C" int draw_skeleton_scope(ivl_scope_t scope, void *_unused) { static int depth = 0; - + if (seen_this_scope_type(scope)) return 0; // Already generated a skeleton for this scope type - + debug_msg("Initial visit to scope type %s at depth %d", ivl_scope_tname(scope), depth); - + switch (ivl_scope_type(scope)) { case IVL_SCT_MODULE: create_skeleton_entity_for(scope, depth); @@ -968,7 +968,7 @@ extern "C" int draw_all_signals(ivl_scope_t scope, void *_parent) { if (!is_default_scope_instance(scope)) return 0; // Not interested in this instance - + if (ivl_scope_type(scope) == IVL_SCT_MODULE) { vhdl_entity *ent = find_entity(scope); assert(ent); @@ -983,7 +983,7 @@ extern "C" int draw_all_signals(ivl_scope_t scope, void *_parent) ivl_scope_t parent = ivl_scope_parent(scope); while (ivl_scope_type(parent) == IVL_SCT_GENERATE) parent = ivl_scope_parent(scope); - + vhdl_entity* ent = find_entity(parent); assert(ent); @@ -1000,7 +1000,7 @@ extern "C" int draw_functions(ivl_scope_t scope, void *_parent) { if (!is_default_scope_instance(scope)) return 0; // Not interested in this instance - + ivl_scope_t parent = static_cast(_parent); if (ivl_scope_type(scope) == IVL_SCT_FUNCTION) { if (draw_function(scope, parent) != 0) @@ -1024,9 +1024,9 @@ extern "C" int draw_constant_drivers(ivl_scope_t scope, void *_parent) { if (!is_default_scope_instance(scope)) return 0; // Not interested in this instance - + ivl_scope_children(scope, draw_constant_drivers, scope); - + if (ivl_scope_type(scope) == IVL_SCT_MODULE) { vhdl_entity *ent = find_entity(scope); assert(ent); @@ -1034,7 +1034,7 @@ extern "C" int draw_constant_drivers(ivl_scope_t scope, void *_parent) int nsigs = ivl_scope_sigs(scope); for (int i = 0; i < nsigs; i++) { ivl_signal_t sig = ivl_scope_sig(scope, i); - + for (unsigned j = ivl_signal_array_base(sig); j < ivl_signal_array_count(sig); j++) { @@ -1042,7 +1042,7 @@ extern "C" int draw_constant_drivers(ivl_scope_t scope, void *_parent) ivl_nexus_t nex = ivl_signal_nex(sig, j); if (!nex) continue; // skip virtual pins seen_nexus(nex); - + nexus_private_t *priv = static_cast(ivl_nexus_get_private(nex)); assert(priv); @@ -1052,11 +1052,11 @@ extern "C" int draw_constant_drivers(ivl_scope_t scope, void *_parent) if (priv->const_driver && ivl_signal_port(sig) != IVL_SIP_INPUT) { // Don't drive inputs assert(j == 0); // TODO: Make work for more words - + vhdl_var_ref *ref = nexus_to_var_ref(arch_scope, nex); - + ent->get_arch()->add_stmt - (new vhdl_cassign_stmt(ref, priv->const_driver)); + (new vhdl_cassign_stmt(ref, priv->const_driver)); priv->const_driver = NULL; } @@ -1065,7 +1065,7 @@ extern "C" int draw_constant_drivers(ivl_scope_t scope, void *_parent) scope_nexus_t *sn = visible_nexus(priv, arch_scope); // Make sure we don't drive inputs - if (ivl_signal_port(sn->sig) != IVL_SIP_INPUT) { + if (ivl_signal_port(sn->sig) != IVL_SIP_INPUT) { for (list::const_iterator it = sn->connect.begin(); it != sn->connect.end(); ++it) { @@ -1075,20 +1075,20 @@ extern "C" int draw_constant_drivers(ivl_scope_t scope, void *_parent) vhdl_type* ltype = vhdl_type::type_for(ivl_signal_width(*it), ivl_signal_signed(*it)); - + vhdl_var_ref *rref = new vhdl_var_ref(get_renamed_signal(sn->sig).c_str(), rtype); vhdl_var_ref *lref = new vhdl_var_ref(get_renamed_signal(*it).c_str(), ltype); - + // Make sure the LHS and RHS have the same type vhdl_expr* rhs = rref->cast(lref->get_type()); - + ent->get_arch()->add_stmt(new vhdl_cassign_stmt(lref, rhs)); } } - sn->connect.clear(); - } + sn->connect.clear(); + } } } @@ -1099,7 +1099,7 @@ extern "C" int draw_all_logic_and_lpm(ivl_scope_t scope, void *_parent) { if (!is_default_scope_instance(scope)) return 0; // Not interested in this instance - + if (ivl_scope_type(scope) == IVL_SCT_MODULE) { vhdl_entity *ent = find_entity(scope); assert(ent); @@ -1110,40 +1110,40 @@ extern "C" int draw_all_logic_and_lpm(ivl_scope_t scope, void *_parent) declare_lpm(ent->get_arch(), scope); } set_active_entity(NULL); - } + } return ivl_scope_children(scope, draw_all_logic_and_lpm, scope); } extern "C" int draw_hierarchy(ivl_scope_t scope, void *_parent) -{ +{ if (ivl_scope_type(scope) == IVL_SCT_MODULE && _parent) { ivl_scope_t parent = static_cast(_parent); // Skip over any containing generate scopes while (ivl_scope_type(parent) == IVL_SCT_GENERATE) parent = ivl_scope_parent(parent); - + if (!is_default_scope_instance(parent)) return 0; // Not generating code for the parent instance so // don't generate for the child - + vhdl_entity *ent = find_entity(scope); assert(ent); - + vhdl_entity *parent_ent = find_entity(parent); assert(parent_ent); vhdl_arch *parent_arch = parent_ent->get_arch(); assert(parent_arch != NULL); - + // Create a forward declaration for it vhdl_scope *parent_scope = parent_arch->get_scope(); if (!parent_scope->have_declared(ent->get_name())) { vhdl_decl *comp_decl = vhdl_component_decl::component_decl_for(ent); parent_arch->get_scope()->add_decl(comp_decl); } - + // And an instantiation statement string inst_name(ivl_scope_basename(scope)); inst_name += genvar_unique_suffix(ivl_scope_parent(scope)); @@ -1154,13 +1154,13 @@ extern "C" int draw_hierarchy(ivl_scope_t scope, void *_parent) // Would produce an invalid instance name inst_name += "_inst"; } - + // Need to replace any [ and ] characters that result // from generate statements string::size_type loc = inst_name.find('[', 0); if (loc != string::npos) inst_name.erase(loc, 1); - + loc = inst_name.find(']', 0); if (loc != string::npos) inst_name.erase(loc, 1); @@ -1177,7 +1177,7 @@ extern "C" int draw_hierarchy(ivl_scope_t scope, void *_parent) // Make sure the name doesn't collide with anything we've // already declared avoid_name_collision(inst_name, parent_arch->get_scope()); - + vhdl_comp_inst *inst = new vhdl_comp_inst(inst_name.c_str(), ent->get_name().c_str()); port_map(scope, parent_ent, inst); @@ -1186,15 +1186,15 @@ extern "C" int draw_hierarchy(ivl_scope_t scope, void *_parent) ss << "Generated from instantiation at " << ivl_scope_file(scope) << ":" << ivl_scope_lineno(scope); inst->set_comment(ss.str().c_str()); - + parent_arch->add_stmt(inst); - } + } return ivl_scope_children(scope, draw_hierarchy, scope); } int draw_scope(ivl_scope_t scope, void *_parent) -{ +{ int rc = draw_skeleton_scope(scope, _parent); if (rc != 0) return rc; @@ -1205,7 +1205,7 @@ int draw_scope(ivl_scope_t scope, void *_parent) rc = draw_all_logic_and_lpm(scope, _parent); if (rc != 0) - return rc; + return rc; rc = draw_hierarchy(scope, _parent); if (rc != 0) @@ -1218,7 +1218,7 @@ int draw_scope(ivl_scope_t scope, void *_parent) rc = draw_constant_drivers(scope, _parent); if (rc != 0) return rc; - + return 0; } diff --git a/tgt-vhdl/state.cc b/tgt-vhdl/state.cc index 0ced93f27..8de2f33d0 100644 --- a/tgt-vhdl/state.cc +++ b/tgt-vhdl/state.cc @@ -53,7 +53,7 @@ using namespace std; * provides a mechanism for renaming signals -- i.e. when * an output has the same name as register: valid in Verilog * but not in VHDL, so two separate signals need to be - * defined. + * defined. */ struct signal_defn_t { std::string renamed; // The name of the VHDL signal @@ -64,7 +64,7 @@ struct signal_defn_t { // These are stored in a list rather than a set so the first // entity added will correspond to the first (top) Verilog module // encountered and hence it will appear first in the output file. -static entity_list_t g_entities; +static entity_list_t g_entities; // Store the mapping of ivl scope names to entity names typedef map scope_name_map_t; @@ -145,7 +145,7 @@ ivl_signal_t find_signal_named(const std::string &name, const vhdl_scope *scope) // Compare the name of an entity against a string struct cmp_ent_name { cmp_ent_name(const string& n) : name_(n) {} - + bool operator()(const vhdl_entity* ent) const { return ent->get_name() == name_; @@ -156,7 +156,7 @@ struct cmp_ent_name { // Find an entity given its name. vhdl_entity* find_entity(const string& name) -{ +{ entity_list_t::const_iterator it = find_if(g_entities.begin(), g_entities.end(), cmp_ent_name(name)); @@ -176,7 +176,7 @@ vhdl_entity* find_entity(ivl_scope_t scope) // Skip over generate scopes while (ivl_scope_type(scope) == IVL_SCT_GENERATE) scope = ivl_scope_parent(scope); - + assert(ivl_scope_type(scope) == IVL_SCT_MODULE); scope_name_map_t::iterator it = g_scope_names.find(ivl_scope_tname(scope)); @@ -213,7 +213,7 @@ void free_all_vhdl_objects() size_t total = vhdl_element::total_allocated(); debug_msg("%d total bytes used for VHDL syntax objects", total); - + g_entities.clear(); } diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index 774ce9d06..77952521e 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -40,7 +40,7 @@ * An alternative is to use the VHPI interface supported by * some VHDL simulators and implement the $finish functionality * in C. This function can be enabled with the flag - * -puse-vhpi-finish=1. + * -puse-vhpi-finish=1. */ static int draw_stask_finish(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt) @@ -53,7 +53,7 @@ static int draw_stask_finish(vhdl_procedural *proc, stmt_container *container, else { container->add_stmt(new vhdl_assert_stmt("SIMULATION FINISHED")); } - + return 0; } @@ -93,7 +93,7 @@ static int draw_stask(vhdl_procedural *proc, stmt_container *container, * * If this block has its own scope with local variables then these * are added to the process as local variables and the statements - * are generated as above. + * are generated as above. */ static int draw_block(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt, bool is_last) @@ -111,7 +111,7 @@ static int draw_block(vhdl_procedural *proc, stmt_container *container, (new vhdl_var_decl(make_safe_name(sig), type)); } } - + int count = ivl_stmt_block_count(stmt); for (int i = 0; i < count; i++) { ivl_statement_t stmt_i = ivl_stmt_block_stmt(stmt, i); @@ -138,7 +138,7 @@ static int draw_noop(vhdl_procedural *proc, stmt_container *container, * we might as well not emit the first zero-time wait. */ void prune_wait_for_0(stmt_container *container) -{ +{ vhdl_wait_stmt *wait0; stmt_container::stmt_list_t &stmts = container->get_stmts(); while (stmts.size() > 0 @@ -167,13 +167,13 @@ static vhdl_var_ref *make_assign_lhs(ivl_lval_t lval, vhdl_scope *scope) if (e_off) { if ((base = translate_expr(e_off)) == NULL) return NULL; - + vhdl_type integer(VHDL_TYPE_INTEGER); base = base->cast(&integer); } - + unsigned lval_width = ivl_lval_width(lval); - + string signame(get_renamed_signal(sig)); vhdl_decl *decl = scope->get_decl(signame); assert(decl); @@ -197,7 +197,7 @@ static vhdl_var_ref *make_assign_lhs(ivl_lval_t lval, vhdl_scope *scope) // ...and use this new variable as the assignment LHS decl = shadow_decl; } - + vhdl_type *ltype = new vhdl_type(*decl->get_type()); vhdl_var_ref *lval_ref = new vhdl_var_ref(decl->get_name(), ltype); if (base) { @@ -221,7 +221,7 @@ static bool assignment_lvals(ivl_statement_t stmt, vhdl_procedural *proc, return false; lvals.push_back(lhs); - } + } return true; } @@ -239,7 +239,7 @@ assign_for(vhdl_decl::assign_type_t atype, vhdl_var_ref *lhs, vhdl_expr *rhs) return new vhdl_assign_stmt(lhs, rhs); case vhdl_decl::ASSIGN_NONBLOCK: return new vhdl_nbassign_stmt(lhs, rhs); - } + } assert(false); return NULL; } @@ -289,7 +289,7 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container, if (lvals.size() == 1) { vhdl_var_ref *lhs = lvals.front(); rhs = rhs->cast(lhs->get_type()); - + ivl_expr_t i_delay; vhdl_expr *after = NULL; if ((i_delay = ivl_stmt_delay_expr(stmt)) != NULL) @@ -300,7 +300,7 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container, // a variable, etc?) vhdl_decl *decl = proc->get_scope()->get_decl(lhs->get_name()); assign_type = decl->assignment_type(); - + // A small optimisation is to expand ternary RHSs into an // if statement (eliminates a function call and produces // more idiomatic code) @@ -308,7 +308,7 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container, rhs2 = rhs2->cast(lhs->get_type()); vhdl_var_ref *lhs2 = make_assign_lhs(ivl_stmt_lval(stmt, 0), proc->get_scope()); - + vhdl_expr *test = translate_expr(ivl_expr_oper1(rval)); if (NULL == test) return; @@ -344,7 +344,7 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container, // declaration as initialisers. This optimisation is only // performed on assignments of constant values to prevent // ordering problems. - + // This also has another application: If this is an `initial' // process and we haven't yet generated a `wait' statement then // moving the assignment to the initialization preserves the @@ -360,7 +360,7 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container, && !decl->has_initial() && rhs->constant() && decl->get_type()->get_name() != VHDL_TYPE_ARRAY) { - + // If this assignment is not in the top-level container // it will not be made on all paths through the code // This precludes any future extraction of an initialiser @@ -379,7 +379,7 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container, vhdl_abstract_assign_stmt *a = assign_for(decl->assignment_type(), lhs, rhs); container->add_stmt(a); - + if (after != NULL) a->set_after(after); } @@ -396,16 +396,16 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container, proc->get_scope()->add_decl(tmp_decl); container->add_stmt(new vhdl_assign_stmt(tmp_decl->make_ref(), rhs)); - + list::iterator it; int width_so_far = 0; for (it = lvals.begin(); it != lvals.end(); ++it) { vhdl_var_ref *tmp_rhs = tmp_decl->make_ref(); - + int lval_width = (*it)->get_type()->get_width(); vhdl_expr *slice_base = new vhdl_const_int(width_so_far); tmp_rhs->set_slice(slice_base, lval_width - 1); - + ivl_expr_t i_delay; vhdl_expr *after = NULL; if ((i_delay = ivl_stmt_delay_expr(stmt)) != NULL) @@ -419,7 +419,7 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container, if (!check_valid_assignment(decl->assignment_type(), proc, stmt)) return; - + vhdl_abstract_assign_stmt *a = assign_for(decl->assignment_type(), *it, tmp_rhs); if (after) @@ -473,7 +473,7 @@ static int draw_assign(vhdl_procedural *proc, stmt_container *container, } else make_assignment(proc, container, stmt, true, assign_type); - + return 0; } @@ -511,7 +511,7 @@ static int draw_delay(vhdl_procedural *proc, stmt_container *container, // Remember that we needed a wait statement so if this is // a process it cannot have a sensitivity list proc->added_wait_stmt(); - + container->add_stmt(wait); // Expand the sub-statement as well @@ -519,12 +519,12 @@ static int draw_delay(vhdl_procedural *proc, stmt_container *container, // is caught here instead if (ivl_statement_type(sub_stmt) != IVL_ST_NOOP) draw_stmt(proc, container, sub_stmt); - + // Any further assignments occur after simulation time 0 // so they cannot be used to initialise signal declarations // (if this scope is an initial process) proc->get_scope()->set_initializing(false); - + return 0; } @@ -582,19 +582,19 @@ static bool draw_synthesisable_wait(vhdl_process *proc, stmt_container *containe { // At the moment this only detects FFs with an asynchronous reset // All other code will fall back on the default draw_wait - + // Store a set of the edge triggered signals // The second item is true if this is positive-edge set edge_triggered; - + const int nevents = ivl_stmt_nevent(stmt); - + for (int i = 0; i < nevents; i++) { ivl_event_t event = ivl_stmt_events(stmt, i); if (ivl_event_nany(event) > 0) return false; - + int npos = ivl_event_npos(event); for (int j = 0; j < npos; j++) edge_triggered.insert(ivl_event_pos(event, j)); @@ -661,13 +661,13 @@ static bool draw_synthesisable_wait(vhdl_process *proc, stmt_container *containe edge = new vhdl_fcall("falling_edge", vhdl_type::boolean()); } assert(edge); - + edge->add_expr(nexus_to_var_ref(proc->get_scope(), *clock_net.begin())); // Draw the clocked branch // For an asynchronous reset we just want this around the else branch, stmt_container *else_container = body->add_elsif(edge); - + draw_stmt(proc, else_container, ivl_stmt_cond_false(sub_stmt)); if (proc->contains_wait_stmt()) { @@ -707,7 +707,7 @@ static bool draw_synthesisable_wait(vhdl_process *proc, stmt_container *containe * The difficulty stems from VHDL's restriction that a process with * a sensitivity list may not contain any `wait' statements: we need * to generate these to accurately model some Verilog statements. - * + * * The steps followed are: * 1) Determine whether this is the top-level statement in the process * 2) If this is top-level, call draw_synthesisable_wait to see if the @@ -753,7 +753,7 @@ static int draw_wait(vhdl_procedural *_proc, stmt_container *container, return 0; int nevents = ivl_stmt_nevent(stmt); - + bool combinatorial = true; // True if no negedge/posedge events for (int i = 0; i < nevents; i++) { ivl_event_t event = ivl_stmt_events(stmt, i); @@ -770,11 +770,11 @@ static int draw_wait(vhdl_procedural *_proc, stmt_container *container, vhdl_wait_stmt *wait = NULL; if (proc->contains_wait_stmt() || !is_top_level) - wait = new vhdl_wait_stmt(VHDL_WAIT_ON); - + wait = new vhdl_wait_stmt(VHDL_WAIT_ON); + for (int i = 0; i < nevents; i++) { ivl_event_t event = ivl_stmt_events(stmt, i); - + int nany = ivl_event_nany(event); for (int j = 0; j < nany; j++) { ivl_nexus_t nexus = ivl_event_any(event, j); @@ -803,22 +803,22 @@ static int draw_wait(vhdl_procedural *_proc, stmt_container *container, stmt_container tmp_container; draw_stmt(proc, &tmp_container, ivl_stmt_sub_stmt(stmt), true); - + for (int i = 0; i < nevents; i++) { ivl_event_t event = ivl_stmt_events(stmt, i); - + int nany = ivl_event_nany(event); for (int j = 0; j < nany; j++) { ivl_nexus_t nexus = ivl_event_any(event, j); vhdl_var_ref *ref = nexus_to_var_ref(proc->get_scope(), nexus); - + ref->set_name(ref->get_name() + "'Event"); test->add_expr(ref); if (!proc->contains_wait_stmt() && is_top_level) proc->add_sensitivity(ref->get_name()); } - + int nneg = ivl_event_nneg(event); for (int j = 0; j < nneg; j++) { ivl_nexus_t nexus = ivl_event_neg(event, j); @@ -826,13 +826,13 @@ static int draw_wait(vhdl_procedural *_proc, stmt_container *container, vhdl_fcall *detect = new vhdl_fcall("falling_edge", vhdl_type::boolean()); detect->add_expr(ref); - + test->add_expr(detect); if (!proc->contains_wait_stmt() && is_top_level) proc->add_sensitivity(ref->get_name()); } - + int npos = ivl_event_npos(event); for (int j = 0; j < npos; j++) { ivl_nexus_t nexus = ivl_event_pos(event, j); @@ -840,14 +840,14 @@ static int draw_wait(vhdl_procedural *_proc, stmt_container *container, vhdl_fcall *detect = new vhdl_fcall("rising_edge", vhdl_type::boolean()); detect->add_expr(ref); - + test->add_expr(detect); if (!proc->contains_wait_stmt() && is_top_level) proc->add_sensitivity(ref->get_name()); } } - + if (proc->contains_wait_stmt() || !is_top_level) { container->add_stmt(new vhdl_wait_stmt(VHDL_WAIT_UNTIL, test)); container->move_stmts_from(&tmp_container); @@ -863,9 +863,9 @@ static int draw_wait(vhdl_procedural *_proc, stmt_container *container, container->add_stmt(edge_detect); } - + } - + return 0; } @@ -875,7 +875,7 @@ static int draw_if(vhdl_procedural *proc, stmt_container *container, vhdl_expr *test = translate_expr(ivl_stmt_cond_expr(stmt)); if (NULL == test) return 1; - + vhdl_if_stmt *vhdif = new vhdl_if_stmt(test); ivl_statement_t cond_true_stmt = ivl_stmt_cond_true(stmt); @@ -887,7 +887,7 @@ static int draw_if(vhdl_procedural *proc, stmt_container *container, draw_stmt(proc, vhdif->get_else_container(), cond_false_stmt, is_last); container->add_stmt(vhdif); - + return 0; } @@ -904,7 +904,7 @@ static vhdl_var_ref *draw_case_test(vhdl_procedural *proc, stmt_container *conta if (typeid(*test) != typeid(vhdl_var_ref)) { const char *tmp_name = "Verilog_Case_Ex"; vhdl_type *test_type = new vhdl_type(*test->get_type()); - + if (!proc->get_scope()->have_declared(tmp_name)) { proc->get_scope()->add_decl (new vhdl_var_decl(tmp_name, new vhdl_type(*test_type))); @@ -925,7 +925,7 @@ static int draw_case(vhdl_procedural *proc, stmt_container *container, vhdl_var_ref *test = draw_case_test(proc, container, stmt); if (NULL == test) return 1; - + vhdl_case_stmt *vhdlcase = new vhdl_case_stmt(test); container->add_stmt(vhdlcase); @@ -933,7 +933,7 @@ static int draw_case(vhdl_procedural *proc, stmt_container *container, // possible case. So make sure we add an 'others' branch // if there isn't a default one. bool have_others = false; - + int nbranches = ivl_stmt_case_count(stmt); for (int i = 0; i < nbranches; i++) { vhdl_expr *when; @@ -947,7 +947,7 @@ static int draw_case(vhdl_procedural *proc, stmt_container *container, when = new vhdl_var_ref("others", NULL); have_others = true; } - + vhdl_case_branch *branch = new vhdl_case_branch(when); vhdlcase->add_branch(branch); @@ -960,8 +960,8 @@ static int draw_case(vhdl_procedural *proc, stmt_container *container, new vhdl_case_branch(new vhdl_var_ref("others", NULL)); others->get_container()->add_stmt(new vhdl_null_stmt()); vhdlcase->add_branch(others); - } - + } + return 0; } @@ -1325,12 +1325,12 @@ int draw_casezx(vhdl_procedural *proc, stmt_container *container, return 1; vhdl_if_stmt *result = NULL; - + int nbranches = ivl_stmt_case_count(stmt); bool is_casez = ivl_statement_type(stmt) == IVL_ST_CASEZ; for (int i = 0; i < nbranches; i++) { stmt_container *where = NULL; - + ivl_expr_t net = ivl_stmt_case_expr(stmt, i); if (net) { vhdl_binop_expr *all = @@ -1377,7 +1377,7 @@ int draw_casezx(vhdl_procedural *proc, stmt_container *container, // We don't actually use the generated `test' expression delete test; - + return 0; } @@ -1393,7 +1393,7 @@ int draw_while(vhdl_procedural *proc, stmt_container *container, int rc = draw_stmt(proc, &tmp_container, ivl_stmt_sub_stmt(stmt)); if (rc != 0) return 1; - + vhdl_expr *test = translate_expr(ivl_stmt_cond_expr(stmt)); if (NULL == test) return 1; @@ -1405,7 +1405,7 @@ int draw_while(vhdl_procedural *proc, stmt_container *container, vhdl_while_stmt *loop = new vhdl_while_stmt(test); draw_stmt(proc, loop->get_container(), ivl_stmt_sub_stmt(stmt)); - + container->add_stmt(loop); return 0; } @@ -1437,7 +1437,7 @@ int draw_repeat(vhdl_procedural *proc, stmt_container *container, container->add_stmt(loop); draw_stmt(proc, loop->get_container(), ivl_stmt_sub_stmt(stmt)); - + return 0; } @@ -1455,7 +1455,7 @@ int draw_utask(vhdl_procedural *proc, stmt_container *container, // TOOD: this completely ignores parameters! draw_stmt(proc, container, ivl_scope_def(tscope), false); - + return 0; } @@ -1473,7 +1473,7 @@ int draw_stmt(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt, bool is_last) { assert(stmt); - + switch (ivl_statement_type(stmt)) { case IVL_ST_STASK: return draw_stask(proc, container, stmt); @@ -1523,6 +1523,6 @@ int draw_stmt(vhdl_procedural *proc, stmt_container *container, error("No VHDL translation for statement at %s:%d (type = %d)", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt), ivl_statement_type(stmt)); - return 1; + return 1; } } diff --git a/tgt-vhdl/support.cc b/tgt-vhdl/support.cc index 5001d5bc8..6f16ba762 100644 --- a/tgt-vhdl/support.cc +++ b/tgt-vhdl/support.cc @@ -92,7 +92,7 @@ void support_function::emit_reduction(std::ostream &of, int level, // Emit a VHDL function emulating a Verilog reduction operator // Where op is the corresponding VHDL operator and unit is the // right-unit of the operator - + of << "(X : std_logic_vector) return std_logic is" << nl_string(indent(level)) << "variable R : std_logic := '" << unit << "';" << nl_string(level) @@ -106,7 +106,7 @@ void support_function::emit_reduction(std::ostream &of, int level, void support_function::emit(std::ostream &of, int level) const { of << nl_string(level) << "function " << function_name(type_); - + switch (type_) { case SF_UNSIGNED_TO_BOOLEAN: of << "(X : unsigned) return Boolean is" << nl_string(level) @@ -169,6 +169,6 @@ void support_function::emit(std::ostream &of, int level) const default: assert(false); } - + of << nl_string(level) << "end function;"; } diff --git a/tgt-vhdl/support.hh b/tgt-vhdl/support.hh index 1487cb036..063234be1 100644 --- a/tgt-vhdl/support.hh +++ b/tgt-vhdl/support.hh @@ -52,7 +52,7 @@ private: void emit_ternary(std::ostream &of, int level) const; void emit_reduction(std::ostream &of, int level, const char *op, char unit) const; - + support_function_t type_; }; diff --git a/tgt-vhdl/vhdl.cc b/tgt-vhdl/vhdl.cc index 9c025a3c2..9437517f2 100644 --- a/tgt-vhdl/vhdl.cc +++ b/tgt-vhdl/vhdl.cc @@ -80,7 +80,7 @@ void debug_msg(const char *fmt, ...) va_start(args, fmt); if (std::strcmp(ivl_design_flag(g_design, "debug"), "")) { - std::fputs("[DEBUG] ", stdout); + std::fputs("[DEBUG] ", stdout); std::vprintf(fmt, args); std::putchar('\n'); } @@ -127,10 +127,10 @@ extern "C" int target_design(ivl_design_t des) emit_all_entities(outfile, max_depth); } - + // Clean up free_all_vhdl_objects(); - + return g_errors; } diff --git a/tgt-vhdl/vhdl_element.cc b/tgt-vhdl/vhdl_element.cc index 6c1b5cbd8..21478c952 100644 --- a/tgt-vhdl/vhdl_element.cc +++ b/tgt-vhdl/vhdl_element.cc @@ -40,7 +40,7 @@ std::string nl_string(int level) { std::ostringstream ss; newline(ss, level); - return ss.str(); + return ss.str(); } /* @@ -98,7 +98,7 @@ void vhdl_element::print() const // This records the pointer allocated in a static field of vhdl_element // so we can delete it just before the code generator exits. void* vhdl_element::operator new(size_t size) throw (bad_alloc) -{ +{ // Let the default new handle the allocation void* ptr = ::operator new(size); @@ -115,7 +115,7 @@ void* vhdl_element::operator new(size_t size) throw (bad_alloc) // This just sets the corresponding pointer in vhdl_element::allocated_ // to NULL (since it's safe to delete a NULL pointer). void vhdl_element::operator delete(void* ptr) -{ +{ // Let the default delete handle the deallocation ::operator delete(ptr); diff --git a/tgt-vhdl/vhdl_element.hh b/tgt-vhdl/vhdl_element.hh index 01f15d48d..a324e227d 100644 --- a/tgt-vhdl/vhdl_element.hh +++ b/tgt-vhdl/vhdl_element.hh @@ -48,7 +48,7 @@ public: void* operator new(size_t size) throw (std::bad_alloc); void operator delete(void* ptr); - + virtual void emit(std::ostream &of, int level=0) const = 0; void print() const; diff --git a/tgt-vhdl/vhdl_helper.hh b/tgt-vhdl/vhdl_helper.hh index fb4b5848c..814c5369d 100644 --- a/tgt-vhdl/vhdl_helper.hh +++ b/tgt-vhdl/vhdl_helper.hh @@ -29,8 +29,8 @@ template void emit_children(std::ostream &of, const std::list &children, int level, const char *delim = "", - bool trailing_newline = true) -{ + bool trailing_newline = true) +{ // Don't indent if there are no children if (children.empty()) newline(of, level); diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 753da7b37..0391b0137 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -33,12 +33,12 @@ using namespace std; vhdl_scope::vhdl_scope() : parent_(NULL), init_(false), sig_assign_(true) { - + } vhdl_scope::~vhdl_scope() { - + } void vhdl_scope::set_initializing(bool i) @@ -109,7 +109,7 @@ vhdl_entity::vhdl_entity(const string& name, vhdl_arch *arch, int depth__) vhdl_entity::~vhdl_entity() { - + } void vhdl_entity::add_port(vhdl_port_decl *decl) @@ -126,7 +126,7 @@ void vhdl_entity::emit(std::ostream &of, int level) const of << "use ieee.numeric_std.all;" << std::endl; of << "use std.textio.all;" << std::endl; of << std::endl; - + emit_comment(of, level); of << "entity " << name_ << " is"; @@ -136,7 +136,7 @@ void vhdl_entity::emit(std::ostream &of, int level) const emit_children(of, ports_.get_decls(), indent(level), ";"); of << ");"; } - + newline(of, level); of << "end entity; "; blank_line(of, level); // Extra blank line after entities @@ -154,7 +154,7 @@ vhdl_const_time* scale_time(const vhdl_entity* ent, uint64_t t) void vhdl_entity::set_time_units(int units, int precision) { int vhdl_units = std::min(units, precision); - + if (vhdl_units >= -3) time_unit_ = TIME_UNIT_MS; else if (vhdl_units >= -6) @@ -167,7 +167,7 @@ void vhdl_entity::set_time_units(int units, int precision) vhdl_arch::~vhdl_arch() { - + } void vhdl_arch::add_stmt(vhdl_process *proc) @@ -213,7 +213,7 @@ void vhdl_process::emit(std::ostream &of, int level) const if (name_.size() > 0) of << name_ << ": "; of << "process "; - + int num_sens = sens_.size(); if (num_sens > 0) { of << "("; @@ -235,7 +235,7 @@ void vhdl_process::emit(std::ostream &of, int level) const stmt_container::~stmt_container() { - + } void stmt_container::add_stmt(vhdl_seq_stmt *stmt) @@ -257,18 +257,18 @@ void stmt_container::move_stmts_from(stmt_container *other) void stmt_container::emit(std::ostream &of, int level, bool newline) const { - emit_children(of, stmts_, level, "", newline); + emit_children(of, stmts_, level, "", newline); } vhdl_comp_inst::vhdl_comp_inst(const char *inst_name, const char *comp_name) : comp_name_(comp_name), inst_name_(inst_name) { - + } vhdl_comp_inst::~vhdl_comp_inst() { - + } void vhdl_comp_inst::map_port(const string& name, vhdl_expr *expr) @@ -300,7 +300,7 @@ void vhdl_comp_inst::emit(std::ostream &of, int level) const newline(of, indent(level)); of << ")"; } - + of << ";"; } @@ -321,7 +321,7 @@ vhdl_component_decl *vhdl_component_decl::component_decl_for(vhdl_entity *ent) (ent->get_name().c_str()); decl->ports_ = ent->get_scope()->get_decls(); - + return decl; } @@ -337,14 +337,14 @@ void vhdl_component_decl::emit(std::ostream &of, int level) const emit_children(of, ports_, indent(level), ";"); of << ");"; } - + newline(of, level); of << "end component;"; } vhdl_wait_stmt::~vhdl_wait_stmt() { - + } void vhdl_wait_stmt::emit(std::ostream &of, int level) const @@ -379,13 +379,13 @@ void vhdl_wait_stmt::emit(std::ostream &of, int level) const } break; } - + of << ";"; } vhdl_decl::~vhdl_decl() { - + } // Make a reference object to this declaration @@ -401,7 +401,7 @@ const vhdl_type *vhdl_decl::get_type() const } void vhdl_decl::set_initial(vhdl_expr *initial) -{ +{ if (!has_initial_) { assert(initial_ == NULL); initial_ = initial; @@ -412,7 +412,7 @@ void vhdl_decl::set_initial(vhdl_expr *initial) void vhdl_port_decl::emit(std::ostream &of, int level) const { of << name_ << " : "; - + switch (mode_) { case VHDL_PORT_IN: of << "in "; @@ -427,7 +427,7 @@ void vhdl_port_decl::emit(std::ostream &of, int level) const of << "buffer "; break; } - + type_->emit(of, level); } @@ -451,12 +451,12 @@ void vhdl_var_decl::emit(std::ostream &of, int level) const { of << "variable " << name_ << " : "; type_->emit(of, level); - + if (initial_) { of << " := "; initial_->emit(of, level); } - + of << ";"; emit_comment(of, level, true); } @@ -465,12 +465,12 @@ void vhdl_signal_decl::emit(std::ostream &of, int level) const { of << "signal " << name_ << " : "; type_->emit(of, level); - + if (initial_) { of << " := "; initial_->emit(of, level); } - + of << ";"; emit_comment(of, level, true); } @@ -484,7 +484,7 @@ void vhdl_type_decl::emit(std::ostream &of, int level) const vhdl_expr::~vhdl_expr() { - + } void vhdl_expr_list::add_expr(vhdl_expr *e) @@ -494,13 +494,13 @@ void vhdl_expr_list::add_expr(vhdl_expr *e) vhdl_expr_list::~vhdl_expr_list() { - + } void vhdl_expr_list::emit(std::ostream &of, int level) const { of << "("; - + int size = exprs_.size(); std::list::const_iterator it; for (it = exprs_.begin(); it != exprs_.end(); ++it) { @@ -522,7 +522,7 @@ void vhdl_pcall_stmt::emit(std::ostream &of, int level) const vhdl_var_ref::~vhdl_var_ref() { - + } void vhdl_var_ref::set_slice(vhdl_expr *s, int w) @@ -531,21 +531,21 @@ void vhdl_var_ref::set_slice(vhdl_expr *s, int w) slice_ = s; slice_width_ = w; - + vhdl_type_name_t tname = type_->get_name(); if (tname == VHDL_TYPE_ARRAY) { type_ = type_->get_base(); } else { assert(tname == VHDL_TYPE_UNSIGNED || tname == VHDL_TYPE_SIGNED); - + if (w > 0) type_ = new vhdl_type(tname, w); else - type_ = vhdl_type::std_logic(); + type_ = vhdl_type::std_logic(); } } - + void vhdl_var_ref::emit(std::ostream &of, int level) const { of << name_; @@ -565,7 +565,7 @@ void vhdl_const_string::emit(std::ostream &of, int level) const // In some instances a string literal can be ambiguous between // a String type and some other types (e.g. std_logic_vector) // The explicit cast to String removes this ambiguity (although - // isn't always strictly necessary) + // isn't always strictly necessary) of << "String'(\"" << value_ << "\")"; } @@ -583,7 +583,7 @@ void vhdl_fcall::emit(std::ostream &of, int level) const vhdl_abstract_assign_stmt::~vhdl_abstract_assign_stmt() { - + } void vhdl_nbassign_stmt::emit(std::ostream &of, int level) const @@ -596,7 +596,7 @@ void vhdl_nbassign_stmt::emit(std::ostream &of, int level) const of << " after "; after_->emit(of, level); } - + of << ";"; } @@ -609,12 +609,12 @@ void vhdl_assign_stmt::emit(std::ostream &of, int level) const } vhdl_const_bits::vhdl_const_bits(const char *value, int width, bool issigned, - bool qualify) + bool qualify) : vhdl_expr(issigned ? vhdl_type::nsigned(width) : vhdl_type::nunsigned(width), true), qualified_(qualify), signed_(issigned) -{ +{ // Can't rely on value being NULL-terminated while (width--) value_.push_back(*value++); @@ -644,9 +644,9 @@ void vhdl_const_bits::emit(std::ostream &of, int level) const && !has_meta_bits() && bits <= 64 && bits % 4 == 0) { of << "X\"" << hex << setfill('0') << setw(bits / 4) << ival; } - else { + else { of << "\""; - + std::string::const_reverse_iterator it; for (it = value_.rbegin(); it != value_.rend(); ++it) of << vl_to_vhdl_bit(*it); @@ -684,7 +684,7 @@ void vhdl_const_time::emit(std::ostream &of, int level) const vhdl_cassign_stmt::~vhdl_cassign_stmt() { - + } void vhdl_cassign_stmt::add_condition(vhdl_expr *value, vhdl_expr *cond) @@ -709,18 +709,18 @@ void vhdl_cassign_stmt::emit(std::ostream &of, int level) const of << "else "; } rhs_->emit(of, level); - + if (after_) { of << " after "; after_->emit(of, level); } - + of << ";"; } void vhdl_assert_stmt::emit(std::ostream &of, int level) const { - of << "assert false"; // TODO: Allow arbitrary expression + of << "assert false"; // TODO: Allow arbitrary expression of << " report \"" << reason_ << "\" severity failure;"; } @@ -733,7 +733,7 @@ vhdl_if_stmt::vhdl_if_stmt(vhdl_expr *test) vhdl_if_stmt::~vhdl_if_stmt() { - + } stmt_container *vhdl_if_stmt::add_elsif(vhdl_expr *test) @@ -746,7 +746,7 @@ stmt_container *vhdl_if_stmt::add_elsif(vhdl_expr *test) void vhdl_if_stmt::emit(std::ostream &of, int level) const { emit_comment(of, level); - + of << "if "; test_->emit(of, level); of << " then"; @@ -759,7 +759,7 @@ void vhdl_if_stmt::emit(std::ostream &of, int level) const of << " then"; (*it).container->emit(of, level); } - + if (!else_part_.empty()) { of << "else"; else_part_.emit(of, level); @@ -769,7 +769,7 @@ void vhdl_if_stmt::emit(std::ostream &of, int level) const vhdl_unaryop_expr::~vhdl_unaryop_expr() { - + } void vhdl_unaryop_expr::emit(std::ostream &of, int level) const @@ -797,7 +797,7 @@ vhdl_binop_expr::vhdl_binop_expr(vhdl_expr *left, vhdl_binop_t op, vhdl_binop_expr::~vhdl_binop_expr() { - + } void vhdl_binop_expr::add_expr(vhdl_expr *e) @@ -812,7 +812,7 @@ void vhdl_binop_expr::emit(std::ostream &of, int level) const of << "("; - assert(operands_.size() > 0); + assert(operands_.size() > 0); std::list::const_iterator it = operands_.begin(); (*it)->emit(of, level); @@ -826,14 +826,14 @@ void vhdl_binop_expr::emit(std::ostream &of, int level) const of << " " << ops[op_] << " "; (*it)->emit(of, level); - } + } of << ")"; } vhdl_bit_spec_expr::~vhdl_bit_spec_expr() { - + } void vhdl_bit_spec_expr::add_bit(int bit, vhdl_expr *e) @@ -845,7 +845,7 @@ void vhdl_bit_spec_expr::add_bit(int bit, vhdl_expr *e) void vhdl_bit_spec_expr::emit(std::ostream &of, int level) const { of << "("; - + std::list::const_iterator it; it = bits_.begin(); while (it != bits_.end()) { @@ -859,13 +859,13 @@ void vhdl_bit_spec_expr::emit(std::ostream &of, int level) const of << (bits_.empty() ? "" : ", ") << "others => "; others_->emit(of, level); } - + of << ")"; } vhdl_case_branch::~vhdl_case_branch() { - + } void vhdl_case_branch::emit(std::ostream &of, int level) const @@ -878,7 +878,7 @@ void vhdl_case_branch::emit(std::ostream &of, int level) const vhdl_case_stmt::~vhdl_case_stmt() { - + } void vhdl_case_stmt::emit(std::ostream &of, int level) const @@ -897,13 +897,13 @@ void vhdl_case_stmt::emit(std::ostream &of, int level) const else newline(of, level); } - + of << "end case;"; } vhdl_while_stmt::~vhdl_while_stmt() { - + } void vhdl_while_stmt::emit(std::ostream &of, int level) const @@ -923,7 +923,7 @@ void vhdl_loop_stmt::emit(std::ostream &of, int level) const vhdl_for_stmt::~vhdl_for_stmt() { - + } void vhdl_for_stmt::emit(std::ostream &of, int level) const @@ -981,7 +981,7 @@ void vhdl_param_decl::emit(std::ostream &of, int level) const vhdl_with_select_stmt::~vhdl_with_select_stmt() { - + } void vhdl_with_select_stmt::emit(std::ostream &of, int level) const @@ -989,12 +989,12 @@ void vhdl_with_select_stmt::emit(std::ostream &of, int level) const of << "with "; test_->emit(of, level); of << " select"; - emit_comment(of, level, true); + emit_comment(of, level, true); newline(of, indent(level)); out_->emit(of, level); - of << " <= "; - + of << " <= "; + when_list_t::const_iterator it = whens_.begin(); while (it != whens_.end()) { (*it).value->emit(of, level); @@ -1004,7 +1004,7 @@ void vhdl_with_select_stmt::emit(std::ostream &of, int level) const } of << " when "; (*it).cond->emit(of, level); - + if (++it != whens_.end() || others_ != NULL) { of << ","; newline(of, indent(level)); diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 961542d99..3f1c78719 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -40,7 +40,7 @@ public: const vhdl_type *get_type() const { return type_; } bool constant() const { return isconst_; } - + vhdl_expr *cast(const vhdl_type *to); virtual vhdl_expr *resize(int newwidth); virtual vhdl_expr *to_boolean(); @@ -63,7 +63,7 @@ public: vhdl_expr *slice = NULL) : vhdl_expr(type), name_(name), slice_(slice), slice_width_(0) {} ~vhdl_var_ref(); - + void emit(std::ostream &of, int level) const; const std::string &get_name() const { return name_; } void set_name(const std::string &name) { name_ = name; } @@ -186,7 +186,7 @@ private: int64_t bits_to_int() const; char sign_bit() const; bool has_meta_bits() const; - + std::string value_; bool qualified_, signed_; }; @@ -243,7 +243,7 @@ private: class vhdl_expr_list : public vhdl_element { public: ~vhdl_expr_list(); - + void emit(std::ostream &of, int level) const; bool empty() const { return exprs_.empty(); } void add_expr(vhdl_expr *e); @@ -315,7 +315,7 @@ public: vhdl_with_select_stmt(vhdl_expr *test, vhdl_var_ref *out) : test_(test), out_(out), others_(NULL) {} ~vhdl_with_select_stmt(); - + void emit(std::ostream &of, int level) const; void add_condition(vhdl_expr *value, vhdl_expr *cond, vhdl_expr *delay=NULL); void add_default(vhdl_expr* value); @@ -343,7 +343,7 @@ public: class stmt_container { public: ~stmt_container(); - + void add_stmt(vhdl_seq_stmt *stmt); void move_stmts_from(stmt_container *other); void emit(std::ostream &of, int level, bool newline=true) const; @@ -369,7 +369,7 @@ public: protected: vhdl_var_ref *lhs_; vhdl_expr *rhs_, *after_; -}; +}; /* @@ -380,7 +380,7 @@ class vhdl_nbassign_stmt : public vhdl_abstract_assign_stmt { public: vhdl_nbassign_stmt(vhdl_var_ref *lhs, vhdl_expr *rhs) : vhdl_abstract_assign_stmt(lhs, rhs) {} - + void emit(std::ostream &of, int level) const; }; @@ -412,7 +412,7 @@ public: vhdl_expr *expr = NULL) : type_(type), expr_(expr) {} ~vhdl_wait_stmt(); - + void emit(std::ostream &of, int level) const; void add_sensitivity(const std::string &s) { sensitivity_.push_back(s); } vhdl_wait_type_t get_type() const { return type_; } @@ -454,7 +454,7 @@ private: vhdl_expr *test; stmt_container *container; }; - + vhdl_expr *test_; stmt_container then_part_, else_part_; std::list elsif_parts_; @@ -495,7 +495,7 @@ private: class vhdl_loop_stmt : public vhdl_seq_stmt { public: virtual ~vhdl_loop_stmt() {} - + stmt_container *get_container() { return &stmts_; } void emit(std::ostream &of, int level) const; private: @@ -519,7 +519,7 @@ public: vhdl_for_stmt(const char *lname, vhdl_expr *from, vhdl_expr *to) : lname_(lname), from_(from), to_(to) {} ~vhdl_for_stmt(); - + void emit(std::ostream &of, int level) const; private: const char *lname_; @@ -534,7 +534,7 @@ private: class vhdl_pcall_stmt : public vhdl_seq_stmt { public: vhdl_pcall_stmt(const char *name) : name_(name) {} - + void emit(std::ostream &of, int level) const; void add_expr(vhdl_expr *e) { exprs_.add_expr(e); } private: @@ -564,12 +564,12 @@ public: // Return a new reference to this declaration vhdl_var_ref* make_ref() const; - + // The different sorts of assignment statement // ASSIGN_CONST is used to generate a variable to shadow a // constant that cannot be assigned to (e.g. a function parameter) enum assign_type_t { ASSIGN_BLOCK, ASSIGN_NONBLOCK, ASSIGN_CONST }; - + // Get the sort of assignment statement to generate for // assignemnts to this declaration // For some sorts of declarations it doesn't make sense @@ -580,7 +580,7 @@ public: // True if this declaration can be read from virtual bool is_readable() const { return true; } - + // Modify this declaration so it can be read from // This does nothing for most declaration types virtual void ensure_readable() {} @@ -592,7 +592,7 @@ protected: }; typedef std::list decl_list_t; - + /* * A forward declaration of a component. At the moment it is assumed @@ -722,7 +722,7 @@ class vhdl_scope { public: vhdl_scope(); ~vhdl_scope(); - + void add_decl(vhdl_decl *decl); void add_forward_decl(vhdl_decl *decl); vhdl_decl *get_decl(const std::string &name) const; @@ -730,7 +730,7 @@ public: bool name_collides(const string& name) const; bool contained_within(const vhdl_scope *other) const; vhdl_scope *get_parent() const; - + bool empty() const { return decls_.empty(); } const decl_list_t &get_decls() const { return decls_; } void set_parent(vhdl_scope *p) { parent_ = p; } @@ -756,7 +756,7 @@ class vhdl_procedural { public: vhdl_procedural() : contains_wait_stmt_(false) {} virtual ~vhdl_procedural() {} - + virtual stmt_container *get_container() { return &stmts_; } virtual vhdl_scope *get_scope() { return &scope_; } @@ -778,7 +778,7 @@ class vhdl_function : public vhdl_decl, public vhdl_procedural { friend class vhdl_forward_fdecl; public: vhdl_function(const char *name, vhdl_type *ret_type); - + virtual void emit(std::ostream &of, int level) const; vhdl_scope *get_scope() { return &variables_; } void add_param(vhdl_param_decl *p) { scope_.add_decl(p); } @@ -848,7 +848,7 @@ public: void set_time_units(int units, int precision); friend vhdl_const_time* scale_time(const vhdl_entity* ent, uint64_t t); - + // Each entity has an associated depth which is how deep in // the Verilog module hierarchy it was found // This is used to limit the maximum depth of modules emitted @@ -857,7 +857,7 @@ private: std::string name_; vhdl_arch *arch_; // Entity may only have a single architecture vhdl_scope ports_; - + // Entities have an associated VHDL time unit // This is used to implement the Verilog timescale directive time_unit_t time_unit_; diff --git a/tgt-vhdl/vhdl_target.h b/tgt-vhdl/vhdl_target.h index 8d99d97a1..3a4aad72a 100644 --- a/tgt-vhdl/vhdl_target.h +++ b/tgt-vhdl/vhdl_target.h @@ -28,11 +28,10 @@ ivl_design_t get_vhdl_design(); vhdl_var_ref *nexus_to_var_ref(vhdl_scope *arch_scope, ivl_nexus_t nexus); vhdl_var_ref* readable_ref(vhdl_scope* scope, ivl_nexus_t nex); string make_safe_name(ivl_signal_t sig); - + int draw_stask_display(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt, bool newline = true); -void prune_wait_for_0(stmt_container *container); +void prune_wait_for_0(stmt_container *container); void require_support_function(support_function_t f); #endif /* #ifndef INC_VHDL_TARGET_H */ - diff --git a/tgt-vhdl/vhdl_type.cc b/tgt-vhdl/vhdl_type.cc index c448f6a5e..c53e8e7aa 100644 --- a/tgt-vhdl/vhdl_type.cc +++ b/tgt-vhdl/vhdl_type.cc @@ -86,7 +86,7 @@ std::string vhdl_type::get_string() const case VHDL_TYPE_STD_ULOGIC: return std::string("std_ulogic"); case VHDL_TYPE_STD_LOGIC_VECTOR: - return std::string("std_logic_vector"); + return std::string("std_logic_vector"); case VHDL_TYPE_STRING: return std::string("String"); case VHDL_TYPE_LINE: diff --git a/tgt-vhdl/vhdl_type.hh b/tgt-vhdl/vhdl_type.hh index 9786ab9ad..c374584a7 100644 --- a/tgt-vhdl/vhdl_type.hh +++ b/tgt-vhdl/vhdl_type.hh @@ -57,7 +57,7 @@ public: // Copy constructor vhdl_type(const vhdl_type &other); - + virtual ~vhdl_type(); void emit(std::ostream &of, int level) const; @@ -69,7 +69,7 @@ public: int get_width() const { return msb_ - lsb_ + 1; } int get_msb() const { return msb_; } int get_lsb() const { return lsb_; } - + // Common types static vhdl_type *std_logic(); static vhdl_type *std_ulogic(); diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index 98204b085..335fa7e59 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -2589,7 +2589,7 @@ static struct vector_info draw_select_unsized_literal(ivl_expr_t expr, /* If we have an undefined index then just produce a 'bx result. */ fprintf(vvp_out, " %%jmp/1 T_%d.%d, 4;\n", thread_count, lab_x); - /* If the subv result is a magic constant, then make a copy in + /* If the subv result is a magic constant, then make a copy in writable vector space and work from there instead. */ if (subv.base < 4) { res.base = allocate_vector(subv.wid); diff --git a/vvp/array.cc b/vvp/array.cc index be0c86ed6..0258a948f 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -769,7 +769,7 @@ static unsigned vpi_array_is_real(vvp_array_t arr) assert(arr->array_count > 0); struct __vpiRealVar*rsig = vpip_realvar_from_handle(arr->nets[0]); if (rsig) { - struct __vpiSignal*vsig = vpip_signal_from_handle(arr->nets[0]); + struct __vpiSignal*vsig = vpip_signal_from_handle(arr->nets[0]); assert(vsig == 0); return 1U; } @@ -1503,7 +1503,6 @@ void vpip_array_word_change(struct __vpiCallback*cb, vpiHandle obj) void vpip_array_change(struct __vpiCallback*cb, vpiHandle obj) { - struct __vpiArray*arr = ARRAY_HANDLE(obj); cb->extra_data = -1; // This is a callback for every element. cb->next = arr->vpi_callbacks; diff --git a/vvp/concat.cc b/vvp/concat.cc index 76a05715c..a2498536d 100644 --- a/vvp/concat.cc +++ b/vvp/concat.cc @@ -69,7 +69,7 @@ void vvp_fun_concat::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit, vvp_context_t) { assert(bit.size() == wid); - + unsigned pdx = port.port(); if (vwid != wid_[pdx]) { diff --git a/vvp/event.cc b/vvp/event.cc index 570755c3e..ca4027fa8 100644 --- a/vvp/event.cc +++ b/vvp/event.cc @@ -51,7 +51,7 @@ void waitable_hooks_s::run_waiting_threads_(vthread_t&threads) vthread_t tmp = threads; if (tmp == 0) return; threads = 0; - + vthread_schedule_list(tmp); } diff --git a/vvp/examples/vector.vvp b/vvp/examples/vector.vvp index dd8071e79..8e249d098 100644 --- a/vvp/examples/vector.vvp +++ b/vvp/examples/vector.vvp @@ -2,7 +2,7 @@ main .scope module, "main"; -T0 %vpi_call 0 0 "$display", "Display the number: %b", 5'b0zx1; +T0 %vpi_call 0 0 "$display", "Display the number: %b", 5'b0zx1; %end; .thread T0; :file_names 2; diff --git a/vvp/schedule.h b/vvp/schedule.h index 966a9ee7e..11628ca13 100644 --- a/vvp/schedule.h +++ b/vvp/schedule.h @@ -65,9 +65,9 @@ extern void schedule_assign_array_word(vvp_array_t mem, * Create an event to propagate the output of a net. */ extern void schedule_propagate_plucked_vector(vvp_net_t*ptr, - vvp_time64_t delay, + vvp_time64_t delay, const vvp_vector4_t&val, - unsigned adr, unsigned wid); + unsigned adr, unsigned wid); /* * This is very similar to schedule_assign_vector, but generates an diff --git a/vvp/vpi_mcd.cc b/vvp/vpi_mcd.cc index c6ebb24f8..bf8ced53a 100644 --- a/vvp/vpi_mcd.cc +++ b/vvp/vpi_mcd.cc @@ -65,7 +65,7 @@ void vpip_mcd_init(FILE *log) fd_table[idx].fp = NULL; fd_table[idx].filename = NULL; } - + mcd_table[0].fp = stdout; mcd_table[0].filename = strdup("stdout"); diff --git a/vvp/vpi_vthr_vector.cc b/vvp/vpi_vthr_vector.cc index add5b8321..f65d2de97 100644 --- a/vvp/vpi_vthr_vector.cc +++ b/vvp/vpi_vthr_vector.cc @@ -318,7 +318,7 @@ static void vthr_vec_get_value(vpiHandle ref, s_vpi_value*vp) break; case vpiObjTypeVal: - vp->format = vpiVectorVal; + vp->format = vpiVectorVal; case vpiVectorVal: vp->value.vector = (s_vpi_vecval*) need_result_buf((wid+31)/32*sizeof(s_vpi_vecval), RBUF_VAL); diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 9aada7eab..b8bc706be 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -1870,8 +1870,8 @@ void vvp_vector4array_aa::reset_instance(vvp_context_t context) for (unsigned idx = 0 ; idx < words_ ; idx += 1) { if (cell->abits_ptr_) { for (unsigned n = 0 ; n < cnt ; n += 1) { - cell->abits_ptr_[n] = vvp_vector4_t::WORD_X_ABITS; - cell->bbits_ptr_[n] = vvp_vector4_t::WORD_X_BBITS; + cell->abits_ptr_[n] = vvp_vector4_t::WORD_X_ABITS; + cell->bbits_ptr_[n] = vvp_vector4_t::WORD_X_BBITS; } } cell++; diff --git a/vvp/vvp_net.h b/vvp/vvp_net.h index 23c709be8..fa6c42b52 100644 --- a/vvp/vvp_net.h +++ b/vvp/vvp_net.h @@ -65,7 +65,6 @@ typedef void*vvp_context_item_t; inline vvp_context_t vvp_allocate_context(unsigned nitem) { - return (vvp_context_t)malloc((2 + nitem) * sizeof(void*)); } diff --git a/vvp/words.cc b/vvp/words.cc index c4029929d..1236547c9 100644 --- a/vvp/words.cc +++ b/vvp/words.cc @@ -394,7 +394,7 @@ static void __compile_real_net2(vvp_net_t*node, vvp_array_t array, obj = vpip_make_real_var(name, node); compile_vpi_symbol(my_label, obj); } - + // REMOVE ME! Giving the net a label is a legacy of the times // when the .net was a functor of its own. In the long run, we // must fix the code generator to not rely on the label of the From fabde6d1b5cbfa7bfe5cf427953a1e2c2c0baf49 Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 16 Sep 2010 14:37:14 -0700 Subject: [PATCH 11/19] Normalize variable bit/indexed part selects using a fixed routine. This patch modifies all the variable bit and indexed part selects to use a common routine. This routine determines the minimum width needed to calculate the result correctly, pads the expression if needed and then converts the expression to signed if required to make the calculation correct. --- elab_expr.cc | 61 ++++++------------------ elab_lval.cc | 26 +++-------- netmisc.cc | 129 +++++++++++++++++++++++++++++++++++++++++++++------ netmisc.h | 16 +++---- 4 files changed, 144 insertions(+), 88 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index f0ed6ffc9..57ab64ae7 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -1011,7 +1011,7 @@ unsigned PEBLeftWidth::test_width(Design*des, NetScope*scope, && wid_left > 0 && wid_left < integer_width) { wid_left = integer_width; - + if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Test width of unsized " << human_readable_op(op_) @@ -1260,7 +1260,7 @@ NetExpr*PECallFunction::cast_to_width_(NetExpr*expr, int wid, bool signed_flag) if (wid < 0) wid = expr->expr_width(); - + if (debug_elaborate) cerr << get_fileline() << ": debug: cast to " << wid << " bits" << endl; @@ -2481,11 +2481,7 @@ NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope, return result_ex; } - if (par_msv >= par_lsv) { - if (par_lsv != 0) base = make_add_expr(base, -par_lsv); - } else { - base = make_sub_expr(par_lsv-wid+1, base); - } + base = normalize_variable_base(base, par_msv, par_lsv, wid, true); NetExpr*tmp = par->dup_expr(); tmp = new NetESelect(tmp, base, wid); @@ -2565,13 +2561,7 @@ NetExpr* PEIdent::elaborate_expr_param_idx_do_(Design*des, NetScope*scope, return result_ex; } - if (par_msv >= par_lsv) { - if (long offset = par_lsv+wid-1) { - base = make_add_expr(base, -offset); - } - } else { - base = make_sub_expr(par_lsv, base); - } + base = normalize_variable_base(base, par_msv, par_lsv, wid, false); NetExpr*tmp = par->dup_expr(); tmp = new NetESelect(tmp, base, wid); @@ -2597,7 +2587,7 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des, if (!name_tail.index.empty()) use_sel = name_tail.index.back().sel; - if (par->expr_type() == IVL_VT_REAL && + if (par->expr_type() == IVL_VT_REAL && use_sel != index_component_t::SEL_NONE) { perm_string name = peek_tail_name(path_); cerr << get_fileline() << ": error: " @@ -2729,17 +2719,10 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des, } else { if (par_me) { - long par_mv = par_me->value().as_long(); - long par_lv = par_le->value().as_long(); - if (par_mv >= par_lv) { - mtmp = par_lv - ? make_add_expr(mtmp, 0-par_lv) - : mtmp; - } else { - if (par_lv != 0) - mtmp = make_add_expr(mtmp, 0-par_mv); - mtmp = make_sub_expr(par_lv-par_mv, mtmp); - } + mtmp = normalize_variable_base(mtmp, + par_me->value().as_long(), + par_le->value().as_long(), + 1, true); } /* The value is constant, but the bit select @@ -2932,7 +2915,7 @@ NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope, cerr << get_fileline() << ": : " "Replacing select with a constant 'bx." << endl; } - + NetEConst*tmp = new NetEConst(verinum(verinum::Vx, 1, false)); tmp->set_line(*this); return tmp; @@ -3040,7 +3023,7 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope, } // Otherwise, make a part select that covers the right // range. - ex = new NetEConst(verinum(net->sig()->sb_to_idx(lsv) + + ex = new NetEConst(verinum(net->sig()->sb_to_idx(lsv) + offset)); if (warn_ob_select) { long rel_base = net->sig()->sb_to_idx(lsv) + offset; @@ -3079,12 +3062,7 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope, return ss; } - if (net->msi() > net->lsi()) { - if (long offset = net->lsi()) - base = make_add_expr(base, -offset); - } else { - base = make_sub_expr(net->lsi()-wid+1, base); - } + base = normalize_variable_base(base, net->msi(), net->lsi(), wid, true); NetESelect*ss = new NetESelect(net, base, wid); ss->set_line(*this); @@ -3171,12 +3149,7 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope, return ss; } - if (net->msi() > net->lsi()) { - if (long offset = net->lsi()+wid-1) - base = make_add_expr(base, -offset); - } else { - base = make_sub_expr(net->lsi(), base); - } + base = normalize_variable_base(base, net->msi(), net->lsi(), wid, false); NetESelect*ss = new NetESelect(net, base, wid); ss->set_line(*this); @@ -3281,12 +3254,8 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope, // complicated task because we need to generate // expressions to convert calculated bit select // values to canonical values that are used internally. - - if (net->sig()->msb() < net->sig()->lsb()) { - ex = make_sub_expr(net->sig()->lsb(), ex); - } else { - ex = make_add_expr(ex, - net->sig()->lsb()); - } + ex = normalize_variable_base(ex, net->sig()->msb(), net->sig()->lsb(), + 1, true); NetESelect*ss = new NetESelect(net, ex, 1); ss->set_line(*this); diff --git a/elab_lval.cc b/elab_lval.cc index f3ca7d083..9d2f38d32 100644 --- a/elab_lval.cc +++ b/elab_lval.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -198,7 +198,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, if (reg->array_dimensions() > 0) return elaborate_lval_net_word_(des, scope, reg); - // This must be after the array word elaboration above! + // This must be after the array word elaboration above! if (reg->get_scalar() && use_sel != index_component_t::SEL_NONE) { cerr << get_fileline() << ": error: can not select part of "; @@ -342,7 +342,6 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des, index_tail.msb->test_width(des, scope, integer_width, integer_width, expr_type_tmp, unsized_flag_tmp); - // Bit selects have a single select expression. Evaluate the // constant value and treat it as a part select with a bit // width of 1. @@ -357,10 +356,7 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des, if (mux) { // Non-constant bit mux. Correct the mux for the range // of the vector, then set the l-value part select expression. - if (reg->msb() < reg->lsb()) - mux = make_sub_expr(reg->lsb(), mux); - else if (reg->lsb() != 0) - mux = make_add_expr(mux, - reg->lsb()); + mux = normalize_variable_base(mux, reg->msb(), reg->lsb(), 1, true); lv->set_part(mux, 1); @@ -535,20 +531,12 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des, } else { /* Correct the mux for the range of the vector. */ if (use_sel == index_component_t::SEL_IDX_UP) { - if (reg->msb() > reg->lsb()) { - if (long offset = reg->lsb()) - base = make_add_expr(base, -offset); - } else { - base = make_sub_expr(reg->lsb()-wid+1, base); - } + base = normalize_variable_base(base, reg->msb(), reg->lsb(), + wid, true); } else { // This is assumed to be a SEL_IDX_DO. - if (reg->msb() > reg->lsb()) { - if (long offset = reg->lsb()+wid-1) - base = make_add_expr(base, -offset); - } else { - base = make_sub_expr(reg->lsb(), base); - } + base = normalize_variable_base(base, reg->msb(), reg->lsb(), + wid, false); } } diff --git a/netmisc.cc b/netmisc.cc index 8bde89a53..76ae01950 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -156,6 +156,120 @@ NetNet* cast_to_real(Design*des, NetScope*scope, NetNet*src) return tmp; } +/* + * Subtract an existing expression from a signed constant. + */ +static NetExpr* make_sub_expr(long val, NetExpr*expr) +{ + verinum val_v (val, expr->expr_width()); + val_v.has_sign(true); + + NetEConst*val_c = new NetEConst(val_v); + val_c->set_line(*expr); + + NetEBAdd*res = new NetEBAdd('-', val_c, expr); + res->set_line(*expr); + + return res; +} + +/* + * This routine is used to calculate the number of bits needed to + * contain the given number. + */ +static unsigned num_bits(long arg) +{ + unsigned res = 0; + + /* For a negative value we have room for one extra value, but + * we have a signed result so we need an extra bit for this. */ + if (arg < 0) { + arg = -arg - 1; + res += 1; + } + + /* Calculate the number of bits needed here. */ + while (arg) { + res += 1; + arg >>= 1; + } + + return res; +} + +/* + * This routine generates the normalization expression needed for a variable + * bit select or a variable base expression for an indexed part select. + */ +NetExpr *normalize_variable_base(NetExpr *base, long msb, long lsb, + unsigned long wid, bool is_up) +{ + long offset = lsb; + + if (msb < lsb) { + /* Correct the offset if needed. */ + if (is_up) offset -= wid - 1; + /* Calculate the space needed for the offset. */ + unsigned min_wid = num_bits(offset); + /* We need enough space for the larger of the offset or the + * base expression. */ + if (min_wid < base->expr_width()) min_wid = base->expr_width(); + /* Now that we have the minimum needed width increase it by + * one to make room for the normalization calculation. */ + min_wid += 1; + /* Pad the base expression to the correct width. */ + base = pad_to_width(base, min_wid, *base); + /* If the base expression is unsigned and either the lsb + * is negative or it does not fill the width of the base + * expression then we could generate negative normalized + * values so cast the expression to signed to get the + * math correct. */ + if ((lsb < 0 || num_bits(lsb+1) <= base->expr_width()) && + ! base->has_sign()) { + /* We need this extra select to hide the signed + * property from the padding above. It will be + * removed automatically during code generation. */ + NetESelect *tmp = new NetESelect(base, 0 , min_wid); + tmp->set_line(*base); + tmp->cast_signed(true); + base = tmp; + } + /* Normalize the expression. */ + base = make_sub_expr(offset, base); + } else { + /* Correct the offset if needed. */ + if (!is_up) offset += wid - 1; + /* If the offset is zero then just return the base (index) + * expression. */ + if (offset == 0) return base; + /* Calculate the space needed for the offset. */ + unsigned min_wid = num_bits(-offset); + /* We need enough space for the larger of the offset or the + * base expression. */ + if (min_wid < base->expr_width()) min_wid = base->expr_width(); + /* Now that we have the minimum needed width increase it by + * one to make room for the normalization calculation. */ + min_wid += 1; + /* Pad the base expression to the correct width. */ + base = pad_to_width(base, min_wid, *base); + /* If the offset is greater than zero then we need to do + * signed math to get the location value correct. */ + if (offset > 0 && ! base->has_sign()) { + /* We need this extra select to hide the signed + * property from the padding above. It will be + * removed automatically during code generation. */ + NetESelect *tmp = new NetESelect(base, 0 , min_wid); + tmp->set_line(*base); + tmp->cast_signed(true); + base = tmp; + } + /* Normalize the expression. */ + base = make_add_expr(base, -offset); + } + + return base; +} + /* * Add a signed constant to an existing expression. Generate a new * NetEBAdd node that has the input expression and an expression made @@ -190,19 +304,6 @@ NetExpr* make_add_expr(NetExpr*expr, long val) return res; } -NetExpr* make_sub_expr(long val, NetExpr*expr) -{ - verinum val_v (val, expr->expr_width()); - val_v.has_sign(true); - NetEConst*val_c = new NetEConst(val_v); - val_c->set_line(*expr); - - NetEBAdd*res = new NetEBAdd('-', val_c, expr); - res->set_line(*expr); - - return res; -} - NetEConst* make_const_x(unsigned long wid) { verinum xxx (verinum::Vx, wid); @@ -430,7 +531,7 @@ const char *human_readable_op(const char op, bool unary) case '>': type = ">"; break; case 'L': type = "<="; break; case 'G': type = ">="; break; - + case '^': type = "^"; break; // XOR case 'X': type = "~^"; break; // XNOR case '&': type = "&"; break; // Bitwise AND diff --git a/netmisc.h b/netmisc.h index 31d97def7..9ca563574 100644 --- a/netmisc.h +++ b/netmisc.h @@ -91,6 +91,13 @@ extern NetExpr*condition_reduce(NetExpr*expr); */ extern NetNet*crop_to_width(Design*des, NetNet*n, unsigned w); +/* + * This function generates an equation to normalize an expression using + * the provided array/vector information. + */ +extern NetExpr*normalize_variable_base(NetExpr *base, long msb, long lsb, + unsigned long wid, bool is_up); + /* * This function takes as input a NetNet signal and adds a constant * value to it. If the val is 0, then simply return sig. Otherwise, @@ -100,21 +107,12 @@ extern NetNet*add_to_net(Design*des, NetNet*sig, long val); extern NetNet*sub_net_from(Design*des, NetScope*scope, long val, NetNet*sig); /* - * These functions make various sorts of expressions, given operands - * of certain type. The order of the operands is preserved in cases - * where order matters. - * * make_add_expr * Make a NetEBAdd expression with the first argument and * the second. This may get turned into a subtract if is * less than zero. If val is exactly zero, then return as is. - * - * make_sub_expr - * Make a NetEBAdd(subtract) node that subtracts the given - * expression from the integer value. */ extern NetExpr*make_add_expr(NetExpr*expr, long val); -extern NetExpr*make_sub_expr(long val, NetExpr*expr); /* * Make a NetEConst object that contains only X bits. From f522ca8a9cf987961f842bd83f9193bde36fd521 Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 17 Sep 2010 10:43:11 -0700 Subject: [PATCH 12/19] Pad and sign convert array index expressions as needed. This patch mimics what was done for vectors, but is simpler since arrays don't use the endian information. It also needs to address the fact that .array/port assumes the expression is unsigned so any signed expression must be padded to make it larger than the maximum array word when it is converted to unsigned. --- elab_expr.cc | 3 +- elab_lval.cc | 3 +- netmisc.cc | 99 ++++++++++++++++++++++++++++++++++++++-------------- netmisc.h | 14 +++----- 4 files changed, 81 insertions(+), 38 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index 57ab64ae7..eacaffde2 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -2839,7 +2839,8 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope, // expression to calculate the canonical address. if (long base = net->array_first()) { - word_index = make_add_expr(word_index, 0-base); + word_index = normalize_variable_array_base( + word_index, base, net->array_count()); eval_expr(word_index); } } diff --git a/elab_lval.cc b/elab_lval.cc index 9d2f38d32..cb7bfd2fb 100644 --- a/elab_lval.cc +++ b/elab_lval.cc @@ -269,7 +269,8 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des, // expression to calculate the canonical address. if (long base = reg->array_first()) { - word = make_add_expr(word, 0-base); + word = normalize_variable_array_base(word, base, + reg->array_count()); eval_expr(word); } diff --git a/netmisc.cc b/netmisc.cc index 76ae01950..9fa1a0e95 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -156,6 +156,40 @@ NetNet* cast_to_real(Design*des, NetScope*scope, NetNet*src) return tmp; } +/* + * Add a signed constant to an existing expression. Generate a new + * NetEBAdd node that has the input expression and an expression made + * from the constant value. + */ +static NetExpr* make_add_expr(NetExpr*expr, long val) +{ + if (val == 0) + return expr; + + // If the value to be added is <0, then instead generate a + // SUBTRACT node and turn the value positive. + char add_op = '+'; + if (val < 0) { + add_op = '-'; + val = -val; + } + + verinum val_v (val); + val_v.has_sign(true); + + if (expr->has_width()) { + val_v = verinum(val_v, expr->expr_width()); + } + + NetEConst*val_c = new NetEConst(val_v); + val_c->set_line(*expr); + + NetEBAdd*res = new NetEBAdd(add_op, expr, val_c); + res->set_line(*expr); + + return res; +} + /* * Subtract an existing expression from a signed constant. */ @@ -271,37 +305,50 @@ NetExpr *normalize_variable_base(NetExpr *base, long msb, long lsb, } /* - * Add a signed constant to an existing expression. Generate a new - * NetEBAdd node that has the input expression and an expression made - * from the constant value. + * This routine generates the normalization expression needed for a variable + * array word select. */ -NetExpr* make_add_expr(NetExpr*expr, long val) +NetExpr *normalize_variable_array_base(NetExpr *base, long offset, + unsigned count) { - if (val == 0) - return expr; + assert(offset != 0); + /* Calculate the space needed for the offset. */ + unsigned min_wid = num_bits(-offset); + /* We need enough space for the larger of the offset or the base + * expression. */ + if (min_wid < base->expr_width()) min_wid = base->expr_width(); + /* Now that we have the minimum needed width increase it by one + * to make room for the normalization calculation. */ + min_wid += 1; + /* Pad the base expression to the correct width. */ + base = pad_to_width(base, min_wid, *base); + /* If the offset is greater than zero then we need to do signed + * math to get the location value correct. */ + if (offset > 0 && ! base->has_sign()) { + /* We need this extra select to hide the signed property + * from the padding above. It will be removed automatically + * during code generation. */ + NetESelect *tmp = new NetESelect(base, 0 , min_wid); + tmp->set_line(*base); + tmp->cast_signed(true); + base = tmp; + } + /* Normalize the expression. */ + base = make_add_expr(base, -offset); - // If the value to be added is <0, then instead generate a - // SUBTRACT node and turn the value positive. - char add_op = '+'; - if (val < 0) { - add_op = '-'; - val = -val; + /* We should not need to do this, but .array/port does not + * handle a small signed index correctly and it is a major + * effort to fix it. For now we will just pad the expression + * enough so that any negative value when converted to + * unsigned is larger than the maximum array word. */ + if (base->has_sign()) { + unsigned range_wid = num_bits(count-1) + 1; + if (min_wid < range_wid) { + base = pad_to_width(base, range_wid, *base); + } } - verinum val_v (val); - val_v.has_sign(true); - - if (expr->has_width()) { - val_v = verinum(val_v, expr->expr_width()); - } - - NetEConst*val_c = new NetEConst(val_v); - val_c->set_line(*expr); - - NetEBAdd*res = new NetEBAdd(add_op, expr, val_c); - res->set_line(*expr); - - return res; + return base; } NetEConst* make_const_x(unsigned long wid) diff --git a/netmisc.h b/netmisc.h index 9ca563574..6992faea0 100644 --- a/netmisc.h +++ b/netmisc.h @@ -92,11 +92,13 @@ extern NetExpr*condition_reduce(NetExpr*expr); extern NetNet*crop_to_width(Design*des, NetNet*n, unsigned w); /* - * This function generates an equation to normalize an expression using - * the provided array/vector information. + * These functions generate an equation to normalize an expression using + * the provided vector/array information. */ extern NetExpr*normalize_variable_base(NetExpr *base, long msb, long lsb, unsigned long wid, bool is_up); +extern NetExpr*normalize_variable_array_base(NetExpr *base, long offset, + unsigned count); /* * This function takes as input a NetNet signal and adds a constant @@ -106,14 +108,6 @@ extern NetExpr*normalize_variable_base(NetExpr *base, long msb, long lsb, extern NetNet*add_to_net(Design*des, NetNet*sig, long val); extern NetNet*sub_net_from(Design*des, NetScope*scope, long val, NetNet*sig); -/* - * make_add_expr - * Make a NetEBAdd expression with the first argument and - * the second. This may get turned into a subtract if is - * less than zero. If val is exactly zero, then return as is. - */ -extern NetExpr*make_add_expr(NetExpr*expr, long val); - /* * Make a NetEConst object that contains only X bits. */ From cac725ed3d02e544a07986324a7ba25f1fa31650 Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 21 Sep 2010 17:28:21 -0700 Subject: [PATCH 13/19] Fix signed/unsigned compare warnings. Fix all the Icarus files that can be so that we do not have any signed/unsigned compare warnings. It also removes const as a return qualifier for two routines in discipline.h. --- discipline.h | 6 +++--- tgt-vvp/draw_mux.c | 5 +++-- tgt-vvp/draw_net_input.c | 18 ++++++++++++------ tgt-vvp/draw_ufunc.c | 2 +- tgt-vvp/draw_vpi.c | 3 ++- tgt-vvp/eval_expr.c | 18 +++++++++--------- tgt-vvp/modpath.c | 2 +- tgt-vvp/vvp_scope.c | 9 +++++---- vpi/sys_display.c | 3 ++- vpi/sys_fileio.c | 5 +++-- vpi/sys_sdf.c | 3 ++- 11 files changed, 43 insertions(+), 31 deletions(-) diff --git a/discipline.h b/discipline.h index 9cfc4294b..0726710a9 100644 --- a/discipline.h +++ b/discipline.h @@ -1,7 +1,7 @@ #ifndef __discipline_H #define __discipline_H /* - * Copyright (c) 2008 Stephen Williams (steve@icarus.com) + * Copyright (c) 2008-2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -55,8 +55,8 @@ class ivl_discipline_s : public LineInfo { perm_string name() const { return name_; } ivl_dis_domain_t domain() const { return domain_; } - const ivl_nature_t potential() const { return potential_; } - const ivl_nature_t flow() const { return flow_; } + ivl_nature_t potential() const { return potential_; } + ivl_nature_t flow() const { return flow_; } private: perm_string name_; diff --git a/tgt-vvp/draw_mux.c b/tgt-vvp/draw_mux.c index 68ae8cf2b..234834900 100644 --- a/tgt-vvp/draw_mux.c +++ b/tgt-vvp/draw_mux.c @@ -105,12 +105,13 @@ static void draw_lpm_mux_ab(ivl_lpm_t net, const char*muxz) static void draw_lpm_mux_nest(ivl_lpm_t net, const char*muxz) { - int idx, level; + unsigned idx, level; unsigned width = ivl_lpm_width(net); unsigned swidth = ivl_lpm_selects(net); char*select_input; - assert(ivl_lpm_size(net) == (1 << swidth)); + assert(swidth < sizeof(unsigned)); + assert(ivl_lpm_size(net) == (1U << swidth)); select_input = strdup(draw_net_input(ivl_lpm_select(net))); diff --git a/tgt-vvp/draw_net_input.c b/tgt-vvp/draw_net_input.c index d0bdbfcbb..b0d72afff 100644 --- a/tgt-vvp/draw_net_input.c +++ b/tgt-vvp/draw_net_input.c @@ -94,7 +94,8 @@ static char* draw_C4_to_string(ivl_net_const_t cptr) for (idx = 0 ; idx < ivl_const_width(cptr) ; idx += 1) { char bitchar = bits[ivl_const_width(cptr)-idx-1]; *dp++ = bitchar; - assert((dp - result) < result_len); + assert(dp >= result); + assert((unsigned)(dp - result) < result_len); } strcpy(dp, ">"); @@ -144,7 +145,8 @@ static char* draw_C8_to_string(ivl_net_const_t cptr, assert(0); break; } - assert(dp - result < nresult); + assert(dp >= result); + assert((unsigned)(dp - result) < nresult); } strcpy(dp, ">"); @@ -260,7 +262,8 @@ static char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr) dp += ivl_logic_width(lptr); *dp++ = '>'; *dp = 0; - assert((dp-result) <= result_len); + assert(dp >= result); + assert((unsigned)(dp - result) <= result_len); return result; } else { char val[4]; @@ -279,7 +282,8 @@ static char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr) dp += 3*ivl_logic_width(lptr); *dp++ = '>'; *dp = 0; - assert((dp-result) <= result_len); + assert(dp >= result); + assert((unsigned)(dp - result) <= result_len); return result; } } @@ -297,7 +301,8 @@ static char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr) dp += ivl_logic_width(lptr); *dp++ = '>'; *dp = 0; - assert((dp-result) <= result_len); + assert(dp >= result); + assert((unsigned)(dp - result) <= result_len); } else { char val[4]; @@ -316,7 +321,8 @@ static char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr) dp += 3*ivl_logic_width(lptr); *dp++ = '>'; *dp = 0; - assert((dp-result) <= result_len); + assert(dp >= result); + assert((unsigned)(dp - result) <= result_len); } diff --git a/tgt-vvp/draw_ufunc.c b/tgt-vvp/draw_ufunc.c index 1b30e9039..8e0f8fcfa 100644 --- a/tgt-vvp/draw_ufunc.c +++ b/tgt-vvp/draw_ufunc.c @@ -156,7 +156,7 @@ int draw_ufunc_real(ivl_expr_t expr) ivl_scope_t def = ivl_expr_def(expr); ivl_signal_t retval = ivl_scope_port(def, 0); int res = 0; - int idx; + unsigned idx; /* If this is an automatic function, allocate the local storage. */ if (ivl_scope_is_auto(def)) { diff --git a/tgt-vvp/draw_vpi.c b/tgt-vvp/draw_vpi.c index 0a2543cc0..ccf4db9da 100644 --- a/tgt-vvp/draw_vpi.c +++ b/tgt-vvp/draw_vpi.c @@ -282,7 +282,8 @@ static void draw_vpi_taskfunc_args(const char*call_string, for (bit = wid ; bit > 0 ; bit -= 1) *dp++ = bits[bit-1]; *dp++ = 0; - assert(dp - buffer <= sizeof buffer); + assert(dp >= buffer); + assert((unsigned)(dp - buffer) <= sizeof buffer); } args[idx].text = strdup(buffer); continue; diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index 335fa7e59..c0ed35ff2 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -929,9 +929,9 @@ static struct vector_info draw_binary_expr_le(ivl_expr_t expr, case 'G': rv = draw_eval_expr_wid(re, owid, STUFF_OK_XZ); if (number_is_immediate(le,16,0) && !number_is_unknown(le)) { - unsigned imm = get_number_immediate(le); + long imm = get_number_immediate(le); assert(imm >= 0); - fprintf(vvp_out, " %%cmpi/%c %u, %u, %u;\n", s_flag, + fprintf(vvp_out, " %%cmpi/%c %u, %ld, %u;\n", s_flag, rv.base, imm, rv.wid); } else { lv = draw_eval_expr_wid(le, owid, STUFF_OK_XZ); @@ -945,9 +945,9 @@ static struct vector_info draw_binary_expr_le(ivl_expr_t expr, case 'L': lv = draw_eval_expr_wid(le, owid, STUFF_OK_XZ); if (number_is_immediate(re,16,0) && !number_is_unknown(re)) { - unsigned imm = get_number_immediate(re); + long imm = get_number_immediate(re); assert(imm >= 0); - fprintf(vvp_out, " %%cmpi/%c %u, %u, %u;\n", s_flag, + fprintf(vvp_out, " %%cmpi/%c %u, %ld, %u;\n", s_flag, lv.base, imm, lv.wid); } else { rv = draw_eval_expr_wid(re, owid, STUFF_OK_XZ); @@ -961,9 +961,9 @@ static struct vector_info draw_binary_expr_le(ivl_expr_t expr, case '<': lv = draw_eval_expr_wid(le, owid, STUFF_OK_XZ); if (number_is_immediate(re,16,0) && !number_is_unknown(re)) { - unsigned imm = get_number_immediate(re); + long imm = get_number_immediate(re); assert(imm >= 0); - fprintf(vvp_out, " %%cmpi/%c %u, %u, %u;\n", s_flag, + fprintf(vvp_out, " %%cmpi/%c %u, %ld, %u;\n", s_flag, lv.base, imm, lv.wid); } else { rv = draw_eval_expr_wid(re, owid, STUFF_OK_XZ); @@ -976,9 +976,9 @@ static struct vector_info draw_binary_expr_le(ivl_expr_t expr, case '>': rv = draw_eval_expr_wid(re, owid, STUFF_OK_XZ); if (number_is_immediate(le,16,0) && !number_is_unknown(le)) { - unsigned imm = get_number_immediate(le); + long imm = get_number_immediate(le); assert(imm >= 0); - fprintf(vvp_out, " %%cmpi/%c %u, %u, %u;\n", s_flag, + fprintf(vvp_out, " %%cmpi/%c %u, %ld, %u;\n", s_flag, rv.base, imm, rv.wid); } else { lv = draw_eval_expr_wid(le, owid, STUFF_OK_XZ); @@ -2609,7 +2609,7 @@ static struct vector_info draw_select_unsized_literal(ivl_expr_t expr, fprintf(vvp_out, " %%mov %u, %u, %u; Pad sub-expression to match width\n", res.base, subv.base, subv.wid); if (ivl_expr_signed(sube)) { - int idx; + unsigned idx; for (idx = subv.wid ; idx < res.wid ; idx += 1) { fprintf(vvp_out, " %%mov %u, %u, 1;\n", res.base+idx, subv.base+subv.wid-1); diff --git a/tgt-vvp/modpath.c b/tgt-vvp/modpath.c index c26087e5e..e65f629e0 100644 --- a/tgt-vvp/modpath.c +++ b/tgt-vvp/modpath.c @@ -28,7 +28,7 @@ static ivl_signal_t find_path_source_port(ivl_delaypath_t path) { - int idx; + unsigned idx; ivl_nexus_t nex = ivl_path_source(path); ivl_scope_t path_scope = ivl_path_scope(path); diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index da38e9647..2c1836c83 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -929,14 +929,15 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr) /* Get all the input label that I will use for parameters to the functor that I create later. */ ninp = ivl_logic_pins(lptr) - 1; + assert(ninp >= 0); input_strings = calloc(ninp, sizeof(char*)); - for (pdx = 0 ; pdx < ninp ; pdx += 1) + for (pdx = 0 ; pdx < (unsigned)ninp ; pdx += 1) input_strings[pdx] = draw_net_input(ivl_logic_pin(lptr, pdx+1)); level = 0; while (ninp) { - int inst; - for (inst = 0; inst < ninp; inst += 4) { + unsigned inst; + for (inst = 0; inst < (unsigned)ninp; inst += 4) { if (ninp > 4) fprintf(vvp_out, "L_%p/%d/%d .functor %s %u", lptr, level, inst, lcasc, vector_width); @@ -949,7 +950,7 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr) fprintf(vvp_out, " [%u %u]", str0, str1); } - for (pdx = inst; pdx < ninp && pdx < inst+4 ; pdx += 1) { + for (pdx = inst; pdx < (unsigned)ninp && pdx < inst+4 ; pdx += 1) { if (level) { fprintf(vvp_out, ", L_%p/%d/%d", lptr, level - 1, pdx*4); diff --git a/vpi/sys_display.c b/vpi/sys_display.c index 2ce1dfde5..bc7773033 100644 --- a/vpi/sys_display.c +++ b/vpi/sys_display.c @@ -265,7 +265,8 @@ static unsigned int get_format_char(char **rtn, int ljust, int plus, unsigned int ini_size = 512; /* The initial size of the buffer. */ /* Make sure the width fits in the initial buffer. */ - if (width+1 > ini_size) ini_size = width + 1; + assert(width >= -1); + if ((unsigned int)(width+1) > ini_size) ini_size = width + 1; /* The default return value is the full format. */ result = malloc(ini_size*sizeof(char)); diff --git a/vpi/sys_fileio.c b/vpi/sys_fileio.c index eaf688663..0b13f4bb8 100644 --- a/vpi/sys_fileio.c +++ b/vpi/sys_fileio.c @@ -545,7 +545,7 @@ static unsigned fread_word(FILE *fp, vpiHandle word, * my local vector. */ val.format = vpiVectorVal; vpi_get_value(word, &val); - for (bidx = 0; bidx < words; bidx += 1) { + for (bidx = 0; (unsigned)bidx < words; bidx += 1) { vector[bidx].aval = val.value.vector[bidx].aval; vector[bidx].bval = val.value.vector[bidx].bval; } @@ -682,10 +682,11 @@ static PLI_INT32 sys_fread_calltf(PLI_BYTE8*name) vector = calloc(words, sizeof(s_vpi_vecval)); bpe = (width+7)/8; + assert(count >= 0); if (is_mem) { unsigned idx; rtn = 0; - for (idx = 0; idx < count; idx += 1) { + for (idx = 0; idx < (unsigned)count; idx += 1) { vpiHandle word; word = vpi_handle_by_index(mem_reg, start+(signed)idx); rtn += fread_word(fp, word, words, bpe, vector); diff --git a/vpi/sys_sdf.c b/vpi/sys_sdf.c index 048c16046..0c8c02760 100644 --- a/vpi/sys_sdf.c +++ b/vpi/sys_sdf.c @@ -71,7 +71,8 @@ void sdf_select_instance(const char*celltype, const char*cellinst) const char*src = cellinst; const char*dp; while ( (dp=strchr(src, '.')) ) { - int len = dp - src; + unsigned len = dp - src; + assert(dp >= src); assert(len < sizeof buffer); strncpy(buffer, src, len); buffer[len] = 0; From 0dad9e3adb58838d1fa4d3b8a4e0d1cbecef4f8a Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 21 Sep 2010 17:41:06 -0700 Subject: [PATCH 14/19] Update fstapi.c to the latest from GTKWave-3.3.12 --- vpi/fstapi.c | 66 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/vpi/fstapi.c b/vpi/fstapi.c index bbb32e737..59211b772 100644 --- a/vpi/fstapi.c +++ b/vpi/fstapi.c @@ -42,6 +42,10 @@ #define FST_MACOSX #endif +#if defined(__CYGWIN__) && defined(__GNUC__) +#define FST_USE_FWRITE_COMBINING +#endif + /***********************/ /*** ***/ @@ -375,7 +379,7 @@ return(rc); static int fstWriterVarint(FILE *handle, uint64_t v) { uint64_t nxt; -unsigned char buf[32]; +unsigned char buf[10]; /* ceil(64/7) = 10 */ unsigned char *pnt = buf; int len; @@ -391,6 +395,50 @@ fstFwrite(buf, len, 1, handle); return(len); } +#ifndef FST_USE_FWRITE_COMBINING +static int fstWriterUint32WithVarint(FILE *handle, uint32_t *u, uint64_t v) +{ +uint64_t nxt; +unsigned char buf[10 + sizeof(uint32_t)]; +unsigned char *pnt = buf + sizeof(uint32_t); +int len; + +memcpy(buf, u, sizeof(uint32_t)); + +while((nxt = v>>7)) + { + *(pnt++) = (v&0x7f) | 0x80; + v = nxt; + } +*(pnt++) = (v&0x7f); + +len = pnt-buf; +fstFwrite(buf, len, 1, handle); +return(len); +} +#else +static int fstWriterUint32WithVarint(FILE *handle, uint32_t *u, uint64_t v, const void *dbuf, size_t siz) +{ +uint64_t nxt; +unsigned char buf[10 + sizeof(uint32_t) + siz]; /* gcc extension ok for cygwin */ +unsigned char *pnt = buf + sizeof(uint32_t); +int len; + +memcpy(buf, u, sizeof(uint32_t)); + +while((nxt = v>>7)) + { + *(pnt++) = (v&0x7f) | 0x80; + v = nxt; + } +*(pnt++) = (v&0x7f); +memcpy(pnt, dbuf, siz); + +len = pnt-buf + siz; +fstFwrite(buf, len, 1, handle); +return(len); +} +#endif /***********************/ /*** ***/ @@ -1555,7 +1603,6 @@ size_t len; if((xc) && (handle <= xc->maxhandle)) { - uint32_t prev_chg; uint32_t fpos; uint32_t *vm4ip; @@ -1573,14 +1620,15 @@ if((xc) && (handle <= xc->maxhandle)) if(!xc->is_initial_time) { - prev_chg = vm4ip[2]; fpos = xc->vchn_siz; - - fstFwrite(&prev_chg, 1, sizeof(uint32_t), xc->vchn_handle); - xc->vchn_siz += 4; - xc->vchn_siz += fstWriterVarint(xc->vchn_handle, xc->tchn_idx - vm4ip[3]); - fstFwrite(buf, len, 1, xc->vchn_handle); - xc->vchn_siz += len; + /* cygwin runs faster if these writes are combined, so the new fstWriterUint32WithVarint function, but should help with regular */ +#ifndef FST_USE_FWRITE_COMBINING + xc->vchn_siz += fstWriterUint32WithVarint(xc->vchn_handle, &vm4ip[2], xc->tchn_idx - vm4ip[3]); /* prev_chg is vm4ip[2] */ + fstFwrite(buf, len, 1, xc->vchn_handle); + xc->vchn_siz += len; +#else + xc->vchn_siz += fstWriterUint32WithVarint(xc->vchn_handle, &vm4ip[2], xc->tchn_idx - vm4ip[3], buf, len); /* do one fwrite op only */ +#endif vm4ip[3] = xc->tchn_idx; vm4ip[2] = fpos; } From b909c74a20ae64e03ef9a6d17357e18e6e8315a6 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 22 Sep 2010 10:34:02 -0700 Subject: [PATCH 15/19] Spelling fixes All fixes are in comments, except for one error message (was "iternal error") --- Makefile.in | 2 +- driver/main.c | 6 +++--- elab_expr.cc | 4 ++-- expr_synth.cc | 2 +- ivl_target.h | 4 ++-- lexor.lex | 2 +- netlist.h | 2 +- parse_misc.h | 2 +- pform.cc | 4 ++-- tgt-vhdl/expr.cc | 2 +- tgt-vhdl/stmt.cc | 2 +- tgt-vhdl/vhdl_syntax.hh | 4 ++-- tgt-vvp/eval_expr.c | 2 +- tgt-vvp/eval_real.c | 2 +- vvp/dff.h | 2 +- vvp/opcodes.txt | 2 +- vvp/vthread.cc | 4 ++-- vvp/vvp_island.cc | 2 +- vvp/vvp_net.cc | 2 +- vvp/vvp_net.h | 8 ++++---- vvp/vvp_net_sig.h | 4 ++-- 21 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Makefile.in b/Makefile.in index 7a9f120cc..fc291bf98 100644 --- a/Makefile.in +++ b/Makefile.in @@ -30,7 +30,7 @@ SHELL = /bin/sh # The "suffix" is used as an installation suffix. It modifies certain # key install paths/files such that a build and install of Icarus Verilog # with the same $(prefix) but a different $(suffix) will not interfere. -# The normal configuratin leaves suffix empty +# The normal configuration leaves suffix empty suffix = @install_suffix@ prefix = @prefix@ diff --git a/driver/main.c b/driver/main.c index 51a7c5e74..b966235d1 100644 --- a/driver/main.c +++ b/driver/main.c @@ -169,8 +169,8 @@ typedef struct t_command_file { p_command_file cmd_file_head = NULL; /* The FIFO head */ p_command_file cmd_file_tail = NULL; /* The FIFO tail */ -/* Temprarily store parameter definition from command line and - * parse it after we have delt with command file +/* Temporarily store parameter definition from command line and + * parse it after we have dealt with command file */ static const char** defparm_base = 0; static int defparm_size = 0; @@ -1105,7 +1105,7 @@ int main(int argc, char **argv) /* If we are planning on opening a dependencies file, then open and truncate it here. The other phases of compilation - will append to the file, so this is necessray to make sure + will append to the file, so this is necessary to make sure it starts out empty. */ if (depfile) { FILE*fd = fopen(depfile, "w"); diff --git a/elab_expr.cc b/elab_expr.cc index eacaffde2..efe32ed0f 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -729,7 +729,7 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des, return tmp; } - // Falback, handle the general case. + // Fallback, handle the general case. if (expr_wid > 0) lp = pad_to_width(lp, expr_wid, *this); tmp = new NetEBShift(op_, lp, rp); @@ -3494,7 +3494,7 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope, // evaluation of ternary expressions, but it doesn't disallow // it. The disadvantage of doing this is that semantic errors // in the unused clause will be missed, but people don't seem - // to mind, and do apreciate the optimization available here. + // to mind, and do appreciate the optimization available here. if (NetEConst*tmp = dynamic_cast (con)) { verinum cval = tmp->value(); ivl_assert(*this, cval.len()==1); diff --git a/expr_synth.cc b/expr_synth.cc index c279364ae..c4d0c39c9 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -907,7 +907,7 @@ NetNet* NetEUnary::synthesize(Design*des, NetScope*scope, NetExpr*root) return sig; } - cerr << get_fileline() << ": iternal error: " + cerr << get_fileline() << ": internal error: " << "NetEUnary::synthesize cannot handle op_=" << op_ << endl; des->errors += 1; return expr_->synthesize(des, scope, root); diff --git a/ivl_target.h b/ivl_target.h index 35946e776..c63531697 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -607,7 +607,7 @@ extern double ivl_const_real(ivl_net_const_t net); * * The discipline domain will not be IVL_DIS_NONE. The "none" domain * is a place-holder internally for incomplete parsing, and is also - * available for code generaters to use. + * available for code generators to use. */ extern const char*ivl_discipline_name(ivl_discipline_t net); extern ivl_dis_domain_t ivl_discipline_domain(ivl_discipline_t net); @@ -1696,7 +1696,7 @@ extern int ivl_scope_time_units(ivl_scope_t net); * * ivl_signal_discipline * If the signal has been declared with a domain (Verilog-AMS) then - * this function wil return a non-nil ivl_discipline_t. + * this function will return a non-nil ivl_discipline_t. * * ivl_signal_msb * ivl_signal_lsb diff --git a/lexor.lex b/lexor.lex index 00e8dc96c..ff96863c4 100644 --- a/lexor.lex +++ b/lexor.lex @@ -1179,7 +1179,7 @@ static void process_ucdrive(const char*txt) cp += strspn(cp, " \t"); if (strncmp(cp, "//", 2) != 0 && (size_t)(cp-yytext) != strlen(yytext)) { - VLerror(yylloc, "Invalid `unconnected_dirve directive (extra " + VLerror(yylloc, "Invalid `unconnected_drive directive (extra " "garbage after precision)."); return; } diff --git a/netlist.h b/netlist.h index 6c25220eb..e2c165d92 100644 --- a/netlist.h +++ b/netlist.h @@ -1829,7 +1829,7 @@ class NetPartSelect : public NetNode { * that makes sense for the technology. * * A NetBUFZ is transparent if strengths are passed through it without - * change. A NetBUFZ is non-transparent if values other then HiZ are + * change. A NetBUFZ is non-transparent if values other than HiZ are * converted to the strength of the output. */ class NetBUFZ : public NetNode { diff --git a/parse_misc.h b/parse_misc.h index 40efbfffa..f3b5dfc9b 100644 --- a/parse_misc.h +++ b/parse_misc.h @@ -78,7 +78,7 @@ extern bool have_timeunit_decl; extern bool have_timeprec_decl; /* - * Export there functions because we have to generate PENumber class + * Export these functions because we have to generate PENumber class * in pform.cc for user defparam definition from command file. */ extern verinum*make_unsized_dec(const char*txt); diff --git a/pform.cc b/pform.cc index 230843bd2..7b5566018 100644 --- a/pform.cc +++ b/pform.cc @@ -65,7 +65,7 @@ void parm_to_defparam_list(const string¶m) // Resolve hierarchical name for defparam. Remember // to deal with bit select for generate scopes. Bit - // select expression should be constant interger. + // select expression should be constant integer. pform_name_t name; char *nkey = key; char *ptr = strchr(key, '.'); @@ -144,7 +144,7 @@ void parm_to_defparam_list(const string¶m) char *num = strchr(value, '\''); if (num != 0) { verinum *val; - // BASED_NUMBER, somthing like - scope.parameter='b11 + // BASED_NUMBER, something like - scope.parameter='b11 // make sure to check 'h' first because 'b'&'d' may be included // in hex format if (strchr(num, 'h') || strchr(num, 'H')) diff --git a/tgt-vhdl/expr.cc b/tgt-vhdl/expr.cc index 11dd41683..a382fb8f6 100644 --- a/tgt-vhdl/expr.cc +++ b/tgt-vhdl/expr.cc @@ -477,7 +477,7 @@ static vhdl_expr *translate_select(ivl_expr_t e) new vhdl_type(*from->get_type())); } else if (from_var_ref->get_type()->get_name() != VHDL_TYPE_STD_LOGIC) { - // We can use the more idomatic VHDL slice notation on a + // We can use the more idiomatic VHDL slice notation on a // single variable reference vhdl_type integer(VHDL_TYPE_INTEGER); from_var_ref->set_slice(base->cast(&integer), ivl_expr_width(e) - 1); diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index 77952521e..7d217eb09 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -747,7 +747,7 @@ static int draw_wait(vhdl_procedural *_proc, stmt_container *container, bool is_top_level = container == proc->get_container() && container->empty(); - // See if this can be implemented in a more idomatic way before we + // See if this can be implemented in a more idiomatic way before we // fall back on the generic translation if (is_top_level && draw_synthesisable_wait(proc, container, stmt)) return 0; diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 3f1c78719..2d792a6a8 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -571,7 +571,7 @@ public: enum assign_type_t { ASSIGN_BLOCK, ASSIGN_NONBLOCK, ASSIGN_CONST }; // Get the sort of assignment statement to generate for - // assignemnts to this declaration + // assignments to this declaration // For some sorts of declarations it doesn't make sense // to assign to it so calling assignment_type just raises // an assertion failure @@ -768,7 +768,7 @@ protected: // If this is true then the body contains a `wait' statement // embedded in it somewhere - // If this is the case then we can't use a sensitvity list for + // If this is the case then we can't use a sensitivity list for // the process bool contains_wait_stmt_; }; diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index c0ed35ff2..248b3df80 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -1942,7 +1942,7 @@ static struct vector_info draw_number_expr(ivl_expr_t expr, unsigned wid) /* * This little helper function generates the instructions to pad a * vector in place. It is assumed that the calling function has set up - * the first sub_sidth bits of the dest vector, and the signed_flag is + * the first sub_width bits of the dest vector, and the signed_flag is * true if the extension is to be signed. */ static void pad_in_place(struct vector_info dest, unsigned sub_width, int signed_flag) diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index f7813a4d6..b3fc68e71 100644 --- a/tgt-vvp/eval_real.c +++ b/tgt-vvp/eval_real.c @@ -166,7 +166,7 @@ static int draw_number_real(ivl_expr_t expr) /* If this is a negative number, then arrange for the 2's complement to be calculated as we scan through the value. Real values are sign-magnitude, and this negation - gets us a magnitide. */ + gets us a magnitude. */ int negate = 0; int carry = 0; diff --git a/vvp/dff.h b/vvp/dff.h index 2915ee960..3f6372b0d 100644 --- a/vvp/dff.h +++ b/vvp/dff.h @@ -30,7 +30,7 @@ * * port-0: D input * port-1: Clock input - * port-2: Clock Enagle input + * port-2: Clock Enable input * port-3: Asynchronous D input. */ class vvp_dff : public vvp_net_fun_t { diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index 6a2351fae..7ea27d598 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -373,7 +373,7 @@ register to read the repetition count from (signed or unsigned). %evctl/i sets the repetition to an immediate unsigned value. %evctl/c clears the event control information. This is needed if a -%assign/e may be skiped since the %assign/e statements clear the +%assign/e may be skipped since the %assign/e statements clear the event control information and the other %evctl statements assert that this information has been cleared. You can get an assert if this information is not managed correctly. diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 5bc2326fd..e70a366e2 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -972,7 +972,7 @@ bool of_ASSIGN_V0(vthread_t thr, vvp_code_t cp) vvp_net_ptr_t ptr (cp->net, 0); if (bit >= 4) { // If the vector is not a synthetic one, then have the - // scheduler pluck it direcly out of my vector space. + // scheduler pluck it directly out of my vector space. schedule_assign_plucked_vector(ptr, delay, thr->bits4, bit, wid); } else { vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid); @@ -2078,7 +2078,7 @@ static unsigned long* divide_bits(unsigned long*ap, unsigned long*bp, unsigned w ap[cur_ptr+btop+1]); } - // cur_res is a guestimate of the result this far. It + // cur_res is a guesstimate of the result this far. It // may be 1 too big. (But it will also be >0) Try it, // and if the difference comes out negative, then adjust. diff --git a/vvp/vvp_island.cc b/vvp/vvp_island.cc index b4166d147..1b79d932e 100644 --- a/vvp/vvp_island.cc +++ b/vvp/vvp_island.cc @@ -291,7 +291,7 @@ vvp_island* compile_find_island(const char*island) * * The is a label in the domain outside the island, and the *