Merge branch 'master' of github.com:steveicarus/iverilog
This commit is contained in:
commit
952169ded9
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2013 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
|
||||
|
|
@ -207,6 +207,7 @@ NetESelect* NetESelect::dup_expr() const
|
|||
base_? base_->dup_expr() : 0,
|
||||
expr_width(), sel_type_);
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->cast_signed(has_sign());
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ NetNet* sub_net_from(Design*des, NetScope*scope, long val, NetNet*sig)
|
|||
} else {
|
||||
verinum zero ((int64_t)val);
|
||||
zero = pad_to_width(zero, sig->vector_width());
|
||||
zero.has_sign(sig->get_signed());
|
||||
NetConst*zero_obj = new NetConst(scope, scope->local_symbol(), zero);
|
||||
zero_obj->set_line(*sig);
|
||||
des->add_node(zero_obj);
|
||||
|
|
|
|||
4
t-dll.cc
4
t-dll.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2013 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
|
||||
|
|
@ -2166,7 +2166,7 @@ bool dll_target::net_const(const NetConst*net)
|
|||
assert(net->pin_count() == 1);
|
||||
|
||||
obj->width_ = net->width();
|
||||
obj->signed_ = 0;
|
||||
obj->signed_ = net->value().has_sign();
|
||||
if (obj->width_ <= sizeof(obj->b.bit_)) {
|
||||
bits = obj->b.bit_;
|
||||
|
||||
|
|
|
|||
|
|
@ -176,19 +176,29 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
vlog_errors += 1;
|
||||
}
|
||||
break;
|
||||
/* Convert Verilog-A min() or max() functions. This only works
|
||||
* when the arguments have no side effect. */
|
||||
/* Convert the Verilog-A min() or max() functions. */
|
||||
case 'm':
|
||||
case 'M':
|
||||
fprintf(vlog_out, "((");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") %s (", oper);
|
||||
emit_expr(scope, ivl_expr_oper2(expr), wid);
|
||||
fprintf(vlog_out, ") ? (");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") : (");
|
||||
emit_expr(scope, ivl_expr_oper2(expr), wid);
|
||||
fprintf(vlog_out, "))");
|
||||
if (ivl_expr_value(expr) == IVL_VT_REAL) {
|
||||
/* For a real expression use the $min()/$max() function. */
|
||||
if (ivl_expr_opcode(expr) == 'm') fprintf(vlog_out, "$min(");
|
||||
else fprintf(vlog_out, "$max(");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ",");
|
||||
emit_expr(scope, ivl_expr_oper2(expr), wid);
|
||||
fprintf(vlog_out, ")");
|
||||
} else {
|
||||
/* This only works when the argument has no side effect. */
|
||||
fprintf(vlog_out, "((");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") %s (", oper);
|
||||
emit_expr(scope, ivl_expr_oper2(expr), wid);
|
||||
fprintf(vlog_out, ") ? (");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") : (");
|
||||
emit_expr(scope, ivl_expr_oper2(expr), wid);
|
||||
fprintf(vlog_out, "))");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
|
|
@ -321,6 +331,27 @@ static void emit_select_name(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit a packed array access as a concatenation of bit selects.
|
||||
*/
|
||||
static void emit_expr_packed(ivl_scope_t scope, ivl_expr_t sig_expr,
|
||||
ivl_expr_t sel_expr, unsigned wid)
|
||||
{
|
||||
unsigned idx;
|
||||
assert(wid > 0);
|
||||
fprintf(vlog_out, "{");
|
||||
for (idx = wid - 1; idx > 0; idx -= 1) {
|
||||
emit_select_name(scope, sig_expr, wid);
|
||||
fprintf(vlog_out, "[");
|
||||
emit_expr(scope, sel_expr, 0);
|
||||
fprintf(vlog_out, " + %u], ", idx);
|
||||
}
|
||||
emit_select_name(scope, sig_expr, wid);
|
||||
fprintf(vlog_out, "[");
|
||||
emit_expr(scope, sel_expr, 0);
|
||||
fprintf(vlog_out, "]}");
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit an indexed part select as a concatenation of bit selects.
|
||||
*/
|
||||
|
|
@ -434,18 +465,19 @@ static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
fprintf(vlog_out, "[");
|
||||
emit_scaled_expr(scope, sel_expr, msb, lsb);
|
||||
fprintf(vlog_out, "]");
|
||||
} else if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) {
|
||||
/* A constant part select. */
|
||||
emit_select_name(scope, sig_expr, wid);
|
||||
emit_scaled_range(scope, sel_expr, width, msb, lsb);
|
||||
} else if (sel_type == IVL_SEL_OTHER) {
|
||||
/* A packed array access. */
|
||||
assert(lsb == 0);
|
||||
assert(msb >= 0);
|
||||
emit_expr_packed(scope, sig_expr, sel_expr, width);
|
||||
} else {
|
||||
if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) {
|
||||
/* A constant part select. */
|
||||
emit_select_name(scope, sig_expr, wid);
|
||||
emit_scaled_range(scope, sel_expr, width,
|
||||
msb, lsb);
|
||||
} else {
|
||||
/* An indexed part select. */
|
||||
assert(sel_type != IVL_SEL_OTHER);
|
||||
emit_expr_ips(scope, sig_expr, sel_expr,
|
||||
sel_type, width, msb, lsb);
|
||||
}
|
||||
/* An indexed part select. */
|
||||
emit_expr_ips(scope, sig_expr, sel_expr, sel_type,
|
||||
width, msb, lsb);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -587,19 +619,23 @@ static void emit_expr_unary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
break;
|
||||
/* Convert Verilog-A abs() function. This only works when the
|
||||
* argument has no side effect. */
|
||||
/* Convert the Verilog-A abs() function. */
|
||||
case 'm':
|
||||
fprintf(vlog_out, "((");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") > ");
|
||||
if (ivl_expr_value(expr) == IVL_VT_REAL) fprintf(vlog_out, "0.0");
|
||||
else fprintf(vlog_out, "0");
|
||||
fprintf(vlog_out, " ? (");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") : -(");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, "))");
|
||||
if (ivl_expr_value(expr) == IVL_VT_REAL) {
|
||||
/* For a real expression use the $abs() function. */
|
||||
fprintf(vlog_out, "$abs(");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ")");
|
||||
} else {
|
||||
/* This only works when the argument has no side effect. */
|
||||
fprintf(vlog_out, "((");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") > 0 ? (");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, ") : -(");
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
fprintf(vlog_out, "))");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(vlog_out, "<unknown>");
|
||||
|
|
|
|||
|
|
@ -465,7 +465,7 @@ void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex, unsigned allow_UD)
|
|||
assert(! must_be_sig);
|
||||
// HERE: I think we need special input code like the following.
|
||||
#if 0
|
||||
/* If these is a signal in this scope that is also driven by
|
||||
/* If there is a signal in this scope that is also driven by
|
||||
* the LPM then use the signal instead. */
|
||||
sig = find_local_signal(scope, ivl_lpm_q(lpm), &word);
|
||||
if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0);
|
||||
|
|
@ -818,13 +818,14 @@ static void emit_lpm_func(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm)
|
||||
{
|
||||
switch (ivl_lpm_type(lpm)) {
|
||||
/* Convert Verilog-A abs() function. This only works when the
|
||||
/* Convert the Verilog-A abs() function. This only works when the
|
||||
* argument has no side effect. */
|
||||
case IVL_LPM_ABS:
|
||||
// HERE: If this is a real net then use the $abs() function to get nan to
|
||||
// work correctly. See the expr code.
|
||||
fprintf(vlog_out, "((");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
fprintf(vlog_out, ") > ");
|
||||
// HERE: If this is a real net then use 0.0. See the expr code.
|
||||
fprintf(vlog_out, "0 ? (");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
fprintf(vlog_out, ") : -(");
|
||||
|
|
@ -1008,9 +1009,12 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_SIGN_EXT:
|
||||
// HERE: pr1002 and one other test fails if this assert is used. A more
|
||||
// robust method is needed to make sure things work as expected.
|
||||
// assert(! sign_extend);
|
||||
sign_extend = 1;
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0);
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 1);
|
||||
sign_extend = 0;
|
||||
break;
|
||||
case IVL_LPM_SUB:
|
||||
fprintf(vlog_out, "(");
|
||||
|
|
|
|||
|
|
@ -627,6 +627,163 @@ static void emit_named_block_scope(ivl_scope_t scope)
|
|||
fprintf(vlog_out, " */\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* In SystemVerilog a task or function can have a process to initialize
|
||||
* variables. In reality SystemVerilog requires this to be before the
|
||||
* initial/always blocks are processed, but that's not how it is currently
|
||||
* implemented in Icarus!
|
||||
*/
|
||||
static int find_tf_process(ivl_process_t proc, ivl_scope_t scope)
|
||||
{
|
||||
if (scope == ivl_process_scope(proc)) {
|
||||
ivl_scope_t mod_scope = scope;
|
||||
/* A task or function can only have initial processes that
|
||||
* are used to set local variables. */
|
||||
assert(ivl_process_type(proc) == IVL_PR_INITIAL);
|
||||
/* Find the module scope for this task/function. */
|
||||
while (ivl_scope_type(mod_scope) != IVL_SCT_MODULE) {
|
||||
mod_scope = ivl_scope_parent(mod_scope);
|
||||
assert(mod_scope);
|
||||
}
|
||||
/* Emit the process in the module scope since that is where
|
||||
* this all started. */
|
||||
emit_process(mod_scope, proc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit any initial blocks for the tasks or functions in a module.
|
||||
*/
|
||||
static int emit_tf_process(ivl_scope_t scope, ivl_scope_t parent)
|
||||
{
|
||||
ivl_scope_type_t sc_type = ivl_scope_type(scope);
|
||||
if ((sc_type == IVL_SCT_FUNCTION) || (sc_type == IVL_SCT_TASK)) {
|
||||
/* Output the initial/always blocks for this module. */
|
||||
ivl_design_process(design, (ivl_process_f)find_tf_process, scope);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void emit_path_delay(ivl_scope_t scope, ivl_delaypath_t dpath)
|
||||
{
|
||||
unsigned idx, count = 6;
|
||||
uint64_t pdlys [12];
|
||||
pdlys[0] = ivl_path_delay(dpath, IVL_PE_01);
|
||||
pdlys[1] = ivl_path_delay(dpath, IVL_PE_10);
|
||||
pdlys[2] = ivl_path_delay(dpath, IVL_PE_0z);
|
||||
pdlys[3] = ivl_path_delay(dpath, IVL_PE_z1);
|
||||
pdlys[4] = ivl_path_delay(dpath, IVL_PE_1z);
|
||||
pdlys[5] = ivl_path_delay(dpath, IVL_PE_z0);
|
||||
pdlys[6] = ivl_path_delay(dpath, IVL_PE_0x);
|
||||
pdlys[7] = ivl_path_delay(dpath, IVL_PE_x1);
|
||||
pdlys[8] = ivl_path_delay(dpath, IVL_PE_1x);
|
||||
pdlys[9] = ivl_path_delay(dpath, IVL_PE_x0);
|
||||
pdlys[10] = ivl_path_delay(dpath, IVL_PE_xz);
|
||||
pdlys[11] = ivl_path_delay(dpath, IVL_PE_zx);
|
||||
/* If the first six pdlys match then this may be a 1 delay form. */
|
||||
if ((pdlys[0] == pdlys[1]) &&
|
||||
(pdlys[0] == pdlys[2]) &&
|
||||
(pdlys[0] == pdlys[3]) &&
|
||||
(pdlys[0] == pdlys[4]) &&
|
||||
(pdlys[0] == pdlys[5])) count = 1;
|
||||
/* Check to see if only a rise and fall value are given for the first
|
||||
* six pdlys. */
|
||||
else if ((pdlys[0] == pdlys[2]) &&
|
||||
(pdlys[0] == pdlys[3]) &&
|
||||
(pdlys[1] == pdlys[4]) &&
|
||||
(pdlys[1] == pdlys[5])) count = 2;
|
||||
/* Check to see if a rise, fall and high-Z value are given for the
|
||||
* first six pdlys. */
|
||||
else if ((pdlys[0] == pdlys[3]) &&
|
||||
(pdlys[1] == pdlys[5]) &&
|
||||
(pdlys[2] == pdlys[4])) count = 3;
|
||||
/* Now check to see if the 'bx related pdlys match the reduced
|
||||
* delay form. If not then this is a twelve delay value. */
|
||||
if ((pdlys[6] != ((pdlys[0] < pdlys[2]) ? pdlys[0] : pdlys[2])) ||
|
||||
(pdlys[8] != ((pdlys[1] < pdlys[4]) ? pdlys[1] : pdlys[4])) ||
|
||||
(pdlys[11] != ((pdlys[3] < pdlys[5]) ? pdlys[3] : pdlys[5])) ||
|
||||
(pdlys[7] != ((pdlys[0] > pdlys[3]) ? pdlys[0] : pdlys[3])) ||
|
||||
(pdlys[9] != ((pdlys[1] > pdlys[5]) ? pdlys[1] : pdlys[5])) ||
|
||||
(pdlys[10] != ((pdlys[2] > pdlys[4]) ? pdlys[2] : pdlys[4]))) {
|
||||
count = 12;
|
||||
}
|
||||
emit_scaled_delay(scope, pdlys[0]);
|
||||
for(idx = 1; idx < count; idx += 1) {
|
||||
fprintf(vlog_out, ", ");
|
||||
emit_scaled_delay(scope, pdlys[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_specify_paths(ivl_scope_t scope, ivl_signal_t sig)
|
||||
{
|
||||
unsigned idx, count = ivl_signal_npath(sig);
|
||||
for(idx = 0; idx < count; idx += 1) {
|
||||
ivl_delaypath_t dpath = ivl_signal_path(sig, idx);
|
||||
ivl_nexus_t cond = ivl_path_condit(dpath);
|
||||
ivl_nexus_t source = ivl_path_source(dpath);
|
||||
unsigned has_edge = 0;
|
||||
fprintf(vlog_out, "%*c", indent, ' ');
|
||||
if (cond) {
|
||||
fprintf(vlog_out, "if (");
|
||||
emit_nexus_as_ca(scope, cond, 0);
|
||||
fprintf(vlog_out, ") ");
|
||||
} else if (ivl_path_is_condit(dpath)) {
|
||||
fprintf(vlog_out, "ifnone ");
|
||||
}
|
||||
fprintf(vlog_out, "(");
|
||||
if (ivl_path_source_posedge(dpath)) {
|
||||
fprintf(vlog_out, "posedge ");
|
||||
has_edge = 1;
|
||||
}
|
||||
if (ivl_path_source_negedge(dpath)) {
|
||||
fprintf(vlog_out, "negedge ");
|
||||
has_edge = 1;
|
||||
}
|
||||
emit_nexus_as_ca(scope, source, 0);
|
||||
fprintf(vlog_out, " =>");
|
||||
/* The compiler does not keep the source expression for an edge
|
||||
* sensitive path so add a constant to get the syntax right. */
|
||||
if (has_edge) {
|
||||
fprintf(vlog_out, "(%s : 1'bx /* Missing */)",
|
||||
ivl_signal_basename(sig));
|
||||
} else {
|
||||
fprintf(vlog_out, "%s", ivl_signal_basename(sig));
|
||||
}
|
||||
fprintf(vlog_out, ") = (");
|
||||
emit_path_delay(scope, dpath);
|
||||
fprintf(vlog_out, ");\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The path delay information from the specify block is attached to the
|
||||
* output ports.
|
||||
*/
|
||||
static void emit_specify(ivl_scope_t scope)
|
||||
{
|
||||
unsigned word, idx, count = ivl_scope_ports(scope);
|
||||
unsigned need_specify = 0;
|
||||
for (idx = 0; idx < count; idx += 1) {
|
||||
ivl_nexus_t nex = ivl_scope_mod_port(scope, idx);
|
||||
ivl_signal_t port = get_port_from_nexus(scope, nex, &word);
|
||||
// HERE: Do we need to use word? See emit_module_port_def().
|
||||
assert(port);
|
||||
if (ivl_signal_npath(port)) {
|
||||
if (! need_specify) {
|
||||
fprintf(vlog_out, "\n%*cspecify\n", indent, ' ');
|
||||
need_specify = 1;
|
||||
indent += indent_incr;
|
||||
}
|
||||
emit_specify_paths(scope, port);
|
||||
}
|
||||
}
|
||||
if (need_specify) {
|
||||
indent -= indent_incr;
|
||||
fprintf(vlog_out, "%*cendspecify\n", indent, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This search method may be slow for a large structural design with a
|
||||
* large number of gate types. That's not what this converter was built
|
||||
|
|
@ -801,6 +958,10 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent)
|
|||
emit_tran(scope, ivl_scope_switch(scope, idx));
|
||||
}
|
||||
|
||||
/* Output any initial blocks for tasks or functions defined
|
||||
* in this module. Used to initialize local variables. */
|
||||
ivl_scope_children(scope, (ivl_scope_f*) emit_tf_process, scope);
|
||||
|
||||
/* Output the initial/always blocks for this module. */
|
||||
ivl_design_process(design, (ivl_process_f)find_process, scope);
|
||||
}
|
||||
|
|
@ -810,9 +971,12 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent)
|
|||
emit_stmt(scope, ivl_scope_def(scope));
|
||||
}
|
||||
|
||||
/* Now print out any sub-scopes. */
|
||||
/* Print any sub-scopes. */
|
||||
ivl_scope_children(scope, (ivl_scope_f*) emit_scope, scope);
|
||||
|
||||
/* And finally print a specify block when needed. */
|
||||
if (sc_type == IVL_SCT_MODULE) emit_specify(scope);
|
||||
|
||||
/* Output the scope ending. */
|
||||
assert(indent >= indent_incr);
|
||||
indent -= indent_incr;
|
||||
|
|
|
|||
|
|
@ -105,6 +105,25 @@ static void emit_stmt_lval_name(ivl_scope_t scope, ivl_lval_t lval,
|
|||
}
|
||||
}
|
||||
|
||||
static void emit_stmt_lval_packed(ivl_scope_t scope, ivl_lval_t lval,
|
||||
ivl_signal_t sig, ivl_expr_t sel_expr,
|
||||
unsigned wid)
|
||||
{
|
||||
unsigned idx;
|
||||
assert(wid > 0);
|
||||
fprintf(vlog_out, "{");
|
||||
for (idx = wid - 1; idx > 0; idx -= 1) {
|
||||
emit_stmt_lval_name(scope, lval, sig);
|
||||
fprintf(vlog_out, "[");
|
||||
emit_expr(scope, sel_expr, 0);
|
||||
fprintf(vlog_out, " + %u], ", idx);
|
||||
}
|
||||
emit_stmt_lval_name(scope, lval, sig);
|
||||
fprintf(vlog_out, "[");
|
||||
emit_expr(scope, sel_expr, 0);
|
||||
fprintf(vlog_out, "]}");
|
||||
}
|
||||
|
||||
static void emit_stmt_lval_ips(ivl_scope_t scope, ivl_lval_t lval,
|
||||
ivl_signal_t sig, ivl_expr_t sel_expr,
|
||||
ivl_select_type_t sel_type,
|
||||
|
|
@ -245,17 +264,18 @@ static void emit_stmt_lval_piece(ivl_scope_t scope, ivl_lval_t lval)
|
|||
fprintf(vlog_out, "[");
|
||||
emit_scaled_expr(scope, sel_expr, msb, lsb);
|
||||
fprintf(vlog_out, "]");
|
||||
} else {
|
||||
} else if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) {
|
||||
/* A constant part select. */
|
||||
if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) {
|
||||
emit_stmt_lval_name(scope, lval, sig);
|
||||
emit_scaled_range(scope, sel_expr, width, msb, lsb);
|
||||
emit_stmt_lval_name(scope, lval, sig);
|
||||
emit_scaled_range(scope, sel_expr, width, msb, lsb);
|
||||
} else if (sel_type == IVL_SEL_OTHER) {
|
||||
assert(lsb == 0);
|
||||
assert(msb >= 0);
|
||||
emit_stmt_lval_packed(scope, lval, sig, sel_expr, width);
|
||||
} else {
|
||||
/* An indexed part select. */
|
||||
} else {
|
||||
assert(sel_type != IVL_SEL_OTHER);
|
||||
emit_stmt_lval_ips(scope, lval, sig, sel_expr, sel_type,
|
||||
width, msb, lsb);
|
||||
}
|
||||
emit_stmt_lval_ips(scope, lval, sig, sel_expr, sel_type,
|
||||
width, msb, lsb);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2012 Cary R. (cygcary@yahoo.com)
|
||||
* Copyright (C) 2010-2013 Cary R. (cygcary@yahoo.com)
|
||||
*
|
||||
* 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
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
static const char*version_string =
|
||||
"Icarus Verilog VLOG95 Code Generator " VERSION " (" VERSION_TAG ")\n\n"
|
||||
"Copyright (C) 2010-2012 Cary R. (cygcary@yahoo.com)\n\n"
|
||||
"Copyright (C) 2010-2013 Cary R. (cygcary@yahoo.com)\n\n"
|
||||
" This program is free software; you can redistribute it and/or modify\n"
|
||||
" it under the terms of the GNU General Public License as published by\n"
|
||||
" the Free Software Foundation; either version 2 of the License, or\n"
|
||||
|
|
@ -175,8 +175,9 @@ int target_design(ivl_design_t des)
|
|||
fprintf(vlog_out, " * 1364-1995 Verilog generated by Icarus Verilog "
|
||||
"VLOG95 Code Generator,\n");
|
||||
fprintf(vlog_out, " * Version: " VERSION " (" VERSION_TAG ")\n");
|
||||
fprintf(vlog_out, " * Converted using %s delays.\n",
|
||||
ivl_design_delay_sel(des));
|
||||
fprintf(vlog_out, " * Converted using %s delays and %s signed support.\n",
|
||||
ivl_design_delay_sel(des),
|
||||
allow_signed ? "with" : "without");
|
||||
fprintf(vlog_out, " */\n");
|
||||
|
||||
sim_precision = ivl_design_time_precision(des);
|
||||
|
|
@ -193,6 +194,25 @@ int target_design(ivl_design_t des)
|
|||
/* Emit any UDPs that are Icarus generated (D-FF). */
|
||||
emit_icarus_generated_udps();
|
||||
|
||||
/* If there were errors then add this information to the output. */
|
||||
if (vlog_errors) {
|
||||
fprintf(vlog_out, "\n");
|
||||
fprintf(vlog_out, "/*\n");
|
||||
if (vlog_errors == 1) {
|
||||
fprintf(vlog_out, " * There was 1 error during "
|
||||
"translation.\n");
|
||||
} else {
|
||||
fprintf(vlog_out, " * There were %d errors during "
|
||||
"translation.\n",
|
||||
vlog_errors);
|
||||
}
|
||||
fprintf(vlog_out, " */\n");
|
||||
/* Add something that makes the file invalid to make sure
|
||||
* the user knows there were errors. */
|
||||
fprintf(vlog_out, "<Add some text to make sure this file is not "
|
||||
"valid Verilog>\n");
|
||||
}
|
||||
|
||||
fclose(vlog_out);
|
||||
|
||||
/* A do nothing call to prevent warnings about this routine not
|
||||
|
|
|
|||
Loading…
Reference in New Issue