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 \
|
||||
architec_elaborate.o entity_elaborate.o expression_elaborate.o \
|
||||
sequential_elaborate.o vtype_elaborate.o \
|
||||
entity_stream.o vtype_stream.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 sequential_emit.o vtype_emit.o \
|
||||
|
|
|
|||
|
|
@ -30,4 +30,6 @@ extern StringHeapLex lex_strings;
|
|||
|
||||
extern StringHeapLex filename_strings;
|
||||
|
||||
extern void library_set_work_path(const char*work_path);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -65,8 +65,11 @@ class ComponentBase : public LineInfo {
|
|||
// empties the list in the process.
|
||||
void set_interface(std::list<InterfacePort*>*ports);
|
||||
|
||||
|
||||
void write_to_stream(std::ostream&fd) const;
|
||||
|
||||
public:
|
||||
void dump_ports(ostream&out, int indent = 0) const;
|
||||
void dump_ports(std::ostream&out, int indent = 0) const;
|
||||
|
||||
protected:
|
||||
// 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 "compiler.h"
|
||||
# include "package.h"
|
||||
# include <fstream>
|
||||
# include <map>
|
||||
# include <string>
|
||||
# include <cassert>
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const char*library_work_path = 0;
|
||||
static void store_package_in_work(const Package*pack);
|
||||
|
||||
struct library_contents {
|
||||
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];
|
||||
|
||||
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)
|
||||
|
|
@ -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("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 <cstdlib>
|
||||
# include <cstring>
|
||||
# include <cerrno>
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
# include <sys/stat.h>
|
||||
|
||||
|
||||
bool verbose_flag = false;
|
||||
|
|
@ -55,6 +57,7 @@ bool verbose_flag = false;
|
|||
const char*dump_design_entities_path = 0;
|
||||
const char*dump_libraries_path = 0;
|
||||
|
||||
|
||||
extern void dump_libraries(ostream&file);
|
||||
|
||||
static void process_debug_token(const char*word)
|
||||
|
|
@ -74,8 +77,9 @@ int main(int argc, char*argv[])
|
|||
{
|
||||
int opt;
|
||||
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':
|
||||
process_debug_token(optarg);
|
||||
|
|
@ -96,8 +100,27 @@ int main(int argc, char*argv[])
|
|||
fputs(NOTICE, stdout);
|
||||
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();
|
||||
int errors = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
# include "package.h"
|
||||
# include "entity.h"
|
||||
|
||||
Package::Package(perm_string n, const ScopeBase&ref)
|
||||
: Scope(ref), name_(n)
|
||||
|
|
@ -27,3 +28,16 @@ Package::Package(perm_string n, const ScopeBase&ref)
|
|||
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 "LineInfo.h"
|
||||
# include <iostream>
|
||||
|
||||
class Package : public Scope, public LineInfo {
|
||||
|
||||
|
|
@ -30,6 +31,9 @@ class Package : public Scope, public LineInfo {
|
|||
|
||||
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:
|
||||
perm_string name_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@ class VType {
|
|||
VType() { }
|
||||
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;
|
||||
|
||||
public:
|
||||
|
|
@ -74,6 +79,7 @@ class VTypePrimitive : public VType {
|
|||
VTypePrimitive(type_t);
|
||||
~VTypePrimitive();
|
||||
|
||||
void write_to_stream(std::ostream&fd) const;
|
||||
void show(std::ostream&) 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();
|
||||
|
||||
void write_to_stream(std::ostream&fd) const;
|
||||
void show(std::ostream&) 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