Merge branch 'master' of git://icarus.com/~steve-icarus/verilog into vhdl
This commit is contained in:
commit
380e3a8121
|
|
@ -2327,7 +2327,7 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope,
|
||||||
} while (0);
|
} while (0);
|
||||||
#else
|
#else
|
||||||
if (name_tail.index.size() > sig->array_dimensions())
|
if (name_tail.index.size() > sig->array_dimensions())
|
||||||
tmp = process_select_(des, scope, sig);
|
tmp = process_select_(des, scope, tmp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return tmp;
|
return tmp;
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ void Module::elaborate_parm_item_(perm_string name, const param_expr_t&cur,
|
||||||
assert(ex);
|
assert(ex);
|
||||||
|
|
||||||
NetExpr*val = ex->elaborate_pexpr(des, scope);
|
NetExpr*val = ex->elaborate_pexpr(des, scope);
|
||||||
if (val == 0) return;
|
|
||||||
NetExpr*msb = 0;
|
NetExpr*msb = 0;
|
||||||
NetExpr*lsb = 0;
|
NetExpr*lsb = 0;
|
||||||
bool signed_flag = cur.signed_flag;
|
bool signed_flag = cur.signed_flag;
|
||||||
|
|
@ -71,19 +71,6 @@ void Module::elaborate_parm_item_(perm_string name, const param_expr_t&cur,
|
||||||
assert(lsb);
|
assert(lsb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signed_flag) {
|
|
||||||
/* If explicitly signed, then say so. */
|
|
||||||
val->cast_signed(true);
|
|
||||||
} else if (cur.msb) {
|
|
||||||
/* If there is a range, then the signedness comes
|
|
||||||
from the type and not the expression. */
|
|
||||||
val->cast_signed(signed_flag);
|
|
||||||
} else {
|
|
||||||
/* otherwise, let the expression describe
|
|
||||||
itself. */
|
|
||||||
signed_flag = val->has_sign();
|
|
||||||
}
|
|
||||||
|
|
||||||
NetScope::range_t*range_list = 0;
|
NetScope::range_t*range_list = 0;
|
||||||
for (Module::range_t*range = cur.range ; range ; range = range->next) {
|
for (Module::range_t*range = cur.range ; range ; range = range->next) {
|
||||||
NetScope::range_t*tmp = new NetScope::range_t;
|
NetScope::range_t*tmp = new NetScope::range_t;
|
||||||
|
|
@ -118,8 +105,29 @@ void Module::elaborate_parm_item_(perm_string name, const param_expr_t&cur,
|
||||||
range_list = tmp;
|
range_list = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = scope->set_parameter(name, val, cur.type, msb, lsb, signed_flag, range_list, cur);
|
/* Set the parameter expression to 0 if the evaluation failed. */
|
||||||
assert(val);
|
if (val == 0) {
|
||||||
|
val = scope->set_parameter(name, val, cur.type, msb, lsb,
|
||||||
|
signed_flag, range_list, cur);
|
||||||
|
delete val;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (signed_flag) {
|
||||||
|
/* If explicitly signed, then say so. */
|
||||||
|
val->cast_signed(true);
|
||||||
|
} else if (cur.msb) {
|
||||||
|
/* If there is a range, then the signedness comes
|
||||||
|
from the type and not the expression. */
|
||||||
|
val->cast_signed(signed_flag);
|
||||||
|
} else {
|
||||||
|
/* otherwise, let the expression describe
|
||||||
|
itself. */
|
||||||
|
signed_flag = val->has_sign();
|
||||||
|
}
|
||||||
|
|
||||||
|
val = scope->set_parameter(name, val, cur.type, msb, lsb, signed_flag,
|
||||||
|
range_list, cur);
|
||||||
delete val;
|
delete val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -316,17 +324,17 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
||||||
// here because the parameter receiving the assignment may be
|
// here because the parameter receiving the assignment may be
|
||||||
// in a scope not discovered by this pass.
|
// in a scope not discovered by this pass.
|
||||||
|
|
||||||
while (! defparms.empty()) {
|
typedef list<Module::named_expr_t>::const_iterator defparms_iter_t;
|
||||||
Module::named_expr_t cur = defparms.front();
|
for (defparms_iter_t cur = defparms.begin()
|
||||||
defparms.pop_front();
|
; cur != defparms.end() ; cur ++) {
|
||||||
|
|
||||||
PExpr*ex = cur.second;
|
PExpr*ex = cur->second;
|
||||||
assert(ex);
|
assert(ex);
|
||||||
|
|
||||||
NetExpr*val = ex->elaborate_pexpr(des, scope);
|
NetExpr*val = ex->elaborate_pexpr(des, scope);
|
||||||
delete ex;
|
|
||||||
if (val == 0) continue;
|
if (val == 0) continue;
|
||||||
scope->defparams.push_back(make_pair(cur.first, val));
|
|
||||||
|
scope->defparams.push_back(make_pair(cur->first, val));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate the attributes. Evaluate them in the scope of the
|
// Evaluate the attributes. Evaluate them in the scope of the
|
||||||
|
|
@ -475,7 +483,12 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||||
container->genvar_tmp_val = genvar;
|
container->genvar_tmp_val = genvar;
|
||||||
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
|
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
|
||||||
NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
|
NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
|
||||||
assert(test);
|
if (test == 0) {
|
||||||
|
cerr << get_fileline() << ": error: Cannot evaluate genvar"
|
||||||
|
<< " conditional expression: " << *loop_test << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
while (test->value().as_long()) {
|
while (test->value().as_long()) {
|
||||||
|
|
||||||
// The actual name of the scope includes the genvar so
|
// The actual name of the scope includes the genvar so
|
||||||
|
|
@ -522,7 +535,12 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||||
// Calculate the step for the loop variable.
|
// Calculate the step for the loop variable.
|
||||||
NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1);
|
NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1);
|
||||||
NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
|
NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
|
||||||
assert(step);
|
if (step == 0) {
|
||||||
|
cerr << get_fileline() << ": error: Cannot evaluate genvar"
|
||||||
|
<< " step expression: " << *loop_step << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (debug_scopes)
|
if (debug_scopes)
|
||||||
cerr << get_fileline() << ": debug: genvar step from "
|
cerr << get_fileline() << ": debug: genvar step from "
|
||||||
<< genvar << " to " << step->value().as_long() << endl;
|
<< genvar << " to " << step->value().as_long() << endl;
|
||||||
|
|
@ -547,7 +565,12 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
|
||||||
{
|
{
|
||||||
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
|
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
|
||||||
NetEConst*test = dynamic_cast<NetEConst*> (test_ex);
|
NetEConst*test = dynamic_cast<NetEConst*> (test_ex);
|
||||||
assert(test);
|
if (test == 0) {
|
||||||
|
cerr << get_fileline() << ": error: Cannot evaluate genvar"
|
||||||
|
<< " conditional expression: " << *loop_test << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// If the condition evaluates as false, then do not create the
|
// If the condition evaluates as false, then do not create the
|
||||||
// scope.
|
// scope.
|
||||||
|
|
@ -589,7 +612,12 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
||||||
{
|
{
|
||||||
NetExpr*case_value_ex = elab_and_eval(des, container, loop_test, -1);
|
NetExpr*case_value_ex = elab_and_eval(des, container, loop_test, -1);
|
||||||
NetEConst*case_value_co = dynamic_cast<NetEConst*>(case_value_ex);
|
NetEConst*case_value_co = dynamic_cast<NetEConst*>(case_value_ex);
|
||||||
assert(case_value_co);
|
if (case_value_co == 0) {
|
||||||
|
cerr << get_fileline() << ": error: Cannot evaluate genvar case"
|
||||||
|
<< " expression: " << *loop_test << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// The name of the scope to generate, whatever that item is.
|
// The name of the scope to generate, whatever that item is.
|
||||||
hname_t use_name (scope_name);
|
hname_t use_name (scope_name);
|
||||||
|
|
|
||||||
21
elab_sig.cc
21
elab_sig.cc
|
|
@ -589,9 +589,17 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
cerr << get_fileline() << ": internal error: I don't know how "
|
if (ports_) {
|
||||||
<< "to deal with return type of function "
|
cerr << get_fileline() << ": internal error: I don't know "
|
||||||
<< scope->basename() << "." << endl;
|
<< "how to deal with return type of function "
|
||||||
|
<< scope->basename() << "." << endl;
|
||||||
|
} else {
|
||||||
|
/* If we do not have any ports or a return type this
|
||||||
|
* is probably a bad function definition. */
|
||||||
|
cerr << get_fileline() << ": error: Bad definition for "
|
||||||
|
<< "function " << scope->basename() << "?" << endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
svector<NetNet*>ports (ports_? ports_->count() : 0);
|
svector<NetNet*>ports (ports_? ports_->count() : 0);
|
||||||
|
|
@ -1003,8 +1011,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": debug: Create signal "
|
cerr << get_fileline() << ": debug: Create signal "
|
||||||
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name_
|
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name_;
|
||||||
<< " in scope " << scope_path(scope) << endl;
|
if (array_dimensions > 0) {
|
||||||
|
cerr << " [" << array_s0 << ":" << array_e0 << "]" << endl;
|
||||||
|
}
|
||||||
|
cerr << " in scope " << scope_path(scope) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -357,11 +357,11 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
|
||||||
|
|
||||||
/* Evaluate the parameter expression, if necessary. */
|
/* Evaluate the parameter expression, if necessary. */
|
||||||
NetExpr*expr = (*cur).second.expr;
|
NetExpr*expr = (*cur).second.expr;
|
||||||
assert(expr);
|
if (expr == NULL) return; // This is an invalid parameter so return.
|
||||||
|
|
||||||
eval_expr(expr);
|
eval_expr(expr);
|
||||||
|
|
||||||
/* The eval_expr may delete any replace the expr pointer, so the
|
/* The eval_expr may delete and replace the expr pointer, so the
|
||||||
second.expr value cannot be relied on. Might as well replace
|
second.expr value cannot be relied on. Might as well replace
|
||||||
it now with the expression that we evaluated. */
|
it now with the expression that we evaluated. */
|
||||||
(*cur).second.expr = expr;
|
(*cur).second.expr = expr;
|
||||||
|
|
|
||||||
230
parse.y
230
parse.y
|
|
@ -351,6 +351,13 @@ number : BASED_NUMBER
|
||||||
based_size = 0; }
|
based_size = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/* real and realtime are exactly the same so save some code
|
||||||
|
* with a common matching rule. */
|
||||||
|
real_or_realtime
|
||||||
|
: K_real
|
||||||
|
| K_realtime
|
||||||
|
;
|
||||||
|
|
||||||
/* Verilog-2001 supports attribute lists, which can be attached to a
|
/* Verilog-2001 supports attribute lists, which can be attached to a
|
||||||
variety of different objects. The syntax inside the (* *) is a
|
variety of different objects. The syntax inside the (* *) is a
|
||||||
comma separated list of names or names with assigned values. */
|
comma separated list of names or names with assigned values. */
|
||||||
|
|
@ -2426,17 +2433,7 @@ parameter_assign_decl
|
||||||
param_active_signed = false;
|
param_active_signed = false;
|
||||||
param_active_type = IVL_VT_LOGIC;
|
param_active_type = IVL_VT_LOGIC;
|
||||||
}
|
}
|
||||||
| K_real
|
| real_or_realtime
|
||||||
{ param_active_range = 0;
|
|
||||||
param_active_signed = true;
|
|
||||||
param_active_type = IVL_VT_REAL;
|
|
||||||
}
|
|
||||||
parameter_assign_list
|
|
||||||
{ param_active_range = 0;
|
|
||||||
param_active_signed = false;
|
|
||||||
param_active_type = IVL_VT_LOGIC;
|
|
||||||
}
|
|
||||||
| K_realtime
|
|
||||||
{ param_active_range = 0;
|
{ param_active_range = 0;
|
||||||
param_active_signed = true;
|
param_active_signed = true;
|
||||||
param_active_type = IVL_VT_REAL;
|
param_active_type = IVL_VT_REAL;
|
||||||
|
|
@ -2565,17 +2562,7 @@ localparam_assign_decl
|
||||||
param_active_signed = false;
|
param_active_signed = false;
|
||||||
param_active_type = IVL_VT_LOGIC;
|
param_active_type = IVL_VT_LOGIC;
|
||||||
}
|
}
|
||||||
| K_real
|
| real_or_realtime
|
||||||
{ param_active_range = 0;
|
|
||||||
param_active_signed = true;
|
|
||||||
param_active_type = IVL_VT_REAL;
|
|
||||||
}
|
|
||||||
localparam_assign_list
|
|
||||||
{ param_active_range = 0;
|
|
||||||
param_active_signed = false;
|
|
||||||
param_active_type = IVL_VT_LOGIC;
|
|
||||||
}
|
|
||||||
| K_realtime
|
|
||||||
{ param_active_range = 0;
|
{ param_active_range = 0;
|
||||||
param_active_signed = true;
|
param_active_signed = true;
|
||||||
param_active_type = IVL_VT_REAL;
|
param_active_type = IVL_VT_REAL;
|
||||||
|
|
@ -3734,39 +3721,43 @@ task_item
|
||||||
| task_port_item { $$ = $1; }
|
| task_port_item { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
reg_opt
|
||||||
|
: K_reg
|
||||||
|
|
|
||||||
|
;
|
||||||
|
|
||||||
task_port_item
|
task_port_item
|
||||||
|
|
||||||
: K_input signed_opt range_opt list_of_identifiers ';'
|
: K_input reg_opt signed_opt range_opt list_of_identifiers ';'
|
||||||
{ svector<PWire*>*tmp
|
{ svector<PWire*>*tmp
|
||||||
= pform_make_task_ports(NetNet::PINPUT,
|
= pform_make_task_ports(NetNet::PINPUT,
|
||||||
IVL_VT_NO_TYPE, $2,
|
IVL_VT_NO_TYPE, $3,
|
||||||
$3, $4,
|
$4, $5,
|
||||||
@1.text, @1.first_line);
|
@1.text, @1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_output signed_opt range_opt list_of_identifiers ';'
|
| K_output reg_opt signed_opt range_opt list_of_identifiers ';'
|
||||||
{ svector<PWire*>*tmp
|
{ svector<PWire*>*tmp
|
||||||
= pform_make_task_ports(NetNet::POUTPUT,
|
= pform_make_task_ports(NetNet::POUTPUT,
|
||||||
IVL_VT_LOGIC, $2,
|
IVL_VT_LOGIC, $3,
|
||||||
$3, $4,
|
$4, $5,
|
||||||
@1.text, @1.first_line);
|
@1.text, @1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_inout signed_opt range_opt list_of_identifiers ';'
|
| K_inout reg_opt signed_opt range_opt list_of_identifiers ';'
|
||||||
{ svector<PWire*>*tmp
|
{ svector<PWire*>*tmp
|
||||||
= pform_make_task_ports(NetNet::PINOUT,
|
= pform_make_task_ports(NetNet::PINOUT,
|
||||||
IVL_VT_LOGIC, $2,
|
IVL_VT_LOGIC, $3,
|
||||||
$3, $4,
|
$4, $5,
|
||||||
@1.text, @1.first_line);
|
@1.text, @1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When the port is an integer, infer a signed vector of the integer
|
/* When the port is an integer, infer a signed vector of the integer
|
||||||
shape. Generate a range to make it work. */
|
shape. Generate a range ([31:0]) to make it work. */
|
||||||
|
|
||||||
| K_input K_integer list_of_identifiers ';'
|
| K_input K_integer list_of_identifiers ';'
|
||||||
{ svector<PExpr*>*range_stub
|
{ svector<PExpr*>*range_stub = new svector<PExpr*>(2);
|
||||||
= new svector<PExpr*>(2);
|
|
||||||
PExpr*re;
|
PExpr*re;
|
||||||
re = new PENumber(new verinum(integer_width-1,
|
re = new PENumber(new verinum(integer_width-1,
|
||||||
integer_width));
|
integer_width));
|
||||||
|
|
@ -3781,8 +3772,7 @@ task_port_item
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_output K_integer list_of_identifiers ';'
|
| K_output K_integer list_of_identifiers ';'
|
||||||
{ svector<PExpr*>*range_stub
|
{ svector<PExpr*>*range_stub = new svector<PExpr*>(2);
|
||||||
= new svector<PExpr*>(2);
|
|
||||||
PExpr*re;
|
PExpr*re;
|
||||||
re = new PENumber(new verinum(integer_width-1,
|
re = new PENumber(new verinum(integer_width-1,
|
||||||
integer_width));
|
integer_width));
|
||||||
|
|
@ -3797,8 +3787,7 @@ task_port_item
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_inout K_integer list_of_identifiers ';'
|
| K_inout K_integer list_of_identifiers ';'
|
||||||
{ svector<PExpr*>*range_stub
|
{ svector<PExpr*>*range_stub = new svector<PExpr*>(2);
|
||||||
= new svector<PExpr*>(2);
|
|
||||||
PExpr*re;
|
PExpr*re;
|
||||||
re = new PENumber(new verinum(integer_width-1,
|
re = new PENumber(new verinum(integer_width-1,
|
||||||
integer_width));
|
integer_width));
|
||||||
|
|
@ -3813,9 +3802,54 @@ task_port_item
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ports can be real. */
|
/* Ports can be time with a width of [63:0] (unsigned). */
|
||||||
|
|
||||||
| K_input K_real list_of_identifiers ';'
|
| K_input K_time list_of_identifiers ';'
|
||||||
|
{ svector<PExpr*>*range_stub = new svector<PExpr*>(2);
|
||||||
|
PExpr*re;
|
||||||
|
re = new PENumber(new verinum((uint64_t)63, integer_width));
|
||||||
|
(*range_stub)[0] = re;
|
||||||
|
re = new PENumber(new verinum((uint64_t)0, integer_width));
|
||||||
|
(*range_stub)[1] = re;
|
||||||
|
svector<PWire*>*tmp
|
||||||
|
= pform_make_task_ports(NetNet::PINPUT,
|
||||||
|
IVL_VT_LOGIC, false,
|
||||||
|
range_stub, $3,
|
||||||
|
@1.text, @1.first_line);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| K_output K_time list_of_identifiers ';'
|
||||||
|
{ svector<PExpr*>*range_stub = new svector<PExpr*>(2);
|
||||||
|
PExpr*re;
|
||||||
|
re = new PENumber(new verinum((uint64_t)63, integer_width));
|
||||||
|
(*range_stub)[0] = re;
|
||||||
|
re = new PENumber(new verinum((uint64_t)0, integer_width));
|
||||||
|
(*range_stub)[1] = re;
|
||||||
|
svector<PWire*>*tmp
|
||||||
|
= pform_make_task_ports(NetNet::POUTPUT,
|
||||||
|
IVL_VT_LOGIC, false,
|
||||||
|
range_stub, $3,
|
||||||
|
@1.text, @1.first_line);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| K_inout K_time list_of_identifiers ';'
|
||||||
|
{ svector<PExpr*>*range_stub = new svector<PExpr*>(2);
|
||||||
|
PExpr*re;
|
||||||
|
re = new PENumber(new verinum((uint64_t)63, integer_width));
|
||||||
|
(*range_stub)[0] = re;
|
||||||
|
re = new PENumber(new verinum((uint64_t)0, integer_width));
|
||||||
|
(*range_stub)[1] = re;
|
||||||
|
svector<PWire*>*tmp
|
||||||
|
= pform_make_task_ports(NetNet::PINOUT,
|
||||||
|
IVL_VT_LOGIC, false,
|
||||||
|
range_stub, $3,
|
||||||
|
@1.text, @1.first_line);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ports can be real or realtime. */
|
||||||
|
|
||||||
|
| K_input real_or_realtime list_of_identifiers ';'
|
||||||
{ svector<PWire*>*tmp
|
{ svector<PWire*>*tmp
|
||||||
= pform_make_task_ports(NetNet::PINPUT,
|
= pform_make_task_ports(NetNet::PINPUT,
|
||||||
IVL_VT_REAL, false,
|
IVL_VT_REAL, false,
|
||||||
|
|
@ -3823,7 +3857,7 @@ task_port_item
|
||||||
@1.text, @1.first_line);
|
@1.text, @1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_output K_real list_of_identifiers ';'
|
| K_output real_or_realtime list_of_identifiers ';'
|
||||||
{ svector<PWire*>*tmp
|
{ svector<PWire*>*tmp
|
||||||
= pform_make_task_ports(NetNet::POUTPUT,
|
= pform_make_task_ports(NetNet::POUTPUT,
|
||||||
IVL_VT_REAL, true,
|
IVL_VT_REAL, true,
|
||||||
|
|
@ -3831,7 +3865,7 @@ task_port_item
|
||||||
@1.text, @1.first_line);
|
@1.text, @1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_inout K_real list_of_identifiers ';'
|
| K_inout real_or_realtime list_of_identifiers ';'
|
||||||
{ svector<PWire*>*tmp
|
{ svector<PWire*>*tmp
|
||||||
= pform_make_task_ports(NetNet::PINOUT,
|
= pform_make_task_ports(NetNet::PINOUT,
|
||||||
IVL_VT_REAL, true,
|
IVL_VT_REAL, true,
|
||||||
|
|
@ -3861,50 +3895,51 @@ task_item_list_opt
|
||||||
|
|
||||||
task_port_decl
|
task_port_decl
|
||||||
|
|
||||||
: K_input signed_opt range_opt IDENTIFIER
|
: K_input reg_opt signed_opt range_opt IDENTIFIER
|
||||||
{ port_declaration_context.port_type = NetNet::PINPUT;
|
{ port_declaration_context.port_type = NetNet::PINPUT;
|
||||||
port_declaration_context.var_type = IVL_VT_LOGIC;
|
port_declaration_context.var_type = IVL_VT_LOGIC;
|
||||||
port_declaration_context.sign_flag = $2;
|
port_declaration_context.sign_flag = $3;
|
||||||
delete port_declaration_context.range;
|
delete port_declaration_context.range;
|
||||||
port_declaration_context.range = copy_range($3);
|
port_declaration_context.range = copy_range($4);
|
||||||
svector<PWire*>*tmp
|
svector<PWire*>*tmp
|
||||||
= pform_make_task_ports(NetNet::PINPUT,
|
= pform_make_task_ports(NetNet::PINPUT,
|
||||||
IVL_VT_LOGIC, $2,
|
IVL_VT_LOGIC, $3,
|
||||||
$3, list_from_identifier($4),
|
$4, list_from_identifier($5),
|
||||||
@1.text, @1.first_line);
|
@1.text, @1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
| K_output signed_opt range_opt IDENTIFIER
|
| K_output reg_opt signed_opt range_opt IDENTIFIER
|
||||||
{ port_declaration_context.port_type = NetNet::POUTPUT;
|
{ port_declaration_context.port_type = NetNet::POUTPUT;
|
||||||
port_declaration_context.var_type = IVL_VT_LOGIC;
|
port_declaration_context.var_type = IVL_VT_LOGIC;
|
||||||
port_declaration_context.sign_flag = $2;
|
port_declaration_context.sign_flag = $3;
|
||||||
delete port_declaration_context.range;
|
delete port_declaration_context.range;
|
||||||
port_declaration_context.range = copy_range($3);
|
port_declaration_context.range = copy_range($4);
|
||||||
svector<PWire*>*tmp
|
svector<PWire*>*tmp
|
||||||
= pform_make_task_ports(NetNet::POUTPUT,
|
= pform_make_task_ports(NetNet::POUTPUT,
|
||||||
IVL_VT_LOGIC, $2,
|
IVL_VT_LOGIC, $3,
|
||||||
$3, list_from_identifier($4),
|
$4, list_from_identifier($5),
|
||||||
@1.text, @1.first_line);
|
@1.text, @1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_inout signed_opt range_opt IDENTIFIER
|
| K_inout reg_opt signed_opt range_opt IDENTIFIER
|
||||||
{ port_declaration_context.port_type = NetNet::PINOUT;
|
{ port_declaration_context.port_type = NetNet::PINOUT;
|
||||||
port_declaration_context.var_type = IVL_VT_LOGIC;
|
port_declaration_context.var_type = IVL_VT_LOGIC;
|
||||||
port_declaration_context.sign_flag = $2;
|
port_declaration_context.sign_flag = $3;
|
||||||
delete port_declaration_context.range;
|
delete port_declaration_context.range;
|
||||||
port_declaration_context.range = copy_range($3);
|
port_declaration_context.range = copy_range($4);
|
||||||
svector<PWire*>*tmp
|
svector<PWire*>*tmp
|
||||||
= pform_make_task_ports(NetNet::PINOUT,
|
= pform_make_task_ports(NetNet::PINOUT,
|
||||||
IVL_VT_LOGIC, $2,
|
IVL_VT_LOGIC, $3,
|
||||||
$3, list_from_identifier($4),
|
$4, list_from_identifier($5),
|
||||||
@1.text, @1.first_line);
|
@1.text, @1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ports can be integer with a width of [31:0]. */
|
||||||
|
|
||||||
| K_input K_integer IDENTIFIER
|
| K_input K_integer IDENTIFIER
|
||||||
{ svector<PExpr*>*range_stub
|
{ svector<PExpr*>*range_stub = new svector<PExpr*>(2);
|
||||||
= new svector<PExpr*>(2);
|
|
||||||
PExpr*re;
|
PExpr*re;
|
||||||
re = new PENumber(new verinum(integer_width-1,
|
re = new PENumber(new verinum(integer_width-1,
|
||||||
integer_width));
|
integer_width));
|
||||||
|
|
@ -3925,8 +3960,7 @@ task_port_decl
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_output K_integer IDENTIFIER
|
| K_output K_integer IDENTIFIER
|
||||||
{ svector<PExpr*>*range_stub
|
{ svector<PExpr*>*range_stub = new svector<PExpr*>(2);
|
||||||
= new svector<PExpr*>(2);
|
|
||||||
PExpr*re;
|
PExpr*re;
|
||||||
re = new PENumber(new verinum(integer_width-1,
|
re = new PENumber(new verinum(integer_width-1,
|
||||||
integer_width));
|
integer_width));
|
||||||
|
|
@ -3947,8 +3981,7 @@ task_port_decl
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_inout K_integer IDENTIFIER
|
| K_inout K_integer IDENTIFIER
|
||||||
{ svector<PExpr*>*range_stub
|
{ svector<PExpr*>*range_stub = new svector<PExpr*>(2);
|
||||||
= new svector<PExpr*>(2);
|
|
||||||
PExpr*re;
|
PExpr*re;
|
||||||
re = new PENumber(new verinum(integer_width-1,
|
re = new PENumber(new verinum(integer_width-1,
|
||||||
integer_width));
|
integer_width));
|
||||||
|
|
@ -3969,9 +4002,72 @@ task_port_decl
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ports can be real. */
|
/* Ports can be time with a width of [63:0] (unsigned). */
|
||||||
|
|
||||||
|
| K_input K_time IDENTIFIER
|
||||||
|
{ svector<PExpr*>*range_stub = new svector<PExpr*>(2);
|
||||||
|
PExpr*re;
|
||||||
|
re = new PENumber(new verinum((uint64_t)63, integer_width));
|
||||||
|
(*range_stub)[0] = re;
|
||||||
|
re = new PENumber(new verinum((uint64_t)0, integer_width));
|
||||||
|
(*range_stub)[1] = re;
|
||||||
|
port_declaration_context.port_type = NetNet::PINPUT;
|
||||||
|
port_declaration_context.var_type = IVL_VT_LOGIC;
|
||||||
|
port_declaration_context.sign_flag = false;
|
||||||
|
delete port_declaration_context.range;
|
||||||
|
port_declaration_context.range = copy_range(range_stub);
|
||||||
|
svector<PWire*>*tmp
|
||||||
|
= pform_make_task_ports(NetNet::PINPUT,
|
||||||
|
IVL_VT_LOGIC, false,
|
||||||
|
range_stub,
|
||||||
|
list_from_identifier($3),
|
||||||
|
@1.text, @1.first_line);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| K_output K_time IDENTIFIER
|
||||||
|
{ svector<PExpr*>*range_stub = new svector<PExpr*>(2);
|
||||||
|
PExpr*re;
|
||||||
|
re = new PENumber(new verinum((uint64_t)63, integer_width));
|
||||||
|
(*range_stub)[0] = re;
|
||||||
|
re = new PENumber(new verinum((uint64_t)0, integer_width));
|
||||||
|
(*range_stub)[1] = re;
|
||||||
|
port_declaration_context.port_type = NetNet::POUTPUT;
|
||||||
|
port_declaration_context.var_type = IVL_VT_LOGIC;
|
||||||
|
port_declaration_context.sign_flag = false;
|
||||||
|
delete port_declaration_context.range;
|
||||||
|
port_declaration_context.range = copy_range(range_stub);
|
||||||
|
svector<PWire*>*tmp
|
||||||
|
= pform_make_task_ports(NetNet::POUTPUT,
|
||||||
|
IVL_VT_LOGIC, false,
|
||||||
|
range_stub,
|
||||||
|
list_from_identifier($3),
|
||||||
|
@1.text, @1.first_line);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| K_inout K_time IDENTIFIER
|
||||||
|
{ svector<PExpr*>*range_stub = new svector<PExpr*>(2);
|
||||||
|
PExpr*re;
|
||||||
|
re = new PENumber(new verinum((uint64_t)63, integer_width));
|
||||||
|
(*range_stub)[0] = re;
|
||||||
|
re = new PENumber(new verinum((uint64_t)0, integer_width));
|
||||||
|
(*range_stub)[1] = re;
|
||||||
|
port_declaration_context.port_type = NetNet::PINOUT;
|
||||||
|
port_declaration_context.var_type = IVL_VT_LOGIC;
|
||||||
|
port_declaration_context.sign_flag = false;
|
||||||
|
delete port_declaration_context.range;
|
||||||
|
port_declaration_context.range = copy_range(range_stub);
|
||||||
|
svector<PWire*>*tmp
|
||||||
|
= pform_make_task_ports(NetNet::PINOUT,
|
||||||
|
IVL_VT_LOGIC, false,
|
||||||
|
range_stub,
|
||||||
|
list_from_identifier($3),
|
||||||
|
@1.text, @1.first_line);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
| K_input K_real IDENTIFIER
|
/* Ports can be real or realtime. */
|
||||||
|
|
||||||
|
| K_input real_or_realtime IDENTIFIER
|
||||||
{ port_declaration_context.port_type = NetNet::PINPUT;
|
{ port_declaration_context.port_type = NetNet::PINPUT;
|
||||||
port_declaration_context.var_type = IVL_VT_REAL;
|
port_declaration_context.var_type = IVL_VT_REAL;
|
||||||
port_declaration_context.sign_flag = false;
|
port_declaration_context.sign_flag = false;
|
||||||
|
|
@ -3984,7 +4080,7 @@ task_port_decl
|
||||||
@1.text, @1.first_line);
|
@1.text, @1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_output K_real IDENTIFIER
|
| K_output real_or_realtime IDENTIFIER
|
||||||
{ port_declaration_context.port_type = NetNet::POUTPUT;
|
{ port_declaration_context.port_type = NetNet::POUTPUT;
|
||||||
port_declaration_context.var_type = IVL_VT_REAL;
|
port_declaration_context.var_type = IVL_VT_REAL;
|
||||||
port_declaration_context.sign_flag = false;
|
port_declaration_context.sign_flag = false;
|
||||||
|
|
@ -3997,7 +4093,7 @@ task_port_decl
|
||||||
@1.text, @1.first_line);
|
@1.text, @1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_inout K_real IDENTIFIER
|
| K_inout real_or_realtime IDENTIFIER
|
||||||
{ port_declaration_context.port_type = NetNet::PINOUT;
|
{ port_declaration_context.port_type = NetNet::PINOUT;
|
||||||
port_declaration_context.var_type = IVL_VT_REAL;
|
port_declaration_context.var_type = IVL_VT_REAL;
|
||||||
port_declaration_context.sign_flag = false;
|
port_declaration_context.sign_flag = false;
|
||||||
|
|
|
||||||
|
|
@ -895,6 +895,10 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
|
||||||
|
|
||||||
static void draw_event_in_scope(ivl_event_t obj)
|
static void draw_event_in_scope(ivl_event_t obj)
|
||||||
{
|
{
|
||||||
|
char tmp[4][32];
|
||||||
|
|
||||||
|
const unsigned ntmp = sizeof(tmp) / sizeof(tmp[0]);
|
||||||
|
|
||||||
unsigned nany = ivl_event_nany(obj);
|
unsigned nany = ivl_event_nany(obj);
|
||||||
unsigned nneg = ivl_event_nneg(obj);
|
unsigned nneg = ivl_event_nneg(obj);
|
||||||
unsigned npos = ivl_event_npos(obj);
|
unsigned npos = ivl_event_npos(obj);
|
||||||
|
|
@ -903,13 +907,13 @@ static void draw_event_in_scope(ivl_event_t obj)
|
||||||
|
|
||||||
/* Figure out how many probe functors are needed. */
|
/* Figure out how many probe functors are needed. */
|
||||||
if (nany > 0)
|
if (nany > 0)
|
||||||
cnt += (nany+3) / 4;
|
cnt += (nany+ntmp-1) / ntmp;
|
||||||
|
|
||||||
if (nneg > 0)
|
if (nneg > 0)
|
||||||
cnt += (nneg+3) / 4;
|
cnt += (nneg+ntmp-1) / ntmp;
|
||||||
|
|
||||||
if (npos > 0)
|
if (npos > 0)
|
||||||
cnt += (npos+3) / 4;
|
cnt += (npos+ntmp-1) / ntmp;
|
||||||
|
|
||||||
if (cnt == 0) {
|
if (cnt == 0) {
|
||||||
/* If none are needed, then this is a named event. The
|
/* If none are needed, then this is a named event. The
|
||||||
|
|
@ -923,48 +927,57 @@ static void draw_event_in_scope(ivl_event_t obj)
|
||||||
unsigned idx;
|
unsigned idx;
|
||||||
unsigned ecnt = 0;
|
unsigned ecnt = 0;
|
||||||
|
|
||||||
for (idx = 0 ; idx < nany ; idx += 4, ecnt += 1) {
|
for (idx = 0 ; idx < nany ; idx += ntmp, ecnt += 1) {
|
||||||
unsigned sub, top;
|
unsigned sub, top;
|
||||||
|
|
||||||
fprintf(vvp_out, "E_%p/%u .event edge", obj, ecnt);
|
top = idx + ntmp;
|
||||||
|
|
||||||
top = idx + 4;
|
|
||||||
if (nany < top)
|
if (nany < top)
|
||||||
top = nany;
|
top = nany;
|
||||||
for (sub = idx ; sub < top ; sub += 1) {
|
for (sub = idx ; sub < top ; sub += 1) {
|
||||||
ivl_nexus_t nex = ivl_event_any(obj, sub);
|
ivl_nexus_t nex = ivl_event_any(obj, sub);
|
||||||
fprintf(vvp_out, ", %s", draw_input_from_net(nex));
|
strncpy(tmp[sub-idx], draw_input_from_net(nex), sizeof(tmp[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf(vvp_out, "E_%p/%u .event edge", obj, ecnt);
|
||||||
|
for (sub = idx ; sub < top ; sub += 1)
|
||||||
|
fprintf(vvp_out, ", %s", tmp[sub-idx]);
|
||||||
|
|
||||||
fprintf(vvp_out, ";\n");
|
fprintf(vvp_out, ";\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (idx = 0 ; idx < nneg ; idx += 4, ecnt += 1) {
|
for (idx = 0 ; idx < nneg ; idx += ntmp, ecnt += 1) {
|
||||||
unsigned sub, top;
|
unsigned sub, top;
|
||||||
|
|
||||||
fprintf(vvp_out, "E_%p/%u .event negedge", obj, ecnt);
|
top = idx + ntmp;
|
||||||
|
|
||||||
top = idx + 4;
|
|
||||||
if (nneg < top)
|
if (nneg < top)
|
||||||
top = nneg;
|
top = nneg;
|
||||||
for (sub = idx ; sub < top ; sub += 1) {
|
for (sub = idx ; sub < top ; sub += 1) {
|
||||||
ivl_nexus_t nex = ivl_event_neg(obj, sub);
|
ivl_nexus_t nex = ivl_event_neg(obj, sub);
|
||||||
fprintf(vvp_out, ", %s", draw_input_from_net(nex));
|
strncpy(tmp[sub-idx], draw_input_from_net(nex), sizeof(tmp[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf(vvp_out, "E_%p/%u .event negedge", obj, ecnt);
|
||||||
|
for (sub = idx ; sub < top ; sub += 1)
|
||||||
|
fprintf(vvp_out, ", %s", tmp[sub-idx]);
|
||||||
|
|
||||||
fprintf(vvp_out, ";\n");
|
fprintf(vvp_out, ";\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (idx = 0 ; idx < npos ; idx += 4, ecnt += 1) {
|
for (idx = 0 ; idx < npos ; idx += ntmp, ecnt += 1) {
|
||||||
unsigned sub, top;
|
unsigned sub, top;
|
||||||
|
|
||||||
fprintf(vvp_out, "E_%p/%u .event posedge", obj, ecnt);
|
top = idx + ntmp;
|
||||||
|
|
||||||
top = idx + 4;
|
|
||||||
if (npos < top)
|
if (npos < top)
|
||||||
top = npos;
|
top = npos;
|
||||||
for (sub = idx ; sub < top ; sub += 1) {
|
for (sub = idx ; sub < top ; sub += 1) {
|
||||||
ivl_nexus_t nex = ivl_event_pos(obj, sub);
|
ivl_nexus_t nex = ivl_event_pos(obj, sub);
|
||||||
fprintf(vvp_out, ", %s", draw_input_from_net(nex));
|
strncpy(tmp[sub-idx], draw_input_from_net(nex), sizeof(tmp[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf(vvp_out, "E_%p/%u .event posedge", obj, ecnt);
|
||||||
|
for (sub = idx ; sub < top ; sub += 1)
|
||||||
|
fprintf(vvp_out, ", %s", tmp[sub-idx]);
|
||||||
|
|
||||||
fprintf(vvp_out, ";\n");
|
fprintf(vvp_out, ";\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -981,20 +994,17 @@ static void draw_event_in_scope(ivl_event_t obj)
|
||||||
} else {
|
} else {
|
||||||
unsigned num_input_strings = nany + nneg + npos;
|
unsigned num_input_strings = nany + nneg + npos;
|
||||||
unsigned idx;
|
unsigned idx;
|
||||||
ivl_nexus_t input_nexa[4];
|
|
||||||
const char*edge = 0;
|
const char*edge = 0;
|
||||||
|
|
||||||
assert(num_input_strings <= 4);
|
assert(num_input_strings <= ntmp);
|
||||||
|
|
||||||
if (nany > 0) {
|
if (nany > 0) {
|
||||||
assert((nneg + npos) == 0);
|
assert((nneg + npos) == 0);
|
||||||
assert(nany <= 4);
|
|
||||||
|
|
||||||
edge = "edge";
|
edge = "edge";
|
||||||
|
|
||||||
for (idx = 0 ; idx < nany ; idx += 1) {
|
for (idx = 0 ; idx < nany ; idx += 1) {
|
||||||
ivl_nexus_t nex = ivl_event_any(obj, idx);
|
ivl_nexus_t nex = ivl_event_any(obj, idx);
|
||||||
input_nexa[idx] = nex;
|
strncpy(tmp[idx], draw_input_from_net(nex), sizeof(tmp[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (nneg > 0) {
|
} else if (nneg > 0) {
|
||||||
|
|
@ -1003,7 +1013,7 @@ static void draw_event_in_scope(ivl_event_t obj)
|
||||||
|
|
||||||
for (idx = 0 ; idx < nneg ; idx += 1) {
|
for (idx = 0 ; idx < nneg ; idx += 1) {
|
||||||
ivl_nexus_t nex = ivl_event_neg(obj, idx);
|
ivl_nexus_t nex = ivl_event_neg(obj, idx);
|
||||||
input_nexa[idx] = nex;
|
strncpy(tmp[idx], draw_input_from_net(nex), sizeof(tmp[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1012,14 +1022,14 @@ static void draw_event_in_scope(ivl_event_t obj)
|
||||||
|
|
||||||
for (idx = 0 ; idx < npos ; idx += 1) {
|
for (idx = 0 ; idx < npos ; idx += 1) {
|
||||||
ivl_nexus_t nex = ivl_event_pos(obj, idx);
|
ivl_nexus_t nex = ivl_event_pos(obj, idx);
|
||||||
input_nexa[idx] = nex;
|
strncpy(tmp[idx], draw_input_from_net(nex), sizeof(tmp[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(vvp_out, "E_%p .event %s", obj, edge);
|
fprintf(vvp_out, "E_%p .event %s", obj, edge);
|
||||||
for (idx = 0 ; idx < num_input_strings ; idx += 1)
|
for (idx = 0 ; idx < num_input_strings ; idx += 1) {
|
||||||
fprintf(vvp_out, ", %s", draw_input_from_net(input_nexa[idx]));
|
fprintf(vvp_out, ", %s", tmp[idx]);
|
||||||
|
}
|
||||||
fprintf(vvp_out, ";\n");
|
fprintf(vvp_out, ";\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -414,8 +414,9 @@ ended, then the %join does not block or yield the thread.
|
||||||
* %load/av <bit>, <array-label>, <wid>
|
* %load/av <bit>, <array-label>, <wid>
|
||||||
|
|
||||||
This instruction loads a word from the specified array. The word
|
This instruction loads a word from the specified array. The word
|
||||||
address is in index register 3. The width should match the width of
|
address is in index register 3. Like %load/v below the width does
|
||||||
the array word.
|
not have to match the width of the array word. See the %load/v
|
||||||
|
description for more information.
|
||||||
|
|
||||||
* %load/avp0 <bit>, <array-label>, <wid>
|
* %load/avp0 <bit>, <array-label>, <wid>
|
||||||
* %load/avp0/s <bit>, <array-label>, <wid>
|
* %load/avp0/s <bit>, <array-label>, <wid>
|
||||||
|
|
|
||||||
|
|
@ -2363,19 +2363,21 @@ bool of_LOAD_AV(vthread_t thr, vvp_code_t cp)
|
||||||
|
|
||||||
vvp_vector4_t word = array_get_word(cp->array, adr);
|
vvp_vector4_t word = array_get_word(cp->array, adr);
|
||||||
|
|
||||||
if (word.size() != wid) {
|
|
||||||
fprintf(stderr, "internal error: array width=%u, word.size()=%u, wid=%u\n",
|
|
||||||
0, word.size(), wid);
|
|
||||||
assert(word.size() == wid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the address once, before we scan the vector. */
|
/* Check the address once, before we scan the vector. */
|
||||||
thr_check_addr(thr, bit+wid-1);
|
thr_check_addr(thr, bit+wid-1);
|
||||||
|
|
||||||
|
if (word.size() > wid)
|
||||||
|
word.resize(wid);
|
||||||
|
|
||||||
/* Copy the vector bits into the bits4 vector. Do the copy
|
/* Copy the vector bits into the bits4 vector. Do the copy
|
||||||
directly to skip the excess calls to thr_check_addr. */
|
directly to skip the excess calls to thr_check_addr. */
|
||||||
thr->bits4.set_vec(bit, word);
|
thr->bits4.set_vec(bit, word);
|
||||||
|
|
||||||
|
/* If the source is shorter then the desired width, then pad
|
||||||
|
with BIT4_X values. */
|
||||||
|
for (unsigned idx = word.size() ; idx < wid ; idx += 1)
|
||||||
|
thr->bits4.set_bit(bit+idx, BIT4_X);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue