Generate port declarations for entities.

But doesn't emit them yet!
This commit is contained in:
Nick Gasson 2008-06-09 16:27:04 +01:00
parent e29954e03f
commit 3106fe0ed6
3 changed files with 95 additions and 19 deletions

View File

@ -74,7 +74,7 @@ static vhdl_expr *inputs_to_expr(vhdl_arch *arch, vhdl_binop_t op,
}
/*
* Covert a gate intput to an unary expression.
* Convert a gate intput to an unary expression.
*/
static vhdl_expr *input_to_expr(vhdl_arch *arch, vhdl_unaryop_t op,
ivl_net_logic_t log)
@ -137,9 +137,26 @@ static void declare_signals(vhdl_arch *arch, ivl_scope_t scope)
sig_type = vhdl_type::std_logic();
else
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);
const char *name = ivl_signal_basename(sig);
ivl_signal_port_t mode = ivl_signal_port(sig);
switch (mode) {
case IVL_SIP_NONE:
arch->add_decl(new vhdl_signal_decl(name, sig_type));
break;
case IVL_SIP_INPUT:
arch->get_parent()->add_port
(new vhdl_port_decl(name, sig_type, VHDL_PORT_IN));
break;
case IVL_SIP_OUTPUT:
arch->get_parent()->add_port
(new vhdl_port_decl(name, sig_type, VHDL_PORT_OUT));
break;
case IVL_SIP_INOUT:
arch->get_parent()->add_port
(new vhdl_port_decl(name, sig_type, VHDL_PORT_INOUT));
break;
}
}
}

View File

@ -22,6 +22,7 @@
#include "vhdl_helper.hh"
#include <cassert>
#include <iostream>
vhdl_entity::vhdl_entity(const char *name, const char *derived_from,
vhdl_arch *arch)
@ -33,6 +34,7 @@ vhdl_entity::vhdl_entity(const char *name, const char *derived_from,
vhdl_entity::~vhdl_entity()
{
delete arch_;
delete_children<vhdl_decl>(ports_);
}
/*
@ -50,6 +52,24 @@ void vhdl_entity::requires_package(const char *spec)
uses_.push_back(spec);
}
/*
* Find a port declaration by name
*/
vhdl_decl *vhdl_entity::get_decl(const std::string &name) const
{
decl_list_t::const_iterator it;
for (it = ports_.begin(); it != ports_.end(); ++it) {
if ((*it)->get_name() == name)
return *it;
}
return NULL;
}
void vhdl_entity::add_port(vhdl_port_decl *decl)
{
ports_.push_back(decl);
}
void vhdl_entity::emit(std::ofstream &of, int level) const
{
// Pretty much every design will use std_logic so we
@ -121,7 +141,10 @@ vhdl_decl *vhdl_arch::get_decl(const std::string &name) const
if ((*it)->get_name() == name)
return *it;
}
return NULL;
// Maybe it's a port rather than an internal signal?
assert(parent_);
return parent_->get_decl(name);
}
/*
@ -286,10 +309,31 @@ void vhdl_wait_stmt::emit(std::ofstream &of, int level) const
of << ";";
}
vhdl_var_decl::~vhdl_var_decl()
vhdl_decl::~vhdl_decl()
{
delete type_;
if (type_ != NULL)
delete type_;
}
void vhdl_port_decl::emit(std::ofstream &of, int level) const
{
of << name_ << " : ";
switch (mode_) {
case VHDL_PORT_IN:
of << "in ";
break;
case VHDL_PORT_OUT:
of << "out ";
break;
case VHDL_PORT_INOUT:
of << "inout ";
break;
}
type_->emit(of, level);
of << ";";
emit_comment(of, level, true);
}
void vhdl_var_decl::emit(std::ofstream &of, int level) const
@ -300,11 +344,6 @@ void vhdl_var_decl::emit(std::ofstream &of, int level) const
emit_comment(of, level, true);
}
vhdl_signal_decl::~vhdl_signal_decl()
{
delete type_;
}
void vhdl_signal_decl::emit(std::ofstream &of, int level) const
{
of << "signal " << name_ << " : ";

View File

@ -276,7 +276,7 @@ class vhdl_decl : public vhdl_element {
public:
vhdl_decl(const char *name, vhdl_type *type=NULL)
: name_(name), type_(type) {}
virtual ~vhdl_decl() {};
virtual ~vhdl_decl();
const std::string &get_name() const { return name_; }
const vhdl_type *get_type() const { return type_; }
@ -296,8 +296,6 @@ typedef std::list<vhdl_decl*> decl_list_t;
*/
class vhdl_component_decl : public vhdl_decl {
public:
virtual ~vhdl_component_decl() {};
static vhdl_component_decl *component_decl_for(const vhdl_entity *ent);
void emit(std::ofstream &of, int level) const;
@ -316,8 +314,6 @@ class vhdl_var_decl : public vhdl_decl {
public:
vhdl_var_decl(const char *name, vhdl_type *type)
: vhdl_decl(name, type) {}
~vhdl_var_decl();
void emit(std::ofstream &of, int level) const;
};
@ -329,9 +325,30 @@ class vhdl_signal_decl : public vhdl_decl {
public:
vhdl_signal_decl(const char *name, vhdl_type *type)
: vhdl_decl(name, type) {}
~vhdl_signal_decl();
virtual void emit(std::ofstream &of, int level) const;
};
enum vhdl_port_mode_t {
VHDL_PORT_IN,
VHDL_PORT_OUT,
VHDL_PORT_INOUT,
};
/*
* A port declaration is like a signal declaration except
* it has a direction and appears in the entity rather than
* the architecture.
*/
class vhdl_port_decl : public vhdl_decl {
public:
vhdl_port_decl(const char *name, vhdl_type *type,
vhdl_port_mode_t mode)
: vhdl_decl(name, type), mode_(mode) {}
void emit(std::ofstream &of, int level) const;
private:
vhdl_port_mode_t mode_;
};
@ -409,7 +426,9 @@ public:
virtual ~vhdl_entity();
void emit(std::ofstream &of, int level=0) const;
void add_port(vhdl_port_decl *decl);
vhdl_arch *get_arch() const { return arch_; }
vhdl_decl *get_decl(const std::string &name) const;
const std::string &get_name() const { return name_; }
void requires_package(const char *spec);
const std::string &get_derived_from() const { return derived_from_; }
@ -418,6 +437,7 @@ private:
vhdl_arch *arch_; // Entity may only have a single architecture
std::string derived_from_;
string_list_t uses_;
decl_list_t ports_;
};
typedef std::list<vhdl_entity*> entity_list_t;