Don't fail when pushing/poping from an empty queue

This commit is contained in:
Cary R 2020-07-23 19:10:38 -07:00
parent 5f8aa24093
commit 1b52a4a578
3 changed files with 44 additions and 21 deletions

View File

@ -1008,7 +1008,8 @@ static void draw_darray_pop(ivl_expr_t expr)
ivl_expr_t arg = ivl_expr_parm(expr, 0);
assert(ivl_expr_type(arg) == IVL_EX_SIGNAL);
fprintf(vvp_out, " %%qpop/%s/v v%p_0;\n", fb, ivl_expr_signal(arg));
fprintf(vvp_out, " %%qpop/%s/v v%p_0, %u;\n", fb, ivl_expr_signal(arg),
ivl_expr_width(expr));
}
static void draw_sfunc_vec4(ivl_expr_t expr)

View File

@ -249,10 +249,10 @@ static const struct opcode_table_s opcode_table[] = {
{ "%putc/str/vec4",of_PUTC_STR_VEC4,2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} },
{ "%qpop/b/real",of_QPOP_B_REAL,1,{OA_FUNC_PTR,OA_NONE,OA_NONE} },
{ "%qpop/b/str", of_QPOP_B_STR, 1,{OA_FUNC_PTR,OA_NONE,OA_NONE} },
{ "%qpop/b/v", of_QPOP_B_V, 1,{OA_FUNC_PTR,OA_NONE,OA_BIT2} },
{ "%qpop/b/v", of_QPOP_B_V, 2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} },
{ "%qpop/f/real",of_QPOP_F_REAL,1,{OA_FUNC_PTR,OA_NONE,OA_NONE} },
{ "%qpop/f/str", of_QPOP_F_STR, 1,{OA_FUNC_PTR,OA_NONE,OA_NONE} },
{ "%qpop/f/v", of_QPOP_F_V, 1,{OA_FUNC_PTR,OA_NONE,OA_BIT2} },
{ "%qpop/f/v", of_QPOP_F_V, 2,{OA_FUNC_PTR,OA_BIT1,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} },

View File

@ -5025,15 +5025,17 @@ bool of_QPOP_B_REAL(vthread_t thr, vvp_code_t cp)
{
vvp_net_t*net = cp->net;
vvp_queue*dqueue = get_queue_object<vvp_queue_string>(thr, net);
vvp_queue*dqueue = get_queue_object<vvp_queue_real>(thr, net);
assert(dqueue);
size_t size = dqueue->get_size();
assert(size > 0);
double value;
if (size) {
dqueue->get_word(size-1, value);
dqueue->pop_back();
} else
value = 0.0;
thr->push_real(value);
return true;
@ -5050,11 +5052,13 @@ bool of_QPOP_B_STR(vthread_t thr, vvp_code_t cp)
assert(dqueue);
size_t size = dqueue->get_size();
assert(size > 0);
string value;
if (size) {
dqueue->get_word(size-1, value);
dqueue->pop_back();
} else
value = "";
thr->push_str(value);
return true;
@ -5066,17 +5070,21 @@ bool of_QPOP_B_STR(vthread_t thr, vvp_code_t cp)
bool of_QPOP_B_V(vthread_t thr, vvp_code_t cp)
{
vvp_net_t*net = cp->net;
unsigned width = cp->bit_idx[0];
vvp_queue*dqueue = get_queue_object<vvp_queue_vec4>(thr, net);
assert(dqueue);
size_t size = dqueue->get_size();
assert(size > 0);
vvp_vector4_t value;
if (size) {
dqueue->get_word(size-1, value);
dqueue->pop_back();
} else
value = vvp_vector4_t(width);
assert(width == value.size());
thr->push_vec4(value);
return true;
}
@ -5088,12 +5096,17 @@ bool of_QPOP_F_REAL(vthread_t thr, vvp_code_t cp)
{
vvp_net_t*net = cp->net;
vvp_queue*dqueue = get_queue_object<vvp_queue_string>(thr, net);
vvp_queue*dqueue = get_queue_object<vvp_queue_real>(thr, net);
assert(dqueue);
size_t size = dqueue->get_size();
double value;
if (size) {
dqueue->get_word(0, value);
dqueue->pop_front();
} else
value = 0.0;
thr->push_real(value);
return true;
@ -5109,9 +5122,14 @@ bool of_QPOP_F_STR(vthread_t thr, vvp_code_t cp)
vvp_queue*dqueue = get_queue_object<vvp_queue_string>(thr, net);
assert(dqueue);
size_t size = dqueue->get_size();
string value;
if (size) {
dqueue->get_word(0, value);
dqueue->pop_front();
} else
value = "";
thr->push_str(value);
return true;
@ -5123,17 +5141,21 @@ bool of_QPOP_F_STR(vthread_t thr, vvp_code_t cp)
bool of_QPOP_F_V(vthread_t thr, vvp_code_t cp)
{
vvp_net_t*net = cp->net;
unsigned width = cp->bit_idx[0];
vvp_queue*dqueue = get_queue_object<vvp_queue_vec4>(thr, net);
assert(dqueue);
size_t size = dqueue->get_size();
assert(size > 0);
vvp_vector4_t value;
if (size) {
dqueue->get_word(0, value);
dqueue->pop_front();
} else
value = vvp_vector4_t(width);
assert(width == value.size());
thr->push_vec4(value);
return true;
}