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);
|
||||
}
|
||||
|
||||
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;
|
||||
dump_node_pins(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;
|
||||
|
||||
/* Cast the right side when needed. */
|
||||
if ((lval->data_type() == IVL_VT_REAL &&
|
||||
rval->data_type() != IVL_VT_REAL)) {
|
||||
if ((lval->data_type() == IVL_VT_REAL) &&
|
||||
(rval->data_type() != IVL_VT_REAL)) {
|
||||
rval = cast_to_real(des, scope, rval);
|
||||
need_driver_flag = false;
|
||||
} else if ((lval->data_type() != IVL_VT_REAL &&
|
||||
rval->data_type() == IVL_VT_REAL)) {
|
||||
rval = cast_to_int(des, scope, rval, lval->vector_width());
|
||||
} else if ((lval->data_type() == IVL_VT_BOOL) &&
|
||||
(rval->data_type() != IVL_VT_BOOL)) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1370,7 +1374,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
// thing needs to go to each instance when arrayed.
|
||||
if ((sig->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());
|
||||
}
|
||||
// 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();
|
||||
for (unsigned pidx = 0; pidx < prts.size(); pidx += 1) {
|
||||
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 /
|
||||
instance.size());
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -993,7 +993,7 @@ NetNet* NetECast::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
|
||||
switch (op()) {
|
||||
case 'i':
|
||||
isig = cast_to_int(des, scope, isig, isig->vector_width());
|
||||
isig = cast_to_int4(des, scope, isig, isig->vector_width());
|
||||
break;
|
||||
case 'r':
|
||||
isig = cast_to_real(des, scope, isig);
|
||||
|
|
|
|||
|
|
@ -272,7 +272,8 @@ typedef enum ivl_lpm_type_e {
|
|||
IVL_LPM_ABS = 32,
|
||||
IVL_LPM_ADD = 0,
|
||||
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_CONCAT = 16,
|
||||
IVL_LPM_CMP_EEQ= 18, /* Case EQ (===) */
|
||||
|
|
|
|||
12
netlist.cc
12
netlist.cc
|
|
@ -951,7 +951,14 @@ const NetScope* NetAnalogTop::scope() const
|
|||
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__)
|
||||
{
|
||||
pin(0).set_dir(Link::OUTPUT);
|
||||
|
|
@ -2457,6 +2464,9 @@ ivl_variable_type_t NetECast::expr_type() const
|
|||
case 'r':
|
||||
ret = IVL_VT_REAL;
|
||||
break;
|
||||
case '2':
|
||||
ret = IVL_VT_BOOL;
|
||||
break;
|
||||
default:
|
||||
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
|
||||
* given width. The input is pin(1) and the output is pin(0).
|
||||
*/
|
||||
class NetCastInt : public NetNode {
|
||||
class NetCastInt4 : public NetNode {
|
||||
|
||||
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_; }
|
||||
|
||||
|
|
@ -3763,6 +3777,7 @@ class NetETernary : public NetExpr {
|
|||
* X -- Reduction NXOR (~^ or ^~)
|
||||
* m -- abs(x) (i.e. "magnitude")
|
||||
* i -- Cast from real to integer (vector)
|
||||
* 2 -- Cast from real or logic (vector) to bool (vector)
|
||||
* r -- Cast from integer (vector) to real
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
return src;
|
||||
|
|
@ -126,7 +146,7 @@ NetNet* cast_to_int(Design*des, NetScope*scope, NetNet*src, unsigned wid)
|
|||
tmp->set_line(*src);
|
||||
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);
|
||||
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
|
||||
* 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);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -787,6 +787,12 @@ void PFunction::dump(ostream&out, unsigned ind) const
|
|||
case PTF_TIME:
|
||||
out << "time ";
|
||||
break;
|
||||
case PTF_ATOM2:
|
||||
out << "int unsigned ";
|
||||
break;
|
||||
case PTF_ATOM2_S:
|
||||
cout << "int signed ";
|
||||
break;
|
||||
}
|
||||
|
||||
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) {
|
||||
case IVL_LPM_ABS:
|
||||
case IVL_LPM_CAST_INT:
|
||||
case IVL_LPM_CAST_INT2:
|
||||
case IVL_LPM_CAST_REAL:
|
||||
assert(idx == 0);
|
||||
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_ADD:
|
||||
case IVL_LPM_CAST_INT:
|
||||
case IVL_LPM_CAST_INT2:
|
||||
case IVL_LPM_CAST_REAL:
|
||||
case IVL_LPM_CMP_GE:
|
||||
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_POW:
|
||||
case IVL_LPM_SUB:
|
||||
case IVL_LPM_CAST_INT2:
|
||||
return net->u_.arith.signed_flag;
|
||||
case IVL_LPM_RE_AND:
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
obj->type = IVL_LPM_CAST_INT;
|
||||
obj->name = net->name(); // NetCastInt names are permallocated
|
||||
obj->type = lpm_type;
|
||||
obj->name = net->name(); // NetCastInt2 names are permallocated
|
||||
assert(net->scope());
|
||||
obj->scope = find_scope(des_, net->scope());
|
||||
assert(obj->scope);
|
||||
|
||||
obj->width = net->width();
|
||||
obj->width = width;
|
||||
obj->u_.arith.signed_flag = signed_flag? 1 : 0;
|
||||
|
||||
const Nexus*nex;
|
||||
|
||||
|
|
@ -1517,37 +1518,19 @@ bool dll_target::lpm_cast_int(const NetCastInt*net)
|
|||
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)
|
||||
{
|
||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||
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;
|
||||
return lpm_arith1_(IVL_LPM_CAST_REAL, 0, net->signed_flag(), net);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
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_add_sub(const NetAddSub*);
|
||||
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*);
|
||||
void lpm_clshift(const NetCLShift*);
|
||||
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);
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
|
|
|
|||
11
target.cc
11
target.cc
|
|
@ -114,10 +114,17 @@ bool target_t::lpm_array_dq(const NetArrayDq*)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool target_t::lpm_cast_int(const NetCastInt*)
|
||||
bool target_t::lpm_cast_int2(const NetCastInt2*)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
3
target.h
3
target.h
|
|
@ -75,7 +75,8 @@ struct target_t {
|
|||
virtual void lpm_add_sub(const NetAddSub*);
|
||||
virtual bool lpm_array_dq(const NetArrayDq*);
|
||||
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 void lpm_compare(const NetCompare*);
|
||||
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_ADD:
|
||||
case IVL_LPM_ARRAY:
|
||||
case IVL_LPM_CAST_INT2:
|
||||
case IVL_LPM_CAST_INT:
|
||||
case IVL_LPM_CAST_REAL:
|
||||
case IVL_LPM_CONCAT:
|
||||
|
|
|
|||
|
|
@ -1223,6 +1223,19 @@ static void draw_lpm_abs(ivl_lpm_t net)
|
|||
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)
|
||||
{
|
||||
const char*src_table[1];
|
||||
|
|
@ -1843,6 +1856,10 @@ static void draw_lpm_in_scope(ivl_lpm_t net)
|
|||
draw_lpm_cast_int(net);
|
||||
return;
|
||||
|
||||
case IVL_LPM_CAST_INT2:
|
||||
draw_lpm_cast_int2(net);
|
||||
return;
|
||||
|
||||
case IVL_LPM_CAST_REAL:
|
||||
draw_lpm_cast_real(net);
|
||||
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:
|
||||
|
||||
<label> .cast/int <width>, <symbol>;
|
||||
<label> .cast/2 <width>, <symbol>;
|
||||
<label> .cast/real <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);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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_;
|
||||
};
|
||||
|
||||
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_ {
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -905,6 +905,22 @@ void compile_arith_cast_int(char*label, long width,
|
|||
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,
|
||||
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);
|
||||
extern void compile_arith_cast_real(char*label, bool signed_flag,
|
||||
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,
|
||||
unsigned argc, struct symb_s*argv);
|
||||
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/s" { return K_ARRAY_S; }
|
||||
".array/port" { return K_ARRAY_PORT; }
|
||||
".cast/2" { return K_CAST_2; }
|
||||
".cast/int" { return K_CAST_INT; }
|
||||
".cast/real" { return K_CAST_REAL; }
|
||||
".cast/real.s" { return K_CAST_REAL_S; }
|
||||
|
|
|
|||
31
vvp/parse.y
31
vvp/parse.y
|
|
@ -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_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_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_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
|
||||
|
|
@ -271,20 +271,25 @@ statement
|
|||
compile_arith_abs($1, obj.cnt, obj.vect);
|
||||
}
|
||||
|
||||
| T_LABEL K_CAST_INT T_NUMBER ',' symbols ';'
|
||||
{ struct symbv_s obj = $5;
|
||||
compile_arith_cast_int($1, $3, obj.cnt, obj.vect);
|
||||
}
|
||||
| T_LABEL K_CAST_INT T_NUMBER ',' symbols ';'
|
||||
{ struct symbv_s obj = $5;
|
||||
compile_arith_cast_int($1, $3, obj.cnt, obj.vect);
|
||||
}
|
||||
|
||||
| T_LABEL K_CAST_REAL symbols ';'
|
||||
{ struct symbv_s obj = $3;
|
||||
compile_arith_cast_real($1, false, obj.cnt, obj.vect);
|
||||
}
|
||||
| T_LABEL K_CAST_REAL symbols ';'
|
||||
{ struct symbv_s obj = $3;
|
||||
compile_arith_cast_real($1, false, obj.cnt, obj.vect);
|
||||
}
|
||||
|
||||
| T_LABEL K_CAST_REAL_S symbols ';'
|
||||
{ struct symbv_s obj = $3;
|
||||
compile_arith_cast_real($1, true, obj.cnt, obj.vect);
|
||||
}
|
||||
| T_LABEL K_CAST_REAL_S symbols ';'
|
||||
{ struct symbv_s obj = $3;
|
||||
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
|
||||
that take like size input vectors. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue