vlog95: Add partial support for getting a nexus name, etc.
This patch adds preliminary support for finding the correct name for a nexus at a given scope level. It also does the following. Report that real modulus is not supported. Fix a bug in the generation of concat expressions. Add missing generation of unary ! operator. Add ability to generate > integer delays. Refactor some of the support code. Make some of the error messages more descriptive. Ignore the ALLOC and FREE statements (only used with automatic tasks).
This commit is contained in:
parent
591c35cd7c
commit
dd0ea9db40
|
|
@ -36,7 +36,7 @@ void emit_event(ivl_scope_t scope, ivl_statement_t stmt)
|
|||
for (idx = 0; idx < count; idx += 1) {
|
||||
if (first) first = 0;
|
||||
else fprintf(vlog_out, " or ");
|
||||
emit_name_of_nexus(ivl_event_any(event, idx));
|
||||
emit_name_of_nexus(scope, ivl_event_any(event, idx));
|
||||
}
|
||||
|
||||
/* Check for positive edge events. */
|
||||
|
|
@ -46,7 +46,7 @@ void emit_event(ivl_scope_t scope, ivl_statement_t stmt)
|
|||
if (first) first = 0;
|
||||
else fprintf(vlog_out, " or ");
|
||||
fprintf(vlog_out, "posedge ");
|
||||
emit_name_of_nexus(ivl_event_pos(event, idx));
|
||||
emit_name_of_nexus(scope, ivl_event_pos(event, idx));
|
||||
}
|
||||
|
||||
/* Check for negative edge events. */
|
||||
|
|
@ -56,7 +56,7 @@ void emit_event(ivl_scope_t scope, ivl_statement_t stmt)
|
|||
if (first) first = 0;
|
||||
else fprintf(vlog_out, " or ");
|
||||
fprintf(vlog_out, "negedge ");
|
||||
emit_name_of_nexus(ivl_event_neg(event, idx));
|
||||
emit_name_of_nexus(scope, ivl_event_neg(event, idx));
|
||||
}
|
||||
|
||||
/* We have a named event if there were no edge events. */
|
||||
|
|
|
|||
|
|
@ -101,11 +101,17 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
|
||||
fprintf(vlog_out, "(");
|
||||
switch(ivl_expr_opcode(expr)) {
|
||||
case '%':
|
||||
if (ivl_expr_value(expr) == IVL_VT_REAL) {
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Real modulus operator "
|
||||
"is not supported.\n",
|
||||
ivl_expr_file(expr), ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
}
|
||||
case '+':
|
||||
case '-':
|
||||
case '*':
|
||||
case '/':
|
||||
case '%':
|
||||
case 'E':
|
||||
case 'e':
|
||||
case 'N':
|
||||
|
|
@ -176,9 +182,12 @@ static void emit_expr_concat(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
|
||||
if (repeat != 1) fprintf(vlog_out, "{%u", repeat);
|
||||
fprintf(vlog_out, "{");
|
||||
count -= 1;
|
||||
for (idx = 0; idx < count; idx += 1) {
|
||||
emit_expr(scope, ivl_expr_parm(expr, idx), 0);
|
||||
fprintf(vlog_out, ", ");
|
||||
}
|
||||
emit_expr(scope, ivl_expr_parm(expr, count), 0);
|
||||
fprintf(vlog_out, "}");
|
||||
if (repeat != 1) fprintf(vlog_out, "}");
|
||||
}
|
||||
|
|
@ -205,8 +214,8 @@ static void emit_expr_number(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
"safely represented.\n",
|
||||
ivl_expr_file(expr), ivl_expr_lineno(expr),
|
||||
rtype);
|
||||
}
|
||||
if (rtype < 0) {
|
||||
vlog_errors += 1;
|
||||
} else if (rtype == -1) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Signed number has "
|
||||
"an undefined bit and cannot be "
|
||||
|
|
@ -214,8 +223,13 @@ static void emit_expr_number(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
ivl_expr_file(expr), ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
} else if (rtype == -2) {
|
||||
fprintf(vlog_out, "'bz");
|
||||
} else if (rtype == -3) {
|
||||
fprintf(vlog_out, "'bx");
|
||||
} else {
|
||||
fprintf(vlog_out, "%"PRId32, value);
|
||||
}
|
||||
fprintf(vlog_out, "%"PRId32, value);
|
||||
/* An unsigned number is represented in hex if all the bits are
|
||||
* defined and it is more than a single bit otherwise it is
|
||||
* represented in binary form to preserve all the information. */
|
||||
|
|
@ -265,18 +279,18 @@ static void emit_expr_scope(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
||||
{
|
||||
ivl_expr_t sel_expr = ivl_expr_oper2(expr);
|
||||
ivl_expr_t sub_expr = ivl_expr_oper1(expr);
|
||||
ivl_expr_t sig_expr = ivl_expr_oper1(expr);
|
||||
if (sel_expr) {
|
||||
ivl_signal_t sig = ivl_expr_signal(sub_expr);
|
||||
ivl_signal_t sig = ivl_expr_signal(sig_expr);
|
||||
int msb = 1;
|
||||
int lsb = 0;
|
||||
unsigned width = ivl_expr_width(expr);
|
||||
assert(width > 0);
|
||||
if (ivl_expr_type(sub_expr) == IVL_EX_SIGNAL) {
|
||||
if (ivl_expr_type(sig_expr) == IVL_EX_SIGNAL) {
|
||||
msb = ivl_signal_msb(sig);
|
||||
lsb = ivl_signal_lsb(sig);
|
||||
}
|
||||
emit_expr(scope, sub_expr, wid);
|
||||
emit_expr(scope, sig_expr, wid);
|
||||
if (width == 1) {
|
||||
fprintf(vlog_out, "[");
|
||||
emit_scaled_expr(scope, sel_expr, msb, lsb);
|
||||
|
|
@ -286,7 +300,7 @@ static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
}
|
||||
} else {
|
||||
// HERE: Should this sign extend if the expression is signed?
|
||||
emit_expr(scope, sub_expr, wid);
|
||||
emit_expr(scope, sig_expr, wid);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -303,8 +317,6 @@ static void emit_expr_func(ivl_scope_t scope, ivl_expr_t expr, const char* name)
|
|||
count -= 1;
|
||||
for (idx = 0; idx < count; idx += 1) {
|
||||
emit_expr(scope, ivl_expr_parm(expr, idx), 0);
|
||||
// HERE: Do we need to support a NULL argument for the system functions?
|
||||
// See what was done system tasks.
|
||||
fprintf(vlog_out, ", ");
|
||||
}
|
||||
emit_expr(scope, ivl_expr_parm(expr, count), 0);
|
||||
|
|
@ -373,6 +385,7 @@ static void emit_expr_unary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
case 'A':
|
||||
case 'N':
|
||||
case 'X':
|
||||
case '!':
|
||||
fprintf(vlog_out, "%s", oper);
|
||||
emit_expr(scope, ivl_expr_oper1(expr), wid);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -49,11 +49,14 @@ void emit_scaled_delay(ivl_scope_t scope, uint64_t delay)
|
|||
}
|
||||
delay /= 10;
|
||||
}
|
||||
// HERE: If there is no frac then this has to fit into 31 bits like any
|
||||
// other integer.
|
||||
fprintf(vlog_out, "%"PRIu64, delay);
|
||||
if (real_dly) {
|
||||
fprintf(vlog_out, ".%s", frac);
|
||||
fprintf(vlog_out, "%"PRIu64".%s", delay, frac);
|
||||
} else {
|
||||
if (delay & 0xffffffff80000000) {
|
||||
fprintf(vlog_out, "(64'd%"PRIu64")", delay);
|
||||
} else {
|
||||
fprintf(vlog_out, "%"PRIu64, delay);
|
||||
}
|
||||
}
|
||||
free(frac);
|
||||
}
|
||||
|
|
@ -153,37 +156,103 @@ void emit_scaled_delayx(ivl_scope_t scope, ivl_expr_t expr)
|
|||
}
|
||||
}
|
||||
|
||||
static int64_t get_valid_int64_from_number(ivl_expr_t expr, int *rtype,
|
||||
const char *msg)
|
||||
{
|
||||
int64_t value = get_int64_from_number(expr, rtype);
|
||||
if (*rtype > 0) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled %s is greater than "
|
||||
"64 bits (%d) and cannot be safely represented.\n",
|
||||
ivl_expr_file(expr), ivl_expr_lineno(expr),
|
||||
msg, *rtype);
|
||||
vlog_errors += 1;
|
||||
return 0;
|
||||
} else if (*rtype < 0) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled %s has an undefined "
|
||||
"bit and cannot be represented.\n",
|
||||
ivl_expr_file(expr), ivl_expr_lineno(expr), msg);
|
||||
vlog_errors += 1;
|
||||
return 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// HERE: Probably need to pass in a msg string to make this work with
|
||||
// indexed part selects.
|
||||
static unsigned is_scaled_expr(ivl_expr_t expr, int msb, int lsb)
|
||||
{
|
||||
int64_t scale_val;
|
||||
int rtype;
|
||||
/* This is as easy as removing the addition/subtraction that was
|
||||
* added to scale the value to be zero based, but we need to verify
|
||||
* that the scaling value is correct first. */
|
||||
if (msb > lsb) {
|
||||
if ((ivl_expr_type(expr) != IVL_EX_BINARY) ||
|
||||
((ivl_expr_opcode(expr) != '+') &&
|
||||
(ivl_expr_opcode(expr) != '-')) ||
|
||||
(ivl_expr_type(ivl_expr_oper2(expr)) != IVL_EX_NUMBER)) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled "
|
||||
"expression value cannot be scaled.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
return 0;
|
||||
}
|
||||
scale_val = get_valid_int64_from_number(
|
||||
ivl_expr_oper2(expr), &rtype,
|
||||
"expression value scale coefficient");
|
||||
} else {
|
||||
if ((ivl_expr_type(expr) != IVL_EX_BINARY) ||
|
||||
((ivl_expr_opcode(expr) != '+') &&
|
||||
(ivl_expr_opcode(expr) != '-')) ||
|
||||
(ivl_expr_type(ivl_expr_oper1(expr)) != IVL_EX_NUMBER)) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled "
|
||||
"expression value cannot be scaled.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
return 0;
|
||||
}
|
||||
scale_val = get_valid_int64_from_number(
|
||||
ivl_expr_oper1(expr), &rtype,
|
||||
"expression value scale coefficient");
|
||||
}
|
||||
if (rtype) return 0;
|
||||
if (ivl_expr_opcode(expr) == '+') scale_val *= -1;
|
||||
if (lsb != scale_val) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled expression value "
|
||||
"scaling coefficient did not match expected "
|
||||
"value (%d != %"PRIu64").\n",
|
||||
ivl_expr_file(expr), ivl_expr_lineno(expr),
|
||||
lsb, scale_val);
|
||||
vlog_errors += 1;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void emit_scaled_range(ivl_scope_t scope, ivl_expr_t expr, unsigned width,
|
||||
int msb, int lsb)
|
||||
{
|
||||
if (msb >= lsb) {
|
||||
if (ivl_expr_type(expr) == IVL_EX_NUMBER) {
|
||||
int rtype;
|
||||
int64_t value = get_int64_from_number(expr, &rtype);
|
||||
if (rtype > 0) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled range is "
|
||||
"greater than 64 bits (%u) and cannot "
|
||||
"be safely represented.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr), rtype);
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
if (rtype < 0) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled range "
|
||||
"has an undefined bit and cannot be "
|
||||
"represented.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
int64_t value = get_valid_int64_from_number(expr, &rtype,
|
||||
"range value");
|
||||
if (rtype) return;
|
||||
value += lsb;
|
||||
fprintf(vlog_out, "[%"PRId64":%"PRId64"]",
|
||||
value + (int64_t)(width - 1), value);
|
||||
} else {
|
||||
// HERE: Need to scale the select expression and create a concatenation of
|
||||
// variable bit selects for that. We need the signal name as well.
|
||||
// As an optimization determine if this is an up or down to simplify
|
||||
// the generated expression.
|
||||
fprintf(vlog_out, "[<invalid>:<invalid>]");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Indexed part-selects "
|
||||
"are not currently supported.\n",
|
||||
|
|
@ -193,31 +262,14 @@ void emit_scaled_range(ivl_scope_t scope, ivl_expr_t expr, unsigned width,
|
|||
} else {
|
||||
if (ivl_expr_type(expr) == IVL_EX_NUMBER) {
|
||||
int rtype;
|
||||
int64_t value = get_int64_from_number(expr, &rtype);
|
||||
if (rtype > 0) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled value is "
|
||||
"greater than 64 bits (%u) and cannot "
|
||||
"be safely represented.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr), rtype);
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
if (rtype < 0) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled value "
|
||||
"has an undefined bit and cannot be "
|
||||
"represented.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
int64_t value = get_valid_int64_from_number(expr, &rtype,
|
||||
"range value");
|
||||
if (rtype) return;
|
||||
value = (int64_t)lsb - value;
|
||||
fprintf(vlog_out, "[%"PRId64":%"PRId64"]",
|
||||
value - (int64_t)(width - 1), value);
|
||||
} else {
|
||||
// HERE: Do basically the same as above.
|
||||
fprintf(vlog_out, "[<invalid>:<invalid>]");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Indexed part-selects "
|
||||
"are not currently supported.\n",
|
||||
|
|
@ -232,175 +284,99 @@ void emit_scaled_expr(ivl_scope_t scope, ivl_expr_t expr, int msb, int lsb)
|
|||
if (msb >= lsb) {
|
||||
if (ivl_expr_type(expr) == IVL_EX_NUMBER) {
|
||||
int rtype;
|
||||
int64_t value = get_int64_from_number(expr, &rtype);
|
||||
if (rtype > 0) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled value is "
|
||||
"greater than 64 bits (%u) and cannot "
|
||||
"be safely represented.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr), rtype);
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
if (rtype < 0) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled value "
|
||||
"has an undefined bit and cannot be "
|
||||
"represented.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
int64_t value = get_valid_int64_from_number(expr, &rtype,
|
||||
"value");
|
||||
if (rtype) return;
|
||||
value += lsb;
|
||||
fprintf(vlog_out, "%"PRId64, value);
|
||||
} else if (lsb == 0) {
|
||||
/* If the LSB is zero then there is no scale. */
|
||||
emit_expr(scope, expr, 0);
|
||||
} else {
|
||||
int64_t scale_val;
|
||||
int rtype;
|
||||
/* This is as easy as removing the addition/subtraction
|
||||
* that was added to scale the value to be zero based,
|
||||
* but we need to verify that the scaling value is
|
||||
* correct first. */
|
||||
if ((ivl_expr_type(expr) != IVL_EX_BINARY) ||
|
||||
((ivl_expr_opcode(expr) != '+') &&
|
||||
(ivl_expr_opcode(expr) != '-')) ||
|
||||
(ivl_expr_type(ivl_expr_oper2(expr)) != IVL_EX_NUMBER)) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled value "
|
||||
"expression/value cannot be scaled.\n ",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
if (is_scaled_expr(expr, msb, lsb)) {
|
||||
emit_expr(scope, ivl_expr_oper1(expr), 0);
|
||||
}
|
||||
scale_val = get_int64_from_number(ivl_expr_oper2(expr),
|
||||
&rtype);
|
||||
if (rtype > 0) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled value "
|
||||
"expression/value scale coefficient "
|
||||
"was greater then 64 bits (%d).\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr),
|
||||
rtype);
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
if (rtype < 0) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled value "
|
||||
"expression/value scale coefficient "
|
||||
"has an undefined bit.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
if (ivl_expr_opcode(expr) == '+') scale_val *= -1;
|
||||
if (lsb != scale_val) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled value "
|
||||
"expression/value scale coefficient "
|
||||
"did not match expected value "
|
||||
"(%d != %"PRIu64").\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr),
|
||||
lsb, scale_val);
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
emit_expr(scope, ivl_expr_oper1(expr), 0);
|
||||
}
|
||||
} else {
|
||||
if (ivl_expr_type(expr) == IVL_EX_NUMBER) {
|
||||
int rtype;
|
||||
int64_t value = get_int64_from_number(expr, &rtype);
|
||||
if (rtype > 0) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled value is "
|
||||
"greater than 64 bits (%u) and cannot "
|
||||
"be safely represented.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr), rtype);
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
if (rtype < 0) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled value "
|
||||
"has an undefined bit and cannot be "
|
||||
"represented.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
int64_t value = get_valid_int64_from_number(expr, &rtype,
|
||||
"value");
|
||||
if (rtype) return;
|
||||
value = (int64_t)lsb - value;
|
||||
fprintf(vlog_out, "%"PRId64, value);
|
||||
} else {
|
||||
int64_t scale_val;
|
||||
int rtype;
|
||||
/* This is as easy as removing the addition/subtraction
|
||||
* that was added to scale the value to be zero based,
|
||||
* but we need to verify that the scaling value is
|
||||
* correct first. */
|
||||
if ((ivl_expr_type(expr) != IVL_EX_BINARY) ||
|
||||
((ivl_expr_opcode(expr) != '+') &&
|
||||
(ivl_expr_opcode(expr) != '-')) ||
|
||||
(ivl_expr_type(ivl_expr_oper1(expr)) != IVL_EX_NUMBER)) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled value "
|
||||
"expression/value cannot be scaled.\n ",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
if (is_scaled_expr(expr, msb, lsb)) {
|
||||
emit_expr(scope, ivl_expr_oper2(expr), 0);
|
||||
}
|
||||
scale_val = get_int64_from_number(ivl_expr_oper1(expr),
|
||||
&rtype);
|
||||
if (rtype > 0) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled value "
|
||||
"expression/value scale coefficient "
|
||||
"was greater then 64 bits (%d).\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr),
|
||||
rtype);
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
if (rtype < 0) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled value "
|
||||
"expression/value scale coefficient "
|
||||
"has an undefined bit.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
if (ivl_expr_opcode(expr) == '+') scale_val *= -1;
|
||||
if (lsb != scale_val) {
|
||||
fprintf(vlog_out, "<invalid>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Scaled value "
|
||||
"expression/value scale coefficient "
|
||||
"did not match expected value "
|
||||
"(%d != %"PRIu64").\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr),
|
||||
lsb, scale_val);
|
||||
vlog_errors += 1;
|
||||
return;
|
||||
}
|
||||
emit_expr(scope, ivl_expr_oper2(expr), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HERE: Do we need the scope to know which name to use?
|
||||
void emit_name_of_nexus(ivl_nexus_t nex)
|
||||
static unsigned find_signal_in_nexus(ivl_scope_t scope, ivl_nexus_t nex)
|
||||
{
|
||||
ivl_signal_t sig, use_sig = 0;
|
||||
unsigned is_array = 0;
|
||||
int64_t array_idx = 0;
|
||||
unsigned idx, count;
|
||||
|
||||
count = ivl_nexus_ptrs(nex);
|
||||
for (idx = 0; idx < count; idx += 1) {
|
||||
ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx);
|
||||
sig = ivl_nexus_ptr_sig(nex_ptr);
|
||||
if (! sig) continue;
|
||||
if (ivl_signal_local(sig)) continue;
|
||||
if (scope == ivl_signal_scope(sig)) {
|
||||
if (use_sig) {
|
||||
// HERE: Which one should we use? For now it's the first one found.
|
||||
fprintf(stderr, "%s:%u: vlog95 warning: Duplicate "
|
||||
"name (%s",
|
||||
ivl_signal_file(sig),
|
||||
ivl_signal_lineno(sig),
|
||||
ivl_signal_basename(sig));
|
||||
if (ivl_signal_dimensions(sig) > 0) {
|
||||
int64_t tmp_idx = ivl_nexus_ptr_pin(nex_ptr);
|
||||
tmp_idx += ivl_signal_array_base(sig);
|
||||
fprintf(stderr, "[%"PRId64"]", tmp_idx);
|
||||
}
|
||||
fprintf(stderr, ") found for nexus ");
|
||||
fprintf(stderr, "(%s", ivl_signal_basename(use_sig));
|
||||
if (is_array) fprintf(stderr, "[%"PRId64"]", array_idx);
|
||||
fprintf(stderr, ")\n");
|
||||
} else {
|
||||
use_sig = sig;
|
||||
if (ivl_signal_dimensions(sig) > 0) {
|
||||
is_array = 1;
|
||||
array_idx = ivl_nexus_ptr_pin(nex_ptr);
|
||||
array_idx += ivl_signal_array_base(sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HERE: Check bit, part, etc. selects to make sure they work as well.
|
||||
if (use_sig) {
|
||||
fprintf(vlog_out, "%s", ivl_signal_basename(use_sig));
|
||||
if (is_array) fprintf(vlog_out, "[%"PRId64"]", array_idx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// HERE: Does this work correctly with an array reference created from @*?
|
||||
void emit_name_of_nexus(ivl_scope_t scope, ivl_nexus_t nex)
|
||||
{
|
||||
/* First look in the local scope for the nexus name. */
|
||||
if (find_signal_in_nexus(scope, nex)) return;
|
||||
|
||||
/* If the signal was not found in the passed scope then look in
|
||||
* the module scope if the passed scope was not the module scope. */
|
||||
if (find_signal_in_nexus(get_module_scope(scope), nex)) return;
|
||||
|
||||
// HERE: Need to check arr[var]? Can this be rebuilt?
|
||||
// Then look for down scopes and then any scope. For all this warn if
|
||||
// multiples are found in a given scope.
|
||||
fprintf(vlog_out, "<missing>");
|
||||
}
|
||||
|
||||
|
|
@ -526,6 +502,11 @@ uint64_t get_uint64_from_number(ivl_expr_t expr, int *result_type)
|
|||
if (bits[idx] == '1') value |= (uint64_t)1 << idx;
|
||||
else if (bits[idx] != '0') {
|
||||
*result_type = -1;
|
||||
/* If the value is entirely x/z then return -2 or -3. */
|
||||
if ((idx == 0) && (trim_wid == 1)) {
|
||||
if (bits[idx] == 'x') *result_type -= 1;
|
||||
*result_type -= 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -537,7 +518,7 @@ uint64_t get_uint64_from_number(ivl_expr_t expr, int *result_type)
|
|||
* Extract an int64_t value from the given number expression. If the result
|
||||
* type is 0 then the returned value is valid. If it is positive then the
|
||||
* value was too large and if it is negative then the value had undefined
|
||||
* bits.
|
||||
* bits. -2 is all bits z and -3 is all bits x.
|
||||
*/
|
||||
int64_t get_int64_from_number(ivl_expr_t expr, int *result_type)
|
||||
{
|
||||
|
|
@ -567,6 +548,11 @@ int64_t get_int64_from_number(ivl_expr_t expr, int *result_type)
|
|||
if (bits[idx] == '1') value |= (int64_t)1 << idx;
|
||||
else if (bits[idx] != '0') {
|
||||
*result_type = -1;
|
||||
/* If the value is entirely x/z then return -2 or -3. */
|
||||
if ((idx == 0) && (trim_wid == 1)) {
|
||||
if (bits[idx] == 'x') *result_type -= 1;
|
||||
*result_type -= 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -582,7 +568,7 @@ int64_t get_int64_from_number(ivl_expr_t expr, int *result_type)
|
|||
* Extract an int32_t value from the given number expression. If the result
|
||||
* type is 0 then the returned value is valid. If it is positive then the
|
||||
* value was too large and if it is negative then the value had undefined
|
||||
* bits.
|
||||
* bits. -2 is all bits z and -3 is all bits x.
|
||||
*/
|
||||
int32_t get_int32_from_number(ivl_expr_t expr, int *result_type)
|
||||
{
|
||||
|
|
@ -612,6 +598,11 @@ int32_t get_int32_from_number(ivl_expr_t expr, int *result_type)
|
|||
if (bits[idx] == '1') value |= (int32_t)1 << idx;
|
||||
else if (bits[idx] != '0') {
|
||||
*result_type = -1;
|
||||
/* If the value is entirely x/z then return -2 or -3. */
|
||||
if ((idx == 0) && (trim_wid == 1)) {
|
||||
if (bits[idx] == 'x') *result_type -= 1;
|
||||
*result_type -= 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,21 +69,24 @@ void emit_func_return(ivl_signal_t sig)
|
|||
|
||||
void emit_var_def(ivl_signal_t sig)
|
||||
{
|
||||
if (ivl_signal_local(sig)) return;
|
||||
fprintf(vlog_out, "%*c", indent, ' ');
|
||||
if (ivl_signal_integer(sig)) {
|
||||
fprintf(vlog_out, "integer %s;\n", ivl_signal_basename(sig));
|
||||
if (ivl_signal_dimensions(sig) > 0) {
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Integer arrays are "
|
||||
"not supported.\n", ivl_signal_file(sig),
|
||||
ivl_signal_lineno(sig));
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Integer arrays (%s) "
|
||||
"are not supported.\n", ivl_signal_file(sig),
|
||||
ivl_signal_lineno(sig),
|
||||
ivl_signal_basename(sig));
|
||||
vlog_errors += 1;
|
||||
}
|
||||
} else if (ivl_signal_data_type(sig) == IVL_VT_REAL) {
|
||||
fprintf(vlog_out, "real %s;\n", ivl_signal_basename(sig));
|
||||
if (ivl_signal_dimensions(sig) > 0) {
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Real arrays are "
|
||||
"not supported.\n", ivl_signal_file(sig),
|
||||
ivl_signal_lineno(sig));
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Real arrays (%s) "
|
||||
"are not supported.\n", ivl_signal_file(sig),
|
||||
ivl_signal_lineno(sig),
|
||||
ivl_signal_basename(sig));
|
||||
vlog_errors += 1;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -104,9 +107,10 @@ void emit_var_def(ivl_signal_t sig)
|
|||
}
|
||||
fprintf(vlog_out, ";\n");
|
||||
if (ivl_signal_signed(sig)) {
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Signed registers are "
|
||||
"not supported.\n", ivl_signal_file(sig),
|
||||
ivl_signal_lineno(sig));
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Signed registers (%s) "
|
||||
"are not supported.\n", ivl_signal_file(sig),
|
||||
ivl_signal_lineno(sig),
|
||||
ivl_signal_basename(sig));
|
||||
vlog_errors += 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -114,30 +118,31 @@ void emit_var_def(ivl_signal_t sig)
|
|||
|
||||
void emit_net_def(ivl_signal_t sig)
|
||||
{
|
||||
fprintf(vlog_out, "%*c", indent, ' ');
|
||||
int msb = ivl_signal_msb(sig);
|
||||
int lsb = ivl_signal_lsb(sig);
|
||||
if (ivl_signal_local(sig)) return;
|
||||
fprintf(vlog_out, "%*c", indent, ' ');
|
||||
if (ivl_signal_data_type(sig) == IVL_VT_REAL){
|
||||
fprintf(vlog_out, "wire %s;\n", ivl_signal_basename(sig));
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Real nets are "
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Real nets (%s) are "
|
||||
"not supported.\n", ivl_signal_file(sig),
|
||||
ivl_signal_lineno(sig));
|
||||
ivl_signal_lineno(sig), ivl_signal_basename(sig));
|
||||
vlog_errors += 1;
|
||||
} else if (ivl_signal_signed(sig)) {
|
||||
fprintf(vlog_out, "wire");
|
||||
if (msb != 0 || lsb != 0) fprintf(vlog_out, " [%d:%d]", msb, lsb);
|
||||
fprintf(vlog_out, " %s;\n", ivl_signal_basename(sig));
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Signed nets are "
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Signed nets (%s) are "
|
||||
"not supported.\n", ivl_signal_file(sig),
|
||||
ivl_signal_lineno(sig));
|
||||
ivl_signal_lineno(sig), ivl_signal_basename(sig));
|
||||
vlog_errors += 1;
|
||||
} else if (ivl_signal_dimensions(sig) > 0) {
|
||||
fprintf(vlog_out, "wire");
|
||||
if (msb != 0 || lsb != 0) fprintf(vlog_out, " [%d:%d]", msb, lsb);
|
||||
fprintf(vlog_out, " %s;\n", ivl_signal_basename(sig));
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Array nets are "
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Array nets (%s) are "
|
||||
"not supported.\n", ivl_signal_file(sig),
|
||||
ivl_signal_lineno(sig));
|
||||
ivl_signal_lineno(sig), ivl_signal_basename(sig));
|
||||
vlog_errors += 1;
|
||||
} else {
|
||||
switch(ivl_signal_type(sig)) {
|
||||
|
|
@ -380,10 +385,10 @@ static void emit_logic(ivl_scope_t scope, ivl_net_logic_t nlogic)
|
|||
count = ivl_logic_pins(nlogic);
|
||||
count -= 1;
|
||||
for (idx = 0; idx < count; idx += 1) {
|
||||
emit_name_of_nexus(ivl_logic_pin(nlogic, idx));
|
||||
emit_name_of_nexus(scope, ivl_logic_pin(nlogic, idx));
|
||||
fprintf(vlog_out, ", ");
|
||||
}
|
||||
emit_name_of_nexus(ivl_logic_pin(nlogic, count));
|
||||
emit_name_of_nexus(scope, ivl_logic_pin(nlogic, count));
|
||||
fprintf(vlog_out, ");\n");
|
||||
}
|
||||
|
||||
|
|
@ -487,9 +492,9 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent)
|
|||
start = 1;
|
||||
fprintf(vlog_out, " %s", ivl_scope_tname(scope));
|
||||
if (is_auto) {
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Automatic function is "
|
||||
"not supported.\n", ivl_scope_file(scope),
|
||||
ivl_scope_lineno(scope));
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Automatic functions "
|
||||
"(%s) are not supported.\n", ivl_scope_file(scope),
|
||||
ivl_scope_lineno(scope), ivl_scope_tname(scope));
|
||||
vlog_errors += 1;
|
||||
}
|
||||
break;
|
||||
|
|
@ -498,9 +503,9 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent)
|
|||
fprintf(vlog_out, "\n%*ctask %s", indent, ' ',
|
||||
ivl_scope_tname(scope));
|
||||
if (is_auto) {
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Automatic task is "
|
||||
"not supported.\n", ivl_scope_file(scope),
|
||||
ivl_scope_lineno(scope));
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Automatic tasks "
|
||||
"(%s) are not supported.\n", ivl_scope_file(scope),
|
||||
ivl_scope_lineno(scope), ivl_scope_tname(scope));
|
||||
vlog_errors += 1;
|
||||
}
|
||||
break;
|
||||
|
|
@ -537,9 +542,10 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent)
|
|||
default:
|
||||
fprintf(vlog_out, "<unknown>");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Unknown port "
|
||||
"direction (%d).\n", ivl_signal_file(port),
|
||||
ivl_signal_lineno(port),
|
||||
(int)ivl_signal_port(port));
|
||||
"direction (%d) for signal %s.\n",
|
||||
ivl_signal_file(port), ivl_signal_lineno(port),
|
||||
(int)ivl_signal_port(port),
|
||||
ivl_signal_basename(port));
|
||||
vlog_errors += 1;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -463,6 +463,11 @@ void emit_stmt(ivl_scope_t scope, ivl_statement_t stmt)
|
|||
single_indent = 0;
|
||||
fprintf(vlog_out, ";\n");
|
||||
break;
|
||||
case IVL_ST_ALLOC:
|
||||
/* This statement is only used with an automatic task so we
|
||||
* can safely skip it. The automatic task definition will
|
||||
* generate an appropriate error message.*/
|
||||
break;
|
||||
case IVL_ST_ASSIGN:
|
||||
emit_stmt_assign(scope, stmt);
|
||||
break;
|
||||
|
|
@ -514,6 +519,11 @@ void emit_stmt(ivl_scope_t scope, ivl_statement_t stmt)
|
|||
emit_stmt_fork(scope, stmt);
|
||||
}
|
||||
break;
|
||||
case IVL_ST_FREE:
|
||||
/* This statement is only used with an automatic task so we
|
||||
* can safely skip it. The automatic task definition will
|
||||
* generate an appropriate error message.*/
|
||||
break;
|
||||
case IVL_ST_RELEASE:
|
||||
emit_stmt_release(scope, stmt);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ extern void emit_scaled_range(ivl_scope_t scope, ivl_expr_t expr,
|
|||
unsigned width, int msb, int lsb);
|
||||
extern void emit_scope_path(ivl_scope_t scope, ivl_scope_t call_scope);
|
||||
extern void emit_scope_module_path(ivl_scope_t scope, ivl_scope_t call_scope);
|
||||
extern void emit_name_of_nexus(ivl_nexus_t nex);
|
||||
extern void emit_name_of_nexus(ivl_scope_t scope, ivl_nexus_t nex);
|
||||
|
||||
/*
|
||||
* Find the enclosing module scope.
|
||||
|
|
|
|||
Loading…
Reference in New Issue