Support declaring queue variables all the way to vvp.

Nothing actually useful happens here, but the declarations
are functional.
This commit is contained in:
Stephen Williams 2014-07-31 17:56:16 -07:00
parent 6d052d4ff7
commit e8b8fcba57
20 changed files with 210 additions and 12 deletions

View File

@ -229,7 +229,10 @@ class PCallTask : public Statement {
NetProc*elaborate_build_call_(Design*des, NetScope*scope,
NetScope*task, NetExpr*use_this) const;
NetProc*elaborate_sys_task_method_(Design*des, NetScope*scope,
NetNet*net,
perm_string method_name,
const char*sys_task_name) const;
bool test_task_calls_ok_(Design*des, NetScope*scope) const;
PPackage*package_;

View File

@ -30,6 +30,7 @@
# include "discipline.h"
# include "netclass.h"
# include "netdarray.h"
# include "netqueue.h"
# include "netvector.h"
# include "ivl_assert.h"
# include "PExpr.h"
@ -113,6 +114,9 @@ ostream& operator << (ostream&o, ivl_variable_type_t val)
case IVL_VT_CLASS:
o << "class";
break;
case IVL_VT_QUEUE:
o << "queue";
break;
}
return o;
}
@ -205,6 +209,12 @@ ostream& netdarray_t::debug_dump(ostream&o) const
return o;
}
ostream& netqueue_t::debug_dump(ostream&fd) const
{
fd << "queue of " << *element_type();
return fd;
}
ostream& netvector_t::debug_dump(ostream&o) const
{
o << type_ << (signed_? " signed" : " unsigned") << packed_dims_;

View File

@ -3427,6 +3427,38 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
return elaborate_build_call_(des, scope, task, 0);
}
/*
* This private method is called to elaborate built-in methods. The
* method_name is the detected name of the built-in method, and the
* sys_task_name is the internal system-task name to use.
*/
NetProc* PCallTask::elaborate_sys_task_method_(Design*des, NetScope*scope,
NetNet*net,
perm_string method_name,
const char*sys_task_name) const
{
NetESignal*sig = new NetESignal(net);
sig->set_line(*this);
vector<NetExpr*>argv (1 + parms_.size());
argv[0] = sig;
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
PExpr*ex = parms_[idx];
if (ex != 0) {
argv[idx+1] = elab_sys_task_arg(des, scope,
method_name,
idx, ex);
} else {
argv[idx+1] = 0;
}
}
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) const
{
pform_name_t use_path = path_;
@ -3453,15 +3485,20 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope) const
// Is this a delete method for dynamic arrays?
if (net->darray_type() && method_name=="delete") {
NetESignal*sig = new NetESignal(net);
return elaborate_sys_task_method_(des, scope, net,
method_name,
"$ivl_darray_method$delete");
}
vector<NetExpr*> argv (1);
argv[0] = sig;
NetSTask*sys = new NetSTask("$ivl_darray_method$delete",
IVL_SFUNC_AS_TASK_IGNORE, argv);
sys->set_line(*this);
return sys;
if (net->queue_type()) {
if (method_name=="push_back")
return elaborate_sys_task_method_(des, scope, net,
method_name,
"$ivl_queue_method$push_back");
if (method_name=="push_front")
return elaborate_sys_task_method_(des, scope, net,
method_name,
"$ivl_queue_method$push_front");
}
if (const netclass_t*class_type = net->class_type()) {

View File

@ -440,6 +440,7 @@ typedef enum ivl_variable_type_e {
IVL_VT_STRING = 5,
IVL_VT_DARRAY = 6, /* Array (esp. dynamic array) */
IVL_VT_CLASS = 7, /* SystemVerilog class instances */
IVL_VT_QUEUE = 8, /* SystemVerilog queue instances */
IVL_VT_VECTOR = IVL_VT_LOGIC /* For compatibility */
} ivl_variable_type_t;

View File

@ -31,6 +31,7 @@
# include "netdarray.h"
# include "netenum.h"
# include "netparray.h"
# include "netqueue.h"
# include "netstruct.h"
# include "netvector.h"
# include "ivl_assert.h"
@ -754,6 +755,11 @@ const netdarray_t* NetNet::darray_type(void) const
return dynamic_cast<const netdarray_t*> (net_type_);
}
const netqueue_t* NetNet::queue_type(void) const
{
return dynamic_cast<const netqueue_t*> (net_type_);
}
const netclass_t* NetNet::class_type(void) const
{
return dynamic_cast<const netclass_t*> (net_type_);

View File

@ -80,6 +80,7 @@ struct enum_type_t;
class netclass_t;
class netdarray_t;
class netparray_t;
class netqueue_t;
class netenum_t;
class netstruct_t;
class netvector_t;
@ -695,6 +696,7 @@ class NetNet : public NetObj, public PortType {
const netenum_t*enumeration(void) const;
const netstruct_t*struct_type(void) const;
const netdarray_t*darray_type(void) const;
const netqueue_t*queue_type(void) const;
const netclass_t*class_type(void) const;
/* Attach a discipline to the net. */

View File

@ -31,6 +31,11 @@ netqueue_t::~netqueue_t()
{
}
ivl_variable_type_t netqueue_t::base_type() const
{
return IVL_VT_QUEUE;
}
bool netqueue_t::test_compatibility(ivl_type_t that) const
{
const netqueue_t*that_q = dynamic_cast<const netqueue_t*>(that);

View File

@ -33,6 +33,13 @@ class netqueue_t : public netdarray_t {
explicit netqueue_t(ivl_type_t vec);
~netqueue_t();
// This is the "base_type()" virtual method of the
// nettype_base_t. The ivl_target api expects this to return
// IVL_VT_QUEUE for queues.
ivl_variable_type_t base_type() const;
std::ostream& debug_dump(std::ostream&) const;
private:
bool test_compatibility(ivl_type_t that) const;
};

View File

@ -44,6 +44,11 @@ EXTERN_C_START
/********* OBJECT TYPES ***********/
#define vpiPackage 600
#define vpiArrayType 606
#define vpiStaticARray 1
#define vpiDynamicArray 2
#define vpiAssocArray 3
#define vpiQueueArray 4
#define vpiLongIntVar 610
#define vpiShortIntVar 611
#define vpiIntVar 612

View File

@ -482,7 +482,7 @@ struct ivl_lval_s {
* structural context.
*/
struct ivl_net_const_s {
ivl_variable_type_t type : 3;
ivl_variable_type_t type : 4;
unsigned width_ : 24;
unsigned signed_ : 1;
perm_string file;

View File

@ -175,6 +175,9 @@ const char*data_type_string(ivl_variable_type_t vtype)
case IVL_VT_CLASS:
vt = "class";
break;
case IVL_VT_QUEUE:
vt = "queue";
break;
}
return vt;

View File

@ -30,6 +30,15 @@ static void show_net_type_darray(ivl_type_t net_type)
show_net_type(element_type);
}
static void show_net_type_queue(ivl_type_t net_type)
{
/* Dynamic arrays have a single element type. */
ivl_type_t element_type = ivl_type_element(net_type);
fprintf(out, "queue of ");
show_net_type(element_type);
}
void show_net_type(ivl_type_t net_type)
{
ivl_variable_type_t data_type = ivl_type_base(net_type);
@ -57,6 +66,9 @@ void show_net_type(ivl_type_t net_type)
case IVL_VT_CLASS:
fprintf(out, "class");
break;
case IVL_VT_QUEUE:
show_net_type_queue(net_type);
break;
case IVL_VT_VOID:
fprintf(out, "void");
break;
@ -112,6 +124,12 @@ void show_type_of_signal(ivl_signal_t net)
fprintf(out, "ERROR-DARRAY");
stub_errors += 1;
break;
case IVL_VT_QUEUE:
/* The QUEUE type MUST be described by an
ivl_signal_net_type object. */
fprintf(out, "ERROR-QUEUE");
stub_errors += 1;
break;
case IVL_VT_VOID:
fprintf(out, "void");
break;

View File

@ -503,6 +503,11 @@ static void draw_reg_in_scope(ivl_signal_t sig)
vvp_mangle_name(ivl_signal_basename(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,
vvp_mangle_name(ivl_signal_basename(sig)),
ivl_signal_local(sig)? " Local signal" : "");
} else if (ivl_signal_data_type(sig) == IVL_VT_STRING) {
fprintf(vvp_out, "v%p_0 .var/str \"%s\";%s\n", sig,
vvp_mangle_name(ivl_signal_basename(sig)),

View File

@ -490,6 +490,7 @@ 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_cobject(char*label, char*name);
extern void compile_var_queue(char*label, char*name);
/*
* This function is used to create a scope port

View File

@ -209,6 +209,7 @@ static char* strdupnew(char const *str)
".var" { return K_VAR; }
".var/cobj" { return K_VAR_COBJECT; }
".var/darray" { return K_VAR_DARRAY; }
".var/queue" { return K_VAR_QUEUE; }
".var/real" { return K_VAR_R; }
".var/s" { return K_VAR_S; }
".var/str" { return K_VAR_STR; }

View File

@ -96,6 +96,7 @@ static struct __vpiModPath*modpath_dst = 0;
%token K_THREAD K_TIMESCALE K_TRAN K_TRANIF0 K_TRANIF1 K_TRANVP
%token K_UFUNC K_UFUNC_E K_UDP K_UDP_C K_UDP_S
%token K_VAR K_VAR_COBJECT K_VAR_DARRAY
%token K_VAR_QUEUE
%token K_VAR_S K_VAR_STR K_VAR_I K_VAR_R K_VAR_2S K_VAR_2U
%token K_vpi_call K_vpi_call_w K_vpi_call_i
%token K_vpi_func K_vpi_func_r
@ -748,6 +749,9 @@ statement
| T_LABEL K_VAR_DARRAY T_STRING ';'
{ compile_var_darray($1, $3); }
| T_LABEL K_VAR_QUEUE T_STRING ';'
{ compile_var_queue($1, $3); }
| T_LABEL K_VAR_COBJECT T_STRING ';'
{ compile_var_cobject($1, $3); }

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2014 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
@ -51,6 +51,8 @@ int __vpiDarrayVar::vpi_get(int code)
vvp_darray*aval = val.peek<vvp_darray>();
switch (code) {
case vpiArrayType:
return vpiDynamicArray;
case vpiSize:
if (aval == 0)
return 0;
@ -77,10 +79,62 @@ vpiHandle vpip_make_darray_var(const char*name, vvp_net_t*net)
return obj;
}
__vpiQueueVar::__vpiQueueVar(__vpiScope*sc, const char*na, vvp_net_t*ne)
: __vpiBaseVar(sc, na, ne)
{
}
int __vpiQueueVar::get_type_code(void) const
{ return vpiArrayVar; }
int __vpiQueueVar::vpi_get(int code)
{
vvp_fun_signal_object*fun = dynamic_cast<vvp_fun_signal_object*> (get_net()->fun);
assert(fun);
vvp_object_t val = fun->get_object();
vvp_darray*aval = val.peek<vvp_darray>();
switch (code) {
case vpiArrayType:
return vpiQueueArray;
case vpiSize:
if (aval == 0)
return 0;
else
return aval->get_size();
default:
return 0;
}
}
void __vpiQueueVar::vpi_get_value(p_vpi_value val)
{
val->format = vpiSuppressVal;
}
vpiHandle vpip_make_queue_var(const char*name, vvp_net_t*net)
{
struct __vpiScope*scope = vpip_peek_current_scope();
const char*use_name = name ? vpip_name_string(name) : 0;
class __vpiQueueVar*obj = new __vpiQueueVar(scope, use_name, net);
return obj;
}
#ifdef CHECK_WITH_VALGRIND
void darray_delete(vpiHandle item)
{
class __vpiDarrayVar*obj = dynamic_cast<__vpiDarrayVar*>(item);
delete obj;
}
void queue_delete(vpiHandle item)
{
class __vpiQueueVar*obj = dynamic_cast<__vpiQueueVar*>(item);
delete obj;
}
#endif

View File

@ -544,6 +544,18 @@ class __vpiDarrayVar : public __vpiBaseVar {
extern vpiHandle vpip_make_darray_var(const char*name, vvp_net_t*net);
class __vpiQueueVar : public __vpiBaseVar {
public:
__vpiQueueVar(__vpiScope*scope, const char*name, vvp_net_t*net);
int get_type_code(void) const;
int vpi_get(int code);
void vpi_get_value(p_vpi_value val);
};
extern vpiHandle vpip_make_queue_var(const char*name, vvp_net_t*net);
class __vpiCobjectVar : public __vpiBaseVar {
public:

View File

@ -49,6 +49,7 @@ extern void class_def_delete(class_type *item);
extern void constant_delete(class __vpiHandle *item);
extern void contexts_delete(struct __vpiScope *scope);
extern void darray_delete(class __vpiHandle *item);
extern void queue_delete(class __vpiHandle *item);
extern void enum_delete(class __vpiHandle *item);
extern void memory_delete(class __vpiHandle *item);
extern void named_event_delete(class __vpiHandle *item);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2014 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
@ -124,6 +124,29 @@ void compile_var_darray(char*label, char*name)
delete[] name;
}
void compile_var_queue(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;
net->fil = tmp;
net->fun = tmp;
} else {
net->fil = 0;
net->fun = new vvp_fun_signal_object_sa;
}
define_functor_symbol(label, net);
vpiHandle obj = vpip_make_queue_var(name, net);
compile_vpi_symbol(label, obj);
vpip_attach_to_current_scope(obj);
free(label);
delete[] name;
}
void compile_var_cobject(char*label, char*name)
{
vvp_net_t*net = new vvp_net_t;