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, NetProc*elaborate_build_call_(Design*des, NetScope*scope,
NetScope*task, NetExpr*use_this) const; 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; bool test_task_calls_ok_(Design*des, NetScope*scope) const;
PPackage*package_; PPackage*package_;

View File

@ -30,6 +30,7 @@
# include "discipline.h" # include "discipline.h"
# include "netclass.h" # include "netclass.h"
# include "netdarray.h" # include "netdarray.h"
# include "netqueue.h"
# include "netvector.h" # include "netvector.h"
# include "ivl_assert.h" # include "ivl_assert.h"
# include "PExpr.h" # include "PExpr.h"
@ -113,6 +114,9 @@ ostream& operator << (ostream&o, ivl_variable_type_t val)
case IVL_VT_CLASS: case IVL_VT_CLASS:
o << "class"; o << "class";
break; break;
case IVL_VT_QUEUE:
o << "queue";
break;
} }
return o; return o;
} }
@ -205,6 +209,12 @@ ostream& netdarray_t::debug_dump(ostream&o) const
return o; 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 ostream& netvector_t::debug_dump(ostream&o) const
{ {
o << type_ << (signed_? " signed" : " unsigned") << packed_dims_; 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); 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 NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope) const
{ {
pform_name_t use_path = path_; 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? // Is this a delete method for dynamic arrays?
if (net->darray_type() && method_name=="delete") { 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); if (net->queue_type()) {
argv[0] = sig; if (method_name=="push_back")
return elaborate_sys_task_method_(des, scope, net,
NetSTask*sys = new NetSTask("$ivl_darray_method$delete", method_name,
IVL_SFUNC_AS_TASK_IGNORE, argv); "$ivl_queue_method$push_back");
sys->set_line(*this); if (method_name=="push_front")
return sys; return elaborate_sys_task_method_(des, scope, net,
method_name,
"$ivl_queue_method$push_front");
} }
if (const netclass_t*class_type = net->class_type()) { 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_STRING = 5,
IVL_VT_DARRAY = 6, /* Array (esp. dynamic array) */ IVL_VT_DARRAY = 6, /* Array (esp. dynamic array) */
IVL_VT_CLASS = 7, /* SystemVerilog class instances */ IVL_VT_CLASS = 7, /* SystemVerilog class instances */
IVL_VT_QUEUE = 8, /* SystemVerilog queue instances */
IVL_VT_VECTOR = IVL_VT_LOGIC /* For compatibility */ IVL_VT_VECTOR = IVL_VT_LOGIC /* For compatibility */
} ivl_variable_type_t; } ivl_variable_type_t;

View File

@ -31,6 +31,7 @@
# include "netdarray.h" # include "netdarray.h"
# include "netenum.h" # include "netenum.h"
# include "netparray.h" # include "netparray.h"
# include "netqueue.h"
# include "netstruct.h" # include "netstruct.h"
# include "netvector.h" # include "netvector.h"
# include "ivl_assert.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_); 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 const netclass_t* NetNet::class_type(void) const
{ {
return dynamic_cast<const netclass_t*> (net_type_); return dynamic_cast<const netclass_t*> (net_type_);

View File

@ -80,6 +80,7 @@ struct enum_type_t;
class netclass_t; class netclass_t;
class netdarray_t; class netdarray_t;
class netparray_t; class netparray_t;
class netqueue_t;
class netenum_t; class netenum_t;
class netstruct_t; class netstruct_t;
class netvector_t; class netvector_t;
@ -695,6 +696,7 @@ class NetNet : public NetObj, public PortType {
const netenum_t*enumeration(void) const; const netenum_t*enumeration(void) const;
const netstruct_t*struct_type(void) const; const netstruct_t*struct_type(void) const;
const netdarray_t*darray_type(void) const; const netdarray_t*darray_type(void) const;
const netqueue_t*queue_type(void) const;
const netclass_t*class_type(void) const; const netclass_t*class_type(void) const;
/* Attach a discipline to the net. */ /* 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 bool netqueue_t::test_compatibility(ivl_type_t that) const
{ {
const netqueue_t*that_q = dynamic_cast<const netqueue_t*>(that); 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); explicit netqueue_t(ivl_type_t vec);
~netqueue_t(); ~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: private:
bool test_compatibility(ivl_type_t that) const; bool test_compatibility(ivl_type_t that) const;
}; };

View File

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

View File

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

View File

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

View File

@ -30,6 +30,15 @@ static void show_net_type_darray(ivl_type_t net_type)
show_net_type(element_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) void show_net_type(ivl_type_t net_type)
{ {
ivl_variable_type_t data_type = ivl_type_base(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: case IVL_VT_CLASS:
fprintf(out, "class"); fprintf(out, "class");
break; break;
case IVL_VT_QUEUE:
show_net_type_queue(net_type);
break;
case IVL_VT_VOID: case IVL_VT_VOID:
fprintf(out, "void"); fprintf(out, "void");
break; break;
@ -112,6 +124,12 @@ void show_type_of_signal(ivl_signal_t net)
fprintf(out, "ERROR-DARRAY"); fprintf(out, "ERROR-DARRAY");
stub_errors += 1; stub_errors += 1;
break; 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: case IVL_VT_VOID:
fprintf(out, "void"); fprintf(out, "void");
break; break;

View File

@ -503,6 +503,11 @@ static void draw_reg_in_scope(ivl_signal_t sig)
vvp_mangle_name(ivl_signal_basename(sig)), vvp_mangle_name(ivl_signal_basename(sig)),
ivl_signal_local(sig)? " Local signal" : ""); 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) { } else if (ivl_signal_data_type(sig) == IVL_VT_STRING) {
fprintf(vvp_out, "v%p_0 .var/str \"%s\";%s\n", sig, fprintf(vvp_out, "v%p_0 .var/str \"%s\";%s\n", sig,
vvp_mangle_name(ivl_signal_basename(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_string(char*label, char*name);
extern void compile_var_darray(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_cobject(char*label, char*name);
extern void compile_var_queue(char*label, char*name);
/* /*
* This function is used to create a scope port * 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" { return K_VAR; }
".var/cobj" { return K_VAR_COBJECT; } ".var/cobj" { return K_VAR_COBJECT; }
".var/darray" { return K_VAR_DARRAY; } ".var/darray" { return K_VAR_DARRAY; }
".var/queue" { return K_VAR_QUEUE; }
".var/real" { return K_VAR_R; } ".var/real" { return K_VAR_R; }
".var/s" { return K_VAR_S; } ".var/s" { return K_VAR_S; }
".var/str" { return K_VAR_STR; } ".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_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_UFUNC K_UFUNC_E K_UDP K_UDP_C K_UDP_S
%token K_VAR K_VAR_COBJECT K_VAR_DARRAY %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_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_call K_vpi_call_w K_vpi_call_i
%token K_vpi_func K_vpi_func_r %token K_vpi_func K_vpi_func_r
@ -748,6 +749,9 @@ statement
| T_LABEL K_VAR_DARRAY T_STRING ';' | T_LABEL K_VAR_DARRAY T_STRING ';'
{ compile_var_darray($1, $3); } { compile_var_darray($1, $3); }
| T_LABEL K_VAR_QUEUE T_STRING ';'
{ compile_var_queue($1, $3); }
| 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

@ -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 * 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
@ -51,6 +51,8 @@ int __vpiDarrayVar::vpi_get(int code)
vvp_darray*aval = val.peek<vvp_darray>(); vvp_darray*aval = val.peek<vvp_darray>();
switch (code) { switch (code) {
case vpiArrayType:
return vpiDynamicArray;
case vpiSize: case vpiSize:
if (aval == 0) if (aval == 0)
return 0; return 0;
@ -77,10 +79,62 @@ vpiHandle vpip_make_darray_var(const char*name, vvp_net_t*net)
return obj; 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 #ifdef CHECK_WITH_VALGRIND
void darray_delete(vpiHandle item) void darray_delete(vpiHandle item)
{ {
class __vpiDarrayVar*obj = dynamic_cast<__vpiDarrayVar*>(item); class __vpiDarrayVar*obj = dynamic_cast<__vpiDarrayVar*>(item);
delete obj; delete obj;
} }
void queue_delete(vpiHandle item)
{
class __vpiQueueVar*obj = dynamic_cast<__vpiQueueVar*>(item);
delete obj;
}
#endif #endif

View File

@ -544,6 +544,18 @@ class __vpiDarrayVar : public __vpiBaseVar {
extern vpiHandle vpip_make_darray_var(const char*name, vvp_net_t*net); 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 { class __vpiCobjectVar : public __vpiBaseVar {
public: public:

View File

@ -49,6 +49,7 @@ extern void class_def_delete(class_type *item);
extern void constant_delete(class __vpiHandle *item); extern void constant_delete(class __vpiHandle *item);
extern void contexts_delete(struct __vpiScope *scope); extern void contexts_delete(struct __vpiScope *scope);
extern void darray_delete(class __vpiHandle *item); extern void darray_delete(class __vpiHandle *item);
extern void queue_delete(class __vpiHandle *item);
extern void enum_delete(class __vpiHandle *item); extern void enum_delete(class __vpiHandle *item);
extern void memory_delete(class __vpiHandle *item); extern void memory_delete(class __vpiHandle *item);
extern void named_event_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 * 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
@ -124,6 +124,29 @@ void compile_var_darray(char*label, char*name)
delete[] 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) void compile_var_cobject(char*label, char*name)
{ {
vvp_net_t*net = new vvp_net_t; vvp_net_t*net = new vvp_net_t;