vlog95: Add support for undefined selects.

This commit is contained in:
Cary R 2013-01-25 12:44:29 -08:00
parent 350369f3fc
commit 59ce217ce2
1 changed files with 28 additions and 15 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2011-2012 Cary R. (cygcary@yahoo.com) * Copyright (C) 2011-2013 Cary R. (cygcary@yahoo.com)
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -281,14 +281,12 @@ static int64_t get_valid_int64_from_number(ivl_expr_t expr, int *rtype,
ivl_expr_file(expr), ivl_expr_lineno(expr), ivl_expr_file(expr), ivl_expr_lineno(expr),
msg, *rtype); msg, *rtype);
vlog_errors += 1; vlog_errors += 1;
return 0;
} else if (*rtype < 0) { } else if (*rtype < 0) {
fprintf(vlog_out, "<invalid>"); fprintf(vlog_out, "<invalid>");
fprintf(stderr, "%s:%u: vlog95 error: Scaled %s has an undefined " fprintf(stderr, "%s:%u: vlog95 error: Scaled %s has an undefined "
"bit and cannot be represented.\n", "bit and cannot be represented.\n",
ivl_expr_file(expr), ivl_expr_lineno(expr), msg); ivl_expr_file(expr), ivl_expr_lineno(expr), msg);
vlog_errors += 1; vlog_errors += 1;
return 0;
} }
return value; return value;
} }
@ -350,22 +348,35 @@ static unsigned is_scaled_expr(ivl_expr_t expr, int msb, int lsb)
return 1; return 1;
} }
static int64_t get_in_range_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 value;
}
void emit_scaled_range(ivl_scope_t scope, ivl_expr_t expr, unsigned width, void emit_scaled_range(ivl_scope_t scope, ivl_expr_t expr, unsigned width,
int msb, int lsb) int msb, int lsb)
{ {
int rtype;
int64_t value = get_in_range_int64_from_number(expr, &rtype,
"range value");
if (rtype < 0) fprintf(vlog_out, "[1'bx:1'bx]");
if (rtype) return;
if (msb >= lsb) { if (msb >= lsb) {
int rtype;
int64_t value = get_valid_int64_from_number(expr, &rtype,
"range value");
if (rtype) return;
value += lsb; value += lsb;
fprintf(vlog_out, "[%"PRId64":%"PRId64"]", fprintf(vlog_out, "[%"PRId64":%"PRId64"]",
value + (int64_t)(width - 1), value); value + (int64_t)(width - 1), value);
} else { } else {
int rtype;
int64_t value = get_valid_int64_from_number(expr, &rtype,
"range value");
if (rtype) return;
value = (int64_t)lsb - value; value = (int64_t)lsb - value;
fprintf(vlog_out, "[%"PRId64":%"PRId64"]", fprintf(vlog_out, "[%"PRId64":%"PRId64"]",
value - (int64_t)(width - 1), value); value - (int64_t)(width - 1), value);
@ -377,8 +388,9 @@ void emit_scaled_expr(ivl_scope_t scope, ivl_expr_t expr, int msb, int lsb)
if (msb >= lsb) { if (msb >= lsb) {
if (ivl_expr_type(expr) == IVL_EX_NUMBER) { if (ivl_expr_type(expr) == IVL_EX_NUMBER) {
int rtype; int rtype;
int64_t value = get_valid_int64_from_number(expr, &rtype, int64_t value = get_in_range_int64_from_number(expr, &rtype,
"value"); "value");
if (rtype < 0) fprintf(vlog_out, "1'bx");
if (rtype) return; if (rtype) return;
value += lsb; value += lsb;
fprintf(vlog_out, "%"PRId64, value); fprintf(vlog_out, "%"PRId64, value);
@ -393,8 +405,9 @@ void emit_scaled_expr(ivl_scope_t scope, ivl_expr_t expr, int msb, int lsb)
} else { } else {
if (ivl_expr_type(expr) == IVL_EX_NUMBER) { if (ivl_expr_type(expr) == IVL_EX_NUMBER) {
int rtype; int rtype;
int64_t value = get_valid_int64_from_number(expr, &rtype, int64_t value = get_in_range_int64_from_number(expr, &rtype,
"value"); "value");
if (rtype < 0) fprintf(vlog_out, "1'bx");
if (rtype) return; if (rtype) return;
value = (int64_t)lsb - value; value = (int64_t)lsb - value;
fprintf(vlog_out, "%"PRId64, value); fprintf(vlog_out, "%"PRId64, value);