Store packages required with entity rather than globally
Add parent link to architecture and process so code generators can push things higher up $display now prints blank lines
This commit is contained in:
parent
dd30c1b39d
commit
4bf2e1669d
|
|
@ -31,7 +31,13 @@
|
||||||
*/
|
*/
|
||||||
static int generate_vhdl_process(vhdl_entity *ent, ivl_process_t proc)
|
static int generate_vhdl_process(vhdl_entity *ent, ivl_process_t proc)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Create a new process and store it in the entity's
|
||||||
|
// architecture. This needs to be done first or the
|
||||||
|
// parent link won't be valid (and draw_stmt needs this
|
||||||
|
// to add information to the architecture)
|
||||||
vhdl_process *vhdl_proc = new vhdl_process();
|
vhdl_process *vhdl_proc = new vhdl_process();
|
||||||
|
ent->get_arch()->add_stmt(vhdl_proc);
|
||||||
|
|
||||||
ivl_statement_t stmt = ivl_process_stmt(proc);
|
ivl_statement_t stmt = ivl_process_stmt(proc);
|
||||||
int rc = draw_stmt(vhdl_proc, stmt);
|
int rc = draw_stmt(vhdl_proc, stmt);
|
||||||
|
|
@ -55,9 +61,6 @@ static int generate_vhdl_process(vhdl_entity *ent, ivl_process_t proc)
|
||||||
ss << ivl_scope_tname(scope);
|
ss << ivl_scope_tname(scope);
|
||||||
vhdl_proc->set_comment(ss.str());
|
vhdl_proc->set_comment(ss.str());
|
||||||
|
|
||||||
// Store it in the entity's architecture
|
|
||||||
ent->get_arch()->add_stmt(vhdl_proc);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,8 @@
|
||||||
*/
|
*/
|
||||||
static int draw_stask_display(vhdl_process *proc, ivl_statement_t stmt)
|
static int draw_stask_display(vhdl_process *proc, ivl_statement_t stmt)
|
||||||
{
|
{
|
||||||
require_package("std.textio");
|
// Add the package requirement to the containing entity
|
||||||
|
proc->get_parent()->get_parent()->requires_package("std.textio");
|
||||||
|
|
||||||
const char *display_line = "Verilog_Display_Line";
|
const char *display_line = "Verilog_Display_Line";
|
||||||
|
|
||||||
|
|
@ -53,10 +54,10 @@ static int draw_stask_display(vhdl_process *proc, ivl_statement_t stmt)
|
||||||
|
|
||||||
// TODO: Write the data into the line
|
// TODO: Write the data into the line
|
||||||
|
|
||||||
// Write_Line(Output, Verilog_Display_Line)
|
// WriteLine(Output, Verilog_Display_Line)
|
||||||
vhdl_var_ref *output_ref = new vhdl_var_ref("Output");
|
vhdl_var_ref *output_ref = new vhdl_var_ref("Output");
|
||||||
vhdl_var_ref *line_ref = new vhdl_var_ref(display_line);
|
vhdl_var_ref *line_ref = new vhdl_var_ref(display_line);
|
||||||
vhdl_pcall_stmt *write_line = new vhdl_pcall_stmt("Write_Line");
|
vhdl_pcall_stmt *write_line = new vhdl_pcall_stmt("WriteLine");
|
||||||
write_line->add_expr(output_ref);
|
write_line->add_expr(output_ref);
|
||||||
write_line->add_expr(line_ref);
|
write_line->add_expr(line_ref);
|
||||||
proc->add_stmt(write_line);
|
proc->add_stmt(write_line);
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,6 @@ static int g_errors = 0; // Total number of errors encountered
|
||||||
|
|
||||||
static entity_list_t g_entities; // All entities to emit
|
static entity_list_t g_entities; // All entities to emit
|
||||||
|
|
||||||
typedef std::string package_name_t;
|
|
||||||
typedef std::list<package_name_t> require_list_t;
|
|
||||||
|
|
||||||
static require_list_t g_requires; // External packages required
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called when an unrecoverable problem is encountered.
|
* Called when an unrecoverable problem is encountered.
|
||||||
|
|
@ -78,21 +73,6 @@ void remember_entity(vhdl_entity* ent)
|
||||||
g_entities.push_back(ent);
|
g_entities.push_back(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Add a package to the list of packages that should be
|
|
||||||
* use-ed at the start of the program.
|
|
||||||
*/
|
|
||||||
void require_package(const char *name)
|
|
||||||
{
|
|
||||||
package_name_t pname(name);
|
|
||||||
require_list_t::iterator it;
|
|
||||||
for (it = g_requires.begin(); it != g_requires.end(); ++it) {
|
|
||||||
if (*it == pname)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
g_requires.push_back(pname);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" int target_design(ivl_design_t des)
|
extern "C" int target_design(ivl_design_t des)
|
||||||
{
|
{
|
||||||
ivl_scope_t *roots;
|
ivl_scope_t *roots;
|
||||||
|
|
@ -108,14 +88,6 @@ extern "C" int target_design(ivl_design_t des)
|
||||||
const char *ofname = ivl_design_flag(des, "-o");
|
const char *ofname = ivl_design_flag(des, "-o");
|
||||||
std::ofstream outfile(ofname);
|
std::ofstream outfile(ofname);
|
||||||
|
|
||||||
// Write all the required packages (and libraries?)
|
|
||||||
//outfile << "library ieee;" << std::endl;
|
|
||||||
for (require_list_t::iterator it = g_requires.begin();
|
|
||||||
it != g_requires.end();
|
|
||||||
++it)
|
|
||||||
outfile << "use " << *it << ".all;" << std::endl;
|
|
||||||
outfile << std::endl;
|
|
||||||
|
|
||||||
for (entity_list_t::iterator it = g_entities.begin();
|
for (entity_list_t::iterator it = g_entities.begin();
|
||||||
it != g_entities.end();
|
it != g_entities.end();
|
||||||
++it)
|
++it)
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ vhdl_entity::vhdl_entity(const char *name, const char *derived_from,
|
||||||
vhdl_arch *arch)
|
vhdl_arch *arch)
|
||||||
: name_(name), arch_(arch), derived_from_(derived_from)
|
: name_(name), arch_(arch), derived_from_(derived_from)
|
||||||
{
|
{
|
||||||
|
arch->parent_ = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
vhdl_entity::~vhdl_entity()
|
vhdl_entity::~vhdl_entity()
|
||||||
|
|
@ -110,8 +110,29 @@ vhdl_entity::~vhdl_entity()
|
||||||
delete arch_;
|
delete arch_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a package to the list of `use' statements before
|
||||||
|
* the entity.
|
||||||
|
*/
|
||||||
|
void vhdl_entity::requires_package(const char *spec)
|
||||||
|
{
|
||||||
|
std::string pname(spec);
|
||||||
|
std::list<std::string>::iterator it;
|
||||||
|
for (it = uses_.begin(); it != uses_.end(); ++it) {
|
||||||
|
if (*it == pname)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uses_.push_back(spec);
|
||||||
|
}
|
||||||
|
|
||||||
void vhdl_entity::emit(std::ofstream &of, int level) const
|
void vhdl_entity::emit(std::ofstream &of, int level) const
|
||||||
{
|
{
|
||||||
|
for (std::list<std::string>::const_iterator it = uses_.begin();
|
||||||
|
it != uses_.end();
|
||||||
|
++it)
|
||||||
|
of << "use " << *it << ".all;" << std::endl;
|
||||||
|
of << std::endl;
|
||||||
|
|
||||||
emit_comment(of, level);
|
emit_comment(of, level);
|
||||||
of << "entity " << name_ << " is";
|
of << "entity " << name_ << " is";
|
||||||
// ...ports...
|
// ...ports...
|
||||||
|
|
@ -123,7 +144,7 @@ void vhdl_entity::emit(std::ofstream &of, int level) const
|
||||||
}
|
}
|
||||||
|
|
||||||
vhdl_arch::vhdl_arch(const char *entity, const char *name)
|
vhdl_arch::vhdl_arch(const char *entity, const char *name)
|
||||||
: name_(name), entity_(entity)
|
: parent_(NULL), name_(name), entity_(entity)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -136,6 +157,7 @@ vhdl_arch::~vhdl_arch()
|
||||||
|
|
||||||
void vhdl_arch::add_stmt(vhdl_conc_stmt *stmt)
|
void vhdl_arch::add_stmt(vhdl_conc_stmt *stmt)
|
||||||
{
|
{
|
||||||
|
stmt->parent_ = this;
|
||||||
stmts_.push_back(stmt);
|
stmts_.push_back(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,6 +166,12 @@ void vhdl_arch::add_decl(vhdl_decl *decl)
|
||||||
decls_.push_back(decl);
|
decls_.push_back(decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vhdl_entity *vhdl_arch::get_parent() const
|
||||||
|
{
|
||||||
|
assert(parent_);
|
||||||
|
return parent_;
|
||||||
|
}
|
||||||
|
|
||||||
void vhdl_arch::emit(std::ofstream &of, int level) const
|
void vhdl_arch::emit(std::ofstream &of, int level) const
|
||||||
{
|
{
|
||||||
emit_comment(of, level);
|
emit_comment(of, level);
|
||||||
|
|
@ -173,6 +201,12 @@ bool vhdl_arch::have_declared_component(const std::string &name) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vhdl_arch *vhdl_conc_stmt::get_parent() const
|
||||||
|
{
|
||||||
|
assert(parent_);
|
||||||
|
return parent_;
|
||||||
|
}
|
||||||
|
|
||||||
vhdl_process::vhdl_process(const char *name)
|
vhdl_process::vhdl_process(const char *name)
|
||||||
: name_(name)
|
: name_(name)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class vhdl_entity;
|
class vhdl_entity;
|
||||||
|
class vhdl_arch;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Any VHDL syntax element. Each element can also contain a comment.
|
* Any VHDL syntax element. Each element can also contain a comment.
|
||||||
|
|
@ -98,8 +99,14 @@ private:
|
||||||
* processes.
|
* processes.
|
||||||
*/
|
*/
|
||||||
class vhdl_conc_stmt : public vhdl_element {
|
class vhdl_conc_stmt : public vhdl_element {
|
||||||
|
friend class vhdl_arch; // Can set its parent
|
||||||
public:
|
public:
|
||||||
|
vhdl_conc_stmt() : parent_(NULL) {}
|
||||||
virtual ~vhdl_conc_stmt() {}
|
virtual ~vhdl_conc_stmt() {}
|
||||||
|
|
||||||
|
vhdl_arch *get_parent() const;
|
||||||
|
private:
|
||||||
|
vhdl_arch *parent_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::list<vhdl_conc_stmt*> conc_stmt_list_t;
|
typedef std::list<vhdl_conc_stmt*> conc_stmt_list_t;
|
||||||
|
|
@ -236,6 +243,7 @@ private:
|
||||||
* An architecture which implements an entity.
|
* An architecture which implements an entity.
|
||||||
*/
|
*/
|
||||||
class vhdl_arch : public vhdl_element {
|
class vhdl_arch : public vhdl_element {
|
||||||
|
friend class vhdl_entity; // Can set its parent
|
||||||
public:
|
public:
|
||||||
vhdl_arch(const char *entity, const char *name="Behavioural");
|
vhdl_arch(const char *entity, const char *name="Behavioural");
|
||||||
virtual ~vhdl_arch();
|
virtual ~vhdl_arch();
|
||||||
|
|
@ -244,7 +252,9 @@ public:
|
||||||
bool have_declared_component(const std::string &name) const;
|
bool have_declared_component(const std::string &name) const;
|
||||||
void add_decl(vhdl_decl *decl);
|
void add_decl(vhdl_decl *decl);
|
||||||
void add_stmt(vhdl_conc_stmt *stmt);
|
void add_stmt(vhdl_conc_stmt *stmt);
|
||||||
|
vhdl_entity *get_parent() const;
|
||||||
private:
|
private:
|
||||||
|
vhdl_entity *parent_;
|
||||||
conc_stmt_list_t stmts_;
|
conc_stmt_list_t stmts_;
|
||||||
decl_list_t decls_;
|
decl_list_t decls_;
|
||||||
std::string name_, entity_;
|
std::string name_, entity_;
|
||||||
|
|
@ -265,12 +275,13 @@ public:
|
||||||
void emit(std::ofstream &of, int level=0) const;
|
void emit(std::ofstream &of, int level=0) const;
|
||||||
vhdl_arch *get_arch() const { return arch_; }
|
vhdl_arch *get_arch() const { return arch_; }
|
||||||
const std::string &get_name() const { return name_; }
|
const std::string &get_name() const { return name_; }
|
||||||
|
void requires_package(const char *spec);
|
||||||
const std::string &get_derived_from() const { return derived_from_; }
|
const std::string &get_derived_from() const { return derived_from_; }
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
vhdl_arch *arch_; // Entity may only have a single architecture
|
vhdl_arch *arch_; // Entity may only have a single architecture
|
||||||
std::string derived_from_;
|
std::string derived_from_;
|
||||||
|
std::list<std::string> uses_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::list<vhdl_entity*> entity_list_t;
|
typedef std::list<vhdl_entity*> entity_list_t;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ int draw_stmt(vhdl_process *proc, ivl_statement_t stmt);
|
||||||
|
|
||||||
void remember_entity(vhdl_entity *ent);
|
void remember_entity(vhdl_entity *ent);
|
||||||
vhdl_entity *find_entity(const std::string &tname);
|
vhdl_entity *find_entity(const std::string &tname);
|
||||||
void require_package(const char *name);
|
|
||||||
|
|
||||||
#endif /* #ifndef INC_VHDL_TARGET_H */
|
#endif /* #ifndef INC_VHDL_TARGET_H */
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue