vvp code generation for push_back/push_front for queue objects.
This commit is contained in:
parent
e8b8fcba57
commit
d891285326
|
|
@ -1820,6 +1820,54 @@ static int show_delete_method(ivl_statement_t net)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int show_push_frontback_method(ivl_statement_t net)
|
||||
{
|
||||
const char*stmt_name = ivl_stmt_name(net);
|
||||
|
||||
show_stmt_file_line(net, "queue: push_back");
|
||||
|
||||
const char*type_code = "?";
|
||||
if (strcmp(stmt_name,"$ivl_queue_method$push_front") == 0)
|
||||
type_code = "qf";
|
||||
else if (strcmp(stmt_name,"$ivl_queue_method$push_back") == 0)
|
||||
type_code = "qb";
|
||||
else
|
||||
type_code = "??";
|
||||
|
||||
unsigned parm_count = ivl_stmt_parm_count(net);
|
||||
if (parm_count != 2)
|
||||
return 1;
|
||||
|
||||
ivl_expr_t parm0 = ivl_stmt_parm(net,0);
|
||||
assert(ivl_expr_type(parm0) == IVL_EX_SIGNAL);
|
||||
ivl_signal_t var = ivl_expr_signal(parm0);
|
||||
ivl_type_t var_type = ivl_signal_net_type(var);
|
||||
assert(ivl_type_base(var_type)== IVL_VT_QUEUE);
|
||||
|
||||
ivl_type_t element_type = ivl_type_element(var_type);
|
||||
|
||||
ivl_expr_t parm1 = ivl_stmt_parm(net,1);
|
||||
struct vector_info vec;
|
||||
switch (ivl_type_base(element_type)) {
|
||||
case IVL_VT_REAL:
|
||||
draw_eval_real(parm1);
|
||||
fprintf(vvp_out, " %%store/%s/r v%p_0;\n", type_code, var);
|
||||
break;
|
||||
case IVL_VT_STRING:
|
||||
draw_eval_string(parm1);
|
||||
fprintf(vvp_out, " %%store/%s/str v%p_0;\n", type_code, var);
|
||||
break;
|
||||
default:
|
||||
vec = draw_eval_expr(parm1, STUFF_OK_RO);
|
||||
fprintf(vvp_out, " %%set/%s v%p_0, %u, %u;\n",
|
||||
type_code, var, vec.base, vec.wid);
|
||||
if (vec.base >= 4) clr_vector(vec);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int show_system_task_call(ivl_statement_t net)
|
||||
{
|
||||
const char*stmt_name = ivl_stmt_name(net);
|
||||
|
|
@ -1827,6 +1875,12 @@ static int show_system_task_call(ivl_statement_t net)
|
|||
if (strcmp(stmt_name,"$ivl_darray_method$delete") == 0)
|
||||
return show_delete_method(net);
|
||||
|
||||
if (strcmp(stmt_name,"$ivl_queue_method$push_front") == 0)
|
||||
return show_push_frontback_method(net);
|
||||
|
||||
if (strcmp(stmt_name,"$ivl_queue_method$push_back") == 0)
|
||||
return show_push_frontback_method(net);
|
||||
|
||||
show_stmt_file_line(net, "System task call.");
|
||||
|
||||
draw_vpi_task_call(net);
|
||||
|
|
|
|||
|
|
@ -181,6 +181,8 @@ extern bool of_RELEASE_WR(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_SCOPY(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_AV(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_DAR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_QB(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_QF(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_DAR_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_DAR_OBJ_REAL(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_DAR_OBJ_STR(vthread_t thr, vvp_code_t code);
|
||||
|
|
@ -192,6 +194,10 @@ extern bool of_SHIFTR_I0(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_SHIFTR_S_I0(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_DAR_R(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_DAR_STR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_QB_R(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_QB_STR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_QF_R(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_QF_STR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_PROP_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_PROP_R(vthread_t thr, vvp_code_t code);
|
||||
|
|
|
|||
|
|
@ -232,6 +232,8 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%set/dar/obj", of_SET_DAR_OBJ, 3,{OA_NUMBER,OA_BIT1,OA_BIT2} },
|
||||
{ "%set/dar/obj/real",of_SET_DAR_OBJ_REAL,1,{OA_NUMBER,OA_NONE,OA_NONE} },
|
||||
{ "%set/dar/obj/str", of_SET_DAR_OBJ_STR, 1,{OA_NUMBER,OA_NONE,OA_NONE} },
|
||||
{ "%set/qb", of_SET_QB, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
||||
{ "%set/qf", of_SET_QF, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
||||
{ "%set/v", of_SET_VEC,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
||||
{ "%set/x0", of_SET_X0, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
||||
{ "%shiftl/i0", of_SHIFTL_I0, 2, {OA_BIT1,OA_NUMBER, OA_NONE} },
|
||||
|
|
@ -239,6 +241,10 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%shiftr/s/i0", of_SHIFTR_S_I0,2,{OA_BIT1,OA_NUMBER, OA_NONE} },
|
||||
{ "%store/dar/r", of_STORE_DAR_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%store/dar/str",of_STORE_DAR_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%store/qb/r", of_STORE_QB_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%store/qb/str", of_STORE_QB_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%store/qf/r", of_STORE_QF_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%store/qf/str", of_STORE_QF_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%store/obj", of_STORE_OBJ, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} },
|
||||
{ "%store/prop/obj",of_STORE_PROP_OBJ,1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%store/prop/r", of_STORE_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
|
|
|
|||
|
|
@ -997,6 +997,12 @@ width is implied from the <wid> that is the argument. This is the part
|
|||
The address (in canonical form) is precalculated and loaded into index
|
||||
register 3. This is the address of the word within the array.
|
||||
|
||||
* %set/qb <var-label>, <bit>, <wid>
|
||||
* %set/qf <var-label>, <bit>, <wid>
|
||||
|
||||
This sets the vector value into the back (qb) or front (qf) of a queue
|
||||
variable.
|
||||
|
||||
* %set/x0 <var-label>, <bit>, <wid>
|
||||
|
||||
This sets the part of a signal vector, the address calculated by
|
||||
|
|
@ -1068,6 +1074,10 @@ index in the index register <index>
|
|||
* %store/stra <array-label>, <index>
|
||||
* %store/dar/r <var-label>
|
||||
* %store/dar/str <var-label>
|
||||
* %store/qf/r <var-label>
|
||||
* %store/qf/str <var-label>
|
||||
* %store/qb/r <var-label>
|
||||
* %store/qb/str <var-label>
|
||||
|
||||
The %store/str instruction pops the top of the string stack and writes
|
||||
it to the string variable.
|
||||
|
|
@ -1077,6 +1087,11 @@ The %store/stra targets an array.
|
|||
The %store/dar/str is similar, but the target is a dynamic array of
|
||||
string string. The index is taken from signed index register 3.
|
||||
|
||||
The %store/qf/* and %store/qb/* instructions are queue manipulations,
|
||||
which implement the push_back (qb) and push_front (qf)
|
||||
functions. These only apply to queue object, and are distinct from the
|
||||
dar versions because the begin/front don't exist, by definition.
|
||||
|
||||
* %sub <bit-l>, <bit-r>, <wid>
|
||||
|
||||
This instruction arithmetically subtracts the right vector out of the
|
||||
|
|
|
|||
112
vvp/vthread.cc
112
vvp/vthread.cc
|
|
@ -5012,6 +5012,64 @@ bool of_SET_DAR_OBJ_STR(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %set/qb <var-label> <bit>, <wid>
|
||||
*/
|
||||
bool of_SET_QB(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned bit = cp->bit_idx[0];
|
||||
unsigned wid = cp->bit_idx[1];
|
||||
|
||||
/* Make a vector of the desired width. */
|
||||
vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid);
|
||||
|
||||
vvp_net_t*net = cp->net;
|
||||
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
|
||||
assert(obj);
|
||||
|
||||
vvp_queue*dqueue = obj->get_object().peek<vvp_queue>();
|
||||
if (dqueue == 0) {
|
||||
assert(obj->get_object().test_nil());
|
||||
dqueue = new vvp_queue_vec4;
|
||||
vvp_object_t val (dqueue);
|
||||
vvp_net_ptr_t ptr (cp->net, 0);
|
||||
vvp_send_object(ptr, val, thr->wt_context);
|
||||
}
|
||||
|
||||
assert(dqueue);
|
||||
dqueue->push_back(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %set/qf <var-label> <bit>, <wid>
|
||||
*/
|
||||
bool of_SET_QF(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned bit = cp->bit_idx[0];
|
||||
unsigned wid = cp->bit_idx[1];
|
||||
|
||||
/* Make a vector of the desired width. */
|
||||
vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid);
|
||||
|
||||
vvp_net_t*net = cp->net;
|
||||
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
|
||||
assert(obj);
|
||||
|
||||
vvp_queue*dqueue = obj->get_object().peek<vvp_queue>();
|
||||
if (dqueue == 0) {
|
||||
assert(obj->get_object().test_nil());
|
||||
dqueue = new vvp_queue_vec4;
|
||||
vvp_object_t val (dqueue);
|
||||
vvp_net_ptr_t ptr (cp->net, 0);
|
||||
vvp_send_object(ptr, val, thr->wt_context);
|
||||
}
|
||||
|
||||
assert(dqueue);
|
||||
dqueue->push_front(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This implements the "%set/v <label>, <bit>, <wid>" instruction.
|
||||
*
|
||||
|
|
@ -5379,6 +5437,60 @@ bool of_STORE_PROP_V(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %store/qb/r <var-label>
|
||||
*/
|
||||
bool of_STORE_QB_R(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
fprintf(stderr, "XXXX %%store/qb/r NOT IMPLEMENTED\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %store/qb/str <var-label>
|
||||
*/
|
||||
bool of_STORE_QB_STR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
// Pop the string to be stored...
|
||||
string value = thr->pop_str();
|
||||
|
||||
vvp_net_t*net = cp->net;
|
||||
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
|
||||
assert(obj);
|
||||
|
||||
vvp_queue*dqueue = obj->get_object().peek<vvp_queue>();
|
||||
if (dqueue == 0) {
|
||||
assert(obj->get_object().test_nil());
|
||||
dqueue = new vvp_queue_string;
|
||||
vvp_object_t val (dqueue);
|
||||
vvp_net_ptr_t ptr (cp->net, 0);
|
||||
vvp_send_object(ptr, val, thr->wt_context);
|
||||
|
||||
}
|
||||
|
||||
assert(dqueue);
|
||||
dqueue->push_back(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %store/qf/r <var-label>
|
||||
*/
|
||||
bool of_STORE_QF_R(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
fprintf(stderr, "XXXX %%store/qf/r NOT IMPLEMENTED\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %store/qf/str <var-label>
|
||||
*/
|
||||
bool of_STORE_QF_STR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
fprintf(stderr, "XXXX %%store/qf/str NOT IMPLEMENTED\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_STORE_REAL(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
double val = thr->pop_real();
|
||||
|
|
|
|||
|
|
@ -137,3 +137,60 @@ void vvp_darray_string::get_word(unsigned adr, string&value)
|
|||
|
||||
value = array_[adr];
|
||||
}
|
||||
|
||||
vvp_queue::~vvp_queue()
|
||||
{
|
||||
}
|
||||
|
||||
void vvp_queue::push_back(const vvp_vector4_t&)
|
||||
{
|
||||
cerr << "XXXX push_back(vvp_vector4_t) not implemented for " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
void vvp_queue::push_front(const vvp_vector4_t&)
|
||||
{
|
||||
cerr << "XXXX push_front(vvp_vector4_t) not implemented for " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
void vvp_queue::push_back(double)
|
||||
{
|
||||
cerr << "XXXX push_back(double) not implemented for " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
void vvp_queue::push_front(double)
|
||||
{
|
||||
cerr << "XXXX push_front(double) not implemented for " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
void vvp_queue::push_back(const string&)
|
||||
{
|
||||
cerr << "XXXX push_back(string) not implemented for " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
void vvp_queue::push_front(const string&)
|
||||
{
|
||||
cerr << "XXXX push_front(string) not implemented for " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
vvp_queue_string::~vvp_queue_string()
|
||||
{
|
||||
}
|
||||
|
||||
void vvp_queue_string::push_back(const string&val)
|
||||
{
|
||||
array_.push_back(val);
|
||||
}
|
||||
|
||||
vvp_queue_vec4::~vvp_queue_vec4()
|
||||
{
|
||||
}
|
||||
|
||||
void vvp_queue_vec4::push_back(const vvp_vector4_t&val)
|
||||
{
|
||||
array_.push_back(val);
|
||||
}
|
||||
|
||||
void vvp_queue_vec4::push_front(const vvp_vector4_t&val)
|
||||
{
|
||||
array_.push_front(val);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
# include "vvp_object.h"
|
||||
# include <list>
|
||||
# include <string>
|
||||
# include <vector>
|
||||
|
||||
|
|
@ -86,4 +87,47 @@ class vvp_darray_string : public vvp_darray {
|
|||
};
|
||||
|
||||
|
||||
class vvp_queue : public vvp_darray {
|
||||
|
||||
public:
|
||||
inline vvp_queue(void) : vvp_darray(0) { }
|
||||
~vvp_queue();
|
||||
|
||||
virtual void push_back(const vvp_vector4_t&value);
|
||||
virtual void push_front(const vvp_vector4_t&value);
|
||||
|
||||
virtual void push_back(double value);
|
||||
virtual void push_front(double value);
|
||||
|
||||
virtual void push_back(const std::string&value);
|
||||
virtual void push_front(const std::string&value);
|
||||
};
|
||||
|
||||
class vvp_queue_vec4 : public vvp_queue {
|
||||
|
||||
public:
|
||||
~vvp_queue_vec4();
|
||||
|
||||
void push_back(const vvp_vector4_t&value);
|
||||
void push_front(const vvp_vector4_t&value);
|
||||
|
||||
private:
|
||||
std::list<vvp_vector4_t> array_;
|
||||
};
|
||||
|
||||
|
||||
class vvp_queue_string : public vvp_queue {
|
||||
|
||||
public:
|
||||
~vvp_queue_string();
|
||||
|
||||
//void set_word(unsigned adr, const std::string&value);
|
||||
//void get_word(unsigned adr, std::string&value);
|
||||
void push_back(const std::string&value);
|
||||
//void push_front(const std::string&value);
|
||||
|
||||
private:
|
||||
std::list<std::string> array_;
|
||||
};
|
||||
|
||||
#endif /* IVL_vvp_darray_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue