Translate IVL_ST_DELAYX statements
This commit is contained in:
parent
be12f56856
commit
d7bb5658f2
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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_;
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -267,7 +281,7 @@ 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
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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_;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue