Get compressed assignment opcodes through to the ivl_target API.
This commit is contained in:
parent
21732a58c9
commit
3dabb2970d
|
|
@ -824,6 +824,9 @@ void NetAssign::dump(ostream&o, unsigned ind) const
|
||||||
o << setw(ind) << "";
|
o << setw(ind) << "";
|
||||||
dump_lval(o);
|
dump_lval(o);
|
||||||
|
|
||||||
|
if (op_)
|
||||||
|
o << " " << op_ << "= ";
|
||||||
|
else
|
||||||
o << " = ";
|
o << " = ";
|
||||||
|
|
||||||
if (const NetExpr*de = get_delay())
|
if (const NetExpr*de = get_delay())
|
||||||
|
|
|
||||||
|
|
@ -2271,7 +2271,7 @@ NetProc* PAssign::elaborate_compressed_(Design*des, NetScope*scope) const
|
||||||
NetExpr*rv = elaborate_rval_(des, scope, count_lval_width(lv), lv->expr_type());
|
NetExpr*rv = elaborate_rval_(des, scope, count_lval_width(lv), lv->expr_type());
|
||||||
if (rv == 0) return 0;
|
if (rv == 0) return 0;
|
||||||
|
|
||||||
NetAssign*cur = new NetAssign(lv, rv);
|
NetAssign*cur = new NetAssign(lv, op_, rv);
|
||||||
cur->set_line(*this);
|
cur->set_line(*this);
|
||||||
|
|
||||||
return cur;
|
return cur;
|
||||||
|
|
|
||||||
1
ivl.def
1
ivl.def
|
|
@ -272,6 +272,7 @@ ivl_stmt_lvals
|
||||||
ivl_stmt_lwidth
|
ivl_stmt_lwidth
|
||||||
ivl_stmt_name
|
ivl_stmt_name
|
||||||
ivl_stmt_nevent
|
ivl_stmt_nevent
|
||||||
|
ivl_stmt_opcode
|
||||||
ivl_stmt_parm
|
ivl_stmt_parm
|
||||||
ivl_stmt_parm_count
|
ivl_stmt_parm_count
|
||||||
ivl_stmt_rval
|
ivl_stmt_rval
|
||||||
|
|
|
||||||
|
|
@ -1995,6 +1995,13 @@ extern unsigned ivl_stmt_lineno(ivl_statement_t net);
|
||||||
* the statement.) The ivl_stmt_delay_expr function returns the
|
* the statement.) The ivl_stmt_delay_expr function returns the
|
||||||
* expression for the delay, or nil if there is no delay expression.
|
* expression for the delay, or nil if there is no delay expression.
|
||||||
*
|
*
|
||||||
|
* The blocking assignment (IVL_ST_ASSIGN) may have an associated
|
||||||
|
* opcode, that can be extracted from ivl_stmt_opcode(). This opcode
|
||||||
|
* is the compressed operator used it statements like this:
|
||||||
|
* foo += <expr>
|
||||||
|
* The ivl_stmt_opcode() returns null (0) if this is not a compressed
|
||||||
|
* assignment statment.
|
||||||
|
*
|
||||||
* - IVL_ST_CASSIGN
|
* - IVL_ST_CASSIGN
|
||||||
* This reflects a procedural continuous assignment to an l-value. The
|
* This reflects a procedural continuous assignment to an l-value. The
|
||||||
* l-value is the same as any other assignment (use ivl_stmt_lval).
|
* l-value is the same as any other assignment (use ivl_stmt_lval).
|
||||||
|
|
@ -2088,6 +2095,8 @@ extern unsigned ivl_stmt_lvals(ivl_statement_t net);
|
||||||
extern unsigned ivl_stmt_lwidth(ivl_statement_t net);
|
extern unsigned ivl_stmt_lwidth(ivl_statement_t net);
|
||||||
/* IVL_ST_STASK */
|
/* IVL_ST_STASK */
|
||||||
extern const char* ivl_stmt_name(ivl_statement_t net);
|
extern const char* ivl_stmt_name(ivl_statement_t net);
|
||||||
|
/* IVL_ST_ASSIGN */
|
||||||
|
extern char ivl_stmt_opcode(ivl_statement_t net);
|
||||||
/* IVL_ST_STASK */
|
/* IVL_ST_STASK */
|
||||||
extern ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx);
|
extern ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx);
|
||||||
/* IVL_ST_STASK */
|
/* IVL_ST_STASK */
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,12 @@ const NetExpr* NetAssignBase::get_delay() const
|
||||||
}
|
}
|
||||||
|
|
||||||
NetAssign::NetAssign(NetAssign_*lv, NetExpr*rv)
|
NetAssign::NetAssign(NetAssign_*lv, NetExpr*rv)
|
||||||
: NetAssignBase(lv, rv)
|
: NetAssignBase(lv, rv), op_(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NetAssign::NetAssign(NetAssign_*lv, char op, NetExpr*rv)
|
||||||
|
: NetAssignBase(lv, rv), op_(op)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2406,15 +2406,19 @@ class NetAssign : public NetAssignBase {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit NetAssign(NetAssign_*lv, NetExpr*rv);
|
explicit NetAssign(NetAssign_*lv, NetExpr*rv);
|
||||||
|
explicit NetAssign(NetAssign_*lv, char op, NetExpr*rv);
|
||||||
~NetAssign();
|
~NetAssign();
|
||||||
|
|
||||||
bool is_asynchronous();
|
bool is_asynchronous();
|
||||||
|
|
||||||
|
inline char assign_operator(void) const { return op_; }
|
||||||
|
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual int match_proc(struct proc_match_t*);
|
virtual int match_proc(struct proc_match_t*);
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
char op_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetAssignNB : public NetAssignBase {
|
class NetAssignNB : public NetAssignBase {
|
||||||
|
|
|
||||||
11
t-dll-api.cc
11
t-dll-api.cc
|
|
@ -2547,6 +2547,17 @@ extern "C" const char* ivl_stmt_name(ivl_statement_t net)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" char ivl_stmt_opcode(ivl_statement_t net)
|
||||||
|
{
|
||||||
|
switch (net->type_) {
|
||||||
|
case IVL_ST_ASSIGN:
|
||||||
|
return net->u_.assign_.oper;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx)
|
extern "C" ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx)
|
||||||
{
|
{
|
||||||
switch (net->type_) {
|
switch (net->type_) {
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,7 @@ bool dll_target::proc_assign(const NetAssign*net)
|
||||||
/* Make the lval fields. */
|
/* Make the lval fields. */
|
||||||
make_assign_lvals_(net);
|
make_assign_lvals_(net);
|
||||||
|
|
||||||
|
stmt_cur_->u_.assign_.oper = net->assign_operator();
|
||||||
assert(expr_ == 0);
|
assert(expr_ == 0);
|
||||||
net->rval()->expr_scan(this);
|
net->rval()->expr_scan(this);
|
||||||
stmt_cur_->u_.assign_.rval_ = expr_;
|
stmt_cur_->u_.assign_.rval_ = expr_;
|
||||||
|
|
|
||||||
1
t-dll.h
1
t-dll.h
|
|
@ -729,6 +729,7 @@ struct ivl_statement_s {
|
||||||
IVL_ST_CASSIGN, IVL_ST_DEASSIGN */
|
IVL_ST_CASSIGN, IVL_ST_DEASSIGN */
|
||||||
unsigned lvals_;
|
unsigned lvals_;
|
||||||
struct ivl_lval_s*lval_;
|
struct ivl_lval_s*lval_;
|
||||||
|
char oper; // Operator if this is a compressed assignment.
|
||||||
ivl_expr_t rval_;
|
ivl_expr_t rval_;
|
||||||
ivl_expr_t delay;
|
ivl_expr_t delay;
|
||||||
// The following are only for NB event control.
|
// The following are only for NB event control.
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,7 @@ void show_stmt_wait(ivl_statement_t net, unsigned ind)
|
||||||
void show_statement(ivl_statement_t net, unsigned ind)
|
void show_statement(ivl_statement_t net, unsigned ind)
|
||||||
{
|
{
|
||||||
unsigned idx;
|
unsigned idx;
|
||||||
|
char opcode = 0;
|
||||||
const ivl_statement_type_t code = ivl_statement_type(net);
|
const ivl_statement_type_t code = ivl_statement_type(net);
|
||||||
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
|
|
@ -188,8 +189,11 @@ void show_statement(ivl_statement_t net, unsigned ind)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IVL_ST_ASSIGN:
|
case IVL_ST_ASSIGN:
|
||||||
fprintf(out, "%*sASSIGN <lwidth=%u>\n", ind, "",
|
opcode = ivl_stmt_opcode(net);
|
||||||
ivl_stmt_lwidth(net));
|
if (opcode == 0)
|
||||||
|
opcode = ' ';
|
||||||
|
fprintf(out, "%*sASSIGN <lwidth=%u> opcode=%c\n", ind, "",
|
||||||
|
ivl_stmt_lwidth(net), opcode);
|
||||||
|
|
||||||
for (idx = 0 ; idx < ivl_stmt_lvals(net) ; idx += 1)
|
for (idx = 0 ; idx < ivl_stmt_lvals(net) ; idx += 1)
|
||||||
show_assign_lval(ivl_stmt_lval(net, idx), ind+4);
|
show_assign_lval(ivl_stmt_lval(net, idx), ind+4);
|
||||||
|
|
|
||||||
|
|
@ -565,6 +565,7 @@ static int show_stmt_alloc(ivl_statement_t net)
|
||||||
static int show_stmt_assign_vector(ivl_statement_t net)
|
static int show_stmt_assign_vector(ivl_statement_t net)
|
||||||
{
|
{
|
||||||
ivl_expr_t rval = ivl_stmt_rval(net);
|
ivl_expr_t rval = ivl_stmt_rval(net);
|
||||||
|
struct vector_info res;
|
||||||
|
|
||||||
/* Handle the special case that the expression is a real
|
/* Handle the special case that the expression is a real
|
||||||
value. Evaluate the real expression, then convert the
|
value. Evaluate the real expression, then convert the
|
||||||
|
|
@ -576,12 +577,10 @@ static int show_stmt_assign_vector(ivl_statement_t net)
|
||||||
assignment. */
|
assignment. */
|
||||||
unsigned wid = ivl_stmt_lwidth(net);
|
unsigned wid = ivl_stmt_lwidth(net);
|
||||||
|
|
||||||
struct vector_info vec;
|
res.base = allocate_vector(wid);
|
||||||
|
res.wid = wid;
|
||||||
|
|
||||||
vec.base = allocate_vector(wid);
|
if (res.base == 0) {
|
||||||
vec.wid = wid;
|
|
||||||
|
|
||||||
if (vec.base == 0) {
|
|
||||||
fprintf(stderr, "%s:%u: vvp.tgt error: "
|
fprintf(stderr, "%s:%u: vvp.tgt error: "
|
||||||
"Unable to allocate %u thread bits for "
|
"Unable to allocate %u thread bits for "
|
||||||
"r-value expression.\n", ivl_expr_file(rval),
|
"r-value expression.\n", ivl_expr_file(rval),
|
||||||
|
|
@ -590,22 +589,20 @@ static int show_stmt_assign_vector(ivl_statement_t net)
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(vvp_out, " %%cvt/vr %u, %d, %u;\n",
|
fprintf(vvp_out, " %%cvt/vr %u, %d, %u;\n",
|
||||||
vec.base, word, vec.wid);
|
res.base, word, res.wid);
|
||||||
|
|
||||||
clr_word(word);
|
clr_word(word);
|
||||||
|
|
||||||
set_vec_to_lval(net, vec);
|
} else {
|
||||||
|
res = draw_eval_expr(rval, 0);
|
||||||
clr_vector(vec);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ivl_stmt_opcode(net) != 0)
|
||||||
|
fprintf(vvp_out, "; UNSUPPORTED ASSIGNMENT OPCODE: %c\n", ivl_stmt_opcode(net));
|
||||||
|
|
||||||
{ struct vector_info res = draw_eval_expr(rval, 0);
|
|
||||||
set_vec_to_lval(net, res);
|
set_vec_to_lval(net, res);
|
||||||
if (res.base > 3)
|
if (res.base > 3)
|
||||||
clr_vector(res);
|
clr_vector(res);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue