Add the %event instruction, remove %ix/get and %ix/get/s.

This commit is contained in:
Stephen Williams 2014-01-05 12:39:52 -08:00
parent 2fc8ce8a16
commit 063c6d6065
7 changed files with 27 additions and 94 deletions

View File

@ -46,17 +46,14 @@
static int eval_bool64_logic(ivl_expr_t expr)
{
int res;
struct vector_info tmp;
const char*s_flag = "";
tmp = draw_eval_expr(expr, STUFF_OK_XZ);
draw_eval_vec4(expr, STUFF_OK_XZ);
res = allocate_word();
if (ivl_expr_signed(expr))
s_flag = "/s";
fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n", s_flag, res,
tmp.base, tmp.wid);
clr_vector(tmp);
fprintf(vvp_out, " %%ix/vec4%s %d;\n", s_flag, res);
return res;
}

View File

@ -245,16 +245,14 @@ static void draw_realnum_real(ivl_expr_t expr)
*/
static void draw_real_logic_expr(ivl_expr_t expr, int stuff_ok_flag)
{
struct vector_info sv = draw_eval_expr(expr, stuff_ok_flag);
draw_eval_vec4(expr, stuff_ok_flag);
const char*sign_flag = ivl_expr_signed(expr)? "/s" : "";
if (sv.wid > 64) {
fprintf(vvp_out, " %%cvt/rv%s %u, %u;\n",
sign_flag, sv.base, sv.wid);
if (ivl_expr_width(expr) > 64) {
fprintf(vvp_out, " %%cvt/rv%s;\n", sign_flag);
} else {
int res = allocate_word();
fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n",
sign_flag, res, sv.base, sv.wid);
fprintf(vvp_out, " %%ix/vec4%s %d;\n", sign_flag, res);
if (ivl_expr_signed(expr))
fprintf(vvp_out, " %%cvt/rs %d;\n", res);
@ -262,8 +260,6 @@ static void draw_real_logic_expr(ivl_expr_t expr, int stuff_ok_flag)
fprintf(vvp_out, " %%cvt/ru %d;\n", res);
clr_word(res);
}
clr_vector(sv);
}
static void draw_select_real(ivl_expr_t expr)
@ -547,15 +543,12 @@ void draw_eval_real(ivl_expr_t expr)
default:
if (ivl_expr_value(expr) == IVL_VT_VECTOR) {
struct vector_info sv = draw_eval_expr(expr, 0);
draw_eval_vec4(expr, 0);
const char*sign_flag = ivl_expr_signed(expr)? "/s" : "";
clr_vector(sv);
int res = allocate_word();
fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n",
sign_flag, res, sv.base, sv.wid);
fprintf(vvp_out, " %%ix/vec4%s %d;\n", sign_flag, res);
fprintf(vvp_out, " %%cvt/rs %d;\n", res);
clr_word(res);

View File

@ -1687,7 +1687,7 @@ static int show_stmt_trigger(ivl_statement_t net)
show_stmt_file_line(net, "Event trigger statement.");
fprintf(vvp_out, " %%set/v E_%p, 0,1;\n", ev);
fprintf(vvp_out, " %%event E_%p;\n", ev);
return 0;
}

View File

@ -101,6 +101,7 @@ extern bool of_DIV_WR(vthread_t thr, vvp_code_t code);
extern bool of_DUP_REAL(vthread_t thr, vvp_code_t code);
extern bool of_DUP_VEC4(vthread_t thr, vvp_code_t code);
extern bool of_END(vthread_t thr, vvp_code_t code);
extern bool of_EVENT(vthread_t thr, vvp_code_t code);
extern bool of_EVCTL(vthread_t thr, vvp_code_t code);
extern bool of_EVCTLC(vthread_t thr, vvp_code_t code);
extern bool of_EVCTLI(vthread_t thr, vvp_code_t code);
@ -117,10 +118,8 @@ extern bool of_FORK(vthread_t thr, vvp_code_t code);
extern bool of_FREE(vthread_t thr, vvp_code_t code);
extern bool of_INV(vthread_t thr, vvp_code_t code);
extern bool of_IX_ADD(vthread_t thr, vvp_code_t code);
extern bool of_IX_GET(vthread_t thr, vvp_code_t code);
extern bool of_IX_GETV(vthread_t thr, vvp_code_t code);
extern bool of_IX_GETV_S(vthread_t thr, vvp_code_t code);
extern bool of_IX_GET_S(vthread_t thr, vvp_code_t code);
extern bool of_IX_LOAD(vthread_t thr, vvp_code_t code);
extern bool of_IX_MOV(vthread_t thr, vvp_code_t code);
extern bool of_IX_MUL(vthread_t thr, vvp_code_t code);

View File

@ -152,6 +152,7 @@ static const struct opcode_table_s opcode_table[] = {
{ "%dup/vec4", of_DUP_VEC4,0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%end", of_END, 0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%evctl", of_EVCTL, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
{ "%event", of_EVENT, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
{ "%evctl/c",of_EVCTLC, 0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%evctl/i",of_EVCTLI, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
{ "%evctl/s",of_EVCTLS, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
@ -165,8 +166,6 @@ static const struct opcode_table_s opcode_table[] = {
{ "%free", of_FREE, 1, {OA_VPI_PTR, OA_NONE, OA_NONE} },
{ "%inv", of_INV, 0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%ix/add", of_IX_ADD, 3, {OA_NUMBER, OA_BIT1, OA_BIT2} },
{ "%ix/get", of_IX_GET, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%ix/get/s",of_IX_GET_S,3,{OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%ix/getv",of_IX_GETV,2, {OA_BIT1, OA_FUNC_PTR, OA_NONE} },
{ "%ix/getv/s",of_IX_GETV_S,2, {OA_BIT1, OA_FUNC_PTR, OA_NONE} },
{ "%ix/load",of_IX_LOAD,3, {OA_NUMBER, OA_BIT1, OA_BIT2} },

View File

@ -520,6 +520,11 @@ event control information and the other %evctl statements assert
that this information has been cleared. You can get an assert if
this information is not managed correctly.
* %event <functor-label>
This instruction is used to send a pulse to an event object. The
<functor-label> is an event variable. This instruction simply writes
an arbitrary value to the event to trigger the event.
* %file_line <file> <line> <description>

View File

@ -2898,6 +2898,17 @@ bool of_END(vthread_t thr, vvp_code_t)
return false;
}
/*
* %event <var-label>
*/
bool of_EVENT(vthread_t thr, vvp_code_t cp)
{
vvp_net_ptr_t ptr (cp->net, 0);
vvp_vector4_t tmp (1, BIT4_X);
vvp_send_vec4(ptr, tmp, 0);
return true;
}
bool of_EVCTL(vthread_t thr, vvp_code_t cp)
{
assert(thr->event == 0 && thr->ecount == 0);
@ -3177,77 +3188,6 @@ bool of_IX_MOV(vthread_t thr, vvp_code_t cp)
return true;
}
/*
* Load a vector into an index register. The format of the
* opcode is:
*
* %ix/get <ix>, <base>, <wid>
*
* where <ix> is the index register, <base> is the base of the
* vector and <wid> is the width in bits.
*
* Index registers only hold binary values, so if any of the
* bits of the vector are x or z, then set the value to 0,
* set bit[4] to 1, and give up.
*/
static uint64_t vector_to_index(vthread_t thr, unsigned base,
unsigned width, bool signed_flag)
{
uint64_t v = 0;
bool unknown_flag = false;
#if 0
vvp_bit4_t vv = BIT4_0;
for (unsigned i = 0 ; i < width ; i += 1) {
vv = thr_get_bit(thr, base);
if (bit4_is_xz(vv)) {
v = 0UL;
unknown_flag = true;
break;
}
v |= (uint64_t) vv << i;
if (base >= 4)
base += 1;
}
/* Extend to fill the integer value. */
if (signed_flag && !unknown_flag) {
uint64_t pad = vv;
for (unsigned i = width ; i < 8*sizeof(v) ; i += 1) {
v |= pad << i;
}
}
#else
fprintf(stderr, "XXXX NOT IMPLEMENTED: vector_to_index(...)\n");
#endif
/* Set bit 4 as a flag if the input is unknown. */
thr->flags[4] = unknown_flag? BIT4_1 : BIT4_0;
return v;
}
bool of_IX_GET(vthread_t thr, vvp_code_t cp)
{
unsigned index = cp->bit_idx[0];
unsigned base = cp->bit_idx[1];
unsigned width = cp->number;
thr->words[index].w_uint = vector_to_index(thr, base, width, false);
return true;
}
bool of_IX_GET_S(vthread_t thr, vvp_code_t cp)
{
unsigned index = cp->bit_idx[0];
unsigned base = cp->bit_idx[1];
unsigned width = cp->number;
thr->words[index].w_int = vector_to_index(thr, base, width, true);
return true;
}
bool of_IX_GETV(vthread_t thr, vvp_code_t cp)
{
unsigned index = cp->bit_idx[0];