vhdlpp: Added means to use 'initial' and 'final' blocks during translation.

This commit is contained in:
Maciej Suminski 2015-11-25 18:15:09 +01:00
parent cb40a845e1
commit e4ba4b5acd
5 changed files with 134 additions and 33 deletions

View File

@ -20,6 +20,7 @@
# include "architec.h"
# include "expression.h"
# include "parse_types.h"
# include "sequential.h"
// Need this for parse_errors?
# include "parse_api.h"
# include <cassert>
@ -229,18 +230,33 @@ Expression*ComponentInstantiation::find_generic_map(perm_string by_name) const
return p->second;
}
StatementList::StatementList(std::list<SequentialStmt*>*statement_list)
{
if(statement_list)
statements_.splice(statements_.end(), *statement_list);
}
StatementList::~StatementList()
{
for(std::list<SequentialStmt*>::iterator it = statements_.begin();
it != statements_.end(); ++it) {
delete *it;
}
}
ProcessStatement::ProcessStatement(perm_string iname,
std::list<Expression*>*sensitivity_list,
std::list<SequentialStmt*>*statements_list)
: iname_(iname)
: StatementList(statements_list), iname_(iname)
{
if (sensitivity_list)
sensitivity_list_.splice(sensitivity_list_.end(), *sensitivity_list);
if (statements_list)
statements_list_.splice(statements_list_.end(), *statements_list);
}
ProcessStatement::~ProcessStatement()
{
for(std::list<Expression*>::iterator it = sensitivity_list_.begin();
it != sensitivity_list_.end(); ++it) {
delete *it;
}
}

View File

@ -215,7 +215,44 @@ class ComponentInstantiation : public Architecture::Statement {
std::map<perm_string,Expression*> port_map_;
};
class ProcessStatement : public Architecture::Statement {
class StatementList : public Architecture::Statement {
public:
StatementList(std::list<SequentialStmt*>*statement_list);
virtual ~StatementList();
virtual int elaborate(Entity*ent, Architecture*arc);
virtual int emit(ostream&out, Entity*entity, Architecture*arc);
virtual void dump(ostream&out, int indent =0) const;
std::list<SequentialStmt*>& stmt_list() { return statements_; }
private:
std::list<SequentialStmt*> statements_;
};
// There is no direct VHDL countepart to SV 'initial' statement,
// but we can still use it during the translation process.
class InitialStatement : public StatementList {
public:
InitialStatement(std::list<SequentialStmt*>*statement_list)
: StatementList(statement_list) {}
int emit(ostream&out, Entity*entity, Architecture*arc);
void dump(ostream&out, int indent =0) const;
};
// There is no direct VHDL countepart to SV 'final' statement,
// but we can still use it during the translation process.
class FinalStatement : public StatementList {
public:
FinalStatement(std::list<SequentialStmt*>*statement_list)
: StatementList(statement_list) {}
int emit(ostream&out, Entity*entity, Architecture*arc);
void dump(ostream&out, int indent =0) const;
};
class ProcessStatement : public StatementList {
public:
ProcessStatement(perm_string iname,
@ -223,20 +260,16 @@ class ProcessStatement : public Architecture::Statement {
std::list<SequentialStmt*>*statement_list);
~ProcessStatement();
virtual int elaborate(Entity*ent, Architecture*arc);
virtual int emit(ostream&out, Entity*entity, Architecture*arc);
virtual void dump(ostream&out, int indent =0) const;
int elaborate(Entity*ent, Architecture*arc);
int emit(ostream&out, Entity*entity, Architecture*arc);
void dump(ostream&out, int indent =0) const;
private:
int rewrite_as_always_edge_(Entity*ent, Architecture*arc);
int extract_anyedge_(Entity*ent, Architecture*arc);
private:
perm_string iname_;
std::list<Expression*> sensitivity_list_;
std::list<SequentialStmt*> statements_list_;
};
#endif /* IVL_architec_H */

View File

@ -95,6 +95,30 @@ void SignalAssignment::dump(ostream&out, int indent) const
}
}
void StatementList::dump(ostream&out, int indent) const
{
out << setw(indent+3) << "" << "sequence of statements:" << endl;
for (list<SequentialStmt*>::const_iterator cur = statements_.begin()
; cur != statements_.end() ; ++cur) {
(*cur)->dump(out, indent+4);
}
}
void InitialStatement::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "InitialStatement file=" << get_fileline() << endl;
StatementList::dump(out, indent);
}
void FinalStatement::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "FinalStatment file=" << get_fileline() << endl;
StatementList::dump(out, indent);
}
void ProcessStatement::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "ProcessStatement name_=" << iname_
@ -107,10 +131,5 @@ void ProcessStatement::dump(ostream&out, int indent) const
(*cur)->dump(out, indent+4);
}
out << setw(indent+3) << "" << "sequence of statements:" << endl;
for (list<SequentialStmt*>::const_iterator cur = statements_list_.begin()
; cur != statements_list_.end() ; ++cur) {
(*cur)->dump(out, indent+4);
}
StatementList::dump(out, indent);
}

View File

@ -179,11 +179,11 @@ int ProcessStatement::rewrite_as_always_edge_(Entity*, Architecture*)
return -1;
// If there are multiple statements, I give up.
if (statements_list_.size() != 1)
if (stmt_list().size() != 1)
return -1;
Expression*se = sensitivity_list_.front();
SequentialStmt*stmt_raw = statements_list_.front();
SequentialStmt*stmt_raw = stmt_list().front();
// If the statement is not an if-statement, I give up.
IfSequential*stmt = dynamic_cast<IfSequential*> (stmt_raw);
@ -258,22 +258,33 @@ int ProcessStatement::rewrite_as_always_edge_(Entity*, Architecture*)
// Replace the statement with the body of the always
// statement, which is the true clause of the top "if"
// statement. There should be no "else" clause.
assert(statements_list_.size() == 1);
statements_list_.pop_front();
assert(stmt_list().size() == 1);
stmt_list().pop_front();
stmt->extract_true(statements_list_);
stmt->extract_true(stmt_list());
delete stmt;
return 0;
}
int StatementList::elaborate(Entity*ent, Architecture*arc)
{
int errors = 0;
for (std::list<SequentialStmt*>::iterator it = statements_.begin();
it != statements_.end(); ++it) {
errors += (*it)->elaborate(ent, arc);
}
return errors;
}
/*
* Change the "process (<expr>) <stmt>" into "always @(<expr>) ..."
*/
int ProcessStatement::extract_anyedge_(Entity*, Architecture*)
{
vector<Expression*> se;
while (! sensitivity_list_.empty()) {
se.push_back(sensitivity_list_.front());
@ -297,10 +308,7 @@ int ProcessStatement::elaborate(Entity*ent, Architecture*arc)
extract_anyedge_(ent, arc);
}
for (list<SequentialStmt*>::iterator cur = statements_list_.begin()
; cur != statements_list_.end() ; ++cur) {
errors += (*cur)->elaborate(ent, arc);
}
StatementList::elaborate(ent, arc);
return errors;
}

View File

@ -246,6 +246,36 @@ int IfGenerate::emit(ostream&out, Entity*ent, Architecture*arc)
return errors;
}
int StatementList::emit(ostream&out, Entity*ent, Architecture*arc)
{
int errors = 0;
for (std::list<SequentialStmt*>::iterator it = statements_.begin();
it != statements_.end(); ++it) {
errors += (*it)->emit(out, ent, arc);
}
return errors;
}
int InitialStatement::emit(ostream&out, Entity*ent, Architecture*arc)
{
out << "initial begin" << endl;
int errors = StatementList::emit(out, ent, arc);
out << "end" << endl;
return errors;
}
int FinalStatement::emit(ostream&out, Entity*ent, Architecture*arc)
{
out << "final begin" << endl;
int errors = StatementList::emit(out, ent, arc);
out << "end" << endl;
return errors;
}
/*
* Emit a process statement using "always" syntax.
*
@ -256,14 +286,9 @@ int IfGenerate::emit(ostream&out, Entity*ent, Architecture*arc)
*/
int ProcessStatement::emit(ostream&out, Entity*ent, Architecture*arc)
{
int errors = 0;
out << "always begin" << endl;
for (list<SequentialStmt*>::iterator cur = statements_list_.begin()
; cur != statements_list_.end() ; ++cur) {
errors += (*cur)->emit(out, ent, arc);
}
int errors = StatementList::emit(out, ent, arc);
if (! sensitivity_list_.empty()) {
out << "@(";