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:
Stephen Williams 2010-10-16 10:53:20 -07:00
parent bad1512cb0
commit 9c634e1640
24 changed files with 215 additions and 69 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -272,7 +272,8 @@ typedef enum ivl_lpm_type_e {
IVL_LPM_ABS = 32, IVL_LPM_ABS = 32,
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 (===) */

View File

@ -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);
} }

View File

@ -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 {

View File

@ -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);

View File

@ -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);
/* /*

View File

@ -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) {

View File

@ -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:

View File

@ -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;
} }
/* /*

View File

@ -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);
}; };

View File

@ -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;
} }

View File

@ -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*);

View File

@ -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:

View File

@ -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;

View File

@ -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>;

View File

@ -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)

View File

@ -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:

View File

@ -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)
{ {

View File

@ -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,

View File

@ -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; }

View File

@ -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
@ -271,20 +271,25 @@ statement
compile_arith_abs($1, obj.cnt, obj.vect); compile_arith_abs($1, obj.cnt, obj.vect);
} }
| T_LABEL K_CAST_INT T_NUMBER ',' symbols ';' | T_LABEL K_CAST_INT T_NUMBER ',' symbols ';'
{ struct symbv_s obj = $5; { struct symbv_s obj = $5;
compile_arith_cast_int($1, $3, obj.cnt, obj.vect); compile_arith_cast_int($1, $3, obj.cnt, obj.vect);
} }
| T_LABEL K_CAST_REAL symbols ';' | T_LABEL K_CAST_REAL symbols ';'
{ struct symbv_s obj = $3; { struct symbv_s obj = $3;
compile_arith_cast_real($1, false, obj.cnt, obj.vect); compile_arith_cast_real($1, false, obj.cnt, obj.vect);
} }
| T_LABEL K_CAST_REAL_S symbols ';' | T_LABEL K_CAST_REAL_S symbols ';'
{ struct symbv_s obj = $3; { struct symbv_s obj = $3;
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. */