Write package headers to a library file
Build up a work library by writing a VHDL representation of the package header into a source file. This representation needs to be accurate enough that later invocations of vhdlpp can read them with the VHDL parser.
This commit is contained in:
parent
2cb9a2360c
commit
38854822da
|
|
@ -63,6 +63,7 @@ O = main.o architec.o compiler.o entity.o \
|
||||||
expression.o package.o scope.o sequential.o vsignal.o vtype.o \
|
expression.o package.o scope.o sequential.o vsignal.o vtype.o \
|
||||||
architec_elaborate.o entity_elaborate.o expression_elaborate.o \
|
architec_elaborate.o entity_elaborate.o expression_elaborate.o \
|
||||||
sequential_elaborate.o vtype_elaborate.o \
|
sequential_elaborate.o vtype_elaborate.o \
|
||||||
|
entity_stream.o vtype_stream.o \
|
||||||
lexor.o lexor_keyword.o parse.o \
|
lexor.o lexor_keyword.o parse.o \
|
||||||
parse_misc.o library.o vhdlreal.o vhdlint.o \
|
parse_misc.o library.o vhdlreal.o vhdlint.o \
|
||||||
architec_emit.o entity_emit.o expression_emit.o sequential_emit.o vtype_emit.o \
|
architec_emit.o entity_emit.o expression_emit.o sequential_emit.o vtype_emit.o \
|
||||||
|
|
|
||||||
|
|
@ -30,4 +30,6 @@ extern StringHeapLex lex_strings;
|
||||||
|
|
||||||
extern StringHeapLex filename_strings;
|
extern StringHeapLex filename_strings;
|
||||||
|
|
||||||
|
extern void library_set_work_path(const char*work_path);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,11 @@ class ComponentBase : public LineInfo {
|
||||||
// empties the list in the process.
|
// empties the list in the process.
|
||||||
void set_interface(std::list<InterfacePort*>*ports);
|
void set_interface(std::list<InterfacePort*>*ports);
|
||||||
|
|
||||||
|
|
||||||
|
void write_to_stream(std::ostream&fd) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void dump_ports(ostream&out, int indent = 0) const;
|
void dump_ports(std::ostream&out, int indent = 0) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// This is really only used by the Entity derived class.
|
// This is really only used by the Entity derived class.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* 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 "entity.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void ComponentBase::write_to_stream(ostream&fd) const
|
||||||
|
{
|
||||||
|
fd << " component " << name_ << " is" << endl;
|
||||||
|
fd << " port(" << endl;
|
||||||
|
|
||||||
|
vector<InterfacePort*>::const_iterator cur = ports_.begin();
|
||||||
|
while (cur != ports_.end()) {
|
||||||
|
InterfacePort*item = *cur;
|
||||||
|
++cur;
|
||||||
|
|
||||||
|
fd << " " << item->name << " : ";
|
||||||
|
switch (item->mode) {
|
||||||
|
case PORT_NONE:
|
||||||
|
fd << "???? ";
|
||||||
|
break;
|
||||||
|
case PORT_IN:
|
||||||
|
fd << "in ";
|
||||||
|
break;
|
||||||
|
case PORT_OUT:
|
||||||
|
fd << "out ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
item->type->write_to_stream(fd);
|
||||||
|
|
||||||
|
if (cur != ports_.end())
|
||||||
|
fd << ";" << endl;
|
||||||
|
else
|
||||||
|
fd << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd << " );" << endl;
|
||||||
|
fd << " end component;" << endl;
|
||||||
|
}
|
||||||
|
|
@ -20,10 +20,16 @@
|
||||||
# include "parse_misc.h"
|
# include "parse_misc.h"
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
# include "package.h"
|
# include "package.h"
|
||||||
|
# include <fstream>
|
||||||
# include <map>
|
# include <map>
|
||||||
|
# include <string>
|
||||||
|
# include <cassert>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
static const char*library_work_path = 0;
|
||||||
|
static void store_package_in_work(const Package*pack);
|
||||||
|
|
||||||
struct library_contents {
|
struct library_contents {
|
||||||
map<perm_string,Package*> packages;
|
map<perm_string,Package*> packages;
|
||||||
};
|
};
|
||||||
|
|
@ -69,6 +75,9 @@ void library_save_package(const char*libname, Package*pack)
|
||||||
struct library_contents&lib = libraries[use_libname];
|
struct library_contents&lib = libraries[use_libname];
|
||||||
|
|
||||||
lib.packages[pack->name()] = pack;
|
lib.packages[pack->name()] = pack;
|
||||||
|
|
||||||
|
if (use_libname == "work")
|
||||||
|
store_package_in_work(pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void library_import(const YYLTYPE&loc, const std::list<perm_string>*names)
|
void library_import(const YYLTYPE&loc, const std::list<perm_string>*names)
|
||||||
|
|
@ -211,3 +220,18 @@ void generate_global_types(ActiveScope*res)
|
||||||
res->bind_name(perm_string::literal("std_logic"), &primitive_STDLOGIC);
|
res->bind_name(perm_string::literal("std_logic"), &primitive_STDLOGIC);
|
||||||
res->bind_name(perm_string::literal("bit_vector"),&primitive_BOOL_VECTOR);
|
res->bind_name(perm_string::literal("bit_vector"),&primitive_BOOL_VECTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void library_set_work_path(const char*path)
|
||||||
|
{
|
||||||
|
assert(library_work_path == 0);
|
||||||
|
library_work_path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void store_package_in_work(const Package*pack)
|
||||||
|
{
|
||||||
|
string path = string(library_work_path).append("/").append(pack->name()).append(".pkg");
|
||||||
|
|
||||||
|
ofstream file (path.c_str(), ios_base::out|ios_base::app);
|
||||||
|
|
||||||
|
pack->write_to_stream(file);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,11 @@ const char NOTICE[] =
|
||||||
# include <cstdio>
|
# include <cstdio>
|
||||||
# include <cstdlib>
|
# include <cstdlib>
|
||||||
# include <cstring>
|
# include <cstring>
|
||||||
|
# include <cerrno>
|
||||||
#if defined(HAVE_GETOPT_H)
|
#if defined(HAVE_GETOPT_H)
|
||||||
# include <getopt.h>
|
# include <getopt.h>
|
||||||
#endif
|
#endif
|
||||||
|
# include <sys/stat.h>
|
||||||
|
|
||||||
|
|
||||||
bool verbose_flag = false;
|
bool verbose_flag = false;
|
||||||
|
|
@ -55,6 +57,7 @@ bool verbose_flag = false;
|
||||||
const char*dump_design_entities_path = 0;
|
const char*dump_design_entities_path = 0;
|
||||||
const char*dump_libraries_path = 0;
|
const char*dump_libraries_path = 0;
|
||||||
|
|
||||||
|
|
||||||
extern void dump_libraries(ostream&file);
|
extern void dump_libraries(ostream&file);
|
||||||
|
|
||||||
static void process_debug_token(const char*word)
|
static void process_debug_token(const char*word)
|
||||||
|
|
@ -74,8 +77,9 @@ int main(int argc, char*argv[])
|
||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
int rc;
|
int rc;
|
||||||
|
const char*work_path = "ivl_vhdl_work";
|
||||||
|
|
||||||
while ( (opt=getopt(argc, argv, "D:vV")) != EOF) switch (opt) {
|
while ( (opt=getopt(argc, argv, "D:vVw:")) != EOF) switch (opt) {
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
process_debug_token(optarg);
|
process_debug_token(optarg);
|
||||||
|
|
@ -96,8 +100,27 @@ int main(int argc, char*argv[])
|
||||||
fputs(NOTICE, stdout);
|
fputs(NOTICE, stdout);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'w':
|
||||||
|
work_path = optarg;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( (rc = mkdir(work_path, 0777)) < 0 ) {
|
||||||
|
if (errno != EEXIST) {
|
||||||
|
fprintf(stderr, "Icarus Verilog VHDL unable to create work directory %s, errno=%d\n", work_path, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
struct stat stat_buf;
|
||||||
|
rc = stat(work_path, &stat_buf);
|
||||||
|
|
||||||
|
if (!S_ISDIR(stat_buf.st_mode)) {
|
||||||
|
fprintf(stderr, "Icarus Verilog VHDL work path `%s' is not a directory.\n", work_path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
library_set_work_path(work_path);
|
||||||
|
|
||||||
preload_global_types();
|
preload_global_types();
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "package.h"
|
# include "package.h"
|
||||||
|
# include "entity.h"
|
||||||
|
|
||||||
Package::Package(perm_string n, const ScopeBase&ref)
|
Package::Package(perm_string n, const ScopeBase&ref)
|
||||||
: Scope(ref), name_(n)
|
: Scope(ref), name_(n)
|
||||||
|
|
@ -27,3 +28,16 @@ Package::Package(perm_string n, const ScopeBase&ref)
|
||||||
Package::~Package()
|
Package::~Package()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Package::write_to_stream(ostream&fd) const
|
||||||
|
{
|
||||||
|
fd << "package " << name_ << " is" << endl;
|
||||||
|
|
||||||
|
for (map<perm_string,ComponentBase*>::const_iterator cur = components_.begin()
|
||||||
|
; cur != components_.end() ; ++cur) {
|
||||||
|
|
||||||
|
cur->second->write_to_stream(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
fd << "end package " << name_ << ";" << endl;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
# include "scope.h"
|
# include "scope.h"
|
||||||
# include "LineInfo.h"
|
# include "LineInfo.h"
|
||||||
|
# include <iostream>
|
||||||
|
|
||||||
class Package : public Scope, public LineInfo {
|
class Package : public Scope, public LineInfo {
|
||||||
|
|
||||||
|
|
@ -30,6 +31,9 @@ class Package : public Scope, public LineInfo {
|
||||||
|
|
||||||
perm_string name() const { return name_; }
|
perm_string name() const { return name_; }
|
||||||
|
|
||||||
|
// This method writes a package header to a library file.
|
||||||
|
void write_to_stream(std::ostream&fd) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,11 @@ class VType {
|
||||||
VType() { }
|
VType() { }
|
||||||
virtual ~VType() =0;
|
virtual ~VType() =0;
|
||||||
|
|
||||||
|
// This virtual method writes a VHDL-accurate representation
|
||||||
|
// of this type to the designated stream. This is used for
|
||||||
|
// writing parsed types to library files.
|
||||||
|
virtual void write_to_stream(std::ostream&fd) const;
|
||||||
|
|
||||||
virtual void show(std::ostream&) const;
|
virtual void show(std::ostream&) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -74,6 +79,7 @@ class VTypePrimitive : public VType {
|
||||||
VTypePrimitive(type_t);
|
VTypePrimitive(type_t);
|
||||||
~VTypePrimitive();
|
~VTypePrimitive();
|
||||||
|
|
||||||
|
void write_to_stream(std::ostream&fd) const;
|
||||||
void show(std::ostream&) const;
|
void show(std::ostream&) const;
|
||||||
void elaborate(decl_t&decl) const;
|
void elaborate(decl_t&decl) const;
|
||||||
|
|
||||||
|
|
@ -116,6 +122,7 @@ class VTypeArray : public VType {
|
||||||
VTypeArray(const VType*etype, const std::vector<range_t>&r, bool signed_vector =false);
|
VTypeArray(const VType*etype, const std::vector<range_t>&r, bool signed_vector =false);
|
||||||
~VTypeArray();
|
~VTypeArray();
|
||||||
|
|
||||||
|
void write_to_stream(std::ostream&fd) const;
|
||||||
void show(std::ostream&) const;
|
void show(std::ostream&) const;
|
||||||
void elaborate(decl_t&decl) const;
|
void elaborate(decl_t&decl) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* 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 <typeinfo>
|
||||||
|
# include <cassert>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void VType::write_to_stream(ostream&fd) const
|
||||||
|
{
|
||||||
|
fd << "/* UNKNOWN TYPE: " << typeid(*this).name() << " */";
|
||||||
|
}
|
||||||
|
|
||||||
|
void VTypeArray::write_to_stream(ostream&fd) const
|
||||||
|
{
|
||||||
|
fd << "array ";
|
||||||
|
if (ranges_.size() > 0) {
|
||||||
|
assert(ranges_.size() < 2);
|
||||||
|
fd << "(" << ranges_[0].msb()
|
||||||
|
<< " downto " << ranges_[0].lsb() << ") ";
|
||||||
|
}
|
||||||
|
|
||||||
|
fd << "of ";
|
||||||
|
etype_->write_to_stream(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VTypePrimitive::write_to_stream(ostream&fd) const
|
||||||
|
{
|
||||||
|
switch (type_) {
|
||||||
|
case INTEGER:
|
||||||
|
fd << "integer";
|
||||||
|
break;
|
||||||
|
case STDLOGIC:
|
||||||
|
fd << "std_logic";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
fd << "/* PRIMITIVE: " << type_ << " */";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue