Translate IVL_ST_DELAYX statements

This commit is contained in:
Nick Gasson 2008-06-19 12:16:19 +01:00
parent be12f56856
commit d7bb5658f2
5 changed files with 58 additions and 9 deletions

View File

@ -291,8 +291,6 @@ static int draw_assign(vhdl_process *proc, stmt_container *container,
static int draw_delay(vhdl_process *proc, stmt_container *container, static int draw_delay(vhdl_process *proc, stmt_container *container,
ivl_statement_t stmt) ivl_statement_t stmt)
{ {
uint64_t value = ivl_stmt_delay_val(stmt);
// This currently ignores the time units and precision // This currently ignores the time units and precision
// of the enclosing scope // of the enclosing scope
// A neat way to do this would be to make these values // A neat way to do this would be to make these values
@ -300,7 +298,23 @@ static int draw_delay(vhdl_process *proc, stmt_container *container,
// VHDL wait statement compute the value from that. // VHDL wait statement compute the value from that.
// The other solution is to add them as parameters to // The other solution is to add them as parameters to
// the vhdl_process class // the vhdl_process class
vhdl_expr *time = new vhdl_const_int(value); vhdl_expr *time;
if (ivl_statement_type(stmt) == IVL_ST_DELAY) {
uint64_t value = ivl_stmt_delay_val(stmt);
time = new vhdl_const_time(value, TIME_UNIT_NS);
}
else {
time = translate_expr(ivl_stmt_delay_expr(stmt));
if (NULL == time)
return 1;
vhdl_type integer(VHDL_TYPE_INTEGER);
time = time->cast(&integer);
vhdl_expr *ns1 = new vhdl_const_time(1, TIME_UNIT_NS);
time = new vhdl_binop_expr(time, VHDL_BINOP_MULT, ns1,
vhdl_type::time());
}
// If the sub-statement is an assignment then VHDL lets // If the sub-statement is an assignment then VHDL lets
// us put the delay after it, which is more compact and // us put the delay after it, which is more compact and
@ -316,7 +330,7 @@ static int draw_delay(vhdl_process *proc, stmt_container *container,
draw_blocking_assigns(proc); draw_blocking_assigns(proc);
vhdl_wait_stmt *wait = vhdl_wait_stmt *wait =
new vhdl_wait_stmt(VHDL_WAIT_FOR_NS, time); new vhdl_wait_stmt(VHDL_WAIT_FOR, time);
container->add_stmt(wait); container->add_stmt(wait);
// Expand the sub-statement as well // Expand the sub-statement as well
@ -472,6 +486,7 @@ int draw_stmt(vhdl_process *proc, stmt_container *container,
case IVL_ST_ASSIGN_NB: case IVL_ST_ASSIGN_NB:
return draw_nbassign(proc, container, stmt); return draw_nbassign(proc, container, stmt);
case IVL_ST_DELAY: case IVL_ST_DELAY:
case IVL_ST_DELAYX:
return draw_delay(proc, container, stmt); return draw_delay(proc, container, stmt);
case IVL_ST_WAIT: case IVL_ST_WAIT:
return draw_wait(proc, container, stmt); return draw_wait(proc, container, stmt);

View File

@ -378,11 +378,10 @@ void vhdl_wait_stmt::emit(std::ofstream &of, int level) const
switch (type_) { switch (type_) {
case VHDL_WAIT_INDEF: case VHDL_WAIT_INDEF:
break; break;
case VHDL_WAIT_FOR_NS: case VHDL_WAIT_FOR:
assert(expr_); assert(expr_);
of << " for "; of << " for ";
expr_->emit(of, level); expr_->emit(of, level);
of << " ns";
break; break;
} }
@ -471,6 +470,12 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
return new vhdl_binop_expr return new vhdl_binop_expr
(this, VHDL_BINOP_EQ, one, vhdl_type::boolean()); (this, VHDL_BINOP_EQ, one, vhdl_type::boolean());
} }
else if (to->get_name() == VHDL_TYPE_INTEGER) {
vhdl_fcall *conv = new vhdl_fcall("To_Integer", new vhdl_type(*to));
conv->add_expr(this);
return conv;
}
else { else {
vhdl_fcall *conv = vhdl_fcall *conv =
new vhdl_fcall(to->get_string().c_str(), new vhdl_type(*to)); new vhdl_fcall(to->get_string().c_str(), new vhdl_type(*to));
@ -555,7 +560,6 @@ void vhdl_nbassign_stmt::emit(std::ofstream &of, int level) const
if (after_) { if (after_) {
of << " after "; of << " after ";
after_->emit(of, level); after_->emit(of, level);
of << " ns";
} }
of << ";"; of << ";";
@ -615,6 +619,15 @@ void vhdl_const_int::emit(std::ofstream &of, int level) const
of << value_; of << value_;
} }
void vhdl_const_time::emit(std::ofstream &of, int level) const
{
of << value_;
switch (units_) {
case TIME_UNIT_NS:
of << " ns";
}
}
vhdl_cassign_stmt::~vhdl_cassign_stmt() vhdl_cassign_stmt::~vhdl_cassign_stmt()
{ {
delete lhs_; delete lhs_;

View File

@ -133,6 +133,20 @@ private:
char bit_; char bit_;
}; };
enum time_unit_t {
TIME_UNIT_NS,
};
class vhdl_const_time : public vhdl_expr {
public:
vhdl_const_time(int64_t value, time_unit_t units)
: vhdl_expr(vhdl_type::time()), value_(value), units_(units) {}
void emit(std::ofstream &of, int level) const;
private:
int64_t value_;
time_unit_t units_;
};
class vhdl_const_int : public vhdl_expr { class vhdl_const_int : public vhdl_expr {
public: public:
vhdl_const_int(int64_t value) vhdl_const_int(int64_t value)
@ -266,8 +280,8 @@ public:
enum vhdl_wait_type_t { enum vhdl_wait_type_t {
VHDL_WAIT_INDEF, // Suspend indefinitely VHDL_WAIT_INDEF, // Suspend indefinitely
VHDL_WAIT_FOR_NS, // Wait for a constant number of nanoseconds VHDL_WAIT_FOR, // Wait for a constant amount of time
}; };
/* /*

View File

@ -58,6 +58,11 @@ vhdl_type *vhdl_type::nsigned(int width)
return new vhdl_type(VHDL_TYPE_SIGNED, width-1, 0); return new vhdl_type(VHDL_TYPE_SIGNED, width-1, 0);
} }
vhdl_type *vhdl_type::time()
{
return new vhdl_type(VHDL_TYPE_TIME);
}
/* /*
* This is just the name of the type, without any parameters. * This is just the name of the type, without any parameters.
*/ */

View File

@ -33,6 +33,7 @@ enum vhdl_type_name_t {
VHDL_TYPE_BOOLEAN, VHDL_TYPE_BOOLEAN,
VHDL_TYPE_SIGNED, VHDL_TYPE_SIGNED,
VHDL_TYPE_UNSIGNED, VHDL_TYPE_UNSIGNED,
VHDL_TYPE_TIME,
}; };
/* /*
@ -63,6 +64,7 @@ public:
static vhdl_type *nsigned(int width); static vhdl_type *nsigned(int width);
static vhdl_type *integer(); static vhdl_type *integer();
static vhdl_type *boolean(); static vhdl_type *boolean();
static vhdl_type *time();
protected: protected:
vhdl_type_name_t name_; vhdl_type_name_t name_;
int msb_, lsb_; int msb_, lsb_;