Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Revert bad merge from vhdl branch

  • Loading branch information...
commit ec49f10e2d00aa8acacf96667547ddac6916e49b 1 parent 7f2cb6a
@steveicarus authored
Showing with 1,253 additions and 1,139 deletions.
  1. +2 −2 Makefile.in
  2. +3 −3 discipline.h
  3. +1 −1  driver/Makefile.in
  4. +2 −2 driver/globals.h
  5. +1 −1  driver/iverilog.man.in
  6. +6 −6 driver/main.c
  7. +19 −49 elab_expr.cc
  8. +9 −20 elab_lval.cc
  9. +4 −4 elab_net.cc
  10. +1 −1  elaborate.cc
  11. +17 −11 eval_tree.cc
  12. +63 −63 examples/des.v
  13. +4 −4 examples/pal_reg.v
  14. +2 −2 examples/sqrt-virtex.v
  15. +2 −2 expr_synth.cc
  16. +2 −2 ivl_target.h
  17. +5 −5 ivlpp/lexor.lex
  18. +1 −1  lexor.lex
  19. +1 −1  main.cc
  20. +1 −1  mingw.txt
  21. +32 −17 net_design.cc
  22. +15 −1 net_expr.cc
  23. +1 −1  net_link.cc
  24. +2 −2 net_scope.cc
  25. +1 −1  netlist.cc
  26. +4 −1 netlist.h
  27. +159 −4 netmisc.cc
  28. +9 −17 netmisc.h
  29. +7 −9 nodangle.cc
  30. +1 −1  parse.y
  31. +1 −1  parse_misc.h
  32. +11 −11 pform.cc
  33. +1 −1  pform.h
  34. +1 −1  symbol_search.cc
  35. +2 −2 tgt-vhdl/Makefile.in
  36. +19 −40 tgt-vhdl/cast.cc
  37. +200 −0 tgt-vhdl/display.cc
  38. +26 −26 tgt-vhdl/expr.cc
  39. +15 −15 tgt-vhdl/logic.cc
  40. +28 −28 tgt-vhdl/lpm.cc
  41. +16 −13 tgt-vhdl/process.cc
  42. +119 −139 tgt-vhdl/scope.cc
  43. +17 −70 tgt-vhdl/state.cc
  44. +119 −270 tgt-vhdl/stmt.cc
  45. +3 −3 tgt-vhdl/support.cc
  46. +1 −1  tgt-vhdl/support.hh
  47. +3 −3 tgt-vhdl/vhdl.cc
  48. +6 −17 tgt-vhdl/vhdl_element.cc
  49. +1 −1  tgt-vhdl/vhdl_element.hh
  50. +2 −2 tgt-vhdl/vhdl_helper.hh
  51. +71 −120 tgt-vhdl/vhdl_syntax.cc
  52. +34 −64 tgt-vhdl/vhdl_syntax.hh
  53. +4 −3 tgt-vhdl/vhdl_target.h
  54. +1 −1  tgt-vhdl/vhdl_type.cc
  55. +2 −2 tgt-vhdl/vhdl_type.hh
  56. +3 −2 tgt-vvp/draw_mux.c
  57. +13 −7 tgt-vvp/draw_net_input.c
  58. +1 −1  tgt-vvp/draw_ufunc.c
  59. +2 −1  tgt-vvp/draw_vpi.c
  60. +11 −11 tgt-vvp/eval_expr.c
  61. +1 −1  tgt-vvp/eval_real.c
  62. +1 −1  tgt-vvp/modpath.c
  63. +48 −5 tgt-vvp/vvp_scope.c
  64. +57 −9 vpi/fstapi.c
  65. +2 −1  vpi/sys_display.c
  66. +3 −2 vpi/sys_fileio.c
  67. +2 −1  vpi/sys_sdf.c
  68. +6 −3 vvp/Makefile.in
  69. +1 −2  vvp/array.cc
  70. +1 −1  vvp/concat.cc
  71. +1 −1  vvp/dff.h
  72. +1 −1  vvp/event.cc
  73. +1 −1  vvp/examples/vector.vvp
  74. +1 −1  vvp/opcodes.txt
  75. +2 −2 vvp/schedule.h
  76. +1 −1  vvp/vpi_mcd.cc
  77. +1 −1  vvp/vpi_vthr_vector.cc
  78. +2 −2 vvp/vthread.cc
  79. +1 −1  vvp/vvp_island.cc
  80. +3 −3 vvp/vvp_net.cc
  81. +4 −5 vvp/vvp_net.h
  82. +2 −2 vvp/vvp_net_sig.h
  83. +1 −1  vvp/words.cc
View
4 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@
@@ -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
View
6 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_;
View
2  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
View
4 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);
View
2  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
View
12 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;
@@ -777,10 +777,10 @@ int main(int argc, char **argv)
turning the last two \ characters to null. Then we append
the lib\ivl$(suffix) to finish. */
{ char *s;
- char basepath[4096], tmp[4096];
- GetModuleFileName(NULL, tmp, sizeof tmp);
+ char basepath[4096], tmppath[4096];
+ GetModuleFileName(NULL, tmppath, sizeof tmppath);
/* Convert to a short name to remove any embedded spaces. */
- GetShortPathName(tmp, basepath, sizeof basepath);
+ GetShortPathName(tmppath, basepath, sizeof basepath);
strncpy(ivl_root, basepath, MAXSIZE);
ivl_root[MAXSIZE-1] = 0;
s = strrchr(ivl_root, sep);
@@ -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");
View
68 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);
@@ -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_)
@@ -1273,7 +1273,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;
@@ -2494,11 +2494,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);
@@ -2578,13 +2574,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);
@@ -2610,7 +2600,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: "
@@ -2742,17 +2732,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
@@ -2869,7 +2852,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);
}
}
@@ -2945,7 +2929,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;
@@ -3053,7 +3037,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;
@@ -3092,12 +3076,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);
@@ -3184,12 +3163,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);
@@ -3294,12 +3268,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);
@@ -3537,7 +3507,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<NetEConst*> (con)) {
verinum cval = tmp->value();
ivl_assert(*this, cval.len()==1);
View
29 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 ";
@@ -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);
}
@@ -342,7 +343,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 +357,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 +532,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);
}
}
View
8 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;
View
2  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: "
View
28 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<NetEConst*>(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<NetEConst*>(nexpr)) {
+ if (const NetEConst*tmp = dynamic_cast<const NetEConst*>(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<NetECReal*>(nexpr)) {
+ if (const NetECReal*tmp = dynamic_cast<const NetECReal*>(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;
View
126 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];
View
8 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);
View
4 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);
View
4 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);
@@ -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)
{
View
4 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
View
10 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;
View
2  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;
}
View
2  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;
View
2  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
View
49 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<const NetECReal*>(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<const NetEConst*>(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<NetECReal*>(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();
View
16 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)
{
View
2  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;
View
4 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;
View
2  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
View
5 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 {
@@ -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<perm_string,NetScope::param_expr_t>::iterator ref_t;
ref_t reference_;
+ bool solving_;
NetEParam(class Design*des, NetScope*scope, ref_t ref);
};
View
163 netmisc.cc
@@ -161,7 +161,7 @@ NetNet* cast_to_real(Design*des, NetScope*scope, NetNet*src)
* NetEBAdd node that has the input expression and an expression made
* from the constant value.
*/
-NetExpr* make_add_expr(NetExpr*expr, long val)
+static NetExpr* make_add_expr(NetExpr*expr, long val)
{
if (val == 0)
return expr;
@@ -190,10 +190,14 @@ NetExpr* make_add_expr(NetExpr*expr, long val)
return res;
}
-NetExpr* make_sub_expr(long val, NetExpr*expr)
+/*
+ * 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);
@@ -203,6 +207,150 @@ NetExpr* make_sub_expr(long val, NetExpr*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;
+}
+
+/*
+ * This routine generates the normalization expression needed for a variable
+ * array word select.
+ */
+NetExpr *normalize_variable_array_base(NetExpr *base, long offset,
+ unsigned count)
+{
+ 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);
+
+ /* 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);
+ }
+ }
+
+ return base;
+}
+
NetEConst* make_const_x(unsigned long wid)
{
verinum xxx (verinum::Vx, wid);
@@ -289,8 +437,15 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope,
void eval_expr(NetExpr*&expr, int prune_width)
{
assert(expr);
- if (dynamic_cast<NetEConst*>(expr)) return;
if (dynamic_cast<NetECReal*>(expr)) return;
+ /* Resize a constant if allowed and needed. */
+ if (NetEConst *tmp = dynamic_cast<NetEConst*>(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) {
@@ -423,7 +578,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
View
26 netmisc.h
@@ -92,6 +92,15 @@ extern NetExpr*condition_reduce(NetExpr*expr);
extern NetNet*crop_to_width(Design*des, NetNet*n, unsigned w);
/*
+ * 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
* value to it. If the val is 0, then simply return sig. Otherwise,
* return a new NetNet value that is the output of an addition.
@@ -100,23 +109,6 @@ 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 <expr> the first argument and
- * <val> the second. This may get turned into a subtract if <val> is
- * less than zero. If val is exactly zero, then return <expr> 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.
*/
extern NetEConst*make_const_x(unsigned long wid);
View
16 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. */
View
2  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
View
2  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);
View
22 pform.cc
@@ -62,10 +62,10 @@ void parm_to_defparam_list(const string&param)
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.
+ // select expression should be constant integer.
pform_name_t name;
char *nkey = key;
char *ptr = strchr(key, '.');
@@ -109,7 +109,7 @@ void parm_to_defparam_list(const string&param)
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&param)
cerr << "<command line>: 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 << "<command line>: error: \'\"\' appears within string value for defparam: " << name
+ cerr << "<command line>: 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);
@@ -144,7 +144,7 @@ void parm_to_defparam_list(const string&param)
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'))
@@ -165,17 +165,17 @@ void parm_to_defparam_list(const string&param)
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, "<command line>", 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<perm_string,LineInfo*>&genvars)
{
LineInfo*lni = new LineInfo();
View
2  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 <key>=<value>, 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.
View
2  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;
View
4 tgt-vhdl/Makefile.in
@@ -50,7 +50,7 @@ dep:
mv $*.d dep
O = vhdl.o state.o vhdl_element.o vhdl_type.o vhdl_syntax.o scope.o process.o \
- stmt.o expr.o lpm.o support.o cast.o logic.o
+ stmt.o expr.o lpm.o display.o support.o cast.o logic.o
ifeq (@WIN32@,yes)
TGTLDFLAGS=-L.. -livl
@@ -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
View
59 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
@@ -58,8 +58,6 @@ 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_STRING:
- return to_string();
case VHDL_TYPE_STD_ULOGIC:
return to_std_ulogic();
default:
@@ -81,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 {
@@ -91,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;
}
}
@@ -112,29 +110,10 @@ vhdl_expr *vhdl_expr::to_integer()
}
else
conv = new vhdl_fcall("To_Integer", vhdl_type::integer());
-
+
conv->add_expr(this);
-
- return conv;
-}
-vhdl_expr *vhdl_expr::to_string()
-{
- bool numeric = type_->get_name() == VHDL_TYPE_UNSIGNED
- || type_->get_name() == VHDL_TYPE_SIGNED;
-
- if (numeric) {
- vhdl_fcall *image = new vhdl_fcall("integer'image", vhdl_type::string());
- image->add_expr(this->cast(vhdl_type::integer()));
- return image;
- }
- else {
- // Assume type'image exists
- vhdl_fcall *image = new vhdl_fcall(type_->get_string() + "'image",
- vhdl_type::string());
- image->add_expr(this);
- return image;
- }
+ return conv;
}
/*
@@ -151,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());
@@ -160,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());
@@ -178,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) {
@@ -217,7 +196,7 @@ vhdl_expr *vhdl_expr::to_std_ulogic()
f->add_expr(this);
return f;
}
- else
+ else
assert(false);
}
@@ -240,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));
@@ -288,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);
}
@@ -301,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);
@@ -325,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;
}
View
200 tgt-vhdl/display.cc
@@ -0,0 +1,200 @@
+/*
+ * VHDL implementation of $display.
+ *
+ * Copyright (C) 2008-2009 Nick Gasson (nick@nickg.me.uk)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "vhdl_target.h"
+
+#include <iostream>
+#include <cstring>
+#include <cassert>
+#include <cctype>
+#include <sstream>
+
+static const char *DISPLAY_LINE = "Verilog_Display_Line";
+
+/*
+ * Write a VHDL expression into the current display line.
+ */
+static void display_write(stmt_container *container, vhdl_expr *expr)
+{
+ vhdl_pcall_stmt *write = new vhdl_pcall_stmt("Write");
+ vhdl_var_ref *ref =
+ new vhdl_var_ref(DISPLAY_LINE, vhdl_type::line());
+ write->add_expr(ref);
+
+ vhdl_type_name_t type = expr->get_type()->get_name();
+ if (type == VHDL_TYPE_SIGNED || type == VHDL_TYPE_UNSIGNED) {
+ vhdl_type integer(VHDL_TYPE_INTEGER);
+ write->add_expr(expr->cast(&integer));
+ }
+ else if (type != VHDL_TYPE_STRING) {
+ // Need to add a call to Type'Image for types not
+ // 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
+ write->add_expr(expr);
+
+ container->add_stmt(write);
+}
+
+/*
+ * Write the value of DISPLAY_LINE to the output.
+ */
+static void display_line(stmt_container *container)
+{
+ vhdl_pcall_stmt *write_line = new vhdl_pcall_stmt("WriteLine");
+ vhdl_var_ref *output_ref =
+ new vhdl_var_ref("std.textio.Output", new vhdl_type(VHDL_TYPE_FILE));
+ write_line->add_expr(output_ref);
+ vhdl_var_ref *ref =
+ new vhdl_var_ref(DISPLAY_LINE, vhdl_type::line());
+ write_line->add_expr(ref);
+ container->add_stmt(write_line);
+}
+
+/*
+ * Parse an octal escape sequence.
+ */
+static char parse_octal(const char *p)
+{
+ assert(*p && *(p+1) && *(p+2));
+ assert(isdigit(*p) && isdigit(*(p+1)) && isdigit(*(p+1)));
+
+ return (*p - '0') * 64
+ + (*(p+1) - '0') * 8
+ + (*(p+2) - '0') * 1;
+}
+
+static void flush_string(std::ostringstream &ss, stmt_container *container)
+{
+ display_write(container, new vhdl_const_string(ss.str().c_str()));
+
+ // Clear the stream
+ ss.str("");
+}
+
+// This should display the hierarchical module name, but we don't support
+// this in VHDL. So just emit a warning.
+static void display_m(stmt_container* container)
+{
+ cerr << "Warning: no VHDL translation for %m format code" << endl;
+}
+
+/*
+ * Generate VHDL for the $display system task.
+ * This is implemented using the functions in std.textio. Each
+ * parameter is written to a line variable in the process and
+ * then the line is written to the special variable `Output'
+ * (which represents the console). Subsequent $displays will
+ * use the same line variable.
+ *
+ * It's possible, although quite unlikely, that there will be
+ * name collision with an existing variable called
+ * `Verilog_Display_Line' -- do something about this?
+ */
+int draw_stask_display(vhdl_procedural *proc, stmt_container *container,
+ ivl_statement_t stmt, bool newline)
+{
+ if (!proc->get_scope()->have_declared(DISPLAY_LINE)) {
+ vhdl_var_decl *line_var =
+ new vhdl_var_decl(DISPLAY_LINE, vhdl_type::line());
+ 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) {
+ // $display may have an empty parameter, in which case
+ // the expression will be null
+ // The behaviour here seems to be to output a space
+ ivl_expr_t net = ivl_stmt_parm(stmt, i++);
+ if (net == NULL) {
+ 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++) {
+ if (*p == '\\') {
+ // Octal escape
+ char ch = parse_octal(p+1);
+ if (ch == '\n') {
+ flush_string(ss, container);
+ display_line(container);
+ }
+ else
+ ss << ch;
+ p += 3;
+ }
+ else if (*p == '%' && *(++p) != '%') {
+ flush_string(ss, container);
+
+ // Skip over width for now
+ while (isdigit(*p)) ++p;
+
+ switch (*p) {
+ case 'm':
+ display_m(container);
+ break;
+ default:
+ {
+ 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);
+ }
+ }
+ }
+ else
+ ss << *p;
+ }
+
+ // Call Write on any non-empty string data left in the buffer
+ 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)
+ return 1;
+
+ display_write(container, base);
+ }
+ }
+
+ if (newline)
+ display_line(container);
+
+ return 0;
+}
View
52 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.
*/