diff --git a/tgt-vlog95/expr.c b/tgt-vlog95/expr.c index 3d32ca023..d1cae99b2 100644 --- a/tgt-vlog95/expr.c +++ b/tgt-vlog95/expr.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Cary R. (cygcary@yahoo.com) + * Copyright (C) 2011-2012 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 @@ -400,9 +400,7 @@ static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) int msb = 1; int lsb = 0; if (type == IVL_EX_SIGNAL) { - ivl_signal_t sig = ivl_expr_signal(sig_expr); - msb = ivl_signal_msb(sig); - lsb = ivl_signal_lsb(sig); + get_sig_msb_lsb(ivl_expr_signal(sig_expr), &msb, &lsb); } /* A bit select. */ if (width == 1) { @@ -430,11 +428,11 @@ static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) /* Select part of a signal when needed. */ if ((ivl_expr_type(sig_expr) == IVL_EX_SIGNAL) && (ivl_expr_width(expr) < ivl_expr_width(sig_expr))) { - ivl_signal_t sig = ivl_expr_signal(sig_expr); - int msb = ivl_signal_msb(sig); - int lsb = ivl_signal_lsb(sig); - int64_t value = lsb; + int msb, lsb; + int64_t value; unsigned e_wid = ivl_expr_width(expr) - 1; + get_sig_msb_lsb(ivl_expr_signal(sig_expr), &msb, &lsb); + value = lsb; if (msb >= lsb) value += e_wid; else value -= e_wid; fprintf(vlog_out, "[%"PRId64":%u]", value, lsb); diff --git a/tgt-vlog95/logic_lpm.c b/tgt-vlog95/logic_lpm.c index 4a57e6616..5664055ec 100644 --- a/tgt-vlog95/logic_lpm.c +++ b/tgt-vlog95/logic_lpm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Cary R. (cygcary@yahoo.com) + * Copyright (C) 2011-2012 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 @@ -696,8 +696,7 @@ static void emit_lpm_part_select(ivl_scope_t scope, ivl_lpm_t lpm) fprintf(vlog_out, "[%d]", array_word); } - msb = ivl_signal_msb(sig); - lsb = ivl_signal_lsb(sig); + get_sig_msb_lsb(sig, &msb, &lsb); if (sign_extend) { assert(base != lsb); if (msb >= lsb) base += lsb; @@ -1222,8 +1221,7 @@ static void emit_lpm_part_pv(ivl_scope_t scope, ivl_lpm_t lpm) if (ivl_signal_dimensions(sig)) { fprintf(vlog_out, "[%"PRId64"]", array_word); } - msb = ivl_signal_msb(sig); - lsb = ivl_signal_lsb(sig); + get_sig_msb_lsb(sig, &msb, &lsb); fprintf(vlog_out, "["); if (width == 1) { if (msb >= lsb) base += lsb; diff --git a/tgt-vlog95/misc.c b/tgt-vlog95/misc.c index 492f88f68..bc35c1a79 100644 --- a/tgt-vlog95/misc.c +++ b/tgt-vlog95/misc.c @@ -857,3 +857,27 @@ void emit_id(const char *id) if (is_escaped(id)) fprintf(vlog_out, "\\%s ", id); else fprintf(vlog_out, "%s", id); } + +/* + * Get the correct MSB and LSB for a signal. + */ +void get_sig_msb_lsb(ivl_signal_t sig, int *msb, int *lsb) +{ + switch (ivl_signal_packed_dimensions(sig)) { + /* For a scalar we use zero for both the MSB and LSB. */ + case 0: + *msb = 0; + *lsb = 0; + break; + case 1: + /* For a vector we use the real MSB and LSB. */ + *msb = ivl_signal_packed_msb(sig, 0); + *lsb = ivl_signal_packed_lsb(sig, 0); + break; + /* For a packed vector we use the normalized MSB and LSB. */ + default: + *msb = ivl_signal_width(sig) - 1; + *lsb = 0; + break; + } +} diff --git a/tgt-vlog95/scope.c b/tgt-vlog95/scope.c index a3bc6b34e..ec66b571c 100644 --- a/tgt-vlog95/scope.c +++ b/tgt-vlog95/scope.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 Cary R. (cygcary@yahoo.com) + * Copyright (C) 2010-2012 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 @@ -61,8 +61,8 @@ void emit_func_return(ivl_signal_t sig) } else if (ivl_signal_data_type(sig) == IVL_VT_REAL) { fprintf(vlog_out, " real"); } else { - int msb = ivl_signal_msb(sig); - int lsb = ivl_signal_lsb(sig); + int msb, lsb; + get_sig_msb_lsb(sig, &msb, &lsb); if (msb != 0 || lsb != 0) fprintf(vlog_out, " [%d:%d]", msb, lsb); } } @@ -109,8 +109,8 @@ void emit_var_def(ivl_signal_t sig) vlog_errors += 1; } } else { - int msb = ivl_signal_msb(sig); - int lsb = ivl_signal_lsb(sig); + int msb, lsb; + get_sig_msb_lsb(sig, &msb, &lsb); fprintf(vlog_out, "reg "); if (ivl_signal_signed(sig)) { if (allow_signed) { @@ -184,8 +184,8 @@ static void save_net_constants(ivl_scope_t scope, ivl_signal_t sig) void emit_net_def(ivl_scope_t scope, ivl_signal_t sig) { - int msb = ivl_signal_msb(sig); - int lsb = ivl_signal_lsb(sig); + int msb, lsb; + get_sig_msb_lsb(sig, &msb, &lsb); if (ivl_signal_local(sig)) return; fprintf(vlog_out, "%*c", indent, ' '); if (ivl_signal_data_type(sig) == IVL_VT_REAL){ @@ -402,8 +402,8 @@ static void emit_sig_type(ivl_signal_t sig) } else if (ivl_signal_data_type(sig) == IVL_VT_REAL) { fprintf(vlog_out, " real"); } else { - int msb = ivl_signal_msb(sig); - int lsb = ivl_signal_lsb(sig); + int msb, lsb; + get_sig_msb_lsb(sig, &msb, &lsb); if (ivl_signal_signed(sig)) { if (allow_signed) { fprintf(vlog_out, " signed"); @@ -432,8 +432,8 @@ static void emit_sig_type(ivl_signal_t sig) ivl_signal_basename(sig)); vlog_errors += 1; } else { - int msb = ivl_signal_msb(sig); - int lsb = ivl_signal_lsb(sig); + int msb, lsb; + get_sig_msb_lsb(sig, &msb, &lsb); if (ivl_signal_signed(sig)) { if (allow_signed) { fprintf(vlog_out, " signed"); @@ -729,6 +729,14 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent) assert(indent != 0); emit_named_block_scope(scope); return 0; /* A named begin/fork is handled in line. */ + case IVL_SCT_GENERATE: + fprintf(stderr, "%s:%u: vlog95 sorry: generate scopes are not " + "currently translated \"%s\".\n", + ivl_scope_file(scope), + ivl_scope_lineno(scope), + ivl_scope_tname(scope)); + vlog_errors += 1; + return 0; default: fprintf(stderr, "%s:%u: vlog95 error: Unsupported scope type " "(%d) named: %s.\n", ivl_scope_file(scope), diff --git a/tgt-vlog95/stmt.c b/tgt-vlog95/stmt.c index 31ee451a5..0ade86f79 100644 --- a/tgt-vlog95/stmt.c +++ b/tgt-vlog95/stmt.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Cary R. (cygcary@yahoo.com) + * Copyright (C) 2011-2012 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 @@ -191,8 +191,7 @@ static void emit_stmt_lval_piece(ivl_scope_t scope, ivl_lval_t lval) } /* We have some kind of select. */ - lsb = ivl_signal_lsb(sig); - msb = ivl_signal_msb(sig); + get_sig_msb_lsb(sig, &msb, &lsb); sel_type = ivl_lval_sel_type(lval); assert(sel_expr); /* A bit select. */ @@ -1119,6 +1118,20 @@ void emit_stmt(ivl_scope_t scope, ivl_statement_t stmt) emit_stmt_fork(scope, stmt); } break; + case IVL_ST_FORK_JOIN_ANY: + fprintf(stderr, "%s:%u: vlog95 sorry: fork/join_any is not " + "currently translated.\n", + ivl_stmt_file(stmt), + ivl_stmt_lineno(stmt)); + vlog_errors += 1; + break; + case IVL_ST_FORK_JOIN_NONE: + fprintf(stderr, "%s:%u: vlog95 sorry: fork/join_none is not " + "currently translated.\n", + ivl_stmt_file(stmt), + ivl_stmt_lineno(stmt)); + vlog_errors += 1; + 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 @@ -1169,6 +1182,13 @@ void emit_process(ivl_scope_t scope, ivl_process_t proc) case IVL_PR_ALWAYS: fprintf(vlog_out, "always"); break; + case IVL_PR_FINAL: + fprintf(vlog_out, "final"); + fprintf(stderr, "%s:%u: vlog95 sorry: final blocks are not " + "currently translated.\n", + ivl_process_file(proc), ivl_process_lineno(proc)); + vlog_errors+= 1; + break; default: fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Unknown process type (%d).\n", diff --git a/tgt-vlog95/vlog95_priv.h b/tgt-vlog95/vlog95_priv.h index 12ce11cc0..9e22637e1 100644 --- a/tgt-vlog95/vlog95_priv.h +++ b/tgt-vlog95/vlog95_priv.h @@ -119,6 +119,11 @@ extern int32_t get_int32_from_number(ivl_expr_t expr, int *return_type); extern int64_t get_int64_from_number(ivl_expr_t expr, int *return_type); extern uint64_t get_uint64_from_number(ivl_expr_t expr, int *return_type); +/* + * Get the appropriate MSB and LSB for a signal. + */ +extern void get_sig_msb_lsb(ivl_signal_t sig, int *msb, int *lsb); + /* * Cleanup functions. */