From 94006cb44cc482808568d0b4f60a8c6452e6c805 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Tue, 3 Jun 2008 19:46:10 +0100 Subject: [PATCH] Working on code generation for $display task --- tgt-vhdl/stmt.cc | 24 +++++++++++--- tgt-vhdl/vhdl_element.cc | 72 +++++++++++++++++++++++++++++----------- tgt-vhdl/vhdl_element.hh | 14 ++++++-- 3 files changed, 84 insertions(+), 26 deletions(-) diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index 1055a9667..2ee58bfc6 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -28,18 +28,32 @@ * This is implemented using the functions in std.textio. Each * parameter is written to a line variable in the process and * then the line is written to the special variable `Output' - * (which represents the console). Subsequent $displays will use - * the same line variable. + * (which represents the console). Subsequent $displays will + * use the same line variable. * * It's possible, although quite unlikely, that there will be * name collision with an existing variable called - * `Verilog_Display_Line' - do something about this? It's also - * possible for there to be a name collision with the special - * variable `Output'. + * `Verilog_Display_Line' -- do something about this? + * It's also possible for there to be a name collision with + * the special variable `Output'. */ static int draw_stask_display(vhdl_process *proc, ivl_statement_t stmt) { require_package("std.textio"); + + const char *display_line = "Verilog_Display_Line"; + + if (!proc->have_declared_var(display_line)) { + vhdl_type *line_type = new vhdl_scalar_type("Line"); + vhdl_var_decl *line_var = + new vhdl_var_decl(display_line, line_type); + line_var->set_comment("For generating $display output"); + proc->add_decl(line_var); + } + + // TODO: Write the data into the line + + // TODO: Write_Line(Output, Verilog_Display_Line) return 0; } diff --git a/tgt-vhdl/vhdl_element.cc b/tgt-vhdl/vhdl_element.cc index 5c0b343c9..f5f7d5f90 100644 --- a/tgt-vhdl/vhdl_element.cc +++ b/tgt-vhdl/vhdl_element.cc @@ -67,16 +67,34 @@ void emit_children(std::ofstream &of, } } +template +void delete_children(std::list &children) +{ + typename std::list::iterator it; + for (it = children.begin(); it != children.end(); ++it) + delete *it; + children.clear(); +} + void vhdl_element::set_comment(std::string comment) { comment_ = comment; } -void vhdl_element::emit_comment(std::ofstream &of, int level) const +/* + * Draw the comment for any element. The comment is either on + * a line before the element (end_of_line is false) or at the + * end of the line containing the element (end_of_line is true). + */ +void vhdl_element::emit_comment(std::ofstream &of, int level, + bool end_of_line) const { if (comment_.size() > 0) { + if (end_of_line) + of << " "; of << "-- " << comment_; - newline(of, level); + if (!end_of_line) + newline(of, level); } } @@ -112,17 +130,8 @@ vhdl_arch::vhdl_arch(const char *entity, const char *name) vhdl_arch::~vhdl_arch() { - for (conc_stmt_list_t::iterator it = stmts_.begin(); - it != stmts_.end(); - ++it) - delete (*it); - stmts_.clear(); - - for (decl_list_t::iterator it = decls_.begin(); - it != decls_.end(); - ++it) - delete (*it); - decls_.clear(); + delete_children(stmts_); + delete_children(decls_); } void vhdl_arch::add_stmt(vhdl_conc_stmt *stmt) @@ -172,10 +181,8 @@ vhdl_process::vhdl_process(const char *name) vhdl_process::~vhdl_process() { - seq_stmt_list_t::iterator it; - for (it = stmts_.begin(); it != stmts_.end(); ++it) - delete (*it); - stmts_.clear(); + delete_children(stmts_); + delete_children(decls_); } void vhdl_process::add_stmt(vhdl_seq_stmt* stmt) @@ -183,14 +190,28 @@ void vhdl_process::add_stmt(vhdl_seq_stmt* stmt) stmts_.push_back(stmt); } +void vhdl_process::add_decl(vhdl_decl* decl) +{ + decls_.push_back(decl); +} + +bool vhdl_process::have_declared_var(const std::string &name) const +{ + decl_list_t::const_iterator it; + for (it = decls_.begin(); it != decls_.end(); ++it) { + if ((*it)->get_name() == name) + return true; + } + return false; +} + void vhdl_process::emit(std::ofstream &of, int level) const { emit_comment(of, level); if (name_.size() > 0) of << name_ << ": "; of << "process is"; // TODO: sensitivity - newline(of, level); - // ...declarations... + emit_children(of, decls_, level); of << "begin"; emit_children(of, stmts_, level); of << "end process;"; @@ -249,3 +270,16 @@ void vhdl_scalar_type::emit(std::ofstream &of, int level) const { of << name_; } + +vhdl_var_decl::~vhdl_var_decl() +{ + delete type_; +} + +void vhdl_var_decl::emit(std::ofstream &of, int level) const +{ + of << "variable " << name_ << " : "; + type_->emit(of, level); + of << ";"; + emit_comment(of, level, true); +} diff --git a/tgt-vhdl/vhdl_element.hh b/tgt-vhdl/vhdl_element.hh index f655ac106..3082aad76 100644 --- a/tgt-vhdl/vhdl_element.hh +++ b/tgt-vhdl/vhdl_element.hh @@ -38,7 +38,8 @@ public: void set_comment(std::string comment); protected: - void emit_comment(std::ofstream &of, int level) const; + void emit_comment(std::ofstream &of, int level, + bool end_of_line=false) const; private: std::string comment_; }; @@ -55,7 +56,7 @@ public: * too much more complex, as Verilog's type system is much * simpler than VHDL's. */ -class vhdl_scalar_type : public vhdl_element { +class vhdl_scalar_type : public vhdl_type { public: vhdl_scalar_type(const char *name) : name_(name) {} @@ -141,7 +142,13 @@ private: */ class vhdl_var_decl : public vhdl_decl { public: + vhdl_var_decl(const char *name, vhdl_type *type) + : vhdl_decl(name), type_(type) {} + ~vhdl_var_decl(); + void emit(std::ofstream &of, int level) const; +private: + vhdl_type *type_; }; @@ -172,8 +179,11 @@ public: void emit(std::ofstream &of, int level) const; void add_stmt(vhdl_seq_stmt *stmt); + void add_decl(vhdl_decl *decl); + bool have_declared_var(const std::string &name) const; private: seq_stmt_list_t stmts_; + decl_list_t decls_; std::string name_; };