diff --git a/ivlpp/lexor.lex b/ivlpp/lexor.lex index 7e4796047..1624f172a 100644 --- a/ivlpp/lexor.lex +++ b/ivlpp/lexor.lex @@ -858,6 +858,7 @@ static int define_continue_flag = 0; static char *find_arg(char*ptr, char*head, char*arg) { char *cp = ptr; + size_t len = strlen(arg); while (1) { /* Look for a candidate match, just return if none is found. */ @@ -868,7 +869,8 @@ static char *find_arg(char*ptr, char*head, char*arg) * match is not in the middle of another identifier. */ if (cp != head && - (isalnum(*(cp-1)) || *(cp-1) == '_' || *(cp-1) == '$')) { + (isalnum(*(cp-1)) || *(cp-1) == '_' || *(cp-1) == '$' || + isalnum(*(cp+len)) || *(cp+len) == '_' || *(cp+len) == '$')) { cp++; continue; } @@ -1470,7 +1472,7 @@ static void do_include() fprintf(depend_file, "%s\n", standby->path); if (line_direct_flag) - fprintf(yyout, "\n`line %u \"%s\" 1\n", istack->lineno+1, standby->path); + fprintf(yyout, "\n`line 1 \"%s\" 1\n", standby->path); standby->next = istack; standby->stringify_flag = 0; diff --git a/parse.y b/parse.y index f63ee1d9b..c97dae85b 100644 --- a/parse.y +++ b/parse.y @@ -2519,7 +2519,7 @@ localparam_assign_decl localparam_assign_list { param_active_range = 0; param_active_signed = false; - param_active_type = IVL_VT_NO_TYPE; + param_active_type = IVL_VT_LOGIC; } | K_signed range { param_active_range = $2; diff --git a/tgt-vvp/draw_net_input.c b/tgt-vvp/draw_net_input.c index 87c13733d..1f9846d9b 100644 --- a/tgt-vvp/draw_net_input.c +++ b/tgt-vvp/draw_net_input.c @@ -315,7 +315,7 @@ static char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr) because it may be an array of reg vectors. */ snprintf(tmp, sizeof tmp, "v%p_%u", sptr, nptr_pin); - if (ivl_signal_array_count(sptr) > 1) { + if (ivl_signal_dimensions(sptr) > 0) { fprintf(vvp_out, "v%p_%u .array/port v%p, %u;\n", sptr, nptr_pin, sptr, nptr_pin); } diff --git a/tgt-vvp/draw_ufunc.c b/tgt-vvp/draw_ufunc.c index 6860b8531..6ea3b3637 100644 --- a/tgt-vvp/draw_ufunc.c +++ b/tgt-vvp/draw_ufunc.c @@ -30,7 +30,7 @@ static void function_argument_logic(ivl_signal_t port, ivl_expr_t exp) struct vector_info res; /* ports cannot be arrays. */ - assert(ivl_signal_array_count(port) == 1); + assert(ivl_signal_dimensions(port) == 0); res = draw_eval_expr_wid(exp, ivl_signal_width(port), 0); /* We could have extra bits so only select the ones we need. */ @@ -46,7 +46,7 @@ static void function_argument_real(ivl_signal_t port, ivl_expr_t exp) int res = draw_eval_real(exp); /* ports cannot be arrays. */ - assert(ivl_signal_array_count(port) == 1); + assert(ivl_signal_dimensions(port) == 0); fprintf(vvp_out, " %%set/wr v%p_0, %d;\n", port, res); clr_word(res); @@ -126,7 +126,7 @@ struct vector_info draw_ufunc_expr(ivl_expr_t exp, unsigned wid) if (load_wid > ivl_signal_width(retval)) load_wid = ivl_signal_width(retval); - assert(ivl_signal_array_count(retval) == 1); + assert(ivl_signal_dimensions(retval) == 0); fprintf(vvp_out, " %%load/v %u, v%p_0, %u;\n", res.base, retval, load_wid); @@ -157,7 +157,7 @@ int draw_ufunc_real(ivl_expr_t exp) fprintf(vvp_out, " %%join;\n"); /* Return value signal cannot be an array. */ - assert(ivl_signal_array_count(retval) == 1); + assert(ivl_signal_dimensions(retval) == 0); /* Load the result into a word. */ res = allocate_word(); diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index 27e803d8d..8a7dda0f2 100644 --- a/tgt-vvp/eval_real.c +++ b/tgt-vvp/eval_real.c @@ -326,7 +326,7 @@ static int draw_signal_real_real(ivl_expr_t exp) int res = allocate_word(); unsigned long word = 0; - if (ivl_signal_array_count(sig) > 1) { + if (ivl_signal_dimensions(sig) > 0) { ivl_expr_t ix = ivl_expr_oper1(exp); if (!number_is_immediate(ix, 8*sizeof(word), 0)) { /* XXXX Need to generate a %load/ar instruction. */ diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index fa550cdde..41220c832 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -235,7 +235,7 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix, if (dexp == 0) { /* Constant delay... */ if (number_is_immediate(word_ix, 64, 0)) { - fprintf(vvp_out, " %%ix/load 3, %lu; address\n", + fprintf(vvp_out, " %%ix/load 3, %lu; address\n", get_number_immediate(word_ix)); } else { /* Calculate array word index into index register 3 */ @@ -298,7 +298,7 @@ static void assign_to_lvector(ivl_lval_t lval, unsigned bit, ivl_expr_t word_ix = ivl_lval_idx(lval); const unsigned long use_word = 0; - if (ivl_signal_array_count(sig) > 1) { + if (ivl_signal_dimensions(sig) > 0) { assert(word_ix); assign_to_array_word(sig, word_ix, bit, delay, dexp, part_off_ex, width); return; @@ -480,7 +480,7 @@ static int show_stmt_assign_sig_real(ivl_statement_t net) var = ivl_lval_sig(lval); assert(var != 0); - assert(ivl_signal_array_count(var) == 1); + assert(ivl_signal_dimensions(var) == 0); fprintf(vvp_out, " %%set/wr v%p_0, %d;\n", var, res); @@ -540,7 +540,7 @@ static int show_stmt_assign_nb_real(ivl_statement_t net) sig = ivl_lval_sig(lval); assert(sig); - if (ivl_signal_array_count(sig) > 1) { + if (ivl_signal_dimensions(sig) > 0) { word_ix = ivl_lval_idx(lval); assert(word_ix); assert(number_is_immediate(word_ix, 8*sizeof(use_word), 0)); @@ -1013,7 +1013,7 @@ static void force_link_rval(ivl_statement_t net, ivl_expr_t rval) use_rword = get_number_immediate(rword_idx); } - assert(ivl_signal_array_count(rsig) == 1); + assert(ivl_signal_dimensions(rsig) == 0); use_rword = 0; fprintf(vvp_out, " %s/link", command_name); diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index c55bcb590..3be138c7e 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -879,15 +879,15 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr) fprintf(vvp_out, "L_%p .delay L_%p/d", lptr, lptr); sig = ivl_expr_signal(rise_exp); - assert(ivl_signal_array_count(sig) == 1); + assert(ivl_signal_dimensions(sig) == 0); fprintf(vvp_out, ", v%p_0", sig); sig = ivl_expr_signal(fall_exp); - assert(ivl_signal_array_count(sig) == 1); + assert(ivl_signal_dimensions(sig) == 0); fprintf(vvp_out, ", v%p_0", sig); sig = ivl_expr_signal(decay_exp); - assert(ivl_signal_array_count(sig) == 1); + assert(ivl_signal_dimensions(sig) == 0); fprintf(vvp_out, ", v%p_0;\n", sig); } } @@ -1564,7 +1564,7 @@ static void draw_lpm_ufunc(ivl_lpm_t net) else fprintf(vvp_out, ", "); - assert(ivl_signal_array_count(psig) == 1); + assert(ivl_signal_dimensions(psig) == 0); fprintf(vvp_out, "v%p_0", psig); } @@ -1574,7 +1574,7 @@ static void draw_lpm_ufunc(ivl_lpm_t net) result is collected. */ { ivl_signal_t psig = ivl_scope_port(def, 0); assert(ivl_lpm_width(net) == ivl_signal_width(psig)); - assert(ivl_signal_array_count(psig) == 1); + assert(ivl_signal_dimensions(psig) == 0); fprintf(vvp_out, " v%p_0", psig); } @@ -1602,9 +1602,10 @@ static void draw_lpm_part(ivl_lpm_t net) net, dly, draw_net_input(ivl_lpm_data(net, 0))); fprintf(vvp_out, ", %u, %u;\n", base, width); } else { + const char*sel_symbol = draw_net_input(sel); fprintf(vvp_out, "L_%p%s .part/v %s", net, dly, draw_net_input(ivl_lpm_data(net,0))); - fprintf(vvp_out, ", %s", draw_net_input(sel)); + fprintf(vvp_out, ", %s", sel_symbol); fprintf(vvp_out, ", %u;\n", width); } } diff --git a/vvp/part.cc b/vvp/part.cc index 5b11485ce..3b7f6e500 100644 --- a/vvp/part.cc +++ b/vvp/part.cc @@ -109,6 +109,21 @@ void vvp_fun_part_pv::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit) vvp_send_vec4_pv(port.ptr()->out, bit, base_, wid_, vwid_); } +void vvp_fun_part_pv::recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit) +{ + assert(port.port() == 0); + + if (bit.size() != wid_) { + cerr << "internal error: part_pv (strength-aware) data mismatch. " + << "base_=" << base_ << ", wid_=" << wid_ + << ", vwid_=" << vwid_ << ", bit=" << bit + << endl; + } + assert(bit.size() == wid_); + + vvp_send_vec8_pv(port.ptr()->out, bit, base_, wid_, vwid_); +} + vvp_fun_part_var::vvp_fun_part_var(unsigned w) : base_(0), wid_(w) { diff --git a/vvp/part.h b/vvp/part.h index 8fa861b1a..3fdffd886 100644 --- a/vvp/part.h +++ b/vvp/part.h @@ -62,6 +62,7 @@ class vvp_fun_part_pv : public vvp_net_fun_t { public: void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit); + void recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit); private: unsigned base_; diff --git a/vvp/resolv.cc b/vvp/resolv.cc index 4448b15c8..d0db6ec3c 100644 --- a/vvp/resolv.cc +++ b/vvp/resolv.cc @@ -97,6 +97,24 @@ void resolv_functor::recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit) vvp_send_vec8(ptr->out, out); } +void resolv_functor::recv_vec8_pv(vvp_net_ptr_t port, const vvp_vector8_t&bit, + unsigned base, unsigned wid, unsigned vwid) +{ + assert(bit.size() == wid); + vvp_vector8_t res (vwid); + + for (unsigned idx = 0 ; idx < base ; idx += 1) + res.set_bit(idx, vvp_scalar_t()); + + for (unsigned idx = 0 ; idx < wid ; idx += 1) + res.set_bit(idx+base, bit.value(idx)); + + for (unsigned idx = base+wid ; idx < vwid ; idx += 1) + res.set_bit(idx, vvp_scalar_t()); + + recv_vec8(port, res); +} + resolv_wired_logic::resolv_wired_logic() { } diff --git a/vvp/resolv.h b/vvp/resolv.h index d7aa6fe94..4f0e683c6 100644 --- a/vvp/resolv.h +++ b/vvp/resolv.h @@ -45,6 +45,8 @@ class resolv_functor : public vvp_net_fun_t { void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit, unsigned base, unsigned wid, unsigned vwid); + void recv_vec8_pv(vvp_net_ptr_t port, const vvp_vector8_t&bit, + unsigned base, unsigned wid, unsigned vwid); private: vvp_vector8_t val_[4]; diff --git a/vvp/vthread.cc b/vvp/vthread.cc index f8a6d5b49..31d1c8602 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -1371,14 +1371,12 @@ bool of_CVT_RI(vthread_t thr, vvp_code_t cp) bool of_CVT_VR(vthread_t thr, vvp_code_t cp) { double r = thr->words[cp->bit_idx[1]].w_real; - long rl = lround(r); unsigned base = cp->bit_idx[0]; unsigned wid = cp->number; - - for (unsigned idx = 0 ; idx < wid ; idx += 1) { - thr_put_bit(thr, base+idx, (rl&1)? BIT4_1 : BIT4_0); - rl >>= 1; - } + vvp_vector4_t tmp(wid, r); + /* Make sure there is enough space for the new vector. */ + thr_check_addr(thr, base+wid-1); + thr->bits4.set_vec(base, tmp); return true; } diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index eb5f154b4..f77850c3e 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -373,9 +373,10 @@ vvp_vector4_t::vvp_vector4_t(unsigned size, double val) return; } - /* We return 'b1 for + or - infinity. */ + /* We return 'b1 for + infinity or 'b0 for - infinity. */ if (val && (val == 0.5*val)) { - allocate_words_(size, WORD_1_ABITS, WORD_1_BBITS); + if (val > 0) allocate_words_(size, WORD_1_ABITS, WORD_1_BBITS); + else allocate_words_(size, WORD_0_ABITS, WORD_0_BBITS); return; } @@ -2123,7 +2124,16 @@ void vvp_net_fun_t::recv_vec4_pv(vvp_net_ptr_t, const vvp_vector4_t&bits, unsigned base, unsigned wid, unsigned vwid) { cerr << "internal error: " << typeid(*this).name() << ": " - << "recv_vect_pv(" << bits << ", " << base + << "recv_vec4_pv(" << bits << ", " << base + << ", " << wid << ", " << vwid << ") not implemented" << endl; + assert(0); +} + +void vvp_net_fun_t::recv_vec8_pv(vvp_net_ptr_t, const vvp_vector8_t&bits, + unsigned base, unsigned wid, unsigned vwid) +{ + cerr << "internal error: " << typeid(*this).name() << ": " + << "recv_vec8_pv(" << bits << ", " << base << ", " << wid << ", " << vwid << ") not implemented" << endl; assert(0); } @@ -2402,6 +2412,12 @@ void vvp_fun_signal::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit, } } +void vvp_fun_signal::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit, + unsigned base, unsigned wid, unsigned vwid) +{ + recv_vec4_pv(ptr, reduce4(bit), base, wid, vwid); +} + void vvp_fun_signal::calculate_output_(vvp_net_ptr_t ptr) { if (force_mask_.size()) { diff --git a/vvp/vvp_net.h b/vvp/vvp_net.h index 2d352c4e3..6e6497179 100644 --- a/vvp/vvp_net.h +++ b/vvp/vvp_net.h @@ -870,6 +870,8 @@ class vvp_net_fun_t { // Part select variants of above virtual void recv_vec4_pv(vvp_net_ptr_t p, const vvp_vector4_t&bit, unsigned base, unsigned wid, unsigned vwid); + virtual void recv_vec8_pv(vvp_net_ptr_t p, const vvp_vector8_t&bit, + unsigned base, unsigned wid, unsigned vwid); virtual void recv_long_pv(vvp_net_ptr_t port, long bit, unsigned base, unsigned wid); @@ -1114,6 +1116,8 @@ class vvp_fun_signal : public vvp_fun_signal_vec { // Part select variants of above void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit, unsigned base, unsigned wid, unsigned vwid); + void recv_vec8_pv(vvp_net_ptr_t port, const vvp_vector8_t&bit, + unsigned base, unsigned wid, unsigned vwid); // Get information about the vector value. unsigned size() const; @@ -1320,4 +1324,17 @@ inline void vvp_send_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&val, } } +inline void vvp_send_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&val, + unsigned base, unsigned wid, unsigned vwid) +{ + while (struct vvp_net_t*cur = ptr.ptr()) { + vvp_net_ptr_t next = cur->port[ptr.port()]; + + if (cur->fun) + cur->fun->recv_vec8_pv(ptr, val, base, wid, vwid); + + ptr = next; + } +} + #endif