Replace type classes with enumeration

This commit is contained in:
Nick Gasson 2008-06-08 12:48:56 +01:00
parent 79558910d1
commit 110a1b2ac7
5 changed files with 84 additions and 69 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -25,6 +25,7 @@
#include <cstring>
#include <typeinfo>
#include <iostream>
#include <sstream>
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)
{

View File

@ -50,16 +50,13 @@ private:
typedef std::list<vhdl_element*> 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_;