From b6df73d3b9b2ebbbdddf71dc2141bce745dd3aec Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sat, 19 Jul 2008 15:15:16 +0100 Subject: [PATCH] Support functions for converting (un)signed -> boolean --- tgt-vhdl/Makefile.in | 2 +- tgt-vhdl/support.cc | 50 +++++++++++++++++++++++++++++++++++++++++ tgt-vhdl/support.hh | 45 +++++++++++++++++++++++++++++++++++++ tgt-vhdl/vhdl_syntax.cc | 22 ++++++++++++++++++ tgt-vhdl/vhdl_syntax.hh | 2 +- tgt-vhdl/vhdl_target.h | 8 +++++++ 6 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 tgt-vhdl/support.cc create mode 100644 tgt-vhdl/support.hh diff --git a/tgt-vhdl/Makefile.in b/tgt-vhdl/Makefile.in index 1b2f15a1c..a6232b0e1 100644 --- a/tgt-vhdl/Makefile.in +++ b/tgt-vhdl/Makefile.in @@ -50,7 +50,7 @@ dep: mv $*.d dep O = vhdl.o vhdl_element.o vhdl_type.o vhdl_syntax.o scope.o process.o \ - stmt.o expr.o lpm.o display.o + stmt.o expr.o lpm.o display.o support.o ifeq (@WIN32@,yes) TGTLDFLAGS=-L.. -livl diff --git a/tgt-vhdl/support.cc b/tgt-vhdl/support.cc new file mode 100644 index 000000000..b8493c263 --- /dev/null +++ b/tgt-vhdl/support.cc @@ -0,0 +1,50 @@ +/* + * Support functions for VHDL output. + * + * Copyright (C) 2008 Nick Gasson (nick@nickg.me.uk) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "vhdl_target.h" +#include "support.hh" + +#include + +void unsigned_to_boolean::emit(std::ostream &of, int level) const +{ + of << "function " << function_name() + << "(X : unsigned) return Boolean is"; + newline(of, level); + of << "begin"; + newline(of, indent(level)); + of << "return X /= To_Unsigned(0, X'Length);"; + newline(of, level); + of << "end function;"; + newline(of, level); +} + +void signed_to_boolean::emit(std::ostream &of, int level) const +{ + of << "function " << function_name() + << "(X : signed) return Boolean is"; + newline(of, level); + of << "begin"; + newline(of, indent(level)); + of << "return X /= To_Signed(0, X'Length);"; + newline(of, level); + of << "end function;"; + newline(of, level); +} diff --git a/tgt-vhdl/support.hh b/tgt-vhdl/support.hh new file mode 100644 index 000000000..386e96f0e --- /dev/null +++ b/tgt-vhdl/support.hh @@ -0,0 +1,45 @@ +/* + * Support functions for VHDL output. + * + * Copyright (C) 2008 Nick Gasson (nick@nickg.me.uk) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INC_SUPPORT_HH +#define INC_SUPPORT_HH + +#include "vhdl_syntax.hh" + +class unsigned_to_boolean : public vhdl_function { +public: + unsigned_to_boolean() + : vhdl_function(function_name(), vhdl_type::boolean()) {} + void emit(std::ostream &of, int level) const; + + static const char *function_name() { return "Unsigned_To_Boolean"; } +}; + + +class signed_to_boolean : public vhdl_function { +public: + signed_to_boolean() + : vhdl_function(function_name(), vhdl_type::boolean()) {} + void emit(std::ostream &of, int level) const; + + static const char *function_name() { return "Signed_To_Boolean"; } +}; + +#endif diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 7eda301da..34dc9062c 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -21,6 +21,9 @@ #include "vhdl_syntax.hh" #include "vhdl_helper.hh" +#include "vhdl_target.h" +#include "support.hh" + #include #include #include @@ -428,6 +431,25 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to) return new vhdl_binop_expr (this, VHDL_BINOP_EQ, one, vhdl_type::boolean()); } + else if (type_->get_name() == VHDL_TYPE_UNSIGNED) { + // Need to use a support function for this conversion + require_support_function(); + + vhdl_fcall *conv = + new vhdl_fcall(unsigned_to_boolean::function_name(), + vhdl_type::boolean()); + conv->add_expr(this); + return conv; + } + else if (type_->get_name() == VHDL_TYPE_SIGNED) { + require_support_function(); + + vhdl_fcall *conv = + new vhdl_fcall(signed_to_boolean::function_name(), + vhdl_type::boolean()); + conv->add_expr(this); + return conv; + } else { assert(false); } diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 00daee489..fcf06286a 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -614,7 +614,7 @@ class vhdl_function : public vhdl_decl, public vhdl_procedural { public: vhdl_function(const char *name, vhdl_type *ret_type); - void emit(std::ostream &of, int level) const; + virtual void emit(std::ostream &of, int level) const; vhdl_scope *get_scope() { return &variables_; } void add_param(vhdl_param_decl *p) { scope_.add_decl(p); } private: diff --git a/tgt-vhdl/vhdl_target.h b/tgt-vhdl/vhdl_target.h index d667783fe..db583206d 100644 --- a/tgt-vhdl/vhdl_target.h +++ b/tgt-vhdl/vhdl_target.h @@ -41,5 +41,13 @@ ivl_signal_t find_signal_named(const string &name, const vhdl_scope *scope); int draw_stask_display(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt, bool newline = true); +template +void require_support_function() +{ + vhdl_scope *scope = get_active_entity()->get_arch()->get_scope(); + if (!scope->have_declared(T::function_name())) + scope->add_decl(new T); +} + #endif /* #ifndef INC_VHDL_TARGET_H */