Basic structure for emitting packages.

This commit is contained in:
Stephen Williams 2013-05-11 20:00:00 -07:00
parent d9fea802da
commit 7f7decde03
9 changed files with 185 additions and 5 deletions

View File

@ -36,5 +36,6 @@ extern StringHeapLex filename_strings;
extern void library_set_work_path(const char*work_path); extern void library_set_work_path(const char*work_path);
extern void library_add_directory(const char*directory); extern void library_add_directory(const char*directory);
extern int emit_packages(void);
#endif #endif

View File

@ -134,6 +134,8 @@ void library_save_package(perm_string parse_library_name, Package*pack)
// library right now, then store it in the work library. // library right now, then store it in the work library.
if (parse_library_name.str() == 0) if (parse_library_name.str() == 0)
store_package_in_work(pack); store_package_in_work(pack);
else
pack->set_library(parse_library_name);
} }
static void import_library_name(const YYLTYPE&loc, perm_string name) static void import_library_name(const YYLTYPE&loc, perm_string name)
@ -369,3 +371,25 @@ static void store_package_in_work(const Package*pack)
pack->write_to_stream(file); pack->write_to_stream(file);
} }
static int emit_packages(perm_string lib_name, const map<perm_string,Package*>&packages)
{
int errors = 0;
for (map<perm_string,Package*>::const_iterator cur = packages.begin()
; cur != packages.end() ; ++cur) {
errors += cur->second->emit_package(cout);
}
return errors;
}
int emit_packages(void)
{
int errors = 0;
for (map<perm_string,struct library_contents>::iterator cur = libraries.begin()
; cur != libraries.end() ; ++cur) {
errors += emit_packages(cur->first, cur->second.packages);
}
return 0;
}

View File

@ -218,17 +218,24 @@ int main(int argc, char*argv[])
} }
if (errors > 0) { if (errors > 0) {
parser_cleanup(); parser_cleanup();
return 2; return 2;
} }
errors = elaborate_entities(); errors = elaborate_entities();
if (errors > 0) { if (errors > 0) {
fprintf(stderr, "%d errors elaborating design.\n", errors); fprintf(stderr, "%d errors elaborating design.\n", errors);
parser_cleanup(); parser_cleanup();
return 3; return 3;
} }
errors = emit_packages();
if (errors > 0) {
fprintf(stderr, "%d errors emitting packages.\n", errors);
parser_cleanup();
return 4;
}
errors = emit_entities(); errors = emit_entities();
if (errors > 0) { if (errors > 0) {
fprintf(stderr, "%d errors emitting design.\n", errors); fprintf(stderr, "%d errors emitting design.\n", errors);

View File

@ -20,6 +20,7 @@
# include "package.h" # include "package.h"
# include "entity.h" # include "entity.h"
# include "parse_misc.h" # include "parse_misc.h"
# include "ivl_assert.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)
@ -31,6 +32,12 @@ Package::~Package()
ScopeBase::cleanup(); ScopeBase::cleanup();
} }
void Package::set_library(perm_string lname)
{
ivl_assert(*this, from_library_.str() == 0);
from_library_ = lname;
}
/* /*
* The Package::write_to_stream is used to write the package to the * The Package::write_to_stream is used to write the package to the
* work space (or library) so writes proper VHDL that the library * work space (or library) so writes proper VHDL that the library

View File

@ -1,7 +1,7 @@
#ifndef __package_H #ifndef __package_H
#define __package_H #define __package_H
/* /*
* Copyright (c) 2011 Stephen Williams (steve@icarus.com) * Copyright (c) 2011-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -29,12 +29,19 @@ class Package : public Scope, public LineInfo {
Package(perm_string name, const ScopeBase&ref); Package(perm_string name, const ScopeBase&ref);
~Package(); ~Package();
// The the library from which this package came. Having a
// source library influences the emit_package() method.
void set_library(perm_string);
perm_string name() const { return name_; } perm_string name() const { return name_; }
// This method writes a package header to a library file. // This method writes a package header to a library file.
void write_to_stream(std::ostream&fd) const; void write_to_stream(std::ostream&fd) const;
int emit_package(std::ostream&fd) const;
private: private:
perm_string from_library_;
perm_string name_; perm_string name_;
}; };

66
vhdlpp/package_emit.cc Normal file
View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2013 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "package.h"
# include <iostream>
using namespace std;
int Package::emit_package(ostream&fd) const
{
// Don't emit the package if there is nothing in it that SV
// cares about.
if (new_types_.empty() && old_subprograms_.empty() && new_subprograms_.empty())
return 0;
// If this package was imported from a library, then do not
// emit it again.
if (from_library_.str() != 0) {
fd << "/* Suppress package " << name()
<< " from library " << from_library_ << " */" << endl;
return 0;
}
int errors = 0;
fd << "package \\" << name() << " ;" << endl;
// Only emit types that were defined within this package. Skip
// the types that were imported from elsewhere.
for (map<perm_string,const VType*>::const_iterator cur = new_types_.begin()
; cur != new_types_.end() ; ++ cur) {
errors += cur->second->emit_def(fd);
fd << " " << cur->first << " ;" << endl;
}
for (map<perm_string,Subprogram*>::const_iterator cur = old_subprograms_.begin()
; cur != old_subprograms_.end() ; ++ cur) {
errors += cur->second->emit_package(fd);
}
for (map<perm_string,Subprogram*>::const_iterator cur = new_subprograms_.begin()
; cur != new_subprograms_.end() ; ++ cur) {
errors += cur->second->emit_package(fd);
}
fd << "endpackage" << endl;
return errors;
}

View File

@ -38,6 +38,9 @@ class Subprogram : public LineInfo {
inline const perm_string&name() const { return name_; } inline const perm_string&name() const { return name_; }
// Emit a definition as it would show up in a package.
int emit_package(std::ostream&fd) const;
void write_to_stream(std::ostream&fd) const; void write_to_stream(std::ostream&fd) const;
void dump(std::ostream&fd) const; void dump(std::ostream&fd) const;

56
vhdlpp/subprogram_emit.cc Normal file
View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2013 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "subprogram.h"
# include "sequential.h"
# include "vtype.h"
# include <iostream>
using namespace std;
int Subprogram::emit_package(ostream&fd) const
{
int errors = 0;
if (return_type_) {
fd << "function ";
return_type_->emit_def(fd);
fd << " " << name_;
fd << ";" << endl;
} else {
fd << "task " << name_ << ";" << endl;
}
if (statements_) {
for (list<SequentialStmt*>::const_iterator cur = statements_->begin()
; cur != statements_->end() ; ++cur) {
errors += (*cur)->emit(fd, 0, 0);
}
} else {
fd << " begin /* empty body */ end" << endl;
}
if (return_type_)
fd << "endfunction" << endl;
else
fd << "endtask" << endl;
return errors;
}

View File

@ -88,9 +88,15 @@ int VTypeArray::emit_def(ostream&out) const
cur = dims.front(); cur = dims.front();
dims.pop_front(); dims.pop_front();
out << "["; out << "[";
errors += cur->dimension(0).msb()->emit(out, 0, 0); if (cur->dimension(0).msb())
errors += cur->dimension(0).msb()->emit(out, 0, 0);
else
out << "?error?";
out << ":"; out << ":";
errors += cur->dimension(0).lsb()->emit(out, 0, 0); if (cur->dimension(0).lsb())
errors += cur->dimension(0).lsb()->emit(out, 0, 0);
else
out << "?error?";
out << "]"; out << "]";
} }
@ -130,6 +136,9 @@ int VTypePrimitive::emit_primitive_type(ostream&out) const
case INTEGER: case INTEGER:
out << "bool [31:0]"; out << "bool [31:0]";
break; break;
case CHARACTER:
out << "char";
break;
default: default:
assert(0); assert(0);
break; break;