From 30cfcbe2dcf04041d447c0632d5ca4b239ac6c51 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 2 Oct 2011 10:56:00 -0700 Subject: [PATCH] Rework elaborate/emit of types. This rework is needed to reasonably handle new types, like enums. --- vhdlpp/Makefile.in | 2 +- vhdlpp/entity.h | 2 +- vhdlpp/entity_elaborate.cc | 5 +-- vhdlpp/vsignal.cc | 2 +- vhdlpp/vtype.h | 35 ++++++++++----- vhdlpp/vtype_elaborate.cc | 69 ----------------------------- vhdlpp/vtype_emit.cc | 91 +++++++++++++++++++++++++++++--------- 7 files changed, 99 insertions(+), 107 deletions(-) delete mode 100644 vhdlpp/vtype_elaborate.cc diff --git a/vhdlpp/Makefile.in b/vhdlpp/Makefile.in index a181be4eb..c60bd9757 100644 --- a/vhdlpp/Makefile.in +++ b/vhdlpp/Makefile.in @@ -62,7 +62,7 @@ M = StringHeap.o LineInfo.o O = main.o architec.o compiler.o entity.o \ expression.o package.o scope.o sequential.o vsignal.o vtype.o \ architec_elaborate.o entity_elaborate.o expression_elaborate.o \ - sequential_elaborate.o vtype_elaborate.o \ + sequential_elaborate.o \ entity_stream.o vtype_stream.o \ lexor.o lexor_keyword.o parse.o \ parse_misc.o library.o vhdlreal.o vhdlint.o \ diff --git a/vhdlpp/entity.h b/vhdlpp/entity.h index c07d70b7e..88846a076 100644 --- a/vhdlpp/entity.h +++ b/vhdlpp/entity.h @@ -23,9 +23,9 @@ # include # include # include +# include "vtype.h" # include "StringHeap.h" # include "LineInfo.h" -# include "vtype.h" typedef enum { PORT_NONE=0, PORT_IN, PORT_OUT } port_mode_t; diff --git a/vhdlpp/entity_elaborate.cc b/vhdlpp/entity_elaborate.cc index 6e738c3bb..586c9041d 100644 --- a/vhdlpp/entity_elaborate.cc +++ b/vhdlpp/entity_elaborate.cc @@ -93,7 +93,6 @@ int Entity::elaborate_ports_(void) ; cur != ports.end() ; ++cur) { InterfacePort*cur_port = *cur; - VType::decl_t cur_decl; const VType*type = cur_port->type; if (type == 0) { @@ -104,8 +103,8 @@ int Entity::elaborate_ports_(void) continue; } - type->elaborate(cur_decl); - + VType::decl_t cur_decl; + cur_decl.type = type; declarations_[cur_port->name] = cur_decl; } diff --git a/vhdlpp/vsignal.cc b/vhdlpp/vsignal.cc index 4e1367ceb..de7685300 100644 --- a/vhdlpp/vsignal.cc +++ b/vhdlpp/vsignal.cc @@ -34,7 +34,7 @@ SigVarBase::~SigVarBase() void SigVarBase::type_elaborate_(VType::decl_t&decl) { - type_->elaborate(decl); + decl.type = type_; } int Signal::emit(ostream&out, Entity*, Architecture*) diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 812f4bc22..0be59e975 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -48,18 +48,21 @@ class VType { virtual void show(std::ostream&) const; public: - enum vtype_t { VNONE, VBOOL, VLOGIC }; + // A couple places use the VType along with a few + // per-declaration details, so provide a common structure for + // holding that stuff together. struct decl_t { - public: - decl_t() : reg_flag(false), signed_flag(false), type(VNONE), msb(0), lsb(0) { } + decl_t() : type(0), reg_flag(false) { } int emit(std::ostream&out, perm_string name) const; - public: + + const VType*type; bool reg_flag; - bool signed_flag; - vtype_t type; - long msb, lsb; }; - virtual void elaborate(decl_t&decl) const =0; + + private: + friend class decl_t; + // This virtual method is called to emit the declaration. + virtual int emit(std::ostream&out, perm_string name, bool reg_flag) const =0; }; inline std::ostream&operator << (std::ostream&out, const VType&item) @@ -85,10 +88,14 @@ class VTypePrimitive : public VType { void write_to_stream(std::ostream&fd) const; void show(std::ostream&) const; - void elaborate(decl_t&decl) const; type_t type() const { return type_; } + int emit_primitive_type(std::ostream&fd) const; + + private: + int emit(std::ostream&out, perm_string name, bool reg_flag) const; + private: type_t type_; }; @@ -128,7 +135,6 @@ class VTypeArray : public VType { void write_to_stream(std::ostream&fd) const; void show(std::ostream&) const; - void elaborate(decl_t&decl) const; size_t dimensions() const; const range_t&dimension(size_t idx) const @@ -138,6 +144,9 @@ class VTypeArray : public VType { const VType* element_type() const; + private: + int emit(std::ostream&out, perm_string name, bool reg_flag) const; + private: const VType*etype_; @@ -151,7 +160,8 @@ class VTypeRange : public VType { VTypeRange(const VType*base, int64_t max_val, int64_t min_val); ~VTypeRange(); - virtual void elaborate(decl_t&decl) const; + private: + int emit(std::ostream&out, perm_string name, bool reg_flag) const; private: const VType*base_; @@ -164,7 +174,8 @@ class VTypeEnum : public VType { VTypeEnum(const std::list*names); ~VTypeEnum(); - virtual void elaborate(decl_t&decl) const; + private: + int emit(std::ostream&out, perm_string name, bool reg_flag) const; private: std::vectornames_; diff --git a/vhdlpp/vtype_elaborate.cc b/vhdlpp/vtype_elaborate.cc deleted file mode 100644 index 99d8d461f..000000000 --- a/vhdlpp/vtype_elaborate.cc +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 "vtype.h" -# include -# include - -using namespace std; - -void VTypeArray::elaborate(VType::decl_t&decl) const -{ - const VTypePrimitive*base = dynamic_cast(etype_); - assert(base != 0); - - base->elaborate(decl); - //assert(decl.msb == decl.lsb == 0); - - decl.msb = dimension(0).msb(); - decl.lsb = dimension(0).lsb(); - decl.signed_flag = signed_flag_; -} - -void VTypePrimitive::elaborate(VType::decl_t&decl) const -{ - decl.type = VNONE; - decl.signed_flag = false; - decl.msb = 0; - decl.lsb = 0; - - switch (type_) { - case BOOLEAN: - case BIT: - decl.type = VBOOL; - break; - case STDLOGIC: - decl.type = VLOGIC; - break; - case INTEGER: - decl.type = VBOOL; - decl.msb = 31; - decl.lsb = 0; - break; - } -} - -void VTypeRange::elaborate(VType::decl_t&decl) const -{ - base_->elaborate(decl); -} - -void VTypeEnum::elaborate(decl_t&) const -{ -} diff --git a/vhdlpp/vtype_emit.cc b/vhdlpp/vtype_emit.cc index c6d536a3d..f65506a86 100644 --- a/vhdlpp/vtype_emit.cc +++ b/vhdlpp/vtype_emit.cc @@ -25,31 +25,82 @@ using namespace std; + int VType::decl_t::emit(ostream&out, perm_string name) const { - const char*wire = reg_flag? "reg" : "wire"; + return type->emit(out, name, reg_flag); +} - switch (type) { - case VType::VNONE: - out << "// N type for " << name << endl; + +int VTypeArray::emit(ostream&out, perm_string name, bool reg_flag) const +{ + int errors = 0; + const VTypePrimitive*base = dynamic_cast (etype_); + assert(base != 0); + assert(dimensions() == 1); + + if (reg_flag) + out << "reg "; + else + out << "wire "; + + base->emit_primitive_type(out); + if (signed_flag_) + out << "signed "; + + out << "[" << dimension(0).msb() << ":" << dimension(0).lsb() << "] "; + + out << "\\" << name << " "; + + return errors; +} + +int VTypeEnum::emit(ostream&out, perm_string name, bool reg_flag) const +{ + int errors = 0; + assert(0); + return errors; +} + +int VTypePrimitive::emit_primitive_type(ostream&out) const +{ + int errors = 0; + switch (type_) { + case BOOLEAN: + case BIT: + out << "bool "; break; - case VType::VLOGIC: - out << wire<< " logic "; - if (signed_flag) - out << "signed "; - if (msb != lsb) - out << "[" << msb << ":" << lsb << "] "; - out << "\\" << name << " "; + case STDLOGIC: + out << "logic "; break; - case VType::VBOOL: - out << wire << " bool "; - if (signed_flag) - out << "signed "; - if (msb != lsb) - out << "[" << msb << ":" << lsb << "] "; - out << "\\" << name << " "; + case INTEGER: + out << "bool [31:0] "; + break; + default: + assert(0); break; } - - return 0; + return errors; +} + +int VTypePrimitive::emit(ostream&out, perm_string name, bool reg_flag) const +{ + int errors = 0; + if (reg_flag) + out << "reg "; + else + out << "wire "; + + errors += emit_primitive_type(out); + + out << "\\" << name << " "; + + return errors; +} + +int VTypeRange::emit(ostream&out, perm_string name, bool reg_flag) const +{ + int errors = 0; + assert(0); + return errors; }