From 063c6d6065c2e790bbbda9d3a60caf19465931aa Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 5 Jan 2014 12:39:52 -0800 Subject: [PATCH] Add the %event instruction, remove %ix/get and %ix/get/s. --- tgt-vvp/eval_bool.c | 7 ++-- tgt-vvp/eval_real.c | 19 ++++------ tgt-vvp/vvp_process.c | 2 +- vvp/codes.h | 3 +- vvp/compile.cc | 3 +- vvp/opcodes.txt | 5 +++ vvp/vthread.cc | 82 ++++++------------------------------------- 7 files changed, 27 insertions(+), 94 deletions(-) diff --git a/tgt-vvp/eval_bool.c b/tgt-vvp/eval_bool.c index d0441ed11..414ba146e 100644 --- a/tgt-vvp/eval_bool.c +++ b/tgt-vvp/eval_bool.c @@ -46,17 +46,14 @@ static int eval_bool64_logic(ivl_expr_t expr) { int res; - struct vector_info tmp; const char*s_flag = ""; - tmp = draw_eval_expr(expr, STUFF_OK_XZ); + draw_eval_vec4(expr, STUFF_OK_XZ); res = allocate_word(); if (ivl_expr_signed(expr)) s_flag = "/s"; - fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n", s_flag, res, - tmp.base, tmp.wid); - clr_vector(tmp); + fprintf(vvp_out, " %%ix/vec4%s %d;\n", s_flag, res); return res; } diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index 854a2670a..f460c0b1d 100644 --- a/tgt-vvp/eval_real.c +++ b/tgt-vvp/eval_real.c @@ -245,16 +245,14 @@ static void draw_realnum_real(ivl_expr_t expr) */ static void draw_real_logic_expr(ivl_expr_t expr, int stuff_ok_flag) { - struct vector_info sv = draw_eval_expr(expr, stuff_ok_flag); + draw_eval_vec4(expr, stuff_ok_flag); const char*sign_flag = ivl_expr_signed(expr)? "/s" : ""; - if (sv.wid > 64) { - fprintf(vvp_out, " %%cvt/rv%s %u, %u;\n", - sign_flag, sv.base, sv.wid); + if (ivl_expr_width(expr) > 64) { + fprintf(vvp_out, " %%cvt/rv%s;\n", sign_flag); } else { int res = allocate_word(); - fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n", - sign_flag, res, sv.base, sv.wid); + fprintf(vvp_out, " %%ix/vec4%s %d;\n", sign_flag, res); if (ivl_expr_signed(expr)) fprintf(vvp_out, " %%cvt/rs %d;\n", res); @@ -262,8 +260,6 @@ static void draw_real_logic_expr(ivl_expr_t expr, int stuff_ok_flag) fprintf(vvp_out, " %%cvt/ru %d;\n", res); clr_word(res); } - - clr_vector(sv); } static void draw_select_real(ivl_expr_t expr) @@ -547,15 +543,12 @@ void draw_eval_real(ivl_expr_t expr) default: if (ivl_expr_value(expr) == IVL_VT_VECTOR) { - struct vector_info sv = draw_eval_expr(expr, 0); + draw_eval_vec4(expr, 0); const char*sign_flag = ivl_expr_signed(expr)? "/s" : ""; - clr_vector(sv); int res = allocate_word(); - fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n", - sign_flag, res, sv.base, sv.wid); - + fprintf(vvp_out, " %%ix/vec4%s %d;\n", sign_flag, res); fprintf(vvp_out, " %%cvt/rs %d;\n", res); clr_word(res); diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index c18a39af4..59c51fede 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -1687,7 +1687,7 @@ static int show_stmt_trigger(ivl_statement_t net) show_stmt_file_line(net, "Event trigger statement."); - fprintf(vvp_out, " %%set/v E_%p, 0,1;\n", ev); + fprintf(vvp_out, " %%event E_%p;\n", ev); return 0; } diff --git a/vvp/codes.h b/vvp/codes.h index ca44ed9be..6e929e0bd 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -101,6 +101,7 @@ extern bool of_DIV_WR(vthread_t thr, vvp_code_t code); extern bool of_DUP_REAL(vthread_t thr, vvp_code_t code); extern bool of_DUP_VEC4(vthread_t thr, vvp_code_t code); extern bool of_END(vthread_t thr, vvp_code_t code); +extern bool of_EVENT(vthread_t thr, vvp_code_t code); extern bool of_EVCTL(vthread_t thr, vvp_code_t code); extern bool of_EVCTLC(vthread_t thr, vvp_code_t code); extern bool of_EVCTLI(vthread_t thr, vvp_code_t code); @@ -117,10 +118,8 @@ extern bool of_FORK(vthread_t thr, vvp_code_t code); extern bool of_FREE(vthread_t thr, vvp_code_t code); extern bool of_INV(vthread_t thr, vvp_code_t code); extern bool of_IX_ADD(vthread_t thr, vvp_code_t code); -extern bool of_IX_GET(vthread_t thr, vvp_code_t code); extern bool of_IX_GETV(vthread_t thr, vvp_code_t code); extern bool of_IX_GETV_S(vthread_t thr, vvp_code_t code); -extern bool of_IX_GET_S(vthread_t thr, vvp_code_t code); extern bool of_IX_LOAD(vthread_t thr, vvp_code_t code); extern bool of_IX_MOV(vthread_t thr, vvp_code_t code); extern bool of_IX_MUL(vthread_t thr, vvp_code_t code); diff --git a/vvp/compile.cc b/vvp/compile.cc index d5bf86cce..8ebf6bb71 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -152,6 +152,7 @@ static const struct opcode_table_s opcode_table[] = { { "%dup/vec4", of_DUP_VEC4,0, {OA_NONE, OA_NONE, OA_NONE} }, { "%end", of_END, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%evctl", of_EVCTL, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} }, + { "%event", of_EVENT, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%evctl/c",of_EVCTLC, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%evctl/i",of_EVCTLI, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} }, { "%evctl/s",of_EVCTLS, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} }, @@ -165,8 +166,6 @@ static const struct opcode_table_s opcode_table[] = { { "%free", of_FREE, 1, {OA_VPI_PTR, OA_NONE, OA_NONE} }, { "%inv", of_INV, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%ix/add", of_IX_ADD, 3, {OA_NUMBER, OA_BIT1, OA_BIT2} }, - { "%ix/get", of_IX_GET, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, - { "%ix/get/s",of_IX_GET_S,3,{OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%ix/getv",of_IX_GETV,2, {OA_BIT1, OA_FUNC_PTR, OA_NONE} }, { "%ix/getv/s",of_IX_GETV_S,2, {OA_BIT1, OA_FUNC_PTR, OA_NONE} }, { "%ix/load",of_IX_LOAD,3, {OA_NUMBER, OA_BIT1, OA_BIT2} }, diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index 497943625..c1a1e995b 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -520,6 +520,11 @@ event control information and the other %evctl statements assert that this information has been cleared. You can get an assert if this information is not managed correctly. +* %event + +This instruction is used to send a pulse to an event object. The + is an event variable. This instruction simply writes +an arbitrary value to the event to trigger the event. * %file_line diff --git a/vvp/vthread.cc b/vvp/vthread.cc index e0bd40089..71791c3cf 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -2898,6 +2898,17 @@ bool of_END(vthread_t thr, vvp_code_t) return false; } +/* + * %event + */ +bool of_EVENT(vthread_t thr, vvp_code_t cp) +{ + vvp_net_ptr_t ptr (cp->net, 0); + vvp_vector4_t tmp (1, BIT4_X); + vvp_send_vec4(ptr, tmp, 0); + return true; +} + bool of_EVCTL(vthread_t thr, vvp_code_t cp) { assert(thr->event == 0 && thr->ecount == 0); @@ -3177,77 +3188,6 @@ bool of_IX_MOV(vthread_t thr, vvp_code_t cp) return true; } -/* - * Load a vector into an index register. The format of the - * opcode is: - * - * %ix/get , , - * - * where is the index register, is the base of the - * vector and is the width in bits. - * - * Index registers only hold binary values, so if any of the - * bits of the vector are x or z, then set the value to 0, - * set bit[4] to 1, and give up. - */ - -static uint64_t vector_to_index(vthread_t thr, unsigned base, - unsigned width, bool signed_flag) -{ - uint64_t v = 0; - bool unknown_flag = false; -#if 0 - vvp_bit4_t vv = BIT4_0; - for (unsigned i = 0 ; i < width ; i += 1) { - vv = thr_get_bit(thr, base); - if (bit4_is_xz(vv)) { - v = 0UL; - unknown_flag = true; - break; - } - - v |= (uint64_t) vv << i; - - if (base >= 4) - base += 1; - } - - /* Extend to fill the integer value. */ - if (signed_flag && !unknown_flag) { - uint64_t pad = vv; - for (unsigned i = width ; i < 8*sizeof(v) ; i += 1) { - v |= pad << i; - } - } -#else - fprintf(stderr, "XXXX NOT IMPLEMENTED: vector_to_index(...)\n"); -#endif - /* Set bit 4 as a flag if the input is unknown. */ - thr->flags[4] = unknown_flag? BIT4_1 : BIT4_0; - - return v; -} - -bool of_IX_GET(vthread_t thr, vvp_code_t cp) -{ - unsigned index = cp->bit_idx[0]; - unsigned base = cp->bit_idx[1]; - unsigned width = cp->number; - - thr->words[index].w_uint = vector_to_index(thr, base, width, false); - return true; -} - -bool of_IX_GET_S(vthread_t thr, vvp_code_t cp) -{ - unsigned index = cp->bit_idx[0]; - unsigned base = cp->bit_idx[1]; - unsigned width = cp->number; - - thr->words[index].w_int = vector_to_index(thr, base, width, true); - return true; -} - bool of_IX_GETV(vthread_t thr, vvp_code_t cp) { unsigned index = cp->bit_idx[0];