iverilog/vhdlpp/debug.cc

515 lines
14 KiB
C++

/*
* Copyright (c) 2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 2014 CERN
* @author Maciej Suminski (maciej.suminski@cern.ch)
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Picture Elements, Inc., 777 Panoramic Way, Berkeley, CA 94704.
*/
# include "entity.h"
# include "architec.h"
# include "expression.h"
# include "parse_types.h"
# include "subprogram.h"
# include "sequential.h"
# include "vsignal.h"
# include "vtype.h"
# include <fstream>
# include <iomanip>
# include <typeinfo>
static ostream& operator << (ostream&out, port_mode_t that)
{
switch (that) {
case PORT_NONE:
out << "NO-PORT";
break;
case PORT_IN:
out << "IN";
break;
case PORT_OUT:
out << "OUT";
break;
default:
out << "PORT-????";
break;
}
return out;
}
void dump_design_entities(ostream&file)
{
for (map<perm_string,Entity*>::iterator cur = design_entities.begin()
; cur != design_entities.end() ; ++cur) {
cur->second->dump(file);
}
}
void ComponentBase::dump_generics(ostream&out, int indent) const
{
if (parms_.empty()) {
out << setw(indent) << "" << "No generics" << endl;
} else {
out << setw(indent) << "" << "GENERICS:" << endl;
for (vector<InterfacePort*>::const_iterator cur = parms_.begin()
; cur != parms_.end() ; ++cur) {
InterfacePort*item = *cur;
out << setw(indent+2) << "" << item->name
<< " : " << item->mode
<< ", type=";
if (item->type)
item->type->show(out);
else
out << "<nil>";
out << ", file=" << item->get_fileline() << endl;
}
}
}
void ComponentBase::dump_ports(ostream&out, int indent) const
{
if (ports_.empty()) {
out << setw(indent) << "" << "No ports" << endl;
} else {
out << setw(indent) << "" << "PORTS:" << endl;
for (vector<InterfacePort*>::const_iterator cur = ports_.begin()
; cur != ports_.end() ; ++cur) {
InterfacePort*item = *cur;
out << setw(indent+2) << "" << item->name
<< " : " << item->mode
<< ", type=";
if (item->type)
item->type->show(out);
else
out << "<nil>";
out << ", file=" << item->get_fileline() << endl;
}
}
}
void Scope::dump_scope(ostream&out) const
{
// Dump types
out << " -- imported types" << endl;
for (map<perm_string,const VType*>::const_iterator cur = use_types_.begin()
; cur != use_types_.end() ; ++cur) {
out << " " << cur->first << ": ";
cur->second->show(out);
out << endl;
}
out << " -- Types from this scope" << endl;
for (map<perm_string,const VType*>::const_iterator cur = cur_types_.begin()
; cur != cur_types_.end() ; ++cur) {
out << " " << cur->first << ": ";
cur->second->show(out);
out << endl;
}
// Dump constants
out << " -- imported constants" << endl;
for (map<perm_string,const_t*>::const_iterator cur = use_constants_.begin()
; cur != use_constants_.end() ; ++cur) {
out << " constant " << cur->first << " = ";
out << endl;
}
out << " -- Constants from this scope" << endl;
for (map<perm_string,const_t*>::const_iterator cur = cur_constants_.begin()
; cur != cur_constants_.end() ; ++cur) {
out << " constant " << cur->first << " = ";
out << endl;
}
// Dump signal declarations
out << " -- Signals" << endl;
for (map<perm_string,Signal*>::const_iterator cur = old_signals_.begin()
; cur != old_signals_.end() ; ++cur) {
if (cur->second)
cur->second->dump(out, 3);
else
out << " signal " << cur->first.str() << ": ???" << endl;
}
for (map<perm_string,Signal*>::const_iterator cur = new_signals_.begin()
; cur != new_signals_.end() ; ++cur) {
if (cur->second)
cur->second->dump(out, 3);
else
out << " signal " << cur->first.str() << ": ???" << endl;
}
// Dump subprograms
out << " -- Imported Subprograms" << endl;
for (map<perm_string,Subprogram*>::const_iterator cur = use_subprograms_.begin()
; cur != use_subprograms_.end() ; ++cur) {
out << " subprogram " << cur->first << " is" << endl;
cur->second->dump(out);
out << " end subprogram " << cur->first << endl;
}
out << " -- Subprograms from this scope" << endl;
for (map<perm_string,Subprogram*>::const_iterator cur = cur_subprograms_.begin()
; cur != cur_subprograms_.end() ; ++cur) {
out << " subprogram " << cur->first << " is" << endl;
cur->second->dump(out);
out << " end subprogram " << cur->first << endl;
}
// Dump component declarations
out << " -- Components" << endl;
for (map<perm_string,ComponentBase*>::const_iterator cur = old_components_.begin()
; cur != old_components_.end() ; ++cur) {
out << " component " << cur->first << " is" << endl;
cur->second->dump_generics(out);
cur->second->dump_ports(out);
out << " end component " << cur->first << endl;
}
for (map<perm_string,ComponentBase*>::const_iterator cur = new_components_.begin()
; cur != new_components_.end() ; ++cur) {
out << " component " << cur->first << " is" << endl;
cur->second->dump_generics(out);
cur->second->dump_ports(out);
out << " end component " << cur->first << endl;
}
}
void Entity::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "entity " << get_name()
<< " file=" << get_fileline() << endl;
dump_ports(out, indent+2);
for (map<perm_string,Architecture*>::const_iterator cur = arch_.begin()
; cur != arch_.end() ; ++cur) {
cur->second->dump(out, get_name(), indent);
}
}
void SigVarBase::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "signal/variable " << name_ << " is ";
if (type_)
out << *type_;
else
out << "?NO TYPE?";
out << endl;
}
void Expression::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "Expression [" << typeid(*this).name() << "]"
<< " at " << get_fileline()<< endl;
}
void ExpAggregate::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "Aggregate expression at " << get_fileline() << endl;
for (size_t idx = 0 ; idx < elements_.size() ; idx += 1)
elements_[idx]->dump(out, indent+2);
}
void ExpAggregate::element_t::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "choices:" << endl;
for (size_t idx = 0 ; idx < fields_.size() ; idx += 1)
fields_[idx]->dump(out, indent+4);
out << setw(indent) << "" << "expression:" << endl;
val_->dump(out, indent+4);
}
void ExpAggregate::choice_t::dump(ostream&out, int indent) const
{
if (others()) {
out << setw(indent) << "" << "=> others" << endl;
return;
}
if (expr_.get()) {
expr_->dump(out, indent);
return;
}
if (range_.get()) {
range_->dump(out, indent);
return;
}
out << setw(indent) << "" << "?choice_t?" << endl;
}
void ExpAttribute::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "Attribute " << name_
<< " at " << get_fileline() << endl;
base_->dump(out, indent+4);
}
void ExpBinary::dump_operands(ostream&out, int indent) const
{
operand1_->dump(out, indent);
operand2_->dump(out, indent);
}
void ExpBitstring::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "Bit string " << value_.size()
<< "b\"";
for (size_t idx = value_.size() ; idx > 0 ; idx -= 1) {
out << value_[idx-1];
}
out << "\"" << endl;
}
void ExpCharacter::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "Character '" << value_ << "'"
<< " at " << get_fileline() << endl;
}
void ExpConditional::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "Conditional expression at "<< get_fileline() << endl;
out << setw(indent) << "" << " when:" << endl;
cond_->dump(out, indent+4);
out << setw(indent) << "" << " do:" << endl;
for (list<Expression*>::const_iterator cur = true_clause_.begin()
; cur != true_clause_.end() ; ++cur) {
(*cur)->dump(out, indent+4);
}
for (list<else_t*>::const_iterator cur = else_clause_.begin()
; cur != else_clause_.end() ; ++cur) {
(*cur)->dump(out, indent);
}
}
void ExpConditional::else_t::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "when:" << endl;
if (cond_) cond_->dump(out, indent+4);
out << setw(indent) << "" << "do:" << endl;
for (list<Expression*>::const_iterator cur = true_clause_.begin()
; cur != true_clause_.end() ; ++cur) {
(*cur)->dump(out, indent+4);
}
}
void ExpEdge::dump(ostream&out, int indent) const
{
out << setw(indent) << "";
switch (fun_) {
case NEGEDGE:
out << "negedge ";
break;
case ANYEDGE:
out << "ANYedge ";
break;
case POSEDGE:
out << "posedge ";
}
out << "at " << get_fileline() << endl;
dump_operand1(out, indent+3);
}
void ExpFunc::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "function " << name_
<< " has " << argv_.size() << " arguments:" << endl;
for (size_t idx = 0 ; idx < argv_.size() ; idx += 1) {
argv_[idx]->dump(out, indent+2);
}
}
void ExpInteger::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "Integer " << value_
<< " at " << get_fileline() << endl;
}
void ExpReal::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "Integer " << value_
<< " at " << get_fileline() << endl;
}
void ExpLogical::dump(ostream&out, int indent) const
{
const char*fun_name = "?";
switch (fun_) {
case AND:
fun_name = "AND";
break;
case OR:
fun_name = "OR";
break;
case NAND:
fun_name = "NAND";
break;
case NOR:
fun_name = "NOR";
break;
case XOR:
fun_name = "XOR";
break;
case XNOR:
fun_name = "XNOR";
break;
}
out << setw(indent) << "" << "Logical " << fun_name
<< " at " << get_fileline() << endl;
dump_operands(out, indent+4);
}
void ExpName::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "ExpName(\"" << name_ << "\")"
<< " at " << get_fileline() << endl;
if (prefix_.get())
prefix_->dump(out, indent+8);
if (index_)
index_->dump(out, indent+6);
if (lsb_)
lsb_->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 ";
switch (fun_) {
case EQ:
out << "=";
break;
case LT:
out << "<";
break;
case GT:
out << ">";
break;
case NEQ:
out << "/=";
break;
case LE:
out << "<=";
break;
case GE:
out << ">=";
break;
}
out << endl;
dump_operands(out, indent+4);
}
void ExpString::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "String \"";
for(vector<char>::const_iterator it = value_.begin();
it != value_.end(); ++it)
out << *it;
out << "\""
<< " at " << get_fileline() << endl;
}
void ExpUAbs::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "abs() at " << get_fileline() << endl;
dump_operand1(out, indent+4);
}
void ExpUnary::dump_operand1(ostream&out, int indent) const
{
operand1_->dump(out, indent);
}
void ExpUNot::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "not() at " << get_fileline() << endl;
dump_operand1(out, indent+4);
}
void named_expr_t::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << name_ << "=>";
expr_->dump(out, indent);
}
void prange_t::dump(ostream&out, int indent) const
{
left_->dump(out, indent);
out << setw(indent) << "" << (direction_ ? "downto" : "to");
right_->dump(out, indent);
}
ostream& Expression::dump_inline(ostream&out) const
{
out << typeid(*this).name();
return out;
}
ostream& ExpInteger::dump_inline(ostream&out) const
{
out << value_;
return out;
}
ostream& ExpReal::dump_inline(ostream&out) const
{
out << value_;
return out;
}
void Subprogram::dump(ostream&fd) const
{
fd << " " << name_;
if (ports_->empty()) {
fd << "()";
} else {
fd << "(";
list<InterfacePort*>::const_iterator cur = ports_->begin();
InterfacePort*curp = *cur;
fd << curp->name << ":";
curp->type->show(fd);
for (++ cur ; cur != ports_->end() ; ++ cur) {
curp = *cur;
fd << "; " << curp->name << ":";
curp->type->show(fd);
}
fd << ")";
}
fd << " return ";
return_type_->show(fd);
fd << endl;
if (statements_== 0 || statements_->empty()) {
fd << " <no definition>" << endl;
} else {
for (list<SequentialStmt*>::const_iterator cur = statements_->begin()
; cur != statements_->end() ; ++cur) {
SequentialStmt*curp = *cur;
curp->dump(fd, 8);
}
}
}