diff --git a/netqueue.h b/netqueue.h index feded7423..ecc64be1f 100644 --- a/netqueue.h +++ b/netqueue.h @@ -41,8 +41,10 @@ class netqueue_t : public netdarray_t { // A queue may have a type that is signed. inline bool get_signed() const { return element_type()->get_signed(); } - // Use the packed width to pass the maximum index - long packed_width(void) const { return max_idx_; } + // Use the packed width to pass the element width + long packed_width(void) const { return element_type()->packed_width(); } + + long max_idx(void) const { return max_idx_; } std::ostream& debug_dump(std::ostream&) const; diff --git a/t-dll.cc b/t-dll.cc index 89601b7f8..8e7b1e5da 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -27,6 +27,7 @@ # include "compiler.h" # include "t-dll.h" # include "netclass.h" +# include "netqueue.h" # include "netmisc.h" # include "discipline.h" # include @@ -2701,11 +2702,18 @@ void dll_target::signal(const NetNet*net) // The back-end API doesn't yet support multi-dimension // unpacked arrays, so just report the canonical dimensions. obj->array_base = 0; - obj->array_words = net->unpacked_count(); + // For a queue we pass the maximum queue size as the array words. + if (obj->net_type->base_type() == IVL_VT_QUEUE) { + long max_size = net->queue_type()->max_idx()+1; + ivl_assert(*net, max_size >= 0); + obj->array_words = max_size; + } else + obj->array_words = net->unpacked_count(); obj->array_addr_swapped = 0; } - ivl_assert(*net, obj->array_words == net->pin_count()); + ivl_assert(*net, (obj->array_words == net->pin_count()) || + (obj->net_type->base_type() == IVL_VT_QUEUE)); if (debug_optimizer && obj->array_words > 1000) cerr << "debug: " "t-dll creating nexus array " << obj->array_words << " long" << endl; if (obj->array_words > 1 && net->pins_are_virtual()) { diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 56467f053..6b7ed69da 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -1780,13 +1780,10 @@ static int show_push_frontback_method(ivl_statement_t net, bool is_front) ivl_type_t var_type = ivl_signal_net_type(var); assert(ivl_type_base(var_type)== IVL_VT_QUEUE); - /* The maximum index value is passed as the signal width. */ - long max_size = ivl_signal_width(var) + 1; - assert(max_size >= 0); int idx = allocate_word(); assert(idx >= 0); /* Save the queue maximum index value to an integer register. */ - fprintf(vvp_out, " %%ix/load %u, %ld, 0;\n", idx, max_size); + fprintf(vvp_out, " %%ix/load %u, %u, 0;\n", idx, ivl_signal_array_count(var)); fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); ivl_type_t element_type = ivl_type_element(var_type); diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index 16a5bcbb0..557a45527 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -540,13 +540,15 @@ static void draw_reg_in_scope(ivl_signal_t sig) swapped ? first: last, swapped ? last : first, msb, lsb); } else if (ivl_signal_data_type(sig) == IVL_VT_DARRAY) { - fprintf(vvp_out, "v%p_0 .var/darray \"%s\";%s\n", sig, + fprintf(vvp_out, "v%p_0 .var/darray \"%s\", %u;%s\n", sig, vvp_mangle_name(ivl_signal_basename(sig)), + ivl_signal_width(sig), ivl_signal_local(sig)? " Local signal" : ""); } else if (ivl_signal_data_type(sig) == IVL_VT_QUEUE) { - fprintf(vvp_out, "v%p_0 .var/queue \"%s\";%s\n", sig, + fprintf(vvp_out, "v%p_0 .var/queue \"%s\", %u;%s\n", sig, vvp_mangle_name(ivl_signal_basename(sig)), + ivl_signal_width(sig), ivl_signal_local(sig)? " Local signal" : ""); } else if (ivl_signal_data_type(sig) == IVL_VT_STRING) { diff --git a/vvp/compile.h b/vvp/compile.h index 8dec1e311..ba62b9220 100644 --- a/vvp/compile.h +++ b/vvp/compile.h @@ -1,7 +1,7 @@ #ifndef IVL_compile_H #define IVL_compile_H /* - * Copyright (c) 2001-2018 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2020 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -504,9 +504,9 @@ extern void compile_variable(char*label, char*name, extern void compile_var_real(char*label, char*name); extern void compile_var_string(char*label, char*name); -extern void compile_var_darray(char*label, char*name); +extern void compile_var_darray(char*label, char*name, unsigned size); extern void compile_var_cobject(char*label, char*name); -extern void compile_var_queue(char*label, char*name); +extern void compile_var_queue(char*label, char*name, unsigned size); /* * This function is used to create a scope port diff --git a/vvp/parse.y b/vvp/parse.y index a6ae822ac..9e553549e 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -1,7 +1,7 @@ %{ /* - * Copyright (c) 2001-2018 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2020 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -768,11 +768,11 @@ statement | T_LABEL K_VAR_STR T_STRING ';' { compile_var_string($1, $3); } - | T_LABEL K_VAR_DARRAY T_STRING ';' - { compile_var_darray($1, $3); } + | T_LABEL K_VAR_DARRAY T_STRING ',' T_NUMBER ';' + { compile_var_darray($1, $3, $5); } - | T_LABEL K_VAR_QUEUE T_STRING ';' - { compile_var_queue($1, $3); } + | T_LABEL K_VAR_QUEUE T_STRING ',' T_NUMBER';' + { compile_var_queue($1, $3, $5); } | T_LABEL K_VAR_COBJECT T_STRING ';' { compile_var_cobject($1, $3); } diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 43123aea8..731a25ecd 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -3671,10 +3671,12 @@ bool of_LOAD_DAR_R(vthread_t thr, vvp_code_t cp) assert(obj); vvp_darray*darray = obj->get_object().peek(); - assert(darray); double word; - darray->get_word(adr, word); + if (darray) + darray->get_word(adr, word); + else + word = 0.0; thr->push_real(word); return true; @@ -3690,12 +3692,14 @@ bool of_LOAD_DAR_STR(vthread_t thr, vvp_code_t cp) assert(obj); vvp_darray*darray = obj->get_object().peek(); - assert(darray); string word; - darray->get_word(adr, word); - thr->push_str(word); + if (darray) + darray->get_word(adr, word); + else + word = ""; + thr->push_str(word); return true; } @@ -3709,12 +3713,14 @@ bool of_LOAD_DAR_VEC4(vthread_t thr, vvp_code_t cp) assert(obj); vvp_darray*darray = obj->get_object().peek(); - assert(darray); vvp_vector4_t word; - darray->get_word(adr, word); - thr->push_vec4(word); + if (darray) + darray->get_word(adr, word); + else + word = vvp_vector4_t(obj->size()); + thr->push_vec4(word); return true; } diff --git a/vvp/vvp_darray.cc b/vvp/vvp_darray.cc index 00ffbfe6f..f07b75753 100644 --- a/vvp/vvp_darray.cc +++ b/vvp/vvp_darray.cc @@ -527,7 +527,7 @@ void vvp_queue_vec4::set_word(unsigned adr, const vvp_vector4_t&value) void vvp_queue_vec4::get_word(unsigned adr, vvp_vector4_t&value) { if (adr >= queue.size()) - value = vvp_vector4_t(); + value = vvp_vector4_t(queue[0].size()); else value = queue[adr]; } diff --git a/vvp/vvp_net_sig.cc b/vvp/vvp_net_sig.cc index c3dfc1576..cd6fd405f 100644 --- a/vvp/vvp_net_sig.cc +++ b/vvp/vvp_net_sig.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2016 Stephen Williams (steve@icarus.com) + * Copyright (c) 2004-2020 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -711,7 +711,8 @@ void vvp_fun_signal_string_aa::operator delete(void*) /* OBJECT signals */ -vvp_fun_signal_object_sa::vvp_fun_signal_object_sa() +vvp_fun_signal_object_sa::vvp_fun_signal_object_sa(unsigned size) +: vvp_fun_signal_object(size) { } @@ -742,7 +743,8 @@ vvp_object_t vvp_fun_signal_object_sa::get_object() const return value_; } -vvp_fun_signal_object_aa::vvp_fun_signal_object_aa() +vvp_fun_signal_object_aa::vvp_fun_signal_object_aa(unsigned size) +: vvp_fun_signal_object(size) { context_idx_ = vpip_add_item_to_context(this, vpip_peek_context_scope()); } diff --git a/vvp/vvp_net_sig.h b/vvp/vvp_net_sig.h index e64e21095..161503d6a 100644 --- a/vvp/vvp_net_sig.h +++ b/vvp/vvp_net_sig.h @@ -1,7 +1,7 @@ #ifndef IVL_vvp_net_sig_H #define IVL_vvp_net_sig_H /* - * Copyright (c) 2004-2016 Stephen Williams (steve@icarus.com) + * Copyright (c) 2004-2020 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -330,10 +330,12 @@ class vvp_fun_signal_string_aa : public vvp_fun_signal_string, public automatic_ class vvp_fun_signal_object : public vvp_fun_signal_base { public: - explicit vvp_fun_signal_object() {}; - unsigned size() const { return 1; } + explicit vvp_fun_signal_object(unsigned size) { size_ = size; }; + unsigned size() const { return size_; } virtual vvp_object_t get_object() const =0; + private: + unsigned size_; }; /* @@ -342,7 +344,7 @@ class vvp_fun_signal_object : public vvp_fun_signal_base { class vvp_fun_signal_object_sa : public vvp_fun_signal_object { public: - explicit vvp_fun_signal_object_sa(); + explicit vvp_fun_signal_object_sa(unsigned size); void recv_object(vvp_net_ptr_t port, vvp_object_t bit, vvp_context_t context); @@ -359,7 +361,7 @@ class vvp_fun_signal_object_sa : public vvp_fun_signal_object { class vvp_fun_signal_object_aa : public vvp_fun_signal_object, public automatic_signal_base, public automatic_hooks_s { public: - explicit vvp_fun_signal_object_aa(); + explicit vvp_fun_signal_object_aa(unsigned size); ~vvp_fun_signal_object_aa(); void alloc_instance(vvp_context_t context); diff --git a/vvp/words.cc b/vvp/words.cc index fcafa939a..f0a79bcaa 100644 --- a/vvp/words.cc +++ b/vvp/words.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2015 Stephen Williams (steve@icarus.com) + * Copyright (c) 2003-2020 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -101,17 +101,17 @@ void compile_var_string(char*label, char*name) delete[] name; } -void compile_var_darray(char*label, char*name) +void compile_var_darray(char*label, char*name, unsigned size) { vvp_net_t*net = new vvp_net_t; if (vpip_peek_current_scope()->is_automatic()) { - vvp_fun_signal_object_aa*tmp = new vvp_fun_signal_object_aa; + vvp_fun_signal_object_aa*tmp = new vvp_fun_signal_object_aa(size); net->fil = tmp; net->fun = tmp; } else { net->fil = 0; - net->fun = new vvp_fun_signal_object_sa; + net->fun = new vvp_fun_signal_object_sa(size); } define_functor_symbol(label, net); @@ -124,17 +124,17 @@ void compile_var_darray(char*label, char*name) delete[] name; } -void compile_var_queue(char*label, char*name) +void compile_var_queue(char*label, char*name, unsigned size) { vvp_net_t*net = new vvp_net_t; if (vpip_peek_current_scope()->is_automatic()) { - vvp_fun_signal_object_aa*tmp = new vvp_fun_signal_object_aa; + vvp_fun_signal_object_aa*tmp = new vvp_fun_signal_object_aa(size); net->fil = tmp; net->fun = tmp; } else { net->fil = 0; - net->fun = new vvp_fun_signal_object_sa; + net->fun = new vvp_fun_signal_object_sa(size); } define_functor_symbol(label, net); @@ -152,12 +152,12 @@ void compile_var_cobject(char*label, char*name) vvp_net_t*net = new vvp_net_t; if (vpip_peek_current_scope()->is_automatic()) { - vvp_fun_signal_object_aa*tmp = new vvp_fun_signal_object_aa; + vvp_fun_signal_object_aa*tmp = new vvp_fun_signal_object_aa(1); net->fil = tmp; net->fun = tmp; } else { net->fil = 0; - net->fun = new vvp_fun_signal_object_sa; + net->fun = new vvp_fun_signal_object_sa(1); } define_functor_symbol(label, net);