diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 572dc48ab..2af631538 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -801,6 +801,37 @@ static int show_stmt_case_r(ivl_statement_t net, ivl_scope_t sscope) return 0; } +static void force_real_to_lval(ivl_statement_t net, int res) +{ + const char*command_name; + + switch (ivl_statement_type(net)) { + case IVL_ST_CASSIGN: + command_name = "%cassign/wr"; + break; + case IVL_ST_FORCE: + command_name = "%force/wr"; + break; + default: + command_name = "ERROR"; + assert(0); + break; + } + + assert(ivl_stmt_lvals(net) == 1); + ivl_lval_t lval = ivl_stmt_lval(net, 0); + ivl_signal_t lsig = ivl_lval_sig(lval); + + assert(ivl_lval_width(lval) == 1); + assert(ivl_lval_part_off(lval) == 0); + assert(ivl_lval_idx(lval) == 0); + /* L-Value must be a signal: reg or wire */ + assert(lsig != 0); + + fprintf(vvp_out, " %s v%p_0, %d;\n", command_name, lsig, res); + +} + static void force_vector_to_lval(ivl_statement_t net, struct vector_info rvec) { unsigned lidx; @@ -936,16 +967,28 @@ static void force_link_rval(ivl_statement_t net, ivl_expr_t rval) static int show_stmt_cassign(ivl_statement_t net) { ivl_expr_t rval; - struct vector_info rvec; + ivl_signal_t sig; rval = ivl_stmt_rval(net); assert(rval); - rvec = draw_eval_expr(rval, STUFF_OK_47); + sig = ivl_lval_sig(ivl_stmt_lval(net, 0)); + if (sig && ivl_signal_data_type(sig) == IVL_VT_REAL) { + int res; - /* Write out initial continuous assign instructions to assign - the expression value to the l-value. */ - force_vector_to_lval(net, rvec); + res = draw_eval_real(ivl_stmt_rval(net)); + clr_word(res); + + force_real_to_lval(net, res); + } else { + struct vector_info rvec; + + rvec = draw_eval_expr(rval, STUFF_OK_47); + + /* Write out initial continuous assign instructions to assign + the expression value to the l-value. */ + force_vector_to_lval(net, rvec); + } force_link_rval(net, rval); @@ -959,6 +1002,18 @@ static int show_stmt_cassign(ivl_statement_t net) */ static int show_stmt_deassign(ivl_statement_t net) { + ivl_signal_t sig = ivl_lval_sig(ivl_stmt_lval(net, 0)); + if (sig && ivl_signal_data_type(sig) == IVL_VT_REAL) { + assert(ivl_stmt_lvals(net) == 1); + ivl_lval_t lval = ivl_stmt_lval(net, 0); + assert(ivl_lval_width(lval) == 1); + assert(ivl_lval_part_off(lval) == 0); + assert(ivl_lval_idx(lval) == 0); + + fprintf(vvp_out, " %%deassign/wr v%p_0;\n", sig); + return 0; + } + unsigned lidx; for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { @@ -1115,16 +1170,28 @@ static int show_stmt_disable(ivl_statement_t net, ivl_scope_t sscope) static int show_stmt_force(ivl_statement_t net) { ivl_expr_t rval; - struct vector_info rvec; + ivl_signal_t sig; rval = ivl_stmt_rval(net); assert(rval); - rvec = draw_eval_expr(rval, STUFF_OK_47); + sig = ivl_lval_sig(ivl_stmt_lval(net, 0)); + if (sig && ivl_signal_data_type(sig) == IVL_VT_REAL) { + int res; - /* Write out initial continuous assign instructions to assign - the expression value to the l-value. */ - force_vector_to_lval(net, rvec); + res = draw_eval_real(ivl_stmt_rval(net)); + clr_word(res); + + force_real_to_lval(net, res); + } else { + struct vector_info rvec; + + rvec = draw_eval_expr(rval, STUFF_OK_47); + + /* Write out initial continuous assign instructions to assign + the expression value to the l-value. */ + force_vector_to_lval(net, rvec); + } force_link_rval(net, rval); @@ -1213,6 +1280,22 @@ static int show_stmt_noop(ivl_statement_t net) static int show_stmt_release(ivl_statement_t net) { + ivl_signal_t sig = ivl_lval_sig(ivl_stmt_lval(net, 0)); + if (sig && ivl_signal_data_type(sig) == IVL_VT_REAL) { + unsigned type = 0; + + assert(ivl_stmt_lvals(net) == 1); + ivl_lval_t lval = ivl_stmt_lval(net, 0); + assert(ivl_lval_width(lval) == 1); + assert(ivl_lval_part_off(lval) == 0); + assert(ivl_lval_idx(lval) == 0); + + if (ivl_signal_type(sig) == IVL_SIT_REG) type = 1; + + fprintf(vvp_out, " %%release/wr v%p_0, %u;\n", sig, type); + return 0; + } + unsigned lidx; for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { diff --git a/vvp/codes.h b/vvp/codes.h index 6cb5c3852..5a74ed374 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -52,6 +52,7 @@ extern bool of_BLEND_WR(vthread_t thr, vvp_code_t code); extern bool of_BREAKPOINT(vthread_t thr, vvp_code_t code); extern bool of_CASSIGN_LINK(vthread_t thr, vvp_code_t code); extern bool of_CASSIGN_V(vthread_t thr, vvp_code_t code); +extern bool of_CASSIGN_WR(vthread_t thr, vvp_code_t code); extern bool of_CASSIGN_X0(vthread_t thr, vvp_code_t code); extern bool of_CMPIS(vthread_t thr, vvp_code_t code); extern bool of_CMPIU(vthread_t thr, vvp_code_t code); @@ -66,6 +67,7 @@ extern bool of_CVT_IR(vthread_t thr, vvp_code_t code); extern bool of_CVT_RI(vthread_t thr, vvp_code_t code); extern bool of_CVT_VR(vthread_t thr, vvp_code_t code); extern bool of_DEASSIGN(vthread_t thr, vvp_code_t code); +extern bool of_DEASSIGN_WR(vthread_t thr, vvp_code_t code); extern bool of_DELAY(vthread_t thr, vvp_code_t code); extern bool of_DELAYX(vthread_t thr, vvp_code_t code); extern bool of_DISABLE(vthread_t thr, vvp_code_t code); @@ -75,6 +77,7 @@ extern bool of_DIV_WR(vthread_t thr, vvp_code_t code); extern bool of_END(vthread_t thr, vvp_code_t code); extern bool of_FORCE_LINK(vthread_t thr, vvp_code_t code); extern bool of_FORCE_V(vthread_t thr, vvp_code_t code); +extern bool of_FORCE_WR(vthread_t thr, vvp_code_t code); extern bool of_FORCE_X0(vthread_t thr, vvp_code_t code); extern bool of_FORK(vthread_t thr, vvp_code_t code); extern bool of_INV(vthread_t thr, vvp_code_t code); @@ -121,6 +124,7 @@ extern bool of_POW(vthread_t thr, vvp_code_t code); extern bool of_POW_WR(vthread_t thr, vvp_code_t code); extern bool of_RELEASE_NET(vthread_t thr, vvp_code_t code); extern bool of_RELEASE_REG(vthread_t thr, vvp_code_t code); +extern bool of_RELEASE_WR(vthread_t thr, vvp_code_t code); extern bool of_SET_AV(vthread_t thr, vvp_code_t code); extern bool of_SET_MV(vthread_t thr, vvp_code_t code); extern bool of_SET_VEC(vthread_t thr, vvp_code_t code); diff --git a/vvp/compile.cc b/vvp/compile.cc index 608232b95..e84f2e6ab 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -101,6 +101,7 @@ const static struct opcode_table_s opcode_table[] = { { "%breakpoint", of_BREAKPOINT, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%cassign/link",of_CASSIGN_LINK,2,{OA_FUNC_PTR,OA_FUNC_PTR2,OA_NONE} }, { "%cassign/v",of_CASSIGN_V,3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} }, + { "%cassign/wr",of_CASSIGN_WR,2,{OA_FUNC_PTR,OA_BIT1, OA_NONE} }, { "%cassign/x0",of_CASSIGN_X0,3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} }, { "%cmp/s", of_CMPS, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%cmp/u", of_CMPU, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, @@ -115,6 +116,7 @@ const static struct opcode_table_s opcode_table[] = { { "%cvt/ri", of_CVT_RI, 2, {OA_BIT1, OA_BIT2, OA_NONE} }, { "%cvt/vr", of_CVT_VR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%deassign",of_DEASSIGN,3,{OA_FUNC_PTR, OA_BIT1, OA_BIT2} }, + { "%deassign/wr",of_DEASSIGN_WR,1,{OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%delay", of_DELAY, 2, {OA_BIT1, OA_BIT2, OA_NONE} }, { "%delayx", of_DELAYX, 1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%div", of_DIV, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, @@ -123,6 +125,7 @@ const static struct opcode_table_s opcode_table[] = { { "%end", of_END, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%force/link",of_FORCE_LINK,2,{OA_FUNC_PTR,OA_FUNC_PTR2,OA_NONE} }, { "%force/v",of_FORCE_V,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} }, + { "%force/wr",of_FORCE_WR,2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} }, { "%force/x0",of_FORCE_X0,3,{OA_FUNC_PTR, OA_BIT1, OA_BIT2} }, { "%inv", of_INV, 2, {OA_BIT1, OA_BIT2, OA_NONE} }, { "%ix/add", of_IX_ADD, 2, {OA_BIT1, OA_NUMBER, OA_NONE} }, @@ -168,6 +171,7 @@ const static struct opcode_table_s opcode_table[] = { { "%pow/wr", of_POW_WR, 2, {OA_BIT1, OA_BIT2, OA_NONE} }, { "%release/net",of_RELEASE_NET,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} }, { "%release/reg",of_RELEASE_REG,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} }, + { "%release/wr",of_RELEASE_WR,2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} }, { "%set/av", of_SET_AV, 3, {OA_ARR_PTR, OA_BIT1, OA_BIT2} }, { "%set/mv", of_SET_MV, 3, {OA_MEM_PTR, OA_BIT1, OA_BIT2} }, { "%set/v", of_SET_VEC,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} }, diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index 6d7c6afa7..2c8f320c6 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -168,6 +168,11 @@ variable. This is similar to %set, but it uses the cassign port signal responds differently. See "VARIABLE STATEMENTS" in the README.txt file. +* %cassign/wr , + +Perform a continuous assign of a constant real value to the target +variable. See %cassign/v above. + * %cassign/x0