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 "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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 << "@(";
|
||||
|
|
|
|||
Loading…
Reference in New Issue