Get compressed assignment opcodes through to the ivl_target API.

This commit is contained in:
Stephen Williams 2011-11-27 16:46:02 -08:00
parent 21732a58c9
commit 3dabb2970d
11 changed files with 56 additions and 20 deletions

View File

@ -824,7 +824,10 @@ void NetAssign::dump(ostream&o, unsigned ind) const
o << setw(ind) << "";
dump_lval(o);
o << " = ";
if (op_)
o << " " << op_ << "= ";
else
o << " = ";
if (const NetExpr*de = get_delay())
o << "#(" << *de << ") ";

View File

@ -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());
if (rv == 0) return 0;
NetAssign*cur = new NetAssign(lv, rv);
NetAssign*cur = new NetAssign(lv, op_, rv);
cur->set_line(*this);
return cur;

View File

@ -272,6 +272,7 @@ ivl_stmt_lvals
ivl_stmt_lwidth
ivl_stmt_name
ivl_stmt_nevent
ivl_stmt_opcode
ivl_stmt_parm
ivl_stmt_parm_count
ivl_stmt_rval

View File

@ -1995,6 +1995,13 @@ extern unsigned ivl_stmt_lineno(ivl_statement_t net);
* the statement.) The ivl_stmt_delay_expr function returns the
* 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
* This reflects a procedural continuous assignment to an l-value. The
* 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);
/* IVL_ST_STASK */
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 */
extern ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx);
/* IVL_ST_STASK */

View File

@ -233,7 +233,12 @@ const NetExpr* NetAssignBase::get_delay() const
}
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)
{
}

View File

@ -2406,15 +2406,19 @@ class NetAssign : public NetAssignBase {
public:
explicit NetAssign(NetAssign_*lv, NetExpr*rv);
explicit NetAssign(NetAssign_*lv, char op, NetExpr*rv);
~NetAssign();
bool is_asynchronous();
inline char assign_operator(void) const { return op_; }
virtual bool emit_proc(struct target_t*) const;
virtual int match_proc(struct proc_match_t*);
virtual void dump(ostream&, unsigned ind) const;
private:
char op_;
};
class NetAssignNB : public NetAssignBase {

View File

@ -2547,6 +2547,17 @@ extern "C" const char* ivl_stmt_name(ivl_statement_t net)
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)
{
switch (net->type_) {

View File

@ -210,6 +210,7 @@ bool dll_target::proc_assign(const NetAssign*net)
/* Make the lval fields. */
make_assign_lvals_(net);
stmt_cur_->u_.assign_.oper = net->assign_operator();
assert(expr_ == 0);
net->rval()->expr_scan(this);
stmt_cur_->u_.assign_.rval_ = expr_;

View File

@ -729,6 +729,7 @@ struct ivl_statement_s {
IVL_ST_CASSIGN, IVL_ST_DEASSIGN */
unsigned lvals_;
struct ivl_lval_s*lval_;
char oper; // Operator if this is a compressed assignment.
ivl_expr_t rval_;
ivl_expr_t delay;
// The following are only for NB event control.

View File

@ -179,6 +179,7 @@ void show_stmt_wait(ivl_statement_t net, unsigned ind)
void show_statement(ivl_statement_t net, unsigned ind)
{
unsigned idx;
char opcode = 0;
const ivl_statement_type_t code = ivl_statement_type(net);
switch (code) {
@ -188,8 +189,11 @@ void show_statement(ivl_statement_t net, unsigned ind)
break;
case IVL_ST_ASSIGN:
fprintf(out, "%*sASSIGN <lwidth=%u>\n", ind, "",
ivl_stmt_lwidth(net));
opcode = ivl_stmt_opcode(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)
show_assign_lval(ivl_stmt_lval(net, idx), ind+4);

View File

@ -565,6 +565,7 @@ static int show_stmt_alloc(ivl_statement_t net)
static int show_stmt_assign_vector(ivl_statement_t net)
{
ivl_expr_t rval = ivl_stmt_rval(net);
struct vector_info res;
/* Handle the special case that the expression is a real
value. Evaluate the real expression, then convert the
@ -576,12 +577,10 @@ static int show_stmt_assign_vector(ivl_statement_t net)
assignment. */
unsigned wid = ivl_stmt_lwidth(net);
struct vector_info vec;
res.base = allocate_vector(wid);
res.wid = wid;
vec.base = allocate_vector(wid);
vec.wid = wid;
if (vec.base == 0) {
if (res.base == 0) {
fprintf(stderr, "%s:%u: vvp.tgt error: "
"Unable to allocate %u thread bits for "
"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",
vec.base, word, vec.wid);
res.base, word, res.wid);
clr_word(word);
set_vec_to_lval(net, vec);
clr_vector(vec);
return 0;
} else {
res = draw_eval_expr(rval, 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);
if (res.base > 3)
clr_vector(res);
}
set_vec_to_lval(net, res);
if (res.base > 3)
clr_vector(res);
return 0;