vhdlpp: Elaborate subprograms in packages.
This commit is contained in:
parent
517c9785e8
commit
3b310e8227
|
|
@ -21,6 +21,7 @@
|
||||||
# include "entity.h"
|
# include "entity.h"
|
||||||
# include "expression.h"
|
# include "expression.h"
|
||||||
# include "sequential.h"
|
# include "sequential.h"
|
||||||
|
# include "subprogram.h"
|
||||||
# include <typeinfo>
|
# include <typeinfo>
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
|
||||||
|
|
@ -59,6 +60,11 @@ int Architecture::elaborate(Entity*entity)
|
||||||
cur->second->elaborate_init_expr(entity, this);
|
cur->second->elaborate_init_expr(entity, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Elaborate subprograms
|
||||||
|
for (map<perm_string,SubprogramHeader*>::const_iterator cur = cur_subprograms_.begin()
|
||||||
|
; cur != cur_subprograms_.end() ; ++cur) {
|
||||||
|
errors += cur->second->elaborate();
|
||||||
|
}
|
||||||
// Create 'initial' and 'final' blocks for implicit
|
// Create 'initial' and 'final' blocks for implicit
|
||||||
// initalization and clean-up actions
|
// initalization and clean-up actions
|
||||||
if(!initializers_.empty())
|
if(!initializers_.empty())
|
||||||
|
|
|
||||||
|
|
@ -216,6 +216,7 @@ int ExpName::elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ)
|
||||||
|
|
||||||
const VType*found_type = 0;
|
const VType*found_type = 0;
|
||||||
|
|
||||||
|
if (ent) {
|
||||||
if (const InterfacePort*cur = ent->find_port(name_)) {
|
if (const InterfacePort*cur = ent->find_port(name_)) {
|
||||||
if (cur->mode != PORT_OUT && cur->mode != PORT_INOUT) {
|
if (cur->mode != PORT_OUT && cur->mode != PORT_INOUT) {
|
||||||
cerr << get_fileline() << ": error: Assignment to "
|
cerr << get_fileline() << ": error: Assignment to "
|
||||||
|
|
@ -234,8 +235,11 @@ int ExpName::elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ)
|
||||||
<< name_ << " from entity "
|
<< name_ << " from entity "
|
||||||
<< ent->get_name() << "." << endl;
|
<< ent->get_name() << "." << endl;
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (Signal*sig = scope->find_signal(name_)) {
|
if (!found_type && scope) {
|
||||||
|
if (Signal*sig = scope->find_signal(name_)) {
|
||||||
// Tell the target signal that this may be a sequential l-value.
|
// Tell the target signal that this may be a sequential l-value.
|
||||||
if (is_sequ) sig->count_ref_sequ();
|
if (is_sequ) sig->count_ref_sequ();
|
||||||
|
|
||||||
|
|
@ -246,6 +250,10 @@ int ExpName::elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ)
|
||||||
if (is_sequ) var->count_ref_sequ();
|
if (is_sequ) var->count_ref_sequ();
|
||||||
|
|
||||||
found_type = var->peek_type();
|
found_type = var->peek_type();
|
||||||
|
|
||||||
|
} else if (const InterfacePort*port = scope->find_param(name_)) {
|
||||||
|
found_type = port->type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found_type == 0) {
|
if (found_type == 0) {
|
||||||
|
|
|
||||||
|
|
@ -417,3 +417,27 @@ int emit_packages(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int elaborate_library_packages(map<perm_string,Package*>packages)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
|
for (map<perm_string,Package*>::iterator cur = packages.begin()
|
||||||
|
; cur != packages.end() ; ++cur) {
|
||||||
|
errors += cur->second->elaborate();
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
int elaborate_libraries()
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
|
for (map<perm_string,struct library_contents>::iterator cur = libraries.begin()
|
||||||
|
; cur != libraries.end() ; ++cur) {
|
||||||
|
errors += elaborate_library_packages(cur->second.packages);
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@ class SubprogramHeader;
|
||||||
extern void library_set_work_path(const char*work_path);
|
extern void library_set_work_path(const char*work_path);
|
||||||
extern void library_add_directory(const char*directory);
|
extern void library_add_directory(const char*directory);
|
||||||
|
|
||||||
|
int elaborate_libraries(void);
|
||||||
|
int emit_packages(void);
|
||||||
|
|
||||||
extern SubprogramHeader*library_find_subprogram(perm_string name);
|
extern SubprogramHeader*library_find_subprogram(perm_string name);
|
||||||
|
|
||||||
#endif /* IVL_library_H */
|
#endif /* IVL_library_H */
|
||||||
|
|
|
||||||
|
|
@ -236,20 +236,27 @@ int main(int argc, char*argv[])
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errors = elaborate_libraries();
|
||||||
|
if (errors > 0) {
|
||||||
|
fprintf(stderr, "%d errors elaborating libraries.\n", errors);
|
||||||
|
parser_cleanup();
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
emit_std_types(cout);
|
emit_std_types(cout);
|
||||||
|
|
||||||
errors = emit_packages();
|
errors = emit_packages();
|
||||||
if (errors > 0) {
|
if (errors > 0) {
|
||||||
fprintf(stderr, "%d errors emitting packages.\n", errors);
|
fprintf(stderr, "%d errors emitting packages.\n", errors);
|
||||||
parser_cleanup();
|
parser_cleanup();
|
||||||
return 4;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
errors = emit_entities();
|
errors = emit_entities();
|
||||||
if (errors > 0) {
|
if (errors > 0) {
|
||||||
fprintf(stderr, "%d errors emitting design.\n", errors);
|
fprintf(stderr, "%d errors emitting design.\n", errors);
|
||||||
parser_cleanup();
|
parser_cleanup();
|
||||||
return 4;
|
return 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
parser_cleanup();
|
parser_cleanup();
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,18 @@ void Package::set_library(perm_string lname)
|
||||||
from_library_ = lname;
|
from_library_ = lname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Package::elaborate()
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
|
for (map<perm_string,SubprogramHeader*>::const_iterator cur = cur_subprograms_.begin()
|
||||||
|
; cur != cur_subprograms_.end() ; ++cur) {
|
||||||
|
errors += cur->second->elaborate();
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The Package::write_to_stream is used to write the package to the
|
* The Package::write_to_stream is used to write the package to the
|
||||||
* work space (or library) so writes proper VHDL that the library
|
* work space (or library) so writes proper VHDL that the library
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ class Package : public Scope, public LineInfo {
|
||||||
void write_to_stream(std::ostream&fd) const;
|
void write_to_stream(std::ostream&fd) const;
|
||||||
|
|
||||||
int emit_package(std::ostream&fd) const;
|
int emit_package(std::ostream&fd) const;
|
||||||
|
int elaborate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
perm_string from_library_;
|
perm_string from_library_;
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@
|
||||||
class ActiveScope;
|
class ActiveScope;
|
||||||
|
|
||||||
void emit_std_types(ostream&out);
|
void emit_std_types(ostream&out);
|
||||||
int emit_packages(void);
|
|
||||||
void generate_global_types(ActiveScope*res);
|
void generate_global_types(ActiveScope*res);
|
||||||
bool is_global_type(perm_string type_name);
|
bool is_global_type(perm_string type_name);
|
||||||
void delete_global_types();
|
void delete_global_types();
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,18 @@ void SubprogramBody::set_statements(list<SequentialStmt*>*stmt)
|
||||||
statements_ = stmt;
|
statements_ = stmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SubprogramBody::elaborate()
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
|
for (list<SequentialStmt*>::const_iterator cur = statements_->begin()
|
||||||
|
; cur != statements_->end() ; ++cur) {
|
||||||
|
errors += (*cur)->elaborate(0, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
void SubprogramBody::write_to_stream(ostream&fd) const
|
void SubprogramBody::write_to_stream(ostream&fd) const
|
||||||
{
|
{
|
||||||
for (map<perm_string,Variable*>::const_iterator cur = new_variables_.begin()
|
for (map<perm_string,Variable*>::const_iterator cur = new_variables_.begin()
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ class SubprogramBody : public LineInfo, public ScopeBase {
|
||||||
void set_statements(std::list<SequentialStmt*>*statements);
|
void set_statements(std::list<SequentialStmt*>*statements);
|
||||||
inline bool empty_statements() const { return !statements_ || statements_->empty(); }
|
inline bool empty_statements() const { return !statements_ || statements_->empty(); }
|
||||||
|
|
||||||
|
int elaborate();
|
||||||
int emit(ostream&out, Entity*ent, ScopeBase*scope);
|
int emit(ostream&out, Entity*ent, ScopeBase*scope);
|
||||||
|
|
||||||
// Emit body as it would show up in a package.
|
// Emit body as it would show up in a package.
|
||||||
|
|
@ -89,6 +90,8 @@ class SubprogramHeader : public LineInfo {
|
||||||
|
|
||||||
inline perm_string name() const { return name_; }
|
inline perm_string name() const { return name_; }
|
||||||
|
|
||||||
|
int elaborate() { return (body_ ? body_->elaborate() : 0); }
|
||||||
|
|
||||||
// Function name used in the emission step. The main purpose of this
|
// Function name used in the emission step. The main purpose of this
|
||||||
// method is to handle functions offered by standard VHDL libraries.
|
// method is to handle functions offered by standard VHDL libraries.
|
||||||
// Allows to return different function names depending on the arguments
|
// Allows to return different function names depending on the arguments
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue