Support declaring queue variables all the way to vvp.
Nothing actually useful happens here, but the declarations are functional.
This commit is contained in:
parent
6d052d4ff7
commit
e8b8fcba57
|
|
@ -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_;
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
|
|
|
|||
53
elaborate.cc
53
elaborate.cc
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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_);
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
2
t-dll.h
2
t-dll.h
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
25
vvp/words.cc
25
vvp/words.cc
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue