From d7bb5658f2c24e37352941985e1c732ed103ffab Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 19 Jun 2008 12:16:19 +0100 Subject: [PATCH] Translate IVL_ST_DELAYX statements --- tgt-vhdl/stmt.cc | 23 +++++++++++++++++++---- tgt-vhdl/vhdl_syntax.cc | 19 ++++++++++++++++--- tgt-vhdl/vhdl_syntax.hh | 18 ++++++++++++++++-- tgt-vhdl/vhdl_type.cc | 5 +++++ tgt-vhdl/vhdl_type.hh | 2 ++ 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index 0f410d667..9ae5d7711 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -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); diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 4a55dbf21..787cda7ea 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -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_; diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 07a9efa1f..c89e20d42 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -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 }; /* diff --git a/tgt-vhdl/vhdl_type.cc b/tgt-vhdl/vhdl_type.cc index 6180a839e..4176cfce4 100644 --- a/tgt-vhdl/vhdl_type.cc +++ b/tgt-vhdl/vhdl_type.cc @@ -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. */ diff --git a/tgt-vhdl/vhdl_type.hh b/tgt-vhdl/vhdl_type.hh index 341c5585a..e4e41d3e2 100644 --- a/tgt-vhdl/vhdl_type.hh +++ b/tgt-vhdl/vhdl_type.hh @@ -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_;