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

View File

@ -23,28 +23,82 @@
#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()
<< "(X : unsigned) return Boolean is";
vhdl_scope *scope = get_active_entity()->get_arch()->get_scope();
if (!scope->have_declared(support_function::function_name(f)))
scope->add_decl(new support_function(f));
}
const char *support_function::function_name(support_function_t type)
{
switch (type) {
case SF_UNSIGNED_TO_BOOLEAN:
return "Unsigned_To_Boolean";
case SF_SIGNED_TO_BOOLEAN:
return "Signed_To_Boolean";
case SF_BOOLEAN_TO_LOGIC:
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);
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";
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;";
newline(of, level);
}

View File

@ -23,23 +23,23 @@
#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"; }
enum support_function_t {
SF_UNSIGNED_TO_BOOLEAN,
SF_SIGNED_TO_BOOLEAN,
SF_BOOLEAN_TO_LOGIC,
};
class signed_to_boolean : public vhdl_function {
class support_function : public vhdl_function {
public:
signed_to_boolean()
: vhdl_function(function_name(), vhdl_type::boolean()) {}
support_function(support_function_t type)
: vhdl_function(function_name(type), function_type(type)),
type_(type) {}
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

View File

@ -7,6 +7,8 @@
#include "vhdl_syntax.hh"
#include "vhdl_type.hh"
#include "support.hh"
#include <string>
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,
ivl_statement_t stmt, bool newline = true);
template <class T>
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);
}
void require_support_function(support_function_t f);
#endif /* #ifndef INC_VHDL_TARGET_H */