Merge branch 'verilog-ams'
This commit is contained in:
commit
10ab5cf698
|
|
@ -247,6 +247,15 @@ void NetObj::dump_obj_attr(ostream&o, unsigned ind) const
|
|||
}
|
||||
}
|
||||
|
||||
void NetAbs::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "Absolute value (NetAbs): " << name()
|
||||
<< " width=" << width() << " pin_count=" << pin_count()
|
||||
<< endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetAddSub::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "Adder (NetAddSub): " << name()
|
||||
|
|
|
|||
40
elab_net.cc
40
elab_net.cc
|
|
@ -3212,6 +3212,32 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
|||
connect(gate->pin(0), sig->pin(0));
|
||||
break;
|
||||
|
||||
case 'm': // abs(sub_sig)
|
||||
// If this expression is self determined, get its width
|
||||
// from the sub_expression.
|
||||
if (owidth == 0)
|
||||
owidth = sub_sig->vector_width();
|
||||
|
||||
if (sub_sig->vector_width() < owidth)
|
||||
sub_sig = pad_to_width(des, sub_sig, owidth);
|
||||
|
||||
sig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, owidth);
|
||||
sig->set_line(*this);
|
||||
sig->data_type(sub_sig->data_type());
|
||||
sig->local_flag(true);
|
||||
|
||||
NetAbs*tmp = new NetAbs(scope, scope->local_symbol(), sub_sig->vector_width());
|
||||
tmp->set_line(*this);
|
||||
des->add_node(tmp);
|
||||
tmp->rise_time(rise);
|
||||
tmp->fall_time(fall);
|
||||
tmp->decay_time(decay);
|
||||
|
||||
connect(tmp->pin(1), sub_sig->pin(0));
|
||||
connect(tmp->pin(0), sig->pin(0));
|
||||
break;
|
||||
|
||||
case 'N': // Reduction NOR
|
||||
case '!': // Reduction NOT
|
||||
reduction=true; rtype = NetUReduce::NOR; break;
|
||||
|
|
@ -3290,7 +3316,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
|||
break;
|
||||
|
||||
default:
|
||||
cerr << "internal error: Unhandled UNARY '" << op_ << "'" << endl;
|
||||
cerr << get_fileline() << ": internal error: Unhandled UNARY '" << op_ << "'" << endl;
|
||||
sig = 0;
|
||||
}
|
||||
|
||||
|
|
@ -3465,6 +3491,18 @@ NetNet* PEUnary::elab_net_unary_real_(Design*des, NetScope*scope,
|
|||
des->errors += 1;
|
||||
break;
|
||||
|
||||
case 'm': // abs()
|
||||
NetAbs*tmp = new NetAbs(scope, scope->local_symbol(), 1);
|
||||
tmp->set_line(*this);
|
||||
tmp->rise_time(rise);
|
||||
tmp->fall_time(fall);
|
||||
tmp->decay_time(decay);
|
||||
des->add_node(tmp);
|
||||
|
||||
connect(tmp->pin(0), sig->pin(0));
|
||||
connect(tmp->pin(1), sub_sig->pin(0));
|
||||
break;
|
||||
|
||||
case '-':
|
||||
NetAddSub*sub = new NetAddSub(scope, scope->local_symbol(), 1);
|
||||
sub->attribute(perm_string::literal("LPM_Direction"),
|
||||
|
|
|
|||
6
emit.cc
6
emit.cc
|
|
@ -49,6 +49,12 @@ bool NetUDP::emit_node(struct target_t*tgt) const
|
|||
return true;
|
||||
}
|
||||
|
||||
bool NetAbs::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->lpm_abs(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetAddSub::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->lpm_add_sub(this);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@ void functor_t::process(class Design*, class NetProcTop*)
|
|||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_abs(class Design*, class NetAbs*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_add_sub(class Design*, class NetAddSub*)
|
||||
{
|
||||
}
|
||||
|
|
@ -174,6 +178,11 @@ void NetNode::functor_node(Design*, functor_t*)
|
|||
{
|
||||
}
|
||||
|
||||
void NetAbs::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_abs(des, this);
|
||||
}
|
||||
|
||||
void NetAddSub::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_add_sub(des, this);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@ struct functor_t {
|
|||
/* This method is called for each process in the design. */
|
||||
virtual void process(class Design*des, class NetProcTop*);
|
||||
|
||||
/* This method is called for each structural abs(). */
|
||||
virtual void lpm_abs(class Design*des, class NetAbs*);
|
||||
|
||||
/* This method is called for each structural adder. */
|
||||
virtual void lpm_add_sub(class Design*des, class NetAddSub*);
|
||||
|
||||
|
|
|
|||
|
|
@ -228,6 +228,7 @@ typedef enum ivl_logic_e {
|
|||
|
||||
/* This is the type of an LPM object. */
|
||||
typedef enum ivl_lpm_type_e {
|
||||
IVL_LPM_ABS = 32,
|
||||
IVL_LPM_ADD = 0,
|
||||
IVL_LPM_ARRAY = 30,
|
||||
IVL_LPM_CONCAT = 16,
|
||||
|
|
|
|||
18
netlist.cc
18
netlist.cc
|
|
@ -1046,6 +1046,24 @@ const verinum& NetFF::sset_value() const
|
|||
}
|
||||
|
||||
|
||||
NetAbs::NetAbs(NetScope*s, perm_string n, unsigned w)
|
||||
: NetNode(s, n, 2), width_(w)
|
||||
{
|
||||
pin(0).set_dir(Link::OUTPUT);
|
||||
pin(0).set_name(perm_string::literal("Result"), 0);
|
||||
pin(1).set_dir(Link::INPUT);
|
||||
pin(1).set_name(perm_string::literal("DataA"), 0);
|
||||
}
|
||||
|
||||
NetAbs::~NetAbs()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned NetAbs::width() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
/*
|
||||
* The NetAddSub class represents an LPM_ADD_SUB device. The pinout is
|
||||
* assigned like so:
|
||||
|
|
|
|||
21
netlist.h
21
netlist.h
|
|
@ -578,6 +578,27 @@ class NetNet : public NetObj {
|
|||
vector<class NetDelaySrc*> delay_paths_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This class implements the LPM_ABS component. The node has a single
|
||||
* input, a signe expression, that it converts to the absolute
|
||||
* value. The gate is simple: pin(0) is the output and pin(1) is the input.
|
||||
*/
|
||||
class NetAbs : public NetNode {
|
||||
|
||||
public:
|
||||
NetAbs(NetScope*s, perm_string n, unsigned width);
|
||||
~NetAbs();
|
||||
|
||||
unsigned width() const;
|
||||
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
virtual bool emit_node(struct target_t*) const;
|
||||
virtual void functor_node(Design*des, functor_t*fun);
|
||||
|
||||
private:
|
||||
unsigned width_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This class implements the LPM_ADD_SUB component as described in the
|
||||
* EDIF LPM Version 2 1 0 standard. It is used as a structural
|
||||
|
|
|
|||
|
|
@ -864,6 +864,10 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
|
|||
{
|
||||
assert(net);
|
||||
switch (net->type) {
|
||||
case IVL_LPM_ABS:
|
||||
assert(idx == 0);
|
||||
return net->u_.arith.a;
|
||||
|
||||
case IVL_LPM_ADD:
|
||||
case IVL_LPM_CMP_EEQ:
|
||||
case IVL_LPM_CMP_EQ:
|
||||
|
|
@ -1002,6 +1006,7 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx)
|
|||
assert(net);
|
||||
|
||||
switch (net->type) {
|
||||
case IVL_LPM_ABS:
|
||||
case IVL_LPM_ADD:
|
||||
case IVL_LPM_DIVIDE:
|
||||
case IVL_LPM_MOD:
|
||||
|
|
@ -1118,6 +1123,7 @@ extern "C" int ivl_lpm_signed(ivl_lpm_t net)
|
|||
case IVL_LPM_FF:
|
||||
case IVL_LPM_MUX:
|
||||
return 0;
|
||||
case IVL_LPM_ABS:
|
||||
case IVL_LPM_ADD:
|
||||
case IVL_LPM_CMP_EEQ:
|
||||
case IVL_LPM_CMP_EQ:
|
||||
|
|
|
|||
32
t-dll.cc
32
t-dll.cc
|
|
@ -1307,6 +1307,38 @@ void dll_target::udp(const NetUDP*net)
|
|||
scope_add_logic(scope, obj);
|
||||
}
|
||||
|
||||
void dll_target::lpm_abs(const NetAbs*net)
|
||||
{
|
||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||
obj->type = IVL_LPM_ABS;
|
||||
obj->name = net->name(); // NetAddSub names are permallocated.
|
||||
assert(net->scope());
|
||||
obj->scope = find_scope(des_, net->scope());
|
||||
assert(obj->scope);
|
||||
|
||||
obj->u_.arith.signed_flag = 0;
|
||||
obj->width = net->width();
|
||||
|
||||
const Nexus*nex;
|
||||
/* the output is pin(0) */
|
||||
nex = net->pin(0).nexus();
|
||||
assert(nex->t_cookie());
|
||||
|
||||
obj->u_.arith.q = nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG);
|
||||
|
||||
nex = net->pin(1).nexus();
|
||||
assert(nex->t_cookie());
|
||||
|
||||
/* pin(1) is the input data. */
|
||||
obj->u_.arith.a = nex->t_cookie();
|
||||
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);
|
||||
}
|
||||
|
||||
void dll_target::lpm_add_sub(const NetAddSub*net)
|
||||
{
|
||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||
|
|
|
|||
1
t-dll.h
1
t-dll.h
|
|
@ -70,6 +70,7 @@ struct dll_target : public target_t, public expr_scan_t {
|
|||
bool ureduce(const NetUReduce*);
|
||||
void net_case_cmp(const NetCaseCmp*);
|
||||
void udp(const NetUDP*);
|
||||
void lpm_abs(const NetAbs*);
|
||||
void lpm_add_sub(const NetAddSub*);
|
||||
bool lpm_array_dq(const NetArrayDq*);
|
||||
void lpm_clshift(const NetCLShift*);
|
||||
|
|
|
|||
|
|
@ -81,6 +81,12 @@ bool target_t::ureduce(const NetUReduce*)
|
|||
return false;
|
||||
}
|
||||
|
||||
void target_t::lpm_abs(const NetAbs*)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
"Unhandled NetAbs." << endl;
|
||||
}
|
||||
|
||||
void target_t::lpm_add_sub(const NetAddSub*)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
|
|
|
|||
1
target.h
1
target.h
|
|
@ -68,6 +68,7 @@ struct target_t {
|
|||
virtual bool func_def(const NetScope*);
|
||||
|
||||
/* LPM style components are handled here. */
|
||||
virtual void lpm_abs(const NetAbs*);
|
||||
virtual void lpm_add_sub(const NetAddSub*);
|
||||
virtual bool lpm_array_dq(const NetArrayDq*);
|
||||
virtual void lpm_clshift(const NetCLShift*);
|
||||
|
|
|
|||
|
|
@ -160,6 +160,28 @@ static void show_ternary_expression(ivl_expr_t net, unsigned ind)
|
|||
}
|
||||
}
|
||||
|
||||
void show_unary_expression(ivl_expr_t net, unsigned ind)
|
||||
{
|
||||
unsigned width = ivl_expr_width(net);
|
||||
const char*sign = ivl_expr_signed(net)? "signed" : "unsigned";
|
||||
const char*vt = vt_type_string(net);
|
||||
|
||||
char name[8];
|
||||
switch (ivl_expr_opcode(net)) {
|
||||
default:
|
||||
snprintf(name, sizeof name, "%c", ivl_expr_opcode(net));
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
snprintf(name, sizeof name, "abs()");
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(out, "%*s<unary \"%s\" width=%u, %s, type=%s>\n", ind, "",
|
||||
name, width, sign, vt);
|
||||
show_expression(ivl_expr_oper1(net), ind+4);
|
||||
}
|
||||
|
||||
void show_expression(ivl_expr_t net, unsigned ind)
|
||||
{
|
||||
unsigned idx;
|
||||
|
|
@ -252,9 +274,7 @@ void show_expression(ivl_expr_t net, unsigned ind)
|
|||
break;
|
||||
|
||||
case IVL_EX_UNARY:
|
||||
fprintf(out, "%*s<unary \"%c\" width=%u, %s, type=%s>\n", ind, "",
|
||||
ivl_expr_opcode(net), width, sign, vt);
|
||||
show_expression(ivl_expr_oper1(net), ind+4);
|
||||
show_unary_expression(net, ind);
|
||||
break;
|
||||
|
||||
case IVL_EX_UFUNC:
|
||||
|
|
|
|||
|
|
@ -175,6 +175,32 @@ static void show_lpm_arithmetic_pins(ivl_lpm_t net)
|
|||
fprintf(out, " DataB: %s\n", nex? ivl_nexus_name(nex) : "");
|
||||
}
|
||||
|
||||
static void show_lpm_abs(ivl_lpm_t net)
|
||||
{
|
||||
unsigned width = ivl_lpm_width(net);
|
||||
|
||||
fprintf(out, " LPM_ABS %s: <width=%u>\n",
|
||||
ivl_lpm_basename(net), width);
|
||||
|
||||
ivl_nexus_t nex;
|
||||
nex = ivl_lpm_q(net, 0);
|
||||
fprintf(out, " Q: %s\n", ivl_nexus_name(ivl_lpm_q(net, 0)));
|
||||
|
||||
nex = ivl_lpm_data(net, 0);
|
||||
fprintf(out, " D: %s\n", nex? ivl_nexus_name(nex) : "");
|
||||
if (nex == 0) {
|
||||
fprintf(out, " ERROR: missing input\n");
|
||||
stub_errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (width_of_nexus(nex) != width) {
|
||||
fprintf(out, " ERROR: D width (%d) is wrong\n",
|
||||
width_of_nexus(nex));
|
||||
stub_errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void show_lpm_add(ivl_lpm_t net)
|
||||
{
|
||||
unsigned width = ivl_lpm_width(net);
|
||||
|
|
@ -796,6 +822,10 @@ static void show_lpm(ivl_lpm_t net)
|
|||
|
||||
switch (ivl_lpm_type(net)) {
|
||||
|
||||
case IVL_LPM_ABS:
|
||||
show_lpm_abs(net);
|
||||
break;
|
||||
|
||||
case IVL_LPM_ADD:
|
||||
show_lpm_add(net);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -2456,6 +2456,32 @@ static struct vector_info draw_unary_expr(ivl_expr_t exp, unsigned wid)
|
|||
}
|
||||
break;
|
||||
|
||||
case 'm': /* abs() */
|
||||
res = draw_eval_expr_wid(sub, wid, 0);
|
||||
|
||||
if (!ivl_expr_signed(sub))
|
||||
break;
|
||||
|
||||
if (res.base == 0 || res.base == 2 || res.base == 3)
|
||||
break;
|
||||
|
||||
/* Handle the special case of a -1 constant. Make the
|
||||
result a 1. */
|
||||
if (res.base == 1) {
|
||||
res.base = allocate_vector(wid);
|
||||
fprintf(vvp_out, " %%movi %d, 1, %u;\n",
|
||||
res.base, res.wid);
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%cmpi/s %d, 0, %u;\n", res.base, res.wid);
|
||||
fprintf(vvp_out, " %%jmp/0xz T_%u.%u, 5;\n", thread_count, local_count);
|
||||
fprintf(vvp_out, " %%inv %d, %u;\n", res.base, res.wid);
|
||||
fprintf(vvp_out, " %%addi %d, 1, %u;\n", res.base, res.wid);
|
||||
fprintf(vvp_out, "T_%u.%u ;\n", thread_count, local_count);
|
||||
local_count += 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "vvp error: unhandled unary: %c\n",
|
||||
ivl_expr_opcode(exp));
|
||||
|
|
|
|||
|
|
@ -679,6 +679,7 @@ static char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
|
|||
if (lpm) switch (ivl_lpm_type(lpm)) {
|
||||
|
||||
case IVL_LPM_FF:
|
||||
case IVL_LPM_ABS:
|
||||
case IVL_LPM_ADD:
|
||||
case IVL_LPM_ARRAY:
|
||||
case IVL_LPM_CONCAT:
|
||||
|
|
@ -1693,6 +1694,17 @@ static const char* draw_lpm_output_delay(ivl_lpm_t net)
|
|||
return dly;
|
||||
}
|
||||
|
||||
static void draw_lpm_abs(ivl_lpm_t net)
|
||||
{
|
||||
const char*src_table[1];
|
||||
draw_lpm_data_inputs(net, 0, 1, src_table);
|
||||
|
||||
const char*dly = draw_lpm_output_delay(net);
|
||||
|
||||
fprintf(vvp_out, "L_%p%s .abs %s;\n",
|
||||
net, dly, src_table[0]);
|
||||
}
|
||||
|
||||
static void draw_lpm_add(ivl_lpm_t net)
|
||||
{
|
||||
const char*src_table[2];
|
||||
|
|
@ -2338,6 +2350,10 @@ static void draw_lpm_in_scope(ivl_lpm_t net)
|
|||
{
|
||||
switch (ivl_lpm_type(net)) {
|
||||
|
||||
case IVL_LPM_ABS:
|
||||
draw_lpm_abs(net);
|
||||
return;
|
||||
|
||||
case IVL_LPM_ADD:
|
||||
case IVL_LPM_SUB:
|
||||
case IVL_LPM_MULT:
|
||||
|
|
|
|||
35
vvp/arith.cc
35
vvp/arith.cc
|
|
@ -55,6 +55,41 @@ void vvp_arith_::dispatch_operand_(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
|||
}
|
||||
|
||||
|
||||
vvp_arith_abs::vvp_arith_abs()
|
||||
{
|
||||
}
|
||||
|
||||
vvp_arith_abs::~vvp_arith_abs()
|
||||
{
|
||||
}
|
||||
|
||||
void vvp_arith_abs::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit)
|
||||
{
|
||||
vvp_vector4_t out (bit.size(), BIT4_0);;
|
||||
|
||||
vvp_bit4_t cmp = compare_gtge_signed(bit, out, BIT4_1);
|
||||
switch (cmp) {
|
||||
case BIT4_1: // bit >= 0
|
||||
out = bit;
|
||||
break;
|
||||
case BIT4_0: // bit < 0
|
||||
out = ~bit;
|
||||
out += 1;
|
||||
break;
|
||||
default: // There's an X.
|
||||
out = vvp_vector4_t(bit.size(), BIT4_X);
|
||||
break;
|
||||
}
|
||||
|
||||
vvp_send_vec4(ptr.ptr()->out, out);
|
||||
}
|
||||
|
||||
void vvp_arith_abs::recv_real(vvp_net_ptr_t ptr, double bit)
|
||||
{
|
||||
double out = fabs(bit);
|
||||
vvp_send_real(ptr.ptr()->out, out);
|
||||
}
|
||||
|
||||
// Division
|
||||
|
||||
vvp_arith_div::vvp_arith_div(unsigned wid, bool signed_flag)
|
||||
|
|
|
|||
11
vvp/arith.h
11
vvp/arith.h
|
|
@ -49,6 +49,17 @@ class vvp_arith_ : public vvp_net_fun_t {
|
|||
vvp_vector4_t x_val_;
|
||||
};
|
||||
|
||||
class vvp_arith_abs : public vvp_net_fun_t {
|
||||
public:
|
||||
explicit vvp_arith_abs();
|
||||
~vvp_arith_abs();
|
||||
|
||||
void recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit);
|
||||
void recv_real(vvp_net_ptr_t ptr, double bit);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class vvp_arith_div : public vvp_arith_ {
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -941,6 +941,21 @@ template <class T_> void make_arith(T_ *arith, char*label,
|
|||
free(argv);
|
||||
}
|
||||
|
||||
void compile_arith_abs(char*label, unsigned argc, struct symb_s*argv)
|
||||
{
|
||||
vvp_arith_abs*arith = new vvp_arith_abs;
|
||||
|
||||
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_div(char*label, long wid, bool signed_flag,
|
||||
unsigned argc, struct symb_s*argv)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -149,6 +149,8 @@ extern void compile_part_select_var(char*label, char*src,
|
|||
*/
|
||||
extern void compile_arith_pow(char*label, long width, bool signed_flag,
|
||||
unsigned argc, struct symb_s*argv);
|
||||
extern void compile_arith_abs(char*label,
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@
|
|||
".alias" { return K_ALIAS; }
|
||||
".alias/real" { return K_ALIAS_R; }
|
||||
".alias/s" { return K_ALIAS_S; }
|
||||
".abs" { return K_ARITH_ABS; }
|
||||
".arith/div" { return K_ARITH_DIV; }
|
||||
".arith/div.r" { return K_ARITH_DIV_R; }
|
||||
".arith/div.s" { return K_ARITH_DIV_S; }
|
||||
|
|
|
|||
11
vvp/parse.y
11
vvp/parse.y
|
|
@ -66,7 +66,8 @@ static struct __vpiModPath*modpath_dst = 0;
|
|||
};
|
||||
|
||||
%token K_ALIAS K_ALIAS_S K_ALIAS_R
|
||||
%token K_ARITH_DIV K_ARITH_DIV_R K_ARITH_DIV_S K_ARITH_MOD K_ARITH_MOD_R
|
||||
%token K_ARITH_ABS K_ARITH_DIV K_ARITH_DIV_R K_ARITH_DIV_S K_ARITH_MOD
|
||||
%token K_ARITH_MOD_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_ARRAY K_ARRAY_I K_ARRAY_R K_ARRAY_S K_ARRAY_PORT
|
||||
|
|
@ -248,6 +249,14 @@ statement
|
|||
symbols ';'
|
||||
{ compile_concat($1, $4, $5, $6, $7, $10.cnt, $10.vect); }
|
||||
|
||||
/* The ABS statement is a special arithmetic node that takes 1
|
||||
input. Re-use the symbols rule. */
|
||||
|
||||
| T_LABEL K_ARITH_ABS symbols ';'
|
||||
{ struct symbv_s obj = $3;
|
||||
compile_arith_abs($1, obj.cnt, obj.vect);
|
||||
}
|
||||
|
||||
/* Arithmetic statements generate functor arrays of a given width
|
||||
that take like size input vectors. */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue