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.
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;

View File

@ -27,6 +27,7 @@
# include "compiler.h"
# include "t-dll.h"
# include "netclass.h"
# include "netqueue.h"
# include "netmisc.h"
# include "discipline.h"
# include <cstdlib>
@ -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;
// 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()) {

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);
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);

View File

@ -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) {

View File

@ -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

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
* 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); }

View File

@ -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<vvp_darray>();
assert(darray);
double 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<vvp_darray>();
assert(darray);
string word;
if (darray)
darray->get_word(adr, word);
thr->push_str(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<vvp_darray>();
assert(darray);
vvp_vector4_t word;
if (darray)
darray->get_word(adr, word);
thr->push_vec4(word);
else
word = vvp_vector4_t(obj->size());
thr->push_vec4(word);
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)
{
if (adr >= queue.size())
value = vvp_vector4_t();
value = vvp_vector4_t(queue[0].size());
else
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
* 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());
}

View File

@ -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);

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
* 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);