vhdlpp: Elaborate subprograms in packages.
This commit is contained in:
parent
517c9785e8
commit
3b310e8227
|
|
@ -21,6 +21,7 @@
|
|||
# include "entity.h"
|
||||
# include "expression.h"
|
||||
# include "sequential.h"
|
||||
# include "subprogram.h"
|
||||
# include <typeinfo>
|
||||
# include <cassert>
|
||||
|
||||
|
|
@ -59,6 +60,11 @@ int Architecture::elaborate(Entity*entity)
|
|||
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
|
||||
// initalization and clean-up actions
|
||||
if(!initializers_.empty())
|
||||
|
|
|
|||
|
|
@ -216,6 +216,7 @@ int ExpName::elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ)
|
|||
|
||||
const VType*found_type = 0;
|
||||
|
||||
if (ent) {
|
||||
if (const InterfacePort*cur = ent->find_port(name_)) {
|
||||
if (cur->mode != PORT_OUT && cur->mode != PORT_INOUT) {
|
||||
cerr << get_fileline() << ": error: Assignment to "
|
||||
|
|
@ -234,8 +235,11 @@ int ExpName::elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ)
|
|||
<< name_ << " from entity "
|
||||
<< ent->get_name() << "." << endl;
|
||||
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.
|
||||
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();
|
||||
|
||||
found_type = var->peek_type();
|
||||
|
||||
} else if (const InterfacePort*port = scope->find_param(name_)) {
|
||||
found_type = port->type;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_type == 0) {
|
||||
|
|
|
|||
|
|
@ -417,3 +417,27 @@ int emit_packages(void)
|
|||
|
||||
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_add_directory(const char*directory);
|
||||
|
||||
int elaborate_libraries(void);
|
||||
int emit_packages(void);
|
||||
|
||||
extern SubprogramHeader*library_find_subprogram(perm_string name);
|
||||
|
||||
#endif /* IVL_library_H */
|
||||
|
|
|
|||
|
|
@ -236,20 +236,27 @@ int main(int argc, char*argv[])
|
|||
return 3;
|
||||
}
|
||||
|
||||
errors = elaborate_libraries();
|
||||
if (errors > 0) {
|
||||
fprintf(stderr, "%d errors elaborating libraries.\n", errors);
|
||||
parser_cleanup();
|
||||
return 4;
|
||||
}
|
||||
|
||||
emit_std_types(cout);
|
||||
|
||||
errors = emit_packages();
|
||||
if (errors > 0) {
|
||||
fprintf(stderr, "%d errors emitting packages.\n", errors);
|
||||
parser_cleanup();
|
||||
return 4;
|
||||
return 5;
|
||||
}
|
||||
|
||||
errors = emit_entities();
|
||||
if (errors > 0) {
|
||||
fprintf(stderr, "%d errors emitting design.\n", errors);
|
||||
parser_cleanup();
|
||||
return 4;
|
||||
return 6;
|
||||
}
|
||||
|
||||
parser_cleanup();
|
||||
|
|
|
|||
|
|
@ -41,6 +41,18 @@ void Package::set_library(perm_string 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
|
||||
* 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;
|
||||
|
||||
int emit_package(std::ostream&fd) const;
|
||||
int elaborate();
|
||||
|
||||
private:
|
||||
perm_string from_library_;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
class ActiveScope;
|
||||
|
||||
void emit_std_types(ostream&out);
|
||||
int emit_packages(void);
|
||||
void generate_global_types(ActiveScope*res);
|
||||
bool is_global_type(perm_string type_name);
|
||||
void delete_global_types();
|
||||
|
|
|
|||
|
|
@ -53,6 +53,18 @@ void SubprogramBody::set_statements(list<SequentialStmt*>*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
|
||||
{
|
||||
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);
|
||||
inline bool empty_statements() const { return !statements_ || statements_->empty(); }
|
||||
|
||||
int elaborate();
|
||||
int emit(ostream&out, Entity*ent, ScopeBase*scope);
|
||||
|
||||
// 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_; }
|
||||
|
||||
int elaborate() { return (body_ ? body_->elaborate() : 0); }
|
||||
|
||||
// Function name used in the emission step. The main purpose of this
|
||||
// method is to handle functions offered by standard VHDL libraries.
|
||||
// Allows to return different function names depending on the arguments
|
||||
|
|
|
|||
Loading…
Reference in New Issue