Fix elaboration and evaluation of SV queue push arguments.

These are assignments to a queue element, so need to consider the
element base type when determining the expression width.

(cherry picked from commit 8da7a14800)
This commit is contained in:
Martin Whitaker 2020-05-01 15:30:44 +01:00
parent 205b7f4b6f
commit 6da261cd52
2 changed files with 48 additions and 8 deletions

View File

@ -1,7 +1,7 @@
#ifndef IVL_Statement_H #ifndef IVL_Statement_H
#define IVL_Statement_H #define IVL_Statement_H
/* /*
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-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
@ -237,6 +237,9 @@ class PCallTask : public Statement {
NetNet*net, NetNet*net,
perm_string method_name, perm_string method_name,
const char*sys_task_name) const; const char*sys_task_name) const;
NetProc*elaborate_queue_method_(Design*des, NetScope*scope,
NetNet*net,
const char*sys_task_name) const;
bool test_task_calls_ok_(Design*des, NetScope*scope) const; bool test_task_calls_ok_(Design*des, NetScope*scope) const;
PPackage*package_; PPackage*package_;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2020 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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
@ -3576,6 +3576,45 @@ NetProc* PCallTask::elaborate_sys_task_method_(Design*des, NetScope*scope,
return sys; return sys;
} }
/*
* This private method is called to elaborate queue push methods. The
* sys_task_name is the internal system-task name to use.
*/
NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope,
NetNet*net,
const char*sys_task_name) const
{
NetESignal*sig = new NetESignal(net);
sig->set_line(*this);
unsigned nparms = parms_.size();
ivl_assert(*this, nparms == 1);
ivl_variable_type_t base_type = net->darray_type()->element_base_type();
int context_width = -1;
switch (base_type) {
case IVL_VT_BOOL:
case IVL_VT_LOGIC:
context_width = net->darray_type()->element_width();
break;
default:
break;
}
vector<NetExpr*>argv (2);
argv[0] = sig;
if (parms_[0] == 0) {
argv[1] = 0;
} else {
argv[1] = elab_and_eval(des, scope, parms_[0], context_width,
false, false, base_type);
}
NetSTask*sys = new NetSTask(sys_task_name, IVL_SFUNC_AS_TASK_IGNORE, argv);
sys->set_line(*this);
return sys;
}
NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope, NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
bool add_this_flag) const bool add_this_flag) const
{ {
@ -3616,13 +3655,11 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
if (net->queue_type()) { if (net->queue_type()) {
if (method_name=="push_back") if (method_name=="push_back")
return elaborate_sys_task_method_(des, scope, net, return elaborate_queue_method_(des, scope, net,
method_name, "$ivl_queue_method$push_back");
"$ivl_queue_method$push_back");
if (method_name=="push_front") if (method_name=="push_front")
return elaborate_sys_task_method_(des, scope, net, return elaborate_queue_method_(des, scope, net,
method_name, "$ivl_queue_method$push_front");
"$ivl_queue_method$push_front");
} }
if (const netclass_t*class_type = net->class_type()) { if (const netclass_t*class_type = net->class_type()) {