From d762253f7412a949d8b9cd8e316135c69da4c4e3 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Mon, 9 Jun 2008 12:40:59 +0100 Subject: [PATCH] Wait statements --- tgt-vhdl/process.cc | 2 +- tgt-vhdl/stmt.cc | 17 ++++++++++++++++- tgt-vhdl/vhdl_syntax.cc | 22 ++++++++++++++++++++-- tgt-vhdl/vhdl_syntax.hh | 13 +++++++++++++ 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/tgt-vhdl/process.cc b/tgt-vhdl/process.cc index 2ce594aac..5a650aa0b 100644 --- a/tgt-vhdl/process.cc +++ b/tgt-vhdl/process.cc @@ -73,7 +73,7 @@ int draw_process(ivl_process_t proc, void *cd) assert(ivl_scope_type(scope) == IVL_SCT_MODULE); vhdl_entity *ent = find_entity(ivl_scope_tname(scope)); assert(ent != NULL); - + // If the scope this process belongs to is the same as the // VHDL entity was generated from, then create a VHDL process // from this Verilog process. This ensures that each process diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index 51f3b113c..7be5d58ae 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -190,7 +190,22 @@ static int draw_nbassign(vhdl_process *proc, ivl_statement_t stmt) */ static int draw_delay(vhdl_process *proc, ivl_statement_t stmt) { - std::cout << "draw_delay" << std::endl; + 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 + // constants in the scope (type is Time), and have the + // VHDL wait statement compute the value from that. + // The other solution is to add them as parameters to + // the vhdl_process class + std::cout << "Delay for " << value << std::endl; + + // Expand the sub-statement as well + // Often this can result in a useless `null' statement + // Maybe add a check here and ignore it if it IVL_ST_NOOP? + draw_stmt(proc, ivl_stmt_sub_stmt(stmt)); + return 0; } diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 3924ec22b..5b997445a 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -262,10 +262,28 @@ void vhdl_component_decl::emit(std::ofstream &of, int level) const of << "end component;"; } +vhdl_wait_stmt::~vhdl_wait_stmt() +{ + if (expr_ != NULL) + delete expr_; +} + void vhdl_wait_stmt::emit(std::ofstream &of, int level) const { - // TODO: There are lots of different types of `wait' - of << "wait;"; + of << "wait"; + + switch (type_) { + case VHDL_WAIT_INDEF: + break; + case VHDL_WAIT_FOR_NS: + assert(expr_); + of << " for "; + expr_->emit(of, level); + of << " ns"; + break; + } + + of << ";"; } diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 525fc1493..c15fdbdfe 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -154,13 +154,26 @@ private: vhdl_expr *rhs_; }; +enum vhdl_wait_type_t { + VHDL_WAIT_INDEF, // Suspend indefinitely + VHDL_WAIT_FOR_NS, // Wait for a constant number of nanoseconds +}; + /* * Delay simulation indefinitely, until an event, or for a * specified time. */ class vhdl_wait_stmt : public vhdl_seq_stmt { public: + vhdl_wait_stmt(vhdl_wait_type_t type = VHDL_WAIT_INDEF, + vhdl_expr *expr = NULL) + : type_(type), expr_(expr) {} + ~vhdl_wait_stmt(); + void emit(std::ofstream &of, int level) const; +private: + vhdl_wait_type_t type_; + vhdl_expr *expr_; };