From 2fc8ce8a162162af32fe4aeb4cde74409a529e54 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 5 Jan 2014 12:04:16 -0800 Subject: [PATCH] Implement vec4 basec %assign delay and event / vpiTimeVal for functions. --- tgt-vvp/eval_vec4.c | 14 +++++++++ vvp/codes.h | 1 - vvp/compile.cc | 1 - vvp/opcodes.txt | 2 +- vvp/vpi_tasks.cc | 23 ++++++++++++++- vvp/vpi_vthr_vector.cc | 2 +- vvp/vthread.cc | 65 +++++++++++++++++++++--------------------- 7 files changed, 71 insertions(+), 37 deletions(-) diff --git a/tgt-vvp/eval_vec4.c b/tgt-vvp/eval_vec4.c index 8e3fdcee7..54f4e1cda 100644 --- a/tgt-vvp/eval_vec4.c +++ b/tgt-vvp/eval_vec4.c @@ -32,11 +32,25 @@ static void draw_binary_vec4_arith(ivl_expr_t expr, int stuff_ok_flag) ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); + unsigned lwid = ivl_expr_width(le); + unsigned rwid = ivl_expr_width(re); + unsigned ewid = ivl_expr_width(expr); + int signed_flag = ivl_expr_signed(le) && ivl_expr_signed(re) ? 1 : 0; const char*signed_string = signed_flag? "/s" : ""; + /* All the arithmetic operations handled here require that the + operands (and the result) be the same width. We further + assume that the core has not given us an operand wider then + the expression width. So padd operands as needed. */ draw_eval_vec4(le, stuff_ok_flag); + if (lwid < ewid) { + fprintf(vvp_out, " %%pad/%c %u;\n", ivl_expr_signed(le)? 's' : 'u', ewid); + } draw_eval_vec4(re, stuff_ok_flag); + if (rwid < ewid) { + fprintf(vvp_out, " %%pad/%c %u;\n", ivl_expr_signed(re)? 's' : 'u', ewid); + } switch (ivl_expr_opcode(expr)) { case '+': diff --git a/vvp/codes.h b/vvp/codes.h index 0ad6ea667..ca44ed9be 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -202,7 +202,6 @@ extern bool of_SET_DAR(vthread_t thr, vvp_code_t code); extern bool of_SET_DAR_OBJ(vthread_t thr, vvp_code_t code); extern bool of_SET_DAR_OBJ_REAL(vthread_t thr, vvp_code_t code); extern bool of_SET_DAR_OBJ_STR(vthread_t thr, vvp_code_t code); -extern bool of_SET_VEC(vthread_t thr, vvp_code_t code); extern bool of_SET_X0(vthread_t thr, vvp_code_t code); extern bool of_SET_X0_X(vthread_t thr, vvp_code_t code); extern bool of_SHIFTL(vthread_t thr, vvp_code_t code); diff --git a/vvp/compile.cc b/vvp/compile.cc index 47fc67a21..d5bf86cce 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -250,7 +250,6 @@ static const struct opcode_table_s opcode_table[] = { { "%set/dar/obj", of_SET_DAR_OBJ, 3,{OA_NUMBER,OA_BIT1,OA_BIT2} }, { "%set/dar/obj/real",of_SET_DAR_OBJ_REAL,1,{OA_NUMBER,OA_NONE,OA_NONE} }, { "%set/dar/obj/str", of_SET_DAR_OBJ_STR, 1,{OA_NUMBER,OA_NONE,OA_NONE} }, - { "%set/v", of_SET_VEC,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} }, { "%set/x0", of_SET_X0, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} }, { "%shiftl", of_SHIFTL, 1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%shiftr", of_SHIFTR, 1, {OA_NUMBER, OA_NONE, OA_NONE} }, diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index d54c3375e..497943625 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -1118,7 +1118,7 @@ values. The "%set/dar/obj/str" opcode does the same but for string values and uses the string stack. -* %set/v , , +* %set/v , , (XXXX Old definition) This sets a vector to a variable, and is used to implement blocking assignments. The identifies the variable to receive the diff --git a/vvp/vpi_tasks.cc b/vvp/vpi_tasks.cc index 7d6efbb48..510a19b81 100644 --- a/vvp/vpi_tasks.cc +++ b/vvp/vpi_tasks.cc @@ -477,6 +477,7 @@ class sysfunc_vec4 : public __vpiSysTaskCall { private: vpiHandle put_value_int_(p_vpi_value vp); + vpiHandle put_value_time_(p_vpi_value vp); private: vvp_vector4_t return_value_; @@ -494,6 +495,24 @@ vpiHandle sysfunc_vec4::put_value_int_(p_vpi_value vp) return 0; } +vpiHandle sysfunc_vec4::put_value_time_(p_vpi_value vp) +{ + unsigned width = return_value_.size(); + long tmp = 0; + for (unsigned idx = 0 ; idx < width ; idx += 1) { + if (idx == 0) + tmp = vp->value.time->low; + else if (idx == 32) + tmp = vp->value.time->high; + else if (idx == 64) + tmp = 0; + + return_value_.set_bit(idx, (tmp&1)? BIT4_1 : BIT4_0); + tmp >>= 1; + } + return 0; +} + vpiHandle sysfunc_vec4::vpi_put_value(p_vpi_value vp, int) { put_value = true; @@ -501,8 +520,10 @@ vpiHandle sysfunc_vec4::vpi_put_value(p_vpi_value vp, int) switch (vp->format) { case vpiIntVal: return put_value_int_(vp); + case vpiTimeVal: + return put_value_time_(vp); default: - fprintf(stderr, "Unsupported format %d.\n", (int)vp->format); + fprintf(stderr, "Unsupported format %d seting sysfunc vec4 value.\n", (int)vp->format); assert(0); } diff --git a/vvp/vpi_vthr_vector.cc b/vvp/vpi_vthr_vector.cc index e58d149e6..edc754203 100644 --- a/vvp/vpi_vthr_vector.cc +++ b/vvp/vpi_vthr_vector.cc @@ -427,7 +427,7 @@ static vpiHandle vthr_vec_put_value(vpiHandle ref, s_vpi_value*vp, int) } default: - fprintf(stderr, "Unsupported format %d.\n", (int)vp->format); + fprintf(stderr, "Unsupported format %d setting vec4 value.\n", (int)vp->format); assert(0); } diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 29b33f919..e0bd40089 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -1204,6 +1204,7 @@ bool of_ASSIGN_AVE(vthread_t thr, vvp_code_t cp) } #else fprintf(stderr, "XXXX NOT IMPLEMENTED: %%assign/av/e ...\n"); + assert(0); #endif return true; } @@ -1348,15 +1349,44 @@ bool of_ASSIGN_V0E(vthread_t thr, vvp_code_t cp) } #endif +/* + * %assign/vec4/d + */ bool of_ASSIGN_VEC4D(vthread_t thr, vvp_code_t cp) { - fprintf(stderr, "XXXX NOT IMPLEMENTED: %%assign/vec4/d\n"); + vvp_net_ptr_t ptr (cp->net, 0); + unsigned del_index = cp->bit_idx[0]; + vvp_time64_t del = thr->words[del_index].w_int; + + vvp_vector4_t value = thr->pop_vec4(); + + vvp_signal_value*sig = dynamic_cast (cp->net->fil); + assert(sig); + + schedule_assign_vector(ptr, 0, sig->value_size(), value, del); + return true; } +/* + * %assign/vec4/e + */ bool of_ASSIGN_VEC4E(vthread_t thr, vvp_code_t cp) { - fprintf(stderr, "XXXX NOT IMPLEMENTED: %%assign/vec4/e\n"); + vvp_net_ptr_t ptr (cp->net, 0); + vvp_vector4_t value = thr->pop_vec4(); + + vvp_signal_value*sig = dynamic_cast (cp->net->fil); + assert(sig); + + if (thr->ecount == 0) { + schedule_assign_vector(ptr, 0, sig->value_size(), value, 0); + } else { + schedule_evctl(ptr, value, 0, sig->value_size(), thr->event, thr->ecount); + } + + thr->event = 0; + thr->ecount = 0; return true; } @@ -5493,36 +5523,6 @@ bool of_SET_DAR_OBJ_STR(vthread_t thr, vvp_code_t cp) return true; } -/* - * This implements the "%set/v