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,
ivl_statement_t stmt)
{
uint64_t value = ivl_stmt_delay_val(stmt);
// This currently ignores the time units and precision
// of the enclosing scope
// 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.
// The other solution is to add them as parameters to
// 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
// 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);
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);
// Expand the sub-statement as well
@ -472,6 +486,7 @@ int draw_stmt(vhdl_process *proc, stmt_container *container,
case IVL_ST_ASSIGN_NB:
return draw_nbassign(proc, container, stmt);
case IVL_ST_DELAY:
case IVL_ST_DELAYX:
return draw_delay(proc, container, stmt);
case IVL_ST_WAIT:
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_) {
case VHDL_WAIT_INDEF:
break;
case VHDL_WAIT_FOR_NS:
case VHDL_WAIT_FOR:
assert(expr_);
of << " for ";
expr_->emit(of, level);
of << " ns";
break;
}
@ -471,6 +470,12 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
return new vhdl_binop_expr
(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 {
vhdl_fcall *conv =
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_) {
of << " after ";
after_->emit(of, level);
of << " ns";
}
of << ";";
@ -615,6 +619,15 @@ void vhdl_const_int::emit(std::ofstream &of, int level) const
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()
{
delete lhs_;

View File

@ -133,6 +133,20 @@ private:
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 {
public:
vhdl_const_int(int64_t value)
@ -266,8 +280,8 @@ public:
enum vhdl_wait_type_t {
VHDL_WAIT_INDEF, // Suspend indefinitely
VHDL_WAIT_FOR_NS, // Wait for a constant number of nanoseconds
VHDL_WAIT_INDEF, // Suspend indefinitely
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);
}
vhdl_type *vhdl_type::time()
{
return new vhdl_type(VHDL_TYPE_TIME);
}
/*
* 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_SIGNED,
VHDL_TYPE_UNSIGNED,
VHDL_TYPE_TIME,
};
/*
@ -63,6 +64,7 @@ public:
static vhdl_type *nsigned(int width);
static vhdl_type *integer();
static vhdl_type *boolean();
static vhdl_type *time();
protected:
vhdl_type_name_t name_;
int msb_, lsb_;