Add `ivl_type_packed_width()` API
The C++ API for `ivl_type_t` has a method to query the total width of a packed type. This is currently not exported to the C API and the tgt-vvp backend implements similar functionality by querying the individual dimensions of a type. Export the `packed_width()` method to the C API. This allows to remove the custom implementation from the tgt-vvp backend. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
3b711ed785
commit
f831d7d76f
1
ivl.def
1
ivl.def
|
|
@ -328,6 +328,7 @@ ivl_type_name
|
||||||
ivl_type_packed_dimensions
|
ivl_type_packed_dimensions
|
||||||
ivl_type_packed_lsb
|
ivl_type_packed_lsb
|
||||||
ivl_type_packed_msb
|
ivl_type_packed_msb
|
||||||
|
ivl_type_packed_width
|
||||||
ivl_type_prop_name
|
ivl_type_prop_name
|
||||||
ivl_type_prop_type
|
ivl_type_prop_type
|
||||||
ivl_type_properties
|
ivl_type_properties
|
||||||
|
|
|
||||||
|
|
@ -2348,6 +2348,9 @@ extern unsigned ivl_switch_lineno(ivl_switch_t net);
|
||||||
* Return the type of the element of an array. This is only valid
|
* Return the type of the element of an array. This is only valid
|
||||||
* for array types.
|
* for array types.
|
||||||
*
|
*
|
||||||
|
* ivl_type_packed_width
|
||||||
|
* Returns the total width of all packed dimensions.
|
||||||
|
*
|
||||||
* ivl_type_signed
|
* ivl_type_signed
|
||||||
* Return TRUE if the type represents a signed packed vector or
|
* Return TRUE if the type represents a signed packed vector or
|
||||||
* signed atomic type, and FALSE otherwise.
|
* signed atomic type, and FALSE otherwise.
|
||||||
|
|
@ -2361,6 +2364,7 @@ extern ivl_type_t ivl_type_element(ivl_type_t net);
|
||||||
extern unsigned ivl_type_packed_dimensions(ivl_type_t net);
|
extern unsigned ivl_type_packed_dimensions(ivl_type_t net);
|
||||||
extern int ivl_type_packed_lsb(ivl_type_t net, unsigned dim);
|
extern int ivl_type_packed_lsb(ivl_type_t net, unsigned dim);
|
||||||
extern int ivl_type_packed_msb(ivl_type_t net, unsigned dim);
|
extern int ivl_type_packed_msb(ivl_type_t net, unsigned dim);
|
||||||
|
extern unsigned ivl_type_packed_width(ivl_type_t net);
|
||||||
extern int ivl_type_signed(ivl_type_t net);
|
extern int ivl_type_signed(ivl_type_t net);
|
||||||
extern const char* ivl_type_name(ivl_type_t net);
|
extern const char* ivl_type_name(ivl_type_t net);
|
||||||
extern int ivl_type_properties(ivl_type_t net);
|
extern int ivl_type_properties(ivl_type_t net);
|
||||||
|
|
|
||||||
|
|
@ -3202,6 +3202,11 @@ extern "C" ivl_type_t ivl_type_element(ivl_type_t net)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" unsigned ivl_type_packed_width(ivl_type_t net)
|
||||||
|
{
|
||||||
|
return net->packed_width();
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" unsigned ivl_type_packed_dimensions(ivl_type_t net)
|
extern "C" unsigned ivl_type_packed_dimensions(ivl_type_t net)
|
||||||
{
|
{
|
||||||
assert(net);
|
assert(net);
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ void darray_new(ivl_type_t element_type, unsigned size_reg)
|
||||||
ivl_variable_type_t type = ivl_type_base(element_type);
|
ivl_variable_type_t type = ivl_type_base(element_type);
|
||||||
|
|
||||||
if ((type == IVL_VT_BOOL) || (type == IVL_VT_LOGIC)) {
|
if ((type == IVL_VT_BOOL) || (type == IVL_VT_LOGIC)) {
|
||||||
wid = width_of_packed_type(element_type);
|
wid = ivl_type_packed_width(element_type);
|
||||||
signed_char = ivl_type_signed(element_type) ? "s" : "";
|
signed_char = ivl_type_signed(element_type) ? "s" : "";
|
||||||
} else {
|
} else {
|
||||||
// REAL or STRING objects are not packable.
|
// REAL or STRING objects are not packable.
|
||||||
|
|
@ -133,7 +133,7 @@ static int eval_darray_new(ivl_expr_t ex)
|
||||||
switch (ivl_type_base(element_type)) {
|
switch (ivl_type_base(element_type)) {
|
||||||
case IVL_VT_BOOL:
|
case IVL_VT_BOOL:
|
||||||
case IVL_VT_LOGIC:
|
case IVL_VT_LOGIC:
|
||||||
wid = width_of_packed_type(element_type);
|
wid = ivl_type_packed_width(element_type);
|
||||||
for (idx = 0 ; idx < cnt ; idx += 1) {
|
for (idx = 0 ; idx < cnt ; idx += 1) {
|
||||||
draw_eval_vec4(init_expr);
|
draw_eval_vec4(init_expr);
|
||||||
fprintf(vvp_out, " %%parti/%c %u, %ld, 6;\n",
|
fprintf(vvp_out, " %%parti/%c %u, %ld, 6;\n",
|
||||||
|
|
|
||||||
|
|
@ -897,21 +897,6 @@ static int show_stmt_assign_sig_string(ivl_statement_t net)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned width_of_packed_type(ivl_type_t net)
|
|
||||||
{
|
|
||||||
unsigned idx;
|
|
||||||
unsigned width = 1;
|
|
||||||
for (idx = 0 ; idx < ivl_type_packed_dimensions(net) ; idx += 1) {
|
|
||||||
int lsb = ivl_type_packed_lsb(net,idx);
|
|
||||||
int msb = ivl_type_packed_msb(net,idx);
|
|
||||||
if (lsb <= msb)
|
|
||||||
width *= msb - lsb + 1;
|
|
||||||
else
|
|
||||||
width *= lsb - msb + 1;
|
|
||||||
}
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function handles the special case that we assign an array
|
* This function handles the special case that we assign an array
|
||||||
* pattern to a dynamic array. Handle this by assigning each
|
* pattern to a dynamic array. Handle this by assigning each
|
||||||
|
|
@ -934,9 +919,9 @@ static int show_stmt_assign_darray_pattern(ivl_statement_t net)
|
||||||
#if 0
|
#if 0
|
||||||
unsigned element_width = 1;
|
unsigned element_width = 1;
|
||||||
if (ivl_type_base(element_type) == IVL_VT_BOOL)
|
if (ivl_type_base(element_type) == IVL_VT_BOOL)
|
||||||
element_width = width_of_packed_type(element_type);
|
element_width = ivl_type_packed_width(element_type);
|
||||||
else if (ivl_type_base(element_type) == IVL_VT_LOGIC)
|
else if (ivl_type_base(element_type) == IVL_VT_LOGIC)
|
||||||
element_width = width_of_packed_type(element_type);
|
element_width = ivl_type_packed_width(element_type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME: At the moment we reallocate the array space.
|
// FIXME: At the moment we reallocate the array space.
|
||||||
|
|
@ -1094,7 +1079,7 @@ static int show_stmt_assign_queue_pattern(ivl_signal_t var, ivl_expr_t rval,
|
||||||
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
||||||
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
||||||
fprintf(vvp_out, " %%store/qdar/v v%p_0, %d, %u;\n", var, max_idx,
|
fprintf(vvp_out, " %%store/qdar/v v%p_0, %d, %u;\n", var, max_idx,
|
||||||
width_of_packed_type(element_type));
|
ivl_type_packed_width(element_type));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IVL_VT_REAL:
|
case IVL_VT_REAL:
|
||||||
|
|
@ -1181,7 +1166,7 @@ static int show_stmt_assign_sig_queue(ivl_statement_t net)
|
||||||
index register 3. */
|
index register 3. */
|
||||||
draw_eval_expr_into_integer(mux, 3);
|
draw_eval_expr_into_integer(mux, 3);
|
||||||
fprintf(vvp_out, " %%store/qdar/v v%p_0, %d, %u;\n", var, idx,
|
fprintf(vvp_out, " %%store/qdar/v v%p_0, %d, %u;\n", var, idx,
|
||||||
width_of_packed_type(element_type));
|
ivl_type_packed_width(element_type));
|
||||||
|
|
||||||
} else if (ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN) {
|
} else if (ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN) {
|
||||||
/* There is no l-value mux, but the r-value is an array
|
/* There is no l-value mux, but the r-value is an array
|
||||||
|
|
@ -1202,7 +1187,7 @@ static int show_stmt_assign_sig_queue(ivl_statement_t net)
|
||||||
assert(ivl_type_base(element_type) == IVL_VT_BOOL ||
|
assert(ivl_type_base(element_type) == IVL_VT_BOOL ||
|
||||||
ivl_type_base(element_type) == IVL_VT_LOGIC);
|
ivl_type_base(element_type) == IVL_VT_LOGIC);
|
||||||
fprintf(vvp_out, " %%store/qobj/v v%p_0, %d, %u;\n",
|
fprintf(vvp_out, " %%store/qobj/v v%p_0, %d, %u;\n",
|
||||||
var, idx, width_of_packed_type(element_type));
|
var, idx, ivl_type_packed_width(element_type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clr_word(idx);
|
clr_word(idx);
|
||||||
|
|
|
||||||
|
|
@ -80,11 +80,6 @@ extern const char* vvp_signal_label(ivl_signal_t sig);
|
||||||
extern unsigned width_of_nexus(ivl_nexus_t nex);
|
extern unsigned width_of_nexus(ivl_nexus_t nex);
|
||||||
extern ivl_variable_type_t data_type_of_nexus(ivl_nexus_t nex);
|
extern ivl_variable_type_t data_type_of_nexus(ivl_nexus_t nex);
|
||||||
|
|
||||||
/*
|
|
||||||
* Calculate the width (in bits) of a packed type.
|
|
||||||
*/
|
|
||||||
extern unsigned width_of_packed_type(ivl_type_t net);
|
|
||||||
|
|
||||||
extern int can_elide_bufz(ivl_net_logic_t net, ivl_nexus_ptr_t nptr);
|
extern int can_elide_bufz(ivl_net_logic_t net, ivl_nexus_ptr_t nptr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1847,7 +1847,7 @@ static int show_insert_method(ivl_statement_t net)
|
||||||
draw_eval_vec4(parm2);
|
draw_eval_vec4(parm2);
|
||||||
fprintf(vvp_out, " %%qinsert/v v%p_0, %d, %u;\n",
|
fprintf(vvp_out, " %%qinsert/v v%p_0, %d, %u;\n",
|
||||||
var, idx,
|
var, idx,
|
||||||
width_of_packed_type(element_type));
|
ivl_type_packed_width(element_type));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1897,7 +1897,7 @@ static int show_push_frontback_method(ivl_statement_t net, bool is_front)
|
||||||
draw_eval_vec4(parm1);
|
draw_eval_vec4(parm1);
|
||||||
fprintf(vvp_out, " %%store/%s/v v%p_0, %d, %u;\n",
|
fprintf(vvp_out, " %%store/%s/v v%p_0, %d, %u;\n",
|
||||||
type_code, var, idx,
|
type_code, var, idx,
|
||||||
width_of_packed_type(element_type));
|
ivl_type_packed_width(element_type));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
clr_word(idx);
|
clr_word(idx);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue