Generate VHDL array type declarations of Verilog arrays

This commit is contained in:
Nick Gasson 2008-07-17 13:08:55 +01:00
parent 3fa5a04947
commit 1d3ac6bc1f
5 changed files with 64 additions and 14 deletions

View File

@ -270,14 +270,33 @@ static void declare_signals(vhdl_entity *ent, ivl_scope_t scope)
ivl_signal_t sig = ivl_scope_sig(scope, i);
remember_signal(sig, ent->get_arch()->get_scope());
if (ivl_signal_dimensions(sig) > 0)
error("Arrays not implemented yet");
vhdl_type *sig_type =
vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig) != 0);
string name(make_safe_name(sig));
rename_signal(sig, name);
vhdl_type *sig_type;
unsigned dimensions = ivl_signal_dimensions(sig);
if (dimensions > 0) {
// Arrays are implemented by generating a separate type
// declaration for each array, and then declaring a
// signal of that type
if (dimensions > 1) {
error("> 1 dimension arrays not implemented yet");
return;
}
string type_name = name + "_Type";
vhdl_type *base_type =
vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig) != 0);
vhdl_type *array_type = vhdl_type::array_of(base_type, type_name, 1, 0);
vhdl_decl *array_decl = new vhdl_type_decl(type_name.c_str(), array_type);
ent->get_arch()->get_scope()->add_decl(array_decl);
sig_type = new vhdl_type(*array_type);
}
else
sig_type =
vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig) != 0);
ivl_signal_port_t mode = ivl_signal_port(sig);
switch (mode) {

View File

@ -380,11 +380,10 @@ void vhdl_signal_decl::emit(std::ostream &of, int level) const
emit_comment(of, level, true);
}
void vhdl_type_decl::emit(std::ofstream &of, int level) const
void vhdl_type_decl::emit(std::ostream &of, int level) const
{
of << "type " << name_ << " is ";
type_->emit(of, level);
of << ";";
of << type_->get_type_decl_string() << ";";
emit_comment(of, level, true);
}

View File

@ -466,7 +466,7 @@ class vhdl_type_decl : public vhdl_decl {
public:
vhdl_type_decl(const char *name, vhdl_type *base)
: vhdl_decl(name, base) {}
void emit(std::ofstream &of, int level) const;
void emit(std::ostream &of, int level) const;
};

View File

@ -22,6 +22,7 @@
#include <cassert>
#include <sstream>
#include <iostream>
vhdl_type *vhdl_type::std_logic()
@ -117,16 +118,27 @@ std::string vhdl_type::get_decl_string() const
ss << " downto " << lsb_ << ")";
return ss.str();
}
default:
return get_string();
}
}
/*
* Like get_decl_string but completely expands array declarations.
*/
std::string vhdl_type::get_type_decl_string() const
{
switch (name_) {
case VHDL_TYPE_ARRAY:
{
std::ostringstream ss;
ss << "array (" << msb_ << " downto "
<< lsb_ << ") of "
<< base_->get_decl_string();
return ss.str();
return ss.str();
}
default:
return get_string();
return get_decl_string();
}
}
@ -135,6 +147,22 @@ void vhdl_type::emit(std::ostream &of, int level) const
of << get_decl_string();
}
vhdl_type::vhdl_type(const vhdl_type &other)
: name_(other.name_), msb_(other.msb_), lsb_(other.lsb_),
array_name_(other.array_name_)
{
if (other.base_ != NULL)
base_ = new vhdl_type(*other.base_);
else
base_ = NULL;
}
vhdl_type::~vhdl_type()
{
if (base_ != NULL)
delete base_;
}
vhdl_type *vhdl_type::std_logic_vector(int msb, int lsb)
{
return new vhdl_type(VHDL_TYPE_STD_LOGIC_VECTOR, msb, lsb);

View File

@ -53,13 +53,17 @@ public:
int msb, int lsb)
: name_(VHDL_TYPE_ARRAY), msb_(msb), lsb_(lsb), base_(base),
array_name_(array_name) {}
virtual ~vhdl_type() {}
// Copy constructor
vhdl_type(const vhdl_type &other);
virtual ~vhdl_type();
void emit(std::ostream &of, int level) const;
vhdl_type_name_t get_name() const { return name_; }
std::string get_string() const;
std::string get_decl_string() const;
std::string get_type_decl_string() const;
vhdl_type *get_base() const;
int get_width() const { return msb_ - lsb_ + 1; }
int get_msb() const { return msb_; }