Return the correct value when a queue or darray references an undefined element

This commit is contained in:
Cary R 2020-07-22 21:46:32 -07:00
parent 5ebd08c7f8
commit e1870acfac
11 changed files with 63 additions and 44 deletions

View File

@ -41,8 +41,10 @@ class netqueue_t : public netdarray_t {
// A queue may have a type that is signed. // A queue may have a type that is signed.
inline bool get_signed() const { return element_type()->get_signed(); } inline bool get_signed() const { return element_type()->get_signed(); }
// Use the packed width to pass the maximum index // Use the packed width to pass the element width
long packed_width(void) const { return max_idx_; } 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; std::ostream& debug_dump(std::ostream&) const;

View File

@ -27,6 +27,7 @@
# include "compiler.h" # include "compiler.h"
# include "t-dll.h" # include "t-dll.h"
# include "netclass.h" # include "netclass.h"
# include "netqueue.h"
# include "netmisc.h" # include "netmisc.h"
# include "discipline.h" # include "discipline.h"
# include <cstdlib> # include <cstdlib>
@ -2701,11 +2702,18 @@ void dll_target::signal(const NetNet*net)
// The back-end API doesn't yet support multi-dimension // The back-end API doesn't yet support multi-dimension
// unpacked arrays, so just report the canonical dimensions. // unpacked arrays, so just report the canonical dimensions.
obj->array_base = 0; 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; 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: " if (debug_optimizer && obj->array_words > 1000) cerr << "debug: "
"t-dll creating nexus array " << obj->array_words << " long" << endl; "t-dll creating nexus array " << obj->array_words << " long" << endl;
if (obj->array_words > 1 && net->pins_are_virtual()) { if (obj->array_words > 1 && net->pins_are_virtual()) {

View File

@ -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); ivl_type_t var_type = ivl_signal_net_type(var);
assert(ivl_type_base(var_type)== IVL_VT_QUEUE); 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(); int idx = allocate_word();
assert(idx >= 0); assert(idx >= 0);
/* Save the queue maximum index value to an integer register. */ /* 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"); fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
ivl_type_t element_type = ivl_type_element(var_type); ivl_type_t element_type = ivl_type_element(var_type);

View File

@ -540,13 +540,15 @@ static void draw_reg_in_scope(ivl_signal_t sig)
swapped ? first: last, swapped ? last : first, msb, lsb); swapped ? first: last, swapped ? last : first, msb, lsb);
} else if (ivl_signal_data_type(sig) == IVL_VT_DARRAY) { } 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)), vvp_mangle_name(ivl_signal_basename(sig)),
ivl_signal_width(sig),
ivl_signal_local(sig)? " Local signal" : ""); ivl_signal_local(sig)? " Local signal" : "");
} else if (ivl_signal_data_type(sig) == IVL_VT_QUEUE) { } 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)), vvp_mangle_name(ivl_signal_basename(sig)),
ivl_signal_width(sig),
ivl_signal_local(sig)? " Local signal" : ""); ivl_signal_local(sig)? " Local signal" : "");
} else if (ivl_signal_data_type(sig) == IVL_VT_STRING) { } else if (ivl_signal_data_type(sig) == IVL_VT_STRING) {

View File

@ -1,7 +1,7 @@
#ifndef IVL_compile_H #ifndef IVL_compile_H
#define 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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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_real(char*label, char*name);
extern void compile_var_string(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_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 * This function is used to create a scope port

View File

@ -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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 ';' | T_LABEL K_VAR_STR T_STRING ';'
{ compile_var_string($1, $3); } { compile_var_string($1, $3); }
| T_LABEL K_VAR_DARRAY T_STRING ';' | T_LABEL K_VAR_DARRAY T_STRING ',' T_NUMBER ';'
{ compile_var_darray($1, $3); } { compile_var_darray($1, $3, $5); }
| T_LABEL K_VAR_QUEUE T_STRING ';' | T_LABEL K_VAR_QUEUE T_STRING ',' T_NUMBER';'
{ compile_var_queue($1, $3); } { compile_var_queue($1, $3, $5); }
| T_LABEL K_VAR_COBJECT T_STRING ';' | T_LABEL K_VAR_COBJECT T_STRING ';'
{ compile_var_cobject($1, $3); } { compile_var_cobject($1, $3); }

View File

@ -3671,10 +3671,12 @@ bool of_LOAD_DAR_R(vthread_t thr, vvp_code_t cp)
assert(obj); assert(obj);
vvp_darray*darray = obj->get_object().peek<vvp_darray>(); vvp_darray*darray = obj->get_object().peek<vvp_darray>();
assert(darray);
double word; double word;
darray->get_word(adr, word); if (darray)
darray->get_word(adr, word);
else
word = 0.0;
thr->push_real(word); thr->push_real(word);
return true; return true;
@ -3690,12 +3692,14 @@ bool of_LOAD_DAR_STR(vthread_t thr, vvp_code_t cp)
assert(obj); assert(obj);
vvp_darray*darray = obj->get_object().peek<vvp_darray>(); vvp_darray*darray = obj->get_object().peek<vvp_darray>();
assert(darray);
string word; string word;
darray->get_word(adr, word); if (darray)
thr->push_str(word); darray->get_word(adr, word);
else
word = "";
thr->push_str(word);
return true; return true;
} }
@ -3709,12 +3713,14 @@ bool of_LOAD_DAR_VEC4(vthread_t thr, vvp_code_t cp)
assert(obj); assert(obj);
vvp_darray*darray = obj->get_object().peek<vvp_darray>(); vvp_darray*darray = obj->get_object().peek<vvp_darray>();
assert(darray);
vvp_vector4_t word; vvp_vector4_t word;
darray->get_word(adr, word); if (darray)
thr->push_vec4(word); darray->get_word(adr, word);
else
word = vvp_vector4_t(obj->size());
thr->push_vec4(word);
return true; return true;
} }

View File

@ -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) void vvp_queue_vec4::get_word(unsigned adr, vvp_vector4_t&value)
{ {
if (adr >= queue.size()) if (adr >= queue.size())
value = vvp_vector4_t(); value = vvp_vector4_t(queue[0].size());
else else
value = queue[adr]; value = queue[adr];
} }

View File

@ -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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 */ /* 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_; 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()); context_idx_ = vpip_add_item_to_context(this, vpip_peek_context_scope());
} }

View File

@ -1,7 +1,7 @@
#ifndef IVL_vvp_net_sig_H #ifndef IVL_vvp_net_sig_H
#define 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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 { class vvp_fun_signal_object : public vvp_fun_signal_base {
public: public:
explicit vvp_fun_signal_object() {}; explicit vvp_fun_signal_object(unsigned size) { size_ = size; };
unsigned size() const { return 1; } unsigned size() const { return size_; }
virtual vvp_object_t get_object() const =0; 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 { class vvp_fun_signal_object_sa : public vvp_fun_signal_object {
public: 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, void recv_object(vvp_net_ptr_t port, vvp_object_t bit,
vvp_context_t context); 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 { class vvp_fun_signal_object_aa : public vvp_fun_signal_object, public automatic_signal_base, public automatic_hooks_s {
public: public:
explicit vvp_fun_signal_object_aa(); explicit vvp_fun_signal_object_aa(unsigned size);
~vvp_fun_signal_object_aa(); ~vvp_fun_signal_object_aa();
void alloc_instance(vvp_context_t context); void alloc_instance(vvp_context_t context);

View File

@ -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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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; 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; vvp_net_t*net = new vvp_net_t;
if (vpip_peek_current_scope()->is_automatic()) { 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->fil = tmp;
net->fun = tmp; net->fun = tmp;
} else { } else {
net->fil = 0; 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); define_functor_symbol(label, net);
@ -124,17 +124,17 @@ void compile_var_darray(char*label, char*name)
delete[] 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; vvp_net_t*net = new vvp_net_t;
if (vpip_peek_current_scope()->is_automatic()) { 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->fil = tmp;
net->fun = tmp; net->fun = tmp;
} else { } else {
net->fil = 0; 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); 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; vvp_net_t*net = new vvp_net_t;
if (vpip_peek_current_scope()->is_automatic()) { 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->fil = tmp;
net->fun = tmp; net->fun = tmp;
} else { } else {
net->fil = 0; 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); define_functor_symbol(label, net);