Basic emit of sequential code
Infrastructure for debug and emit of sequential statements in processes. This does not properly handle the actual semantics of the behavioral code, but it provides an infrastructure where we can handle all the tricky elaboration to come.
This commit is contained in:
parent
27b58a7f93
commit
fc25ccde06
|
|
@ -63,8 +63,8 @@ O = main.o architec.o architec_elaborate.o compiler.o entity.o entity_elaborate.
|
|||
expression.o package.o scope.o sequential.o vsignal.o vtype.o vtype_elaborate.o \
|
||||
lexor.o lexor_keyword.o parse.o \
|
||||
parse_misc.o library.o vhdlreal.o vhdlint.o \
|
||||
architec_emit.o entity_emit.o expression_emit.o vtype_emit.o \
|
||||
debug.o architec_debug.o \
|
||||
architec_emit.o entity_emit.o expression_emit.o sequential_emit.o vtype_emit.o \
|
||||
debug.o architec_debug.o sequential_debug.o \
|
||||
$M
|
||||
|
||||
all: dep vhdlpp@EXEEXT@
|
||||
|
|
|
|||
|
|
@ -71,9 +71,15 @@ ComponentInstantiation::~ComponentInstantiation()
|
|||
{
|
||||
}
|
||||
|
||||
ProcessStatement::ProcessStatement(perm_string iname)
|
||||
: iname_(iname)
|
||||
ProcessStatement::ProcessStatement(perm_string iname,
|
||||
std::list<Expression*>*sensitivity_list,
|
||||
std::list<SequentialStmt*>*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()
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ class ComponentBase;
|
|||
class Entity;
|
||||
class Expression;
|
||||
class ExpName;
|
||||
class SequentialStmt;
|
||||
class Signal;
|
||||
class named_expr_t;
|
||||
|
||||
|
|
@ -125,15 +126,21 @@ class ComponentInstantiation : public Architecture::Statement {
|
|||
class ProcessStatement : public Architecture::Statement {
|
||||
|
||||
public:
|
||||
ProcessStatement(perm_string iname);
|
||||
ProcessStatement(perm_string iname,
|
||||
std::list<Expression*>*sensitivity_list,
|
||||
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;
|
||||
|
||||
private:
|
||||
perm_string iname_;
|
||||
|
||||
std::list<Expression*> sensitivity_list_;
|
||||
std::list<SequentialStmt*> statements_list_;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,10 +19,13 @@
|
|||
|
||||
# include "architec.h"
|
||||
# include "expression.h"
|
||||
# include "sequential.h"
|
||||
# include <fstream>
|
||||
# include <iomanip>
|
||||
# include <typeinfo>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void Architecture::dump(ostream&out, perm_string of_entity, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "architecture " << name_
|
||||
|
|
@ -70,4 +73,18 @@ void ProcessStatement::dump(ostream&out, int indent) const
|
|||
{
|
||||
out << setw(indent) << "" << "ProcessStatement name_=" << iname_
|
||||
<< " file=" << get_fileline() << endl;
|
||||
|
||||
out << setw(indent+3) << "" << "Sensitivity_list:" << endl;
|
||||
|
||||
for (list<Expression*>::const_iterator cur = sensitivity_list_.begin()
|
||||
; cur != sensitivity_list_.end() ; ++cur) {
|
||||
(*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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
# include "architec.h"
|
||||
# include "entity.h"
|
||||
# include "expression.h"
|
||||
# include "sequential.h"
|
||||
# include "vsignal.h"
|
||||
# include <iostream>
|
||||
# include <typeinfo>
|
||||
|
|
@ -104,3 +105,34 @@ int ComponentInstantiation::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
|
||||
return errors;
|
||||
}
|
||||
|
||||
int ProcessStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
out << "always";
|
||||
|
||||
if (sensitivity_list_.size() > 0) {
|
||||
out << " @(";
|
||||
const char*comma = 0;
|
||||
for (list<Expression*>::iterator cur = sensitivity_list_.begin()
|
||||
; cur != sensitivity_list_.end() ; ++cur) {
|
||||
|
||||
if (comma) out << comma;
|
||||
errors += (*cur)->emit(out, ent, arc);
|
||||
comma = ", ";
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
|
||||
out << " begin" << endl;
|
||||
|
||||
for (list<SequentialStmt*>::iterator cur = statements_list_.begin()
|
||||
; cur != statements_list_.end() ; ++cur) {
|
||||
(*cur)->emit(out, ent, arc);
|
||||
}
|
||||
|
||||
out << "end" << endl;
|
||||
return errors;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -232,6 +232,11 @@ void ExpName::dump(ostream&out, int indent) const
|
|||
index_->dump(out, indent+6);
|
||||
}
|
||||
|
||||
void ExpNameALL::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "ExpNameALL at " << get_fileline() << endl;
|
||||
}
|
||||
|
||||
void ExpRelation::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "Relation ";
|
||||
|
|
|
|||
|
|
@ -185,12 +185,13 @@ class ExpLogical : public ExpBinary {
|
|||
|
||||
/*
|
||||
* The ExpName class represents an expression that is an identifier or
|
||||
* other sort of name.
|
||||
* other sort of name. The ExpNameALL is a special case of ExpName
|
||||
* that represents the "all" keyword is contexts that can handle it.
|
||||
*/
|
||||
class ExpName : public Expression {
|
||||
|
||||
public:
|
||||
ExpName(perm_string nn);
|
||||
explicit ExpName(perm_string nn);
|
||||
ExpName(perm_string nn, Expression*index);
|
||||
~ExpName();
|
||||
|
||||
|
|
@ -206,6 +207,15 @@ class ExpName : public Expression {
|
|||
Expression*index_;
|
||||
};
|
||||
|
||||
class ExpNameALL : public ExpName {
|
||||
|
||||
public:
|
||||
ExpNameALL() : ExpName(perm_string()) { }
|
||||
|
||||
public:
|
||||
void dump(ostream&out, int indent =0) const;
|
||||
};
|
||||
|
||||
class ExpRelation : public ExpBinary {
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -196,6 +196,8 @@ const VType*parse_type_by_name(perm_string name)
|
|||
%type <expr> shift_expression simple_expression term waveform_element
|
||||
|
||||
%type <expr_list> waveform waveform_elements
|
||||
%type <expr_list> name_list
|
||||
%type <expr_list> process_sensitivity_list process_sensitivity_list_opt
|
||||
|
||||
%type <named_expr> association_element
|
||||
%type <named_expr_list> association_list port_map_aspect port_map_aspect_opt
|
||||
|
|
@ -894,7 +896,15 @@ name
|
|||
/* Handle name lists as lists of expressions. */
|
||||
name_list
|
||||
: name_list ',' name
|
||||
{ std::list<Expression*>*tmp = $1;
|
||||
tmp->push_back($3);
|
||||
$$ = tmp;
|
||||
}
|
||||
| name
|
||||
{ std::list<Expression*>*tmp = new std::list<Expression*>;
|
||||
tmp->push_back($1);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
package_declaration
|
||||
|
|
@ -1028,6 +1038,7 @@ primary
|
|||
{ perm_string name = lex_strings.make($3);
|
||||
ExpName*base = dynamic_cast<ExpName*> ($1);
|
||||
ExpAttribute*tmp = new ExpAttribute(base, name);
|
||||
FILE_NAME(tmp, @3);
|
||||
delete[]$3;
|
||||
$$ = tmp;
|
||||
}
|
||||
|
|
@ -1065,8 +1076,10 @@ process_statement
|
|||
delete[]$12;
|
||||
}
|
||||
|
||||
ProcessStatement*tmp = new ProcessStatement(iname);
|
||||
ProcessStatement*tmp = new ProcessStatement(iname, $5, $8);
|
||||
FILE_NAME(tmp, @4);
|
||||
delete $5;
|
||||
delete $8;
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
|
|
@ -1080,16 +1093,33 @@ process_statement
|
|||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* A process_sentitivity_list is:
|
||||
* <nil> if the list is not present, or
|
||||
* or a non-empty list of actual expressions.
|
||||
*/
|
||||
process_sensitivity_list_opt
|
||||
: '(' process_sensitivity_list ')'
|
||||
{ $$ = $2; }
|
||||
| '(' error ')'
|
||||
{ errormsg(@2, "Error in process sensitivity list\n"); }
|
||||
{ errormsg(@2, "Error in process sensitivity list\n");
|
||||
yyerrok;
|
||||
$$ = 0;
|
||||
}
|
||||
|
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
process_sensitivity_list
|
||||
: K_all
|
||||
{ std::list<Expression*>*tmp = new std::list<Expression*>;
|
||||
ExpName*all = new ExpNameALL;
|
||||
FILE_NAME(all, @1);
|
||||
tmp->push_back(all);
|
||||
$$ = tmp;
|
||||
}
|
||||
| name_list
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
relation
|
||||
|
|
|
|||
|
|
@ -22,14 +22,19 @@
|
|||
# include "LineInfo.h"
|
||||
# include <list>
|
||||
|
||||
class Architecture;
|
||||
class Entity;
|
||||
class Expression;
|
||||
|
||||
class SequentialStmt : public LineInfo {
|
||||
|
||||
public:
|
||||
SequentialStmt();
|
||||
~SequentialStmt();
|
||||
virtual ~SequentialStmt() =0;
|
||||
|
||||
public:
|
||||
virtual int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||
virtual void dump(ostream&out, int indent) const;
|
||||
};
|
||||
|
||||
class IfSequential : public SequentialStmt {
|
||||
|
|
@ -39,6 +44,10 @@ class IfSequential : public SequentialStmt {
|
|||
std::list<SequentialStmt*>*fa);
|
||||
~IfSequential();
|
||||
|
||||
public:
|
||||
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||
void dump(ostream&out, int indent) const;
|
||||
|
||||
private:
|
||||
Expression*cond_;
|
||||
std::list<SequentialStmt*> if_;
|
||||
|
|
@ -50,6 +59,10 @@ class SignalSeqAssignment : public SequentialStmt {
|
|||
SignalSeqAssignment(Expression*sig, std::list<Expression*>*wav);
|
||||
~SignalSeqAssignment();
|
||||
|
||||
public:
|
||||
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||
void dump(ostream&out, int indent) const;
|
||||
|
||||
private:
|
||||
Expression*lval_;
|
||||
std::list<Expression*> waveform_;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "sequential.h"
|
||||
# include "expression.h"
|
||||
# include <fstream>
|
||||
# include <iomanip>
|
||||
# include <typeinfo>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void SequentialStmt::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "SequentialStmt[" << typeid(*this).name() << "]"
|
||||
<< " at file=" << get_fileline() << endl;
|
||||
}
|
||||
|
||||
void IfSequential::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "IfSequential at file=" << get_fileline() << endl;
|
||||
out << setw(indent+3) << "" << "Condition:" << endl;
|
||||
cond_->dump(out, indent+4);
|
||||
|
||||
out << setw(indent+3) << "" << "TRUE clause (" << if_.size() << "):" << endl;
|
||||
for (list<SequentialStmt*>::const_iterator cur = if_.begin()
|
||||
; cur != if_.end() ; ++cur)
|
||||
(*cur)->dump(out, indent+4);
|
||||
|
||||
out << setw(indent+3) << "" << "FALSE clause (" << else_.size() << "):" << endl;
|
||||
for (list<SequentialStmt*>::const_iterator cur = else_.begin()
|
||||
; cur != else_.end() ; ++cur)
|
||||
(*cur)->dump(out, indent+4);
|
||||
|
||||
}
|
||||
|
||||
void SignalSeqAssignment::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "SignalSeqAssignment at file=" << get_fileline() << endl;
|
||||
|
||||
out << setw(indent+3) << "" << "l-value:" << endl;
|
||||
lval_->dump(out, indent+4);
|
||||
|
||||
out << setw(indent+3) << "" << "r-values (" << waveform_.size() << "):" << endl;
|
||||
for (list<Expression*>::const_iterator cur = waveform_.begin()
|
||||
; cur != waveform_.end() ; ++cur)
|
||||
(*cur)->dump(out, indent+4);
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "sequential.h"
|
||||
# include "expression.h"
|
||||
# include <iostream>
|
||||
# include <typeinfo>
|
||||
|
||||
int SequentialStmt::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
{
|
||||
out << " // " << get_fileline() << ": internal error: "
|
||||
<< "I don't know how to emit this sequential statement! "
|
||||
<< "type=" << typeid(*this).name() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int IfSequential::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
{
|
||||
int errors = 0;
|
||||
out << "if (";
|
||||
errors += cond_->emit(out, ent, arc);
|
||||
out << ") begin" << endl;
|
||||
|
||||
for (list<SequentialStmt*>::iterator cur = if_.begin()
|
||||
; cur != if_.end() ; ++cur)
|
||||
(*cur)->emit(out, ent, arc);
|
||||
|
||||
if (else_.size() > 0) {
|
||||
out << "end else begin" << endl;
|
||||
|
||||
for (list<SequentialStmt*>::iterator cur = else_.begin()
|
||||
; cur != else_.end() ; ++cur)
|
||||
(*cur)->emit(out, ent, arc);
|
||||
|
||||
}
|
||||
|
||||
out << "end" << endl;
|
||||
return errors;
|
||||
}
|
||||
|
||||
int SignalSeqAssignment::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
errors += lval_->emit(out, ent, arc);
|
||||
|
||||
if (waveform_.size() != 1) {
|
||||
out << "/* Confusing waveform? */;" << endl;
|
||||
errors += 1;
|
||||
|
||||
} else {
|
||||
Expression*tmp = waveform_.front();
|
||||
out << " <= ";
|
||||
tmp->emit(out, ent, arc);
|
||||
out << ";" << endl;
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
Loading…
Reference in New Issue