Import parameters from packages.

This commit is contained in:
Stephen Williams 2013-02-14 17:53:47 -08:00
parent c4386da666
commit 99b8086ad2
8 changed files with 112 additions and 9 deletions

View File

@ -22,6 +22,7 @@
# include "PScope.h"
# include "LineInfo.h"
# include "StringHeap.h"
# include <iostream>
/*
* SystemVerilog supports class declarations with their own lexical
@ -35,6 +36,7 @@ class PPackage : public PScopeExtra, public LineInfo {
explicit PPackage (perm_string name, LexicalScope*parent);
~PPackage();
void pform_dump(std::ostream&out) const;
};
#endif

View File

@ -987,6 +987,12 @@ int main(int argc, char*argv[])
; cur != disciplines.end() ; ++ cur ) {
pform_dump(out, (*cur).second);
}
out << "PFORM DUMP PACKAGES:" << endl;
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
; pac != pform_packages.end() ; ++ pac) {
pform_dump(out, pac->second);
}
out << "PFORM DUMP MODULES:" << endl;
for (map<perm_string,Module*>::iterator mod = pform_modules.begin()
; mod != pform_modules.end() ; ++ mod ) {

11
parse.y
View File

@ -1354,13 +1354,19 @@ package_declaration /* IEEE1800-2005 A.1.2 */
package_import_declaration /* IEEE1800-2005 A.2.1.3 */
: K_import package_import_item_list ';'
{ yyerror(@1, "sorry: Package import declarations not supported.");
}
{ }
;
package_import_item
: IDENTIFIER K_SCOPE_RES IDENTIFIER
{ pform_package_import(@2, $1, $3);
delete[]$1;
delete[]$3;
}
| IDENTIFIER K_SCOPE_RES '*'
{ pform_package_import(@2, $1, 0);
delete[]$1;
}
;
package_import_item_list
@ -1370,6 +1376,7 @@ package_import_item_list
package_item /* IEEE1800-2005 A.1.10 */
: timeunits_declaration
| K_parameter param_type parameter_assign_list ';'
| K_localparam param_type localparam_assign_list ';'
| type_declaration
| function_declaration

View File

@ -22,9 +22,11 @@
# include <cstdio>
# include "StringHeap.h"
# include <string>
# include <ostream>
# include <map>
class Module;
class PPackage;
class PUdp;
/*
@ -32,8 +34,11 @@ class PUdp;
* Verilog source into pform for elaboration. The parser adds modules
* to these maps as it compiles modules in the Verilog source.
*/
extern map<perm_string,Module*> pform_modules;
extern map<perm_string,PUdp*> pform_primitives;
extern std::map<perm_string,Module*> pform_modules;
extern std::map<perm_string,PUdp*> pform_primitives;
extern std::map<perm_string,PPackage*> pform_packages;
extern void pform_dump(std::ostream&out, const PPackage*pac);
/*
* This code actually invokes the parser to make modules. The first

View File

@ -294,6 +294,12 @@ static PScopeExtra* find_nearest_scopex(LexicalScope*scope)
return scopex;
}
LexicalScope* pform_peek_scope(void)
{
assert(lexical_scope);
return lexical_scope;
}
PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name)
{
PClass*class_scope = new PClass(name, lexical_scope);

17
pform.h
View File

@ -187,10 +187,6 @@ extern void pform_class_property(const struct vlltype&loc,
std::list<decl_assignment_t*>*decls);
extern void pform_end_class_declaration(void);
extern void pform_start_package_declaration(const struct vlltype&loc,
const char*type);
extern void pform_end_package_declaration(const struct vlltype&loc);
extern void pform_make_udp(perm_string name, list<perm_string>*parms,
svector<PWire*>*decl, list<string>*table,
Statement*init,
@ -202,6 +198,14 @@ extern void pform_make_udp(perm_string name,
list<perm_string>*parms,
list<string>*table,
const char*file, unsigned lineno);
/*
* Package related functions.
*/
extern void pform_start_package_declaration(const struct vlltype&loc,
const char*type);
extern void pform_end_package_declaration(const struct vlltype&loc);
extern void pform_package_import(const struct vlltype&loc,
const char*pkg_name, const char*ident);
/*
* Enter/exit name scopes. The push_scope function pushes the scope
@ -210,6 +214,11 @@ extern void pform_make_udp(perm_string name,
*/
extern void pform_pop_scope();
/*
* Peek at the current (most recently active) scope.
*/
extern LexicalScope* pform_peek_scope();
extern PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name);
extern PPackage* pform_push_package_scope(const struct vlltype&loc, perm_string name);
extern PTask*pform_push_task_scope(const struct vlltype&loc, char*name,

View File

@ -29,6 +29,7 @@
# include "PClass.h"
# include "PEvent.h"
# include "PGenerate.h"
# include "PPackage.h"
# include "PSpec.h"
# include "discipline.h"
# include "ivl_target_priv.h"
@ -1496,3 +1497,16 @@ void pform_dump(std::ostream&out, const ivl_discipline_s*dis)
out << " flow " << tmp->name() << ";" << endl;
out << "enddiscipline" << endl;
}
void pform_dump(std::ostream&out, const PPackage*pac)
{
pac->pform_dump(out);
}
void PPackage::pform_dump(std::ostream&out) const
{
out << "package " << pscope_name() << endl;
dump_localparams_(out, 4);
dump_parameters_(out, 4);
out << "endpackage" << endl;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2012 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
@ -20,23 +21,76 @@
# include "pform.h"
# include "PPackage.h"
# include "parse_misc.h"
# include "parse_api.h"
# include <map>
# include <sstream>
# include "ivl_assert.h"
using namespace std;
/*
* This is a map of packages that have been defined.
*/
map<perm_string,PPackage*> pform_packages;
static PPackage*pform_cur_package = 0;
void pform_start_package_declaration(const struct vlltype&loc, const char*name)
{
VLerror(loc, "sorry: Package declarations not supported.");
ivl_assert(loc, pform_cur_package == 0);
perm_string use_name = lex_strings.make(name);
PPackage*pkg_scope = pform_push_package_scope(loc, use_name);
FILE_NAME(pkg_scope, loc);
pform_cur_package = pkg_scope;
}
void pform_end_package_declaration(const struct vlltype&loc)
{
ivl_assert(loc, pform_cur_package);
perm_string use_name = pform_cur_package->pscope_name();
map<perm_string,PPackage*>::const_iterator test = pform_packages.find(use_name);
if (test != pform_packages.end()) {
ostringstream msg;
msg << "Package " << use_name << " was already declared here: "
<< test->second->get_fileline() << ends;
VLerror(msg.str().c_str());
} else {
pform_packages[use_name] = pform_cur_package;
}
pform_packages[use_name] = pform_cur_package;
pform_cur_package = 0;
pform_pop_scope();
}
/*
* Do the import early, during processing. This requires that the
* package is declared in pform ahead of time (it is) and that we can
* simply transfer definitions to the current scope (we can).
*/
void pform_package_import(const struct vlltype&, const char*pkg_name, const char*ident)
{
perm_string use_name = lex_strings.make(pkg_name);
map<perm_string,PPackage*>::const_iterator pcur = pform_packages.find(use_name);
if (pcur == pform_packages.end()) {
ostringstream msg;
msg << "Package " << pkg_name << " not found." << ends;
VLerror(msg.str().c_str());
return;
}
perm_string use_ident;
if (ident) use_ident = lex_strings.make(ident);
PPackage*pkg = pcur->second;
LexicalScope*scope = pform_peek_scope();
for (map<perm_string,LexicalScope::param_expr_t>::const_iterator cur = pkg->parameters.begin()
; cur != pkg->parameters.end() ; ++cur) {
scope->parameters[cur->first] = cur->second;
}
}