vvp code generation for push_back/push_front for queue objects.

This commit is contained in:
Stephen Williams 2014-08-04 20:11:21 -07:00
parent e8b8fcba57
commit d891285326
7 changed files with 294 additions and 0 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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} },

View File

@ -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

View File

@ -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();

View File

@ -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);
}

View File

@ -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 */