Refactor support function code a bit

This commit is contained in:
Nick Gasson 2008-07-19 20:49:55 +01:00
parent 0cb6ea34d7
commit af3ee49f57
4 changed files with 96 additions and 45 deletions

View File

@ -48,19 +48,19 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
} }
else if (type_->get_name() == VHDL_TYPE_UNSIGNED) { else if (type_->get_name() == VHDL_TYPE_UNSIGNED) {
// Need to use a support function for this conversion // Need to use a support function for this conversion
require_support_function<unsigned_to_boolean>(); require_support_function(SF_UNSIGNED_TO_BOOLEAN);
vhdl_fcall *conv = vhdl_fcall *conv =
new vhdl_fcall(unsigned_to_boolean::function_name(), new vhdl_fcall(support_function::function_name(SF_UNSIGNED_TO_BOOLEAN),
vhdl_type::boolean()); vhdl_type::boolean());
conv->add_expr(this); conv->add_expr(this);
return conv; return conv;
} }
else if (type_->get_name() == VHDL_TYPE_SIGNED) { else if (type_->get_name() == VHDL_TYPE_SIGNED) {
require_support_function<signed_to_boolean>(); require_support_function(SF_SIGNED_TO_BOOLEAN);
vhdl_fcall *conv = vhdl_fcall *conv =
new vhdl_fcall(signed_to_boolean::function_name(), new vhdl_fcall(support_function::function_name(SF_SIGNED_TO_BOOLEAN),
vhdl_type::boolean()); vhdl_type::boolean());
conv->add_expr(this); conv->add_expr(this);
return conv; return conv;
@ -77,10 +77,11 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
} }
else if (to->get_name() == VHDL_TYPE_STD_LOGIC && else if (to->get_name() == VHDL_TYPE_STD_LOGIC &&
type_->get_name() == VHDL_TYPE_BOOLEAN) { type_->get_name() == VHDL_TYPE_BOOLEAN) {
// Verilog assumes active-high logic and there require_support_function(SF_BOOLEAN_TO_LOGIC);
// is a special routine in verilog_support.vhd
// to do this for us vhdl_fcall *ah =
vhdl_fcall *ah = new vhdl_fcall("Active_High", vhdl_type::std_logic()); new vhdl_fcall(support_function::function_name(SF_BOOLEAN_TO_LOGIC),
vhdl_type::std_logic());
ah->add_expr(this); ah->add_expr(this);
return ah; return ah;

View File

@ -23,28 +23,82 @@
#include <cassert> #include <cassert>
void unsigned_to_boolean::emit(std::ostream &of, int level) const void require_support_function(support_function_t f)
{ {
of << "function " << function_name() vhdl_scope *scope = get_active_entity()->get_arch()->get_scope();
<< "(X : unsigned) return Boolean is"; if (!scope->have_declared(support_function::function_name(f)))
newline(of, level); scope->add_decl(new support_function(f));
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 const char *support_function::function_name(support_function_t type)
{ {
of << "function " << function_name() switch (type) {
<< "(X : signed) return Boolean is"; case SF_UNSIGNED_TO_BOOLEAN:
newline(of, level); return "Unsigned_To_Boolean";
of << "begin"; case SF_SIGNED_TO_BOOLEAN:
newline(of, indent(level)); return "Signed_To_Boolean";
of << "return X /= To_Signed(0, X'Length);"; case SF_BOOLEAN_TO_LOGIC:
newline(of, level); return "Boolean_To_Logic";
default:
assert(false);
}
}
vhdl_type *support_function::function_type(support_function_t type)
{
switch (type) {
case SF_UNSIGNED_TO_BOOLEAN:
return vhdl_type::boolean();
case SF_SIGNED_TO_BOOLEAN:
return vhdl_type::boolean();
case SF_BOOLEAN_TO_LOGIC:
return vhdl_type::std_logic();
default:
assert(false);
}
}
void support_function::emit(std::ostream &of, int level) const
{
of << "function " << function_name(type_);
switch (type_) {
case SF_UNSIGNED_TO_BOOLEAN:
of << "(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);
break;
case SF_SIGNED_TO_BOOLEAN:
of << "(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);
break;
case SF_BOOLEAN_TO_LOGIC:
of << "(B : Boolean) return std_logic is";
newline(of, level);
of << "begin";
newline(of, indent(level));
of << "if B then";
newline(of, indent(indent(level)));
of << "return '1'";
newline(of, indent(level));
of << "else";
newline(of, indent(indent(level)));
of << "return '0'";
newline(of, indent(level));
of << "end if;";
newline(of, level);
break;
default:
assert(false);
}
of << "end function;"; of << "end function;";
newline(of, level); newline(of, level);
} }

View File

@ -23,23 +23,23 @@
#include "vhdl_syntax.hh" #include "vhdl_syntax.hh"
class unsigned_to_boolean : public vhdl_function { enum support_function_t {
public: SF_UNSIGNED_TO_BOOLEAN,
unsigned_to_boolean() SF_SIGNED_TO_BOOLEAN,
: vhdl_function(function_name(), vhdl_type::boolean()) {} SF_BOOLEAN_TO_LOGIC,
void emit(std::ostream &of, int level) const;
static const char *function_name() { return "Unsigned_To_Boolean"; }
}; };
class support_function : public vhdl_function {
class signed_to_boolean : public vhdl_function {
public: public:
signed_to_boolean() support_function(support_function_t type)
: vhdl_function(function_name(), vhdl_type::boolean()) {} : vhdl_function(function_name(type), function_type(type)),
type_(type) {}
void emit(std::ostream &of, int level) const; void emit(std::ostream &of, int level) const;
static const char *function_name(support_function_t type);
static vhdl_type *function_type(support_function_t type);
static const char *function_name() { return "Signed_To_Boolean"; } private:
support_function_t type_;
}; };
#endif #endif

View File

@ -7,6 +7,8 @@
#include "vhdl_syntax.hh" #include "vhdl_syntax.hh"
#include "vhdl_type.hh" #include "vhdl_type.hh"
#include "support.hh"
#include <string> #include <string>
using namespace std; using namespace std;
@ -41,13 +43,7 @@ ivl_signal_t find_signal_named(const string &name, const vhdl_scope *scope);
int draw_stask_display(vhdl_procedural *proc, stmt_container *container, int draw_stask_display(vhdl_procedural *proc, stmt_container *container,
ivl_statement_t stmt, bool newline = true); ivl_statement_t stmt, bool newline = true);
template <class T> void require_support_function(support_function_t f);
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 */ #endif /* #ifndef INC_VHDL_TARGET_H */