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) static int eval_bool64_logic(ivl_expr_t expr)
{ {
int res; int res;
struct vector_info tmp;
const char*s_flag = ""; const char*s_flag = "";
tmp = draw_eval_expr(expr, STUFF_OK_XZ); draw_eval_vec4(expr, STUFF_OK_XZ);
res = allocate_word(); res = allocate_word();
if (ivl_expr_signed(expr)) if (ivl_expr_signed(expr))
s_flag = "/s"; s_flag = "/s";
fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n", s_flag, res, fprintf(vvp_out, " %%ix/vec4%s %d;\n", s_flag, res);
tmp.base, tmp.wid);
clr_vector(tmp);
return 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) 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" : ""; const char*sign_flag = ivl_expr_signed(expr)? "/s" : "";
if (sv.wid > 64) { if (ivl_expr_width(expr) > 64) {
fprintf(vvp_out, " %%cvt/rv%s %u, %u;\n", fprintf(vvp_out, " %%cvt/rv%s;\n", sign_flag);
sign_flag, sv.base, sv.wid);
} else { } else {
int res = allocate_word(); int res = allocate_word();
fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n", fprintf(vvp_out, " %%ix/vec4%s %d;\n", sign_flag, res);
sign_flag, res, sv.base, sv.wid);
if (ivl_expr_signed(expr)) if (ivl_expr_signed(expr))
fprintf(vvp_out, " %%cvt/rs %d;\n", res); 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); fprintf(vvp_out, " %%cvt/ru %d;\n", res);
clr_word(res); clr_word(res);
} }
clr_vector(sv);
} }
static void draw_select_real(ivl_expr_t expr) static void draw_select_real(ivl_expr_t expr)
@ -547,15 +543,12 @@ void draw_eval_real(ivl_expr_t expr)
default: default:
if (ivl_expr_value(expr) == IVL_VT_VECTOR) { 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" : ""; const char*sign_flag = ivl_expr_signed(expr)? "/s" : "";
clr_vector(sv);
int res = allocate_word(); int res = allocate_word();
fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n", fprintf(vvp_out, " %%ix/vec4%s %d;\n", sign_flag, res);
sign_flag, res, sv.base, sv.wid);
fprintf(vvp_out, " %%cvt/rs %d;\n", res); fprintf(vvp_out, " %%cvt/rs %d;\n", res);
clr_word(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."); 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; 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_REAL(vthread_t thr, vvp_code_t code);
extern bool of_DUP_VEC4(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_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_EVCTL(vthread_t thr, vvp_code_t code);
extern bool of_EVCTLC(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); 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_FREE(vthread_t thr, vvp_code_t code);
extern bool of_INV(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_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(vthread_t thr, vvp_code_t code);
extern bool of_IX_GETV_S(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_LOAD(vthread_t thr, vvp_code_t code);
extern bool of_IX_MOV(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); 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} }, { "%dup/vec4", of_DUP_VEC4,0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%end", of_END, 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} }, { "%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/c",of_EVCTLC, 0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%evctl/i",of_EVCTLI, 2, {OA_FUNC_PTR, OA_BIT1, 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} }, { "%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} }, { "%free", of_FREE, 1, {OA_VPI_PTR, OA_NONE, OA_NONE} },
{ "%inv", of_INV, 0, {OA_NONE, 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/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",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/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} }, { "%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 that this information has been cleared. You can get an assert if
this information is not managed correctly. 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> * %file_line <file> <line> <description>

View File

@ -2898,6 +2898,17 @@ bool of_END(vthread_t thr, vvp_code_t)
return false; 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) bool of_EVCTL(vthread_t thr, vvp_code_t cp)
{ {
assert(thr->event == 0 && thr->ecount == 0); assert(thr->event == 0 && thr->ecount == 0);
@ -3177,77 +3188,6 @@ bool of_IX_MOV(vthread_t thr, vvp_code_t cp)
return true; 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) bool of_IX_GETV(vthread_t thr, vvp_code_t cp)
{ {
unsigned index = cp->bit_idx[0]; unsigned index = cp->bit_idx[0];