Add a net node for casting to IVL_VT_BOOL values.
BOOL values have a specific cast from LOGIC, this node takes care of it. Also arrange for the elaboration to insert them in the right planes and for the code generator to generate them.
This commit is contained in:
parent
bad1512cb0
commit
9c634e1640
|
|
@ -335,9 +335,17 @@ void NetArrayDq::dump_node(ostream&o, unsigned ind) const
|
||||||
dump_obj_attr(o, ind+4);
|
dump_obj_attr(o, ind+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetCastInt::dump_node(ostream&o, unsigned ind) const
|
void NetCastInt2::dump_node(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
o << setw(ind) << "" << "Cast to int. (NetCastInt): " <<
|
o << setw(ind) << "" << "Cast to int2. (NetCastInt2): " <<
|
||||||
|
name() << " width=" << width() << endl;
|
||||||
|
dump_node_pins(o, ind+4);
|
||||||
|
dump_obj_attr(o, ind+4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetCastInt4::dump_node(ostream&o, unsigned ind) const
|
||||||
|
{
|
||||||
|
o << setw(ind) << "" << "Cast to int4. (NetCastInt4): " <<
|
||||||
name() << " width=" << width() << endl;
|
name() << " width=" << width() << endl;
|
||||||
dump_node_pins(o, ind+4);
|
dump_node_pins(o, ind+4);
|
||||||
dump_obj_attr(o, ind+4);
|
dump_obj_attr(o, ind+4);
|
||||||
|
|
|
||||||
18
elaborate.cc
18
elaborate.cc
|
|
@ -129,13 +129,17 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
||||||
need_driver_flag = true;
|
need_driver_flag = true;
|
||||||
|
|
||||||
/* Cast the right side when needed. */
|
/* Cast the right side when needed. */
|
||||||
if ((lval->data_type() == IVL_VT_REAL &&
|
if ((lval->data_type() == IVL_VT_REAL) &&
|
||||||
rval->data_type() != IVL_VT_REAL)) {
|
(rval->data_type() != IVL_VT_REAL)) {
|
||||||
rval = cast_to_real(des, scope, rval);
|
rval = cast_to_real(des, scope, rval);
|
||||||
need_driver_flag = false;
|
need_driver_flag = false;
|
||||||
} else if ((lval->data_type() != IVL_VT_REAL &&
|
} else if ((lval->data_type() == IVL_VT_BOOL) &&
|
||||||
rval->data_type() == IVL_VT_REAL)) {
|
(rval->data_type() != IVL_VT_BOOL)) {
|
||||||
rval = cast_to_int(des, scope, rval, lval->vector_width());
|
rval = cast_to_int2(des, scope, rval, lval->vector_width());
|
||||||
|
need_driver_flag = false;
|
||||||
|
} else if ((lval->data_type() != IVL_VT_REAL) &&
|
||||||
|
(rval->data_type() == IVL_VT_REAL)) {
|
||||||
|
rval = cast_to_int4(des, scope, rval, lval->vector_width());
|
||||||
need_driver_flag = false;
|
need_driver_flag = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1370,7 +1374,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
// thing needs to go to each instance when arrayed.
|
// thing needs to go to each instance when arrayed.
|
||||||
if ((sig->data_type() == IVL_VT_REAL ) &&
|
if ((sig->data_type() == IVL_VT_REAL ) &&
|
||||||
!prts.empty() && (prts[0]->data_type() != IVL_VT_REAL )) {
|
!prts.empty() && (prts[0]->data_type() != IVL_VT_REAL )) {
|
||||||
sig = cast_to_int(des, scope, sig,
|
sig = cast_to_int4(des, scope, sig,
|
||||||
prts_vector_width/instance.size());
|
prts_vector_width/instance.size());
|
||||||
}
|
}
|
||||||
// If we have a bit/vector signal driving a real port
|
// If we have a bit/vector signal driving a real port
|
||||||
|
|
@ -1478,7 +1482,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
prts_vector_width = sig->vector_width();
|
prts_vector_width = sig->vector_width();
|
||||||
for (unsigned pidx = 0; pidx < prts.size(); pidx += 1) {
|
for (unsigned pidx = 0; pidx < prts.size(); pidx += 1) {
|
||||||
prts[pidx]->port_type(NetNet::NOT_A_PORT);
|
prts[pidx]->port_type(NetNet::NOT_A_PORT);
|
||||||
prts[pidx] = cast_to_int(des, scope, prts[pidx],
|
prts[pidx] = cast_to_int4(des, scope, prts[pidx],
|
||||||
prts_vector_width /
|
prts_vector_width /
|
||||||
instance.size());
|
instance.size());
|
||||||
prts[pidx]->port_type(NetNet::POUTPUT);
|
prts[pidx]->port_type(NetNet::POUTPUT);
|
||||||
|
|
|
||||||
9
emit.cc
9
emit.cc
|
|
@ -72,9 +72,14 @@ bool NetCaseCmp::emit_node(struct target_t*tgt) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetCastInt::emit_node(struct target_t*tgt) const
|
bool NetCastInt2::emit_node(struct target_t*tgt) const
|
||||||
{
|
{
|
||||||
return tgt->lpm_cast_int(this);
|
return tgt->lpm_cast_int2(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetCastInt4::emit_node(struct target_t*tgt) const
|
||||||
|
{
|
||||||
|
return tgt->lpm_cast_int4(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetCastReal::emit_node(struct target_t*tgt) const
|
bool NetCastReal::emit_node(struct target_t*tgt) const
|
||||||
|
|
|
||||||
|
|
@ -993,7 +993,7 @@ NetNet* NetECast::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||||
|
|
||||||
switch (op()) {
|
switch (op()) {
|
||||||
case 'i':
|
case 'i':
|
||||||
isig = cast_to_int(des, scope, isig, isig->vector_width());
|
isig = cast_to_int4(des, scope, isig, isig->vector_width());
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
isig = cast_to_real(des, scope, isig);
|
isig = cast_to_real(des, scope, isig);
|
||||||
|
|
|
||||||
|
|
@ -273,6 +273,7 @@ typedef enum ivl_lpm_type_e {
|
||||||
IVL_LPM_ADD = 0,
|
IVL_LPM_ADD = 0,
|
||||||
IVL_LPM_ARRAY = 30,
|
IVL_LPM_ARRAY = 30,
|
||||||
IVL_LPM_CAST_INT = 34,
|
IVL_LPM_CAST_INT = 34,
|
||||||
|
IVL_LPM_CAST_INT2 = 35,
|
||||||
IVL_LPM_CAST_REAL = 33,
|
IVL_LPM_CAST_REAL = 33,
|
||||||
IVL_LPM_CONCAT = 16,
|
IVL_LPM_CONCAT = 16,
|
||||||
IVL_LPM_CMP_EEQ= 18, /* Case EQ (===) */
|
IVL_LPM_CMP_EEQ= 18, /* Case EQ (===) */
|
||||||
|
|
|
||||||
12
netlist.cc
12
netlist.cc
|
|
@ -951,7 +951,14 @@ const NetScope* NetAnalogTop::scope() const
|
||||||
return scope_;
|
return scope_;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetCastInt::NetCastInt(NetScope*scope__, perm_string n, unsigned width__)
|
NetCastInt2::NetCastInt2(NetScope*scope__, perm_string n, unsigned width__)
|
||||||
|
: NetNode(scope__, n, 2), width_(width__)
|
||||||
|
{
|
||||||
|
pin(0).set_dir(Link::OUTPUT);
|
||||||
|
pin(1).set_dir(Link::INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetCastInt4::NetCastInt4(NetScope*scope__, perm_string n, unsigned width__)
|
||||||
: NetNode(scope__, n, 2), width_(width__)
|
: NetNode(scope__, n, 2), width_(width__)
|
||||||
{
|
{
|
||||||
pin(0).set_dir(Link::OUTPUT);
|
pin(0).set_dir(Link::OUTPUT);
|
||||||
|
|
@ -2457,6 +2464,9 @@ ivl_variable_type_t NetECast::expr_type() const
|
||||||
case 'r':
|
case 'r':
|
||||||
ret = IVL_VT_REAL;
|
ret = IVL_VT_REAL;
|
||||||
break;
|
break;
|
||||||
|
case '2':
|
||||||
|
ret = IVL_VT_BOOL;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
netlist.h
19
netlist.h
|
|
@ -1016,10 +1016,24 @@ class NetArrayDq : public NetNode {
|
||||||
* Convert an IVL_VT_REAL input to a logical value with the
|
* Convert an IVL_VT_REAL input to a logical value with the
|
||||||
* given width. The input is pin(1) and the output is pin(0).
|
* given width. The input is pin(1) and the output is pin(0).
|
||||||
*/
|
*/
|
||||||
class NetCastInt : public NetNode {
|
class NetCastInt4 : public NetNode {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NetCastInt(NetScope*s, perm_string n, unsigned width);
|
NetCastInt4(NetScope*s, perm_string n, unsigned width);
|
||||||
|
|
||||||
|
unsigned width() const { return width_; }
|
||||||
|
|
||||||
|
virtual void dump_node(ostream&, unsigned ind) const;
|
||||||
|
virtual bool emit_node(struct target_t*) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned width_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NetCastInt2 : public NetNode {
|
||||||
|
|
||||||
|
public:
|
||||||
|
NetCastInt2(NetScope*s, perm_string n, unsigned width);
|
||||||
|
|
||||||
unsigned width() const { return width_; }
|
unsigned width() const { return width_; }
|
||||||
|
|
||||||
|
|
@ -3763,6 +3777,7 @@ class NetETernary : public NetExpr {
|
||||||
* X -- Reduction NXOR (~^ or ^~)
|
* X -- Reduction NXOR (~^ or ^~)
|
||||||
* m -- abs(x) (i.e. "magnitude")
|
* m -- abs(x) (i.e. "magnitude")
|
||||||
* i -- Cast from real to integer (vector)
|
* i -- Cast from real to integer (vector)
|
||||||
|
* 2 -- Cast from real or logic (vector) to bool (vector)
|
||||||
* r -- Cast from integer (vector) to real
|
* r -- Cast from integer (vector) to real
|
||||||
*/
|
*/
|
||||||
class NetEUnary : public NetExpr {
|
class NetEUnary : public NetExpr {
|
||||||
|
|
|
||||||
24
netmisc.cc
24
netmisc.cc
|
|
@ -116,7 +116,27 @@ NetNet* sub_net_from(Design*des, NetScope*scope, long val, NetNet*sig)
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetNet* cast_to_int(Design*des, NetScope*scope, NetNet*src, unsigned wid)
|
NetNet* cast_to_int2(Design*des, NetScope*scope, NetNet*src, unsigned wid)
|
||||||
|
{
|
||||||
|
if (src->data_type() == IVL_VT_BOOL)
|
||||||
|
return src;
|
||||||
|
|
||||||
|
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid);
|
||||||
|
tmp->data_type(IVL_VT_BOOL);
|
||||||
|
tmp->set_line(*src);
|
||||||
|
tmp->local_flag(true);
|
||||||
|
|
||||||
|
NetCastInt2*cast = new NetCastInt2(scope, scope->local_symbol(), wid);
|
||||||
|
cast->set_line(*src);
|
||||||
|
des->add_node(cast);
|
||||||
|
|
||||||
|
connect(cast->pin(0), tmp->pin(0));
|
||||||
|
connect(cast->pin(1), src->pin(0));
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetNet* cast_to_int4(Design*des, NetScope*scope, NetNet*src, unsigned wid)
|
||||||
{
|
{
|
||||||
if (src->data_type() != IVL_VT_REAL)
|
if (src->data_type() != IVL_VT_REAL)
|
||||||
return src;
|
return src;
|
||||||
|
|
@ -126,7 +146,7 @@ NetNet* cast_to_int(Design*des, NetScope*scope, NetNet*src, unsigned wid)
|
||||||
tmp->set_line(*src);
|
tmp->set_line(*src);
|
||||||
tmp->local_flag(true);
|
tmp->local_flag(true);
|
||||||
|
|
||||||
NetCastInt*cast = new NetCastInt(scope, scope->local_symbol(), wid);
|
NetCastInt4*cast = new NetCastInt4(scope, scope->local_symbol(), wid);
|
||||||
cast->set_line(*src);
|
cast->set_line(*src);
|
||||||
des->add_node(cast);
|
des->add_node(cast);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,8 @@ extern NetNet*pad_to_width_signed(Design*des, NetNet*n, unsigned w,
|
||||||
* Generate the nodes necessary to cast an expression (a net) to a
|
* Generate the nodes necessary to cast an expression (a net) to a
|
||||||
* real value.
|
* real value.
|
||||||
*/
|
*/
|
||||||
extern NetNet*cast_to_int(Design*des, NetScope*scope, NetNet*src, unsigned wid);
|
extern NetNet*cast_to_int4(Design*des, NetScope*scope, NetNet*src, unsigned wid);
|
||||||
|
extern NetNet*cast_to_int2(Design*des, NetScope*scope, NetNet*src, unsigned wid);
|
||||||
extern NetNet*cast_to_real(Design*des, NetScope*scope, NetNet*src);
|
extern NetNet*cast_to_real(Design*des, NetScope*scope, NetNet*src);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -787,6 +787,12 @@ void PFunction::dump(ostream&out, unsigned ind) const
|
||||||
case PTF_TIME:
|
case PTF_TIME:
|
||||||
out << "time ";
|
out << "time ";
|
||||||
break;
|
break;
|
||||||
|
case PTF_ATOM2:
|
||||||
|
out << "int unsigned ";
|
||||||
|
break;
|
||||||
|
case PTF_ATOM2_S:
|
||||||
|
cout << "int signed ";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (return_type_.range) {
|
if (return_type_.range) {
|
||||||
|
|
|
||||||
|
|
@ -963,6 +963,7 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
|
||||||
switch (net->type) {
|
switch (net->type) {
|
||||||
case IVL_LPM_ABS:
|
case IVL_LPM_ABS:
|
||||||
case IVL_LPM_CAST_INT:
|
case IVL_LPM_CAST_INT:
|
||||||
|
case IVL_LPM_CAST_INT2:
|
||||||
case IVL_LPM_CAST_REAL:
|
case IVL_LPM_CAST_REAL:
|
||||||
assert(idx == 0);
|
assert(idx == 0);
|
||||||
return net->u_.arith.a;
|
return net->u_.arith.a;
|
||||||
|
|
@ -1107,6 +1108,7 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net)
|
||||||
case IVL_LPM_ABS:
|
case IVL_LPM_ABS:
|
||||||
case IVL_LPM_ADD:
|
case IVL_LPM_ADD:
|
||||||
case IVL_LPM_CAST_INT:
|
case IVL_LPM_CAST_INT:
|
||||||
|
case IVL_LPM_CAST_INT2:
|
||||||
case IVL_LPM_CAST_REAL:
|
case IVL_LPM_CAST_REAL:
|
||||||
case IVL_LPM_CMP_GE:
|
case IVL_LPM_CMP_GE:
|
||||||
case IVL_LPM_CMP_GT:
|
case IVL_LPM_CMP_GT:
|
||||||
|
|
@ -1258,6 +1260,7 @@ extern "C" int ivl_lpm_signed(ivl_lpm_t net)
|
||||||
case IVL_LPM_MULT:
|
case IVL_LPM_MULT:
|
||||||
case IVL_LPM_POW:
|
case IVL_LPM_POW:
|
||||||
case IVL_LPM_SUB:
|
case IVL_LPM_SUB:
|
||||||
|
case IVL_LPM_CAST_INT2:
|
||||||
return net->u_.arith.signed_flag;
|
return net->u_.arith.signed_flag;
|
||||||
case IVL_LPM_RE_AND:
|
case IVL_LPM_RE_AND:
|
||||||
case IVL_LPM_RE_OR:
|
case IVL_LPM_RE_OR:
|
||||||
|
|
|
||||||
49
t-dll.cc
49
t-dll.cc
|
|
@ -1485,16 +1485,17 @@ void dll_target::lpm_clshift(const NetCLShift*net)
|
||||||
scope_add_lpm(obj->scope, obj);
|
scope_add_lpm(obj->scope, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dll_target::lpm_cast_int(const NetCastInt*net)
|
bool dll_target::lpm_arith1_(ivl_lpm_type_t lpm_type, unsigned width, bool signed_flag, const NetNode*net)
|
||||||
{
|
{
|
||||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||||
obj->type = IVL_LPM_CAST_INT;
|
obj->type = lpm_type;
|
||||||
obj->name = net->name(); // NetCastInt names are permallocated
|
obj->name = net->name(); // NetCastInt2 names are permallocated
|
||||||
assert(net->scope());
|
assert(net->scope());
|
||||||
obj->scope = find_scope(des_, net->scope());
|
obj->scope = find_scope(des_, net->scope());
|
||||||
assert(obj->scope);
|
assert(obj->scope);
|
||||||
|
|
||||||
obj->width = net->width();
|
obj->width = width;
|
||||||
|
obj->u_.arith.signed_flag = signed_flag? 1 : 0;
|
||||||
|
|
||||||
const Nexus*nex;
|
const Nexus*nex;
|
||||||
|
|
||||||
|
|
@ -1517,37 +1518,19 @@ bool dll_target::lpm_cast_int(const NetCastInt*net)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dll_target::lpm_cast_int2(const NetCastInt2*net)
|
||||||
|
{
|
||||||
|
return lpm_arith1_(IVL_LPM_CAST_INT2, net->width(), true, net);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dll_target::lpm_cast_int4(const NetCastInt4*net)
|
||||||
|
{
|
||||||
|
return lpm_arith1_(IVL_LPM_CAST_INT, net->width(), true, net);
|
||||||
|
}
|
||||||
|
|
||||||
bool dll_target::lpm_cast_real(const NetCastReal*net)
|
bool dll_target::lpm_cast_real(const NetCastReal*net)
|
||||||
{
|
{
|
||||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
return lpm_arith1_(IVL_LPM_CAST_REAL, 0, net->signed_flag(), net);
|
||||||
obj->type = IVL_LPM_CAST_REAL;
|
|
||||||
obj->name = net->name(); // NetCastReal names are permallocated
|
|
||||||
assert(net->scope());
|
|
||||||
obj->scope = find_scope(des_, net->scope());
|
|
||||||
assert(obj->scope);
|
|
||||||
|
|
||||||
obj->width = 0;
|
|
||||||
obj->u_.arith.signed_flag = net->signed_flag()? 1 : 0;
|
|
||||||
|
|
||||||
const Nexus*nex;
|
|
||||||
|
|
||||||
nex = net->pin(0).nexus();
|
|
||||||
assert(nex->t_cookie());
|
|
||||||
|
|
||||||
obj->u_.arith.q = nex->t_cookie();
|
|
||||||
|
|
||||||
nex = net->pin(1).nexus();
|
|
||||||
assert(nex->t_cookie());
|
|
||||||
obj->u_.arith.a = nex->t_cookie();
|
|
||||||
|
|
||||||
nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG);
|
|
||||||
nexus_lpm_add(obj->u_.arith.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
|
|
||||||
|
|
||||||
make_lpm_delays_(obj, net);
|
|
||||||
|
|
||||||
scope_add_lpm(obj->scope, obj);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
5
t-dll.h
5
t-dll.h
|
|
@ -67,7 +67,8 @@ struct dll_target : public target_t, public expr_scan_t {
|
||||||
void lpm_abs(const NetAbs*);
|
void lpm_abs(const NetAbs*);
|
||||||
void lpm_add_sub(const NetAddSub*);
|
void lpm_add_sub(const NetAddSub*);
|
||||||
bool lpm_array_dq(const NetArrayDq*);
|
bool lpm_array_dq(const NetArrayDq*);
|
||||||
bool lpm_cast_int(const NetCastInt*);
|
bool lpm_cast_int2(const NetCastInt2*);
|
||||||
|
bool lpm_cast_int4(const NetCastInt4*);
|
||||||
bool lpm_cast_real(const NetCastReal*);
|
bool lpm_cast_real(const NetCastReal*);
|
||||||
void lpm_clshift(const NetCLShift*);
|
void lpm_clshift(const NetCLShift*);
|
||||||
void lpm_compare(const NetCompare*);
|
void lpm_compare(const NetCompare*);
|
||||||
|
|
@ -175,6 +176,8 @@ struct dll_target : public target_t, public expr_scan_t {
|
||||||
|
|
||||||
ivl_event_t make_lpm_trigger(const NetEvWait*ev);
|
ivl_event_t make_lpm_trigger(const NetEvWait*ev);
|
||||||
|
|
||||||
|
bool lpm_arith1_(ivl_lpm_type_t lpm_type, unsigned wid, bool signed_flag, const NetNode*net);
|
||||||
|
|
||||||
static ivl_expr_t expr_from_value_(const verinum&that);
|
static ivl_expr_t expr_from_value_(const verinum&that);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
11
target.cc
11
target.cc
|
|
@ -114,10 +114,17 @@ bool target_t::lpm_array_dq(const NetArrayDq*)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool target_t::lpm_cast_int(const NetCastInt*)
|
bool target_t::lpm_cast_int2(const NetCastInt2*)
|
||||||
{
|
{
|
||||||
cerr << "target (" << typeid(*this).name() << "): "
|
cerr << "target (" << typeid(*this).name() << "): "
|
||||||
"Unhandled NetCastInt." << endl;
|
"Unhandled NetCastInt2." << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool target_t::lpm_cast_int4(const NetCastInt4*)
|
||||||
|
{
|
||||||
|
cerr << "target (" << typeid(*this).name() << "): "
|
||||||
|
"Unhandled NetCastInt4." << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
3
target.h
3
target.h
|
|
@ -75,7 +75,8 @@ struct target_t {
|
||||||
virtual void lpm_add_sub(const NetAddSub*);
|
virtual void lpm_add_sub(const NetAddSub*);
|
||||||
virtual bool lpm_array_dq(const NetArrayDq*);
|
virtual bool lpm_array_dq(const NetArrayDq*);
|
||||||
virtual void lpm_clshift(const NetCLShift*);
|
virtual void lpm_clshift(const NetCLShift*);
|
||||||
virtual bool lpm_cast_int(const NetCastInt*);
|
virtual bool lpm_cast_int2(const NetCastInt2*);
|
||||||
|
virtual bool lpm_cast_int4(const NetCastInt4*);
|
||||||
virtual bool lpm_cast_real(const NetCastReal*);
|
virtual bool lpm_cast_real(const NetCastReal*);
|
||||||
virtual void lpm_compare(const NetCompare*);
|
virtual void lpm_compare(const NetCompare*);
|
||||||
virtual void lpm_divide(const NetDivide*);
|
virtual void lpm_divide(const NetDivide*);
|
||||||
|
|
|
||||||
|
|
@ -467,6 +467,7 @@ static char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
|
||||||
case IVL_LPM_ABS:
|
case IVL_LPM_ABS:
|
||||||
case IVL_LPM_ADD:
|
case IVL_LPM_ADD:
|
||||||
case IVL_LPM_ARRAY:
|
case IVL_LPM_ARRAY:
|
||||||
|
case IVL_LPM_CAST_INT2:
|
||||||
case IVL_LPM_CAST_INT:
|
case IVL_LPM_CAST_INT:
|
||||||
case IVL_LPM_CAST_REAL:
|
case IVL_LPM_CAST_REAL:
|
||||||
case IVL_LPM_CONCAT:
|
case IVL_LPM_CONCAT:
|
||||||
|
|
|
||||||
|
|
@ -1223,6 +1223,19 @@ static void draw_lpm_abs(ivl_lpm_t net)
|
||||||
net, dly, src_table[0]);
|
net, dly, src_table[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void draw_lpm_cast_int2(ivl_lpm_t net)
|
||||||
|
{
|
||||||
|
const char*src_table[1];
|
||||||
|
const char*dly;
|
||||||
|
|
||||||
|
draw_lpm_data_inputs(net, 0, 1, src_table);
|
||||||
|
|
||||||
|
dly = draw_lpm_output_delay(net, IVL_VT_BOOL);
|
||||||
|
|
||||||
|
fprintf(vvp_out, "L_%p%s .cast/2 %u, %s;\n",
|
||||||
|
net, dly, ivl_lpm_width(net), src_table[0]);
|
||||||
|
}
|
||||||
|
|
||||||
static void draw_lpm_cast_int(ivl_lpm_t net)
|
static void draw_lpm_cast_int(ivl_lpm_t net)
|
||||||
{
|
{
|
||||||
const char*src_table[1];
|
const char*src_table[1];
|
||||||
|
|
@ -1843,6 +1856,10 @@ static void draw_lpm_in_scope(ivl_lpm_t net)
|
||||||
draw_lpm_cast_int(net);
|
draw_lpm_cast_int(net);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case IVL_LPM_CAST_INT2:
|
||||||
|
draw_lpm_cast_int2(net);
|
||||||
|
return;
|
||||||
|
|
||||||
case IVL_LPM_CAST_REAL:
|
case IVL_LPM_CAST_REAL:
|
||||||
draw_lpm_cast_real(net);
|
draw_lpm_cast_real(net);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -358,6 +358,7 @@ net or from a bit based net to a real valued net. These statements
|
||||||
are used to perform that operation:
|
are used to perform that operation:
|
||||||
|
|
||||||
<label> .cast/int <width>, <symbol>;
|
<label> .cast/int <width>, <symbol>;
|
||||||
|
<label> .cast/2 <width>, <symbol>;
|
||||||
<label> .cast/real <symbol>;
|
<label> .cast/real <symbol>;
|
||||||
<label> .cast/real.s <symbol>;
|
<label> .cast/real.s <symbol>;
|
||||||
|
|
||||||
|
|
|
||||||
22
vvp/arith.cc
22
vvp/arith.cc
|
|
@ -121,6 +121,28 @@ void vvp_arith_cast_real::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
||||||
ptr.ptr()->send_real(val, 0);
|
ptr.ptr()->send_real(val, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vvp_arith_cast_vec2::vvp_arith_cast_vec2(unsigned wid)
|
||||||
|
: wid_(wid)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
vvp_arith_cast_vec2::~vvp_arith_cast_vec2()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void vvp_arith_cast_vec2::recv_real(vvp_net_ptr_t ptr, double bit,
|
||||||
|
vvp_context_t)
|
||||||
|
{
|
||||||
|
ptr.ptr()->send_vec4(vvp_vector4_t(wid_, bit), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vvp_arith_cast_vec2::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
||||||
|
vvp_context_t)
|
||||||
|
{
|
||||||
|
vvp_vector2_t tmp = bit;
|
||||||
|
ptr.ptr()->send_vec4(vector2_to_vector4(tmp,tmp.size()), 0);
|
||||||
|
}
|
||||||
|
|
||||||
// Division
|
// Division
|
||||||
|
|
||||||
vvp_arith_div::vvp_arith_div(unsigned wid, bool signed_flag)
|
vvp_arith_div::vvp_arith_div(unsigned wid, bool signed_flag)
|
||||||
|
|
|
||||||
14
vvp/arith.h
14
vvp/arith.h
|
|
@ -86,6 +86,20 @@ class vvp_arith_cast_real : public vvp_net_fun_t {
|
||||||
bool signed_;
|
bool signed_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class vvp_arith_cast_vec2 : public vvp_net_fun_t {
|
||||||
|
public:
|
||||||
|
explicit vvp_arith_cast_vec2(unsigned wid);
|
||||||
|
~vvp_arith_cast_vec2();
|
||||||
|
|
||||||
|
void recv_real(vvp_net_ptr_t ptr, double bit,
|
||||||
|
vvp_context_t);
|
||||||
|
void recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
||||||
|
vvp_context_t);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned wid_;
|
||||||
|
};
|
||||||
|
|
||||||
class vvp_arith_div : public vvp_arith_ {
|
class vvp_arith_div : public vvp_arith_ {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -905,6 +905,22 @@ void compile_arith_cast_int(char*label, long width,
|
||||||
free(argv);
|
free(argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void compile_arith_cast_vec2(char*label, long width,
|
||||||
|
unsigned argc, struct symb_s*argv)
|
||||||
|
{
|
||||||
|
vvp_arith_cast_vec2*arith = new vvp_arith_cast_vec2((unsigned) width);
|
||||||
|
|
||||||
|
vvp_net_t* ptr = new vvp_net_t;
|
||||||
|
ptr->fun = arith;
|
||||||
|
|
||||||
|
define_functor_symbol(label, ptr);
|
||||||
|
free(label);
|
||||||
|
|
||||||
|
assert(argc == 1);
|
||||||
|
inputs_connect(ptr, argc, argv);
|
||||||
|
free(argv);
|
||||||
|
}
|
||||||
|
|
||||||
void compile_arith_cast_real(char*label, bool signed_flag,
|
void compile_arith_cast_real(char*label, bool signed_flag,
|
||||||
unsigned argc, struct symb_s*argv)
|
unsigned argc, struct symb_s*argv)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,8 @@ extern void compile_arith_cast_int(char*label, long width,
|
||||||
unsigned argc, struct symb_s*argv);
|
unsigned argc, struct symb_s*argv);
|
||||||
extern void compile_arith_cast_real(char*label, bool signed_flag,
|
extern void compile_arith_cast_real(char*label, bool signed_flag,
|
||||||
unsigned argc, struct symb_s*argv);
|
unsigned argc, struct symb_s*argv);
|
||||||
|
extern void compile_arith_cast_vec2(char*label, long width,
|
||||||
|
unsigned argc, struct symb_s*argv);
|
||||||
extern void compile_arith_div(char*label, long width, bool signed_flag,
|
extern void compile_arith_div(char*label, long width, bool signed_flag,
|
||||||
unsigned argc, struct symb_s*argv);
|
unsigned argc, struct symb_s*argv);
|
||||||
extern void compile_arith_mod(char*label, long width, bool signed_flag,
|
extern void compile_arith_mod(char*label, long width, bool signed_flag,
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,7 @@ static char* strdupnew(char const *str)
|
||||||
".array/real" { return K_ARRAY_R; }
|
".array/real" { return K_ARRAY_R; }
|
||||||
".array/s" { return K_ARRAY_S; }
|
".array/s" { return K_ARRAY_S; }
|
||||||
".array/port" { return K_ARRAY_PORT; }
|
".array/port" { return K_ARRAY_PORT; }
|
||||||
|
".cast/2" { return K_CAST_2; }
|
||||||
".cast/int" { return K_CAST_INT; }
|
".cast/int" { return K_CAST_INT; }
|
||||||
".cast/real" { return K_CAST_REAL; }
|
".cast/real" { return K_CAST_REAL; }
|
||||||
".cast/real.s" { return K_CAST_REAL_S; }
|
".cast/real.s" { return K_CAST_REAL_S; }
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ static struct __vpiModPath*modpath_dst = 0;
|
||||||
%token K_ARITH_MULT K_ARITH_MULT_R K_ARITH_SUB K_ARITH_SUB_R
|
%token K_ARITH_MULT K_ARITH_MULT_R K_ARITH_SUB K_ARITH_SUB_R
|
||||||
%token K_ARITH_SUM K_ARITH_SUM_R K_ARITH_POW K_ARITH_POW_R K_ARITH_POW_S
|
%token K_ARITH_SUM K_ARITH_SUM_R K_ARITH_POW K_ARITH_POW_R K_ARITH_POW_S
|
||||||
%token K_ARRAY K_ARRAY_I K_ARRAY_R K_ARRAY_S K_ARRAY_PORT
|
%token K_ARRAY K_ARRAY_I K_ARRAY_R K_ARRAY_S K_ARRAY_PORT
|
||||||
%token K_CAST_INT K_CAST_REAL K_CAST_REAL_S
|
%token K_CAST_INT K_CAST_REAL K_CAST_REAL_S K_CAST_2
|
||||||
%token K_CMP_EEQ K_CMP_EQ K_CMP_EQ_R K_CMP_NEE K_CMP_NE K_CMP_NE_R
|
%token K_CMP_EEQ K_CMP_EQ K_CMP_EQ_R K_CMP_NEE K_CMP_NE K_CMP_NE_R
|
||||||
%token K_CMP_GE K_CMP_GE_R K_CMP_GE_S K_CMP_GT K_CMP_GT_R K_CMP_GT_S
|
%token K_CMP_GE K_CMP_GE_R K_CMP_GE_S K_CMP_GT K_CMP_GT_R K_CMP_GT_S
|
||||||
%token K_CONCAT K_DEBUG K_DELAY K_DFF
|
%token K_CONCAT K_DEBUG K_DELAY K_DFF
|
||||||
|
|
@ -286,6 +286,11 @@ statement
|
||||||
compile_arith_cast_real($1, true, obj.cnt, obj.vect);
|
compile_arith_cast_real($1, true, obj.cnt, obj.vect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
| T_LABEL K_CAST_2 T_NUMBER ',' symbols ';'
|
||||||
|
{ struct symbv_s obj = $5;
|
||||||
|
compile_arith_cast_vec2($1, $3, obj.cnt, obj.vect);
|
||||||
|
}
|
||||||
|
|
||||||
/* Arithmetic statements generate functor arrays of a given width
|
/* Arithmetic statements generate functor arrays of a given width
|
||||||
that take like size input vectors. */
|
that take like size input vectors. */
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue