From 110a1b2ac7f36d4a34d97e5cbf5c4cb2ec6bb31a Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 8 Jun 2008 12:48:56 +0100 Subject: [PATCH] Replace type classes with enumeration --- tgt-vhdl/expr.cc | 2 +- tgt-vhdl/scope.cc | 4 +-- tgt-vhdl/stmt.cc | 17 +++++----- tgt-vhdl/vhdl_element.cc | 73 +++++++++++++++++++++++++++------------- tgt-vhdl/vhdl_element.hh | 57 +++++++++++++------------------ 5 files changed, 84 insertions(+), 69 deletions(-) diff --git a/tgt-vhdl/expr.cc b/tgt-vhdl/expr.cc index b208700c8..29f1d312c 100644 --- a/tgt-vhdl/expr.cc +++ b/tgt-vhdl/expr.cc @@ -42,7 +42,7 @@ static vhdl_expr *translate_signal(ivl_expr_t e) ivl_signal_t sig = ivl_expr_signal(e); // Assume all signals are single bits at the moment - vhdl_type *type = vhdl_scalar_type::std_logic(); + vhdl_type *type = vhdl_type::std_logic(); return new vhdl_var_ref(ivl_signal_basename(sig), type); } diff --git a/tgt-vhdl/scope.cc b/tgt-vhdl/scope.cc index d804e67dd..b6f19d57a 100644 --- a/tgt-vhdl/scope.cc +++ b/tgt-vhdl/scope.cc @@ -37,9 +37,9 @@ static void declare_signals(vhdl_arch *arch, ivl_scope_t scope) int width = ivl_signal_width(sig); vhdl_type *sig_type; if (width > 0) - sig_type = vhdl_scalar_type::std_logic(); + sig_type = vhdl_type::std_logic(); else - sig_type = vhdl_vector_type::std_logic_vector(width-1, 0); + sig_type = vhdl_type::std_logic_vector(width-1, 0); vhdl_signal_decl *decl = new vhdl_signal_decl(ivl_signal_basename(sig), sig_type); arch->add_decl(decl); diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index 9d4fa789a..51f3b113c 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -45,9 +45,8 @@ static int draw_stask_display(vhdl_process *proc, ivl_statement_t stmt) 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); + new vhdl_var_decl(display_line, vhdl_type::line()); line_var->set_comment("For generating $display output"); proc->add_decl(line_var); } @@ -67,12 +66,12 @@ static int draw_stask_display(vhdl_process *proc, ivl_statement_t stmt) // Need to add a call to Type'Image for types not // supported by std.textio - if (base->get_type()->get_name() != "String") { - std::string name(base->get_type()->get_name()); + if (base->get_type()->get_name() != VHDL_TYPE_STRING) { + std::string name(base->get_type()->get_string()); name += "'Image"; vhdl_fcall *cast - = new vhdl_fcall(name.c_str(), vhdl_scalar_type::string()); + = new vhdl_fcall(name.c_str(), vhdl_type::string()); cast->add_expr(base); e = cast; } @@ -84,7 +83,7 @@ static int draw_stask_display(vhdl_process *proc, ivl_statement_t stmt) vhdl_pcall_stmt *write = new vhdl_pcall_stmt("Write"); vhdl_var_ref *ref = - new vhdl_var_ref(display_line, vhdl_scalar_type::line()); + new vhdl_var_ref(display_line, vhdl_type::line()); write->add_expr(ref); write->add_expr(e); @@ -94,10 +93,10 @@ static int draw_stask_display(vhdl_process *proc, ivl_statement_t stmt) // WriteLine(Output, Verilog_Display_Line) vhdl_pcall_stmt *write_line = new vhdl_pcall_stmt("WriteLine"); vhdl_var_ref *output_ref = - new vhdl_var_ref("std.textio.Output", new vhdl_scalar_type("File")); + new vhdl_var_ref("std.textio.Output", new vhdl_type(VHDL_TYPE_FILE)); write_line->add_expr(output_ref); vhdl_var_ref *ref = - new vhdl_var_ref(display_line, vhdl_scalar_type::line()); + new vhdl_var_ref(display_line, vhdl_type::line()); write_line->add_expr(ref); proc->add_stmt(write_line); @@ -170,7 +169,7 @@ static int draw_nbassign(vhdl_process *proc, ivl_statement_t stmt) vhdl_expr *rhs_raw = translate_expr(ivl_stmt_rval(stmt)); if (NULL == rhs_raw) return 1; - vhdl_expr *rhs = decl->get_type()->cast(rhs_raw); + vhdl_expr *rhs = rhs_raw->cast(decl->get_type()); // The type here can be null as it is never actually needed vhdl_var_ref *lval_ref = new vhdl_var_ref(signame, NULL); diff --git a/tgt-vhdl/vhdl_element.cc b/tgt-vhdl/vhdl_element.cc index 211102aef..fdc47b76f 100644 --- a/tgt-vhdl/vhdl_element.cc +++ b/tgt-vhdl/vhdl_element.cc @@ -25,6 +25,7 @@ #include #include #include +#include static const int VHDL_INDENT = 2; // Spaces to indent @@ -344,31 +345,67 @@ void vhdl_wait_stmt::emit(std::ofstream &of, int level) const of << "wait;"; } -vhdl_scalar_type *vhdl_scalar_type::std_logic() +vhdl_type *vhdl_type::std_logic() { - return new vhdl_scalar_type("std_logic"); + return new vhdl_type(VHDL_TYPE_STD_LOGIC); } -vhdl_scalar_type *vhdl_scalar_type::string() +vhdl_type *vhdl_type::string() { - return new vhdl_scalar_type("String"); + return new vhdl_type(VHDL_TYPE_STRING); } -vhdl_scalar_type *vhdl_scalar_type::line() +vhdl_type *vhdl_type::line() { - return new vhdl_scalar_type("Line"); + return new vhdl_type(VHDL_TYPE_LINE); } -void vhdl_scalar_type::emit(std::ofstream &of, int level) const +std::string vhdl_type::get_string() const { - of << name_; + switch (name_) { + case VHDL_TYPE_STD_LOGIC: + return std::string("std_logic"); + case VHDL_TYPE_STD_LOGIC_VECTOR: + { + std::ostringstream ss; + ss << "std_logic_vector(" << msb_; + ss << " downto " << lsb_ << ")"; + return ss.str(); + } + case VHDL_TYPE_STRING: + return std::string("String"); + case VHDL_TYPE_LINE: + return std::string("Line"); + case VHDL_TYPE_FILE: + return std::string("File"); + default: + return std::string("BadType"); + } +} + +void vhdl_type::emit(std::ofstream &of, int level) const +{ + of << get_string(); +} + +/* + * The default cast just assumes there's a VHDL cast function to + * do the job for us. + */ +vhdl_expr *vhdl_expr::cast(const vhdl_type *to) +{ + vhdl_fcall *conv = + new vhdl_fcall(to->get_string().c_str(), new vhdl_type(*to)); + conv->add_expr(this); + + return conv; } /* * Cast something to a scalar type. There are a few ugly hacks here * to handle special cases. */ -vhdl_expr *vhdl_scalar_type::cast(vhdl_expr *expr) const +/*vhdl_expr *vhdl_scalar_type::cast(vhdl_expr *expr) const { if (typeid(*expr) == typeid(vhdl_const_bits) && name_ == "std_logic") { @@ -396,21 +433,11 @@ vhdl_expr *vhdl_scalar_type::cast(vhdl_expr *expr) const return conv; } -} + }*/ -vhdl_vector_type *vhdl_vector_type::std_logic_vector(int msb, int lsb) +vhdl_type *vhdl_type::std_logic_vector(int msb, int lsb) { - return new vhdl_vector_type("std_logic_vector", msb, lsb); -} - -void vhdl_vector_type::emit(std::ofstream &of, int level) const -{ - of << name_ << "(" << msb_ << " downto " << lsb_ << ")"; -} - -vhdl_expr *vhdl_vector_type::cast(vhdl_expr *expr) const -{ - return expr; + return new vhdl_type(VHDL_TYPE_STD_LOGIC_VECTOR, msb, lsb); } vhdl_var_decl::~vhdl_var_decl() @@ -510,7 +537,7 @@ void vhdl_nbassign_stmt::emit(std::ofstream &of, int level) const } vhdl_const_bits::vhdl_const_bits(const char *value) - : vhdl_expr(vhdl_vector_type::std_logic_vector(strlen(value)-1, 0)), + : vhdl_expr(vhdl_type::std_logic_vector(strlen(value)-1, 0)), value_(value) { diff --git a/tgt-vhdl/vhdl_element.hh b/tgt-vhdl/vhdl_element.hh index dd5b27129..5454fd6ed 100644 --- a/tgt-vhdl/vhdl_element.hh +++ b/tgt-vhdl/vhdl_element.hh @@ -50,16 +50,13 @@ private: typedef std::list element_list_t; -class vhdl_type : public vhdl_element { -public: - vhdl_type(const char *name) : name_(name) {} - virtual ~vhdl_type() {} - virtual vhdl_expr *cast(vhdl_expr *expr) const = 0; - - const std::string &get_name() const { return name_; } -protected: - std::string name_; +enum vhdl_type_name_t { + VHDL_TYPE_STD_LOGIC, + VHDL_TYPE_STD_LOGIC_VECTOR, + VHDL_TYPE_STRING, + VHDL_TYPE_LINE, + VHDL_TYPE_FILE }; /* @@ -67,43 +64,35 @@ protected: * too much more complex, as Verilog's type system is much * simpler than VHDL's. */ -class vhdl_scalar_type : public vhdl_type { +class vhdl_type : public vhdl_element { public: - vhdl_scalar_type(const char *name) - : vhdl_type(name) {} + vhdl_type(vhdl_type_name_t name, int msb = 0, int lsb = 0) + : name_(name), msb_(msb), lsb_(lsb) {} + virtual ~vhdl_type() {} void emit(std::ofstream &of, int level) const; - vhdl_expr *cast(vhdl_expr *expr) const; + vhdl_type_name_t get_name() const { return name_; } + std::string get_string() const; + int get_width() const { return msb_ - lsb_ + 1; } // Common types - static vhdl_scalar_type *std_logic(); - static vhdl_scalar_type *string(); - static vhdl_scalar_type *line(); -}; - -/* - * A vector type like std_logic_vector. - */ -class vhdl_vector_type : public vhdl_type { -public: - vhdl_vector_type(const char *name, int msb, int lsb) - : vhdl_type(name), msb_(msb), lsb_(lsb) {} - - void emit(std::ofstream &of, int level) const; - vhdl_expr *cast(vhdl_expr *expr) const; - - // Common types - static vhdl_vector_type *std_logic_vector(int msb, int lsb); -private: + static vhdl_type *std_logic(); + static vhdl_type *string(); + static vhdl_type *line(); + static vhdl_type *std_logic_vector(int msb, int lsb); +protected: + vhdl_type_name_t name_; int msb_, lsb_; }; + class vhdl_expr : public vhdl_element { public: vhdl_expr(vhdl_type* type) : type_(type) {} virtual ~vhdl_expr(); const vhdl_type *get_type() const { return type_; } + virtual vhdl_expr *cast(const vhdl_type *to); private: vhdl_type *type_; }; @@ -126,7 +115,7 @@ private: class vhdl_const_string : public vhdl_expr { public: vhdl_const_string(const char *value) - : vhdl_expr(vhdl_scalar_type::string()), value_(value) {} + : vhdl_expr(vhdl_type::string()), value_(value) {} void emit(std::ofstream &of, int level) const; private: @@ -145,7 +134,7 @@ private: class vhdl_const_bit : public vhdl_expr { public: vhdl_const_bit(char bit) - : vhdl_expr(vhdl_scalar_type::std_logic()), bit_(bit) {} + : vhdl_expr(vhdl_type::std_logic()), bit_(bit) {} void emit(std::ofstream &of, int level) const; private: char bit_;