vhdlpp: Added means to use 'initial' and 'final' blocks during translation.
This commit is contained in:
parent
cb40a845e1
commit
e4ba4b5acd
|
|
@ -20,6 +20,7 @@
|
||||||
# include "architec.h"
|
# include "architec.h"
|
||||||
# include "expression.h"
|
# include "expression.h"
|
||||||
# include "parse_types.h"
|
# include "parse_types.h"
|
||||||
|
# include "sequential.h"
|
||||||
// Need this for parse_errors?
|
// Need this for parse_errors?
|
||||||
# include "parse_api.h"
|
# include "parse_api.h"
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
|
@ -229,18 +230,33 @@ Expression*ComponentInstantiation::find_generic_map(perm_string by_name) const
|
||||||
return p->second;
|
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,
|
ProcessStatement::ProcessStatement(perm_string iname,
|
||||||
std::list<Expression*>*sensitivity_list,
|
std::list<Expression*>*sensitivity_list,
|
||||||
std::list<SequentialStmt*>*statements_list)
|
std::list<SequentialStmt*>*statements_list)
|
||||||
: iname_(iname)
|
: StatementList(statements_list), iname_(iname)
|
||||||
{
|
{
|
||||||
if (sensitivity_list)
|
if (sensitivity_list)
|
||||||
sensitivity_list_.splice(sensitivity_list_.end(), *sensitivity_list);
|
sensitivity_list_.splice(sensitivity_list_.end(), *sensitivity_list);
|
||||||
if (statements_list)
|
|
||||||
statements_list_.splice(statements_list_.end(), *statements_list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessStatement::~ProcessStatement()
|
ProcessStatement::~ProcessStatement()
|
||||||
{
|
{
|
||||||
|
for(std::list<Expression*>::iterator it = sensitivity_list_.begin();
|
||||||
|
it != sensitivity_list_.end(); ++it) {
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,44 @@ class ComponentInstantiation : public Architecture::Statement {
|
||||||
std::map<perm_string,Expression*> port_map_;
|
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:
|
public:
|
||||||
ProcessStatement(perm_string iname,
|
ProcessStatement(perm_string iname,
|
||||||
|
|
@ -223,20 +260,16 @@ class ProcessStatement : public Architecture::Statement {
|
||||||
std::list<SequentialStmt*>*statement_list);
|
std::list<SequentialStmt*>*statement_list);
|
||||||
~ProcessStatement();
|
~ProcessStatement();
|
||||||
|
|
||||||
virtual int elaborate(Entity*ent, Architecture*arc);
|
int elaborate(Entity*ent, Architecture*arc);
|
||||||
virtual int emit(ostream&out, Entity*entity, Architecture*arc);
|
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||||
virtual void dump(ostream&out, int indent =0) const;
|
void dump(ostream&out, int indent =0) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int rewrite_as_always_edge_(Entity*ent, Architecture*arc);
|
int rewrite_as_always_edge_(Entity*ent, Architecture*arc);
|
||||||
int extract_anyedge_(Entity*ent, Architecture*arc);
|
int extract_anyedge_(Entity*ent, Architecture*arc);
|
||||||
|
|
||||||
private:
|
|
||||||
perm_string iname_;
|
perm_string iname_;
|
||||||
|
|
||||||
std::list<Expression*> sensitivity_list_;
|
std::list<Expression*> sensitivity_list_;
|
||||||
std::list<SequentialStmt*> statements_list_;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* IVL_architec_H */
|
#endif /* IVL_architec_H */
|
||||||
|
|
|
||||||
|
|
@ -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
|
void ProcessStatement::dump(ostream&out, int indent) const
|
||||||
{
|
{
|
||||||
out << setw(indent) << "" << "ProcessStatement name_=" << iname_
|
out << setw(indent) << "" << "ProcessStatement name_=" << iname_
|
||||||
|
|
@ -107,10 +131,5 @@ void ProcessStatement::dump(ostream&out, int indent) const
|
||||||
(*cur)->dump(out, indent+4);
|
(*cur)->dump(out, indent+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
out << setw(indent+3) << "" << "sequence of statements:" << endl;
|
StatementList::dump(out, indent);
|
||||||
|
|
||||||
for (list<SequentialStmt*>::const_iterator cur = statements_list_.begin()
|
|
||||||
; cur != statements_list_.end() ; ++cur) {
|
|
||||||
(*cur)->dump(out, indent+4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -179,11 +179,11 @@ int ProcessStatement::rewrite_as_always_edge_(Entity*, Architecture*)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// If there are multiple statements, I give up.
|
// If there are multiple statements, I give up.
|
||||||
if (statements_list_.size() != 1)
|
if (stmt_list().size() != 1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
Expression*se = sensitivity_list_.front();
|
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.
|
// If the statement is not an if-statement, I give up.
|
||||||
IfSequential*stmt = dynamic_cast<IfSequential*> (stmt_raw);
|
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
|
// Replace the statement with the body of the always
|
||||||
// statement, which is the true clause of the top "if"
|
// statement, which is the true clause of the top "if"
|
||||||
// statement. There should be no "else" clause.
|
// statement. There should be no "else" clause.
|
||||||
assert(statements_list_.size() == 1);
|
assert(stmt_list().size() == 1);
|
||||||
statements_list_.pop_front();
|
stmt_list().pop_front();
|
||||||
|
|
||||||
stmt->extract_true(statements_list_);
|
stmt->extract_true(stmt_list());
|
||||||
|
|
||||||
delete stmt;
|
delete stmt;
|
||||||
|
|
||||||
return 0;
|
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>) ..."
|
* Change the "process (<expr>) <stmt>" into "always @(<expr>) ..."
|
||||||
*/
|
*/
|
||||||
int ProcessStatement::extract_anyedge_(Entity*, Architecture*)
|
int ProcessStatement::extract_anyedge_(Entity*, Architecture*)
|
||||||
{
|
{
|
||||||
|
|
||||||
vector<Expression*> se;
|
vector<Expression*> se;
|
||||||
while (! sensitivity_list_.empty()) {
|
while (! sensitivity_list_.empty()) {
|
||||||
se.push_back(sensitivity_list_.front());
|
se.push_back(sensitivity_list_.front());
|
||||||
|
|
@ -297,10 +308,7 @@ int ProcessStatement::elaborate(Entity*ent, Architecture*arc)
|
||||||
extract_anyedge_(ent, arc);
|
extract_anyedge_(ent, arc);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (list<SequentialStmt*>::iterator cur = statements_list_.begin()
|
StatementList::elaborate(ent, arc);
|
||||||
; cur != statements_list_.end() ; ++cur) {
|
|
||||||
errors += (*cur)->elaborate(ent, arc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -246,6 +246,36 @@ int IfGenerate::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
return errors;
|
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.
|
* 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 ProcessStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
{
|
{
|
||||||
int errors = 0;
|
|
||||||
|
|
||||||
out << "always begin" << endl;
|
out << "always begin" << endl;
|
||||||
|
|
||||||
for (list<SequentialStmt*>::iterator cur = statements_list_.begin()
|
int errors = StatementList::emit(out, ent, arc);
|
||||||
; cur != statements_list_.end() ; ++cur) {
|
|
||||||
errors += (*cur)->emit(out, ent, arc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! sensitivity_list_.empty()) {
|
if (! sensitivity_list_.empty()) {
|
||||||
out << "@(";
|
out << "@(";
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue