From d71a1cb9c103eb473f6a107086de12ed30ffc1dd Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Tue, 20 May 2008 11:51:17 -0700 Subject: [PATCH] Fix non-blocking assign to part select of memory word. Memory words may have part selects assigned, but the code messed up the testing for the validity of the part select base. This fixes do detect constant bases so that base validity tests are handled at compile time. --- tgt-vvp/vvp_process.c | 70 +++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index af93740ce..f104175e1 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -220,44 +220,70 @@ static void set_to_lvariable(ivl_lval_t lval, static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix, unsigned bit, unsigned delay, ivl_expr_t dexp, - unsigned width) + ivl_expr_t part_off_ex, unsigned width) { unsigned skip_assign = transient_id++; + unsigned part_off = 0; + if (part_off_ex == 0) { + part_off = 0; + } else if (number_is_immediate(part_off_ex, 64)) { + part_off = get_number_immediate(part_off_ex); + part_off_ex = 0; + } + if (dexp == 0) { /* Constant delay... */ - /* Calculate array word index into index register 3 */ - draw_eval_expr_into_integer(word_ix, 3); - /* Skip assignment if word expression is not defined. */ - fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_assign); - + if (number_is_immediate(word_ix, 64)) { + fprintf(vvp_out, " %%ix/load 3, %lu; address\n", + get_number_immediate(word_ix)); + } else { + /* Calculate array word index into index register 3 */ + draw_eval_expr_into_integer(word_ix, 3); + /* Skip assignment if word expression is not defined. */ + fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_assign); + } /* Store expression width into index word 0 */ - fprintf(vvp_out, " %%ix/load 0, %u; // word width\n", width); - /* Store constant (0) word part select into index 1 */ - fprintf(vvp_out, " %%ix/load 1, 0;\n"); - + fprintf(vvp_out, " %%ix/load 0, %u; word width\n", width); + if (part_off_ex) { + draw_eval_expr_into_integer(part_off_ex, 1); + /* If the index expression has XZ bits, skip the assign. */ + fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_assign); + } else { + /* Store word part select base into index 1 */ + fprintf(vvp_out, " %%ix/load 1, %u; part base\n", part_off); + } fprintf(vvp_out, " %%assign/av v%p, %u, %u;\n", lsig, delay, bit); - fprintf(vvp_out, "t_%u ;\n", skip_assign); } else { /* Calculated delay... */ int delay_index = allocate_word(); draw_eval_expr_into_integer(dexp, delay_index); - /* Calculate array word index into index register 3 */ - draw_eval_expr_into_integer(word_ix, 3); - /* Skip assignment if word expression is not defined. */ - fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_assign); - + if (number_is_immediate(word_ix, 64)) { + fprintf(vvp_out, " %%ix/load 3, %lu; address\n", + get_number_immediate(word_ix)); + } else { + /* Calculate array word index into index register 3 */ + draw_eval_expr_into_integer(word_ix, 3); + /* Skip assignment if word expression is not defined. */ + fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_assign); + } /* Store expression width into index word 0 */ - fprintf(vvp_out, " %%ix/load 0, %u; // word width\n", width); - /* Store constant (0) word part select into index 1 */ - fprintf(vvp_out, " %%ix/load 1, 0;\n"); - + fprintf(vvp_out, " %%ix/load 0, %u; word width\n", width); + if (part_off_ex) { + draw_eval_expr_into_integer(part_off_ex, 1); + /* If the index expression has XZ bits, skip the assign. */ + fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_assign); + } else { + /* Store word part select into index 1 */ + fprintf(vvp_out, " %%ix/load 1, %u; part off\n", part_off); + } fprintf(vvp_out, " %%assign/av/d v%p, %d, %u;\n", lsig, delay_index, bit); - fprintf(vvp_out, "t_%u ;\n", skip_assign); } + fprintf(vvp_out, "t_%u ;\n", skip_assign); + clear_expression_lookaside(); } @@ -274,7 +300,7 @@ static void assign_to_lvector(ivl_lval_t lval, unsigned bit, if (ivl_signal_array_count(sig) > 1) { assert(word_ix); - assign_to_array_word(sig, word_ix, bit, delay, dexp, width); + assign_to_array_word(sig, word_ix, bit, delay, dexp, part_off_ex, width); return; }