Merge branch 'package-imports-rework'
This commit is contained in:
commit
9bb2147fb5
|
|
@ -118,9 +118,9 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
||||||
pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \
|
pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \
|
||||||
pform_class_type.o pform_string_type.o pform_struct_type.o pform_types.o \
|
pform_class_type.o pform_string_type.o pform_struct_type.o pform_types.o \
|
||||||
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \
|
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \
|
||||||
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PGate.o \
|
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PFunction.o \
|
||||||
PGenerate.o PModport.o PPackage.o PScope.o PSpec.o PTask.o PUdp.o \
|
PGate.o PGenerate.o PModport.o PNamedItem.o PPackage.o PScope.o PSpec.o \
|
||||||
PFunction.o PWire.o Statement.o AStatement.o $M $(FF) $(TT)
|
PTask.o PUdp.o PWire.o Statement.o AStatement.o $M $(FF) $(TT)
|
||||||
|
|
||||||
all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
|
all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
|
||||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||||
|
|
|
||||||
12
Module.cc
12
Module.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2019 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
|
||||||
|
|
@ -122,3 +122,13 @@ const list<PGate*>& Module::get_gates() const
|
||||||
{
|
{
|
||||||
return gates_;
|
return gates_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType Module::symbol_type() const
|
||||||
|
{
|
||||||
|
if (program_block)
|
||||||
|
return PROGRAM;
|
||||||
|
if (is_interface)
|
||||||
|
return INTERFACE;
|
||||||
|
|
||||||
|
return MODULE;
|
||||||
|
}
|
||||||
|
|
|
||||||
10
Module.h
10
Module.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_Module_H
|
#ifndef IVL_Module_H
|
||||||
#define IVL_Module_H
|
#define IVL_Module_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2019 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
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
# include "HName.h"
|
# include "HName.h"
|
||||||
# include "named.h"
|
# include "named.h"
|
||||||
# include "PScope.h"
|
# include "PScope.h"
|
||||||
# include "LineInfo.h"
|
# include "PNamedItem.h"
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "pform_types.h"
|
# include "pform_types.h"
|
||||||
class PExpr;
|
class PExpr;
|
||||||
|
|
@ -54,7 +54,7 @@ class NetScope;
|
||||||
* these containers as well.
|
* these containers as well.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Module : public PScopeExtra, public LineInfo {
|
class Module : public PScopeExtra, public PNamedItem {
|
||||||
|
|
||||||
/* The module ports are in general a vector of port_t
|
/* The module ports are in general a vector of port_t
|
||||||
objects. Each port has a name and an ordered list of
|
objects. Each port has a name and an ordered list of
|
||||||
|
|
@ -97,7 +97,7 @@ class Module : public PScopeExtra, public LineInfo {
|
||||||
/* specparams are simpler than other parameters, in that they
|
/* specparams are simpler than other parameters, in that they
|
||||||
can have a range, but not an explicit type. The restrictions
|
can have a range, but not an explicit type. The restrictions
|
||||||
are enforced by the parser. */
|
are enforced by the parser. */
|
||||||
map<perm_string,param_expr_t>specparams;
|
map<perm_string,param_expr_t*>specparams;
|
||||||
|
|
||||||
/* The module also has defparam assignments which don't create
|
/* The module also has defparam assignments which don't create
|
||||||
new parameters within the module, but may be used to set
|
new parameters within the module, but may be used to set
|
||||||
|
|
@ -160,6 +160,8 @@ class Module : public PScopeExtra, public LineInfo {
|
||||||
|
|
||||||
bool elaborate_sig(Design*, NetScope*scope) const;
|
bool elaborate_sig(Design*, NetScope*scope) const;
|
||||||
|
|
||||||
|
SymbolType symbol_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void dump_specparams_(ostream&out, unsigned indent) const;
|
void dump_specparams_(ostream&out, unsigned indent) const;
|
||||||
list<PGate*> gates_;
|
list<PGate*> gates_;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2012-2019 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
|
||||||
|
|
@ -28,3 +28,8 @@ PClass::PClass(perm_string name, LexicalScope*parent)
|
||||||
PClass::~PClass()
|
PClass::~PClass()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType PClass::symbol_type() const
|
||||||
|
{
|
||||||
|
return CLASS;
|
||||||
|
}
|
||||||
|
|
|
||||||
8
PClass.h
8
PClass.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_PClass_H
|
#ifndef IVL_PClass_H
|
||||||
#define IVL_PClass_H
|
#define IVL_PClass_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2012-2019 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
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "PScope.h"
|
# include "PScope.h"
|
||||||
# include "LineInfo.h"
|
# include "PNamedItem.h"
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@ class PChainConstructor;
|
||||||
* collected.
|
* collected.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PClass : public PScopeExtra, public LineInfo {
|
class PClass : public PScopeExtra, public PNamedItem {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PClass (perm_string name, LexicalScope*parent);
|
explicit PClass (perm_string name, LexicalScope*parent);
|
||||||
|
|
@ -40,6 +40,8 @@ class PClass : public PScopeExtra, public LineInfo {
|
||||||
|
|
||||||
void dump(std::ostream&out, unsigned indent) const;
|
void dump(std::ostream&out, unsigned indent) const;
|
||||||
|
|
||||||
|
SymbolType symbol_type() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class_type_t*type;
|
class_type_t*type;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2004 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2004-2019 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
|
||||||
|
|
@ -35,3 +35,7 @@ perm_string PEvent::name() const
|
||||||
return name_;
|
return name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType PEvent::symbol_type() const
|
||||||
|
{
|
||||||
|
return EVENT;
|
||||||
|
}
|
||||||
|
|
|
||||||
8
PEvent.h
8
PEvent.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_PEvent_H
|
#ifndef IVL_PEvent_H
|
||||||
#define IVL_PEvent_H
|
#define IVL_PEvent_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2019 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
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "LineInfo.h"
|
# include "PNamedItem.h"
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
||||||
|
|
@ -31,7 +31,7 @@ class NetScope;
|
||||||
* are declared in Verilog as ``event foo;'' The name passed to the
|
* are declared in Verilog as ``event foo;'' The name passed to the
|
||||||
* constructor is the "foo" part of the declaration.
|
* constructor is the "foo" part of the declaration.
|
||||||
*/
|
*/
|
||||||
class PEvent : public LineInfo {
|
class PEvent : public PNamedItem {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// The name is a perm-allocated string. It is the simple name
|
// The name is a perm-allocated string. It is the simple name
|
||||||
|
|
@ -43,6 +43,8 @@ class PEvent : public LineInfo {
|
||||||
|
|
||||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
|
SymbolType symbol_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
|
|
||||||
|
|
|
||||||
4
PExpr.h
4
PExpr.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_PExpr_H
|
#ifndef IVL_PExpr_H
|
||||||
#define IVL_PExpr_H
|
#define IVL_PExpr_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2016 Stephen Williams <steve@icarus.com>
|
* Copyright (c) 1998-2019 Stephen Williams <steve@icarus.com>
|
||||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
* Copyright CERN 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
|
||||||
|
|
@ -379,6 +379,8 @@ class PEIdent : public PExpr {
|
||||||
|
|
||||||
virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
|
virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
|
const PPackage* package() const { return package_; }
|
||||||
|
|
||||||
const pform_name_t& path() const { return path_; }
|
const pform_name_t& path() const { return path_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2013 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1999-2019 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
|
||||||
|
|
@ -83,3 +83,8 @@ PChainConstructor* PFunction::extract_chain_constructor()
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType PFunction::symbol_type() const
|
||||||
|
{
|
||||||
|
return FUNCTION;
|
||||||
|
}
|
||||||
|
|
|
||||||
7
PGate.cc
7
PGate.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2013 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1999-2019 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
|
||||||
|
|
@ -117,6 +117,11 @@ unsigned PGate::delay_count() const
|
||||||
return delay_.delay_count();
|
return delay_.delay_count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType PGate::symbol_type() const
|
||||||
|
{
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
PGAssign::PGAssign(list<PExpr*>*pins)
|
PGAssign::PGAssign(list<PExpr*>*pins)
|
||||||
: PGate(perm_string(), pins)
|
: PGate(perm_string(), pins)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
8
PGate.h
8
PGate.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_PGate_H
|
#ifndef IVL_PGate_H
|
||||||
#define IVL_PGate_H
|
#define IVL_PGate_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2019 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
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
# include "svector.h"
|
# include "svector.h"
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
# include "named.h"
|
# include "named.h"
|
||||||
# include "LineInfo.h"
|
# include "PNamedItem.h"
|
||||||
# include "PDelays.h"
|
# include "PDelays.h"
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include <map>
|
# include <map>
|
||||||
|
|
@ -47,7 +47,7 @@ class Module;
|
||||||
* single strength pair. There is a strength of the 0 drive, and a
|
* single strength pair. There is a strength of the 0 drive, and a
|
||||||
* strength of the 1 drive.
|
* strength of the 1 drive.
|
||||||
*/
|
*/
|
||||||
class PGate : public LineInfo {
|
class PGate : public PNamedItem {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PGate(perm_string name, list<PExpr*>*pins,
|
explicit PGate(perm_string name, list<PExpr*>*pins,
|
||||||
|
|
@ -88,6 +88,8 @@ class PGate : public LineInfo {
|
||||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
|
SymbolType symbol_type() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const vector<PExpr*>& get_pins() const { return pins_; }
|
const vector<PExpr*>& get_pins() const { return pins_; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2011 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2006-2019 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
|
||||||
|
|
@ -112,3 +112,8 @@ ostream& operator << (ostream&out, PGenerate::scheme_t type)
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType PGenerate::symbol_type() const
|
||||||
|
{
|
||||||
|
return GENBLOCK;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_PGenerate_H
|
#ifndef IVL_PGenerate_H
|
||||||
#define IVL_PGenerate_H
|
#define IVL_PGenerate_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2014 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2006-2019 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
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "LineInfo.h"
|
# include "PNamedItem.h"
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
# include "HName.h"
|
# include "HName.h"
|
||||||
# include "PScope.h"
|
# include "PScope.h"
|
||||||
|
|
@ -50,7 +50,7 @@ class PWire;
|
||||||
* The parent points to the GS_CASE that contains this item.
|
* The parent points to the GS_CASE that contains this item.
|
||||||
* the loop_test is compared with the parent->loop_test expression.
|
* the loop_test is compared with the parent->loop_test expression.
|
||||||
*/
|
*/
|
||||||
class PGenerate : public LineInfo, public LexicalScope {
|
class PGenerate : public PNamedItem, public LexicalScope {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PGenerate(LexicalScope*parent, unsigned id_number);
|
explicit PGenerate(LexicalScope*parent, unsigned id_number);
|
||||||
|
|
@ -107,6 +107,8 @@ class PGenerate : public LineInfo, public LexicalScope {
|
||||||
|
|
||||||
void dump(ostream&out, unsigned indent) const;
|
void dump(ostream&out, unsigned indent) const;
|
||||||
|
|
||||||
|
SymbolType symbol_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool generate_scope_loop_(Design*des, NetScope*container);
|
bool generate_scope_loop_(Design*des, NetScope*container);
|
||||||
bool generate_scope_condit_(Design*des, NetScope*container, bool else_flag);
|
bool generate_scope_condit_(Design*des, NetScope*container, bool else_flag);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2015-2019 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,3 +29,8 @@ PModport::PModport(perm_string n)
|
||||||
PModport::~PModport()
|
PModport::~PModport()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType PModport::symbol_type() const
|
||||||
|
{
|
||||||
|
return MODPORT;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_PModport_H
|
#ifndef IVL_PModport_H
|
||||||
#define IVL_PModport_H
|
#define IVL_PModport_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2015-2019 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
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "LineInfo.h"
|
# include "PNamedItem.h"
|
||||||
# include "PScope.h"
|
# include "PScope.h"
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
/*
|
/*
|
||||||
* The PModport class represents a parsed SystemVerilog modport list.
|
* The PModport class represents a parsed SystemVerilog modport list.
|
||||||
*/
|
*/
|
||||||
class PModport : public LineInfo {
|
class PModport : public PNamedItem {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// The name is a perm-allocated string. It is the simple name
|
// The name is a perm-allocated string. It is the simple name
|
||||||
|
|
@ -41,6 +41,8 @@ class PModport : public LineInfo {
|
||||||
typedef pair <NetNet::PortType,PExpr*> simple_port_t;
|
typedef pair <NetNet::PortType,PExpr*> simple_port_t;
|
||||||
map<perm_string,simple_port_t> simple_ports;
|
map<perm_string,simple_port_t> simple_ports;
|
||||||
|
|
||||||
|
SymbolType symbol_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Martin Whitaker (icarus@martin-whitaker.me.uk)
|
||||||
|
*
|
||||||
|
* 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 "PNamedItem.h"
|
||||||
|
# include <ostream>
|
||||||
|
|
||||||
|
PNamedItem::PNamedItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PNamedItem::~PNamedItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType PNamedItem::symbol_type() const
|
||||||
|
{
|
||||||
|
return ANY;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator << (std::ostream&o, PNamedItem::SymbolType st)
|
||||||
|
{
|
||||||
|
switch (st) {
|
||||||
|
case PNamedItem::ANY:
|
||||||
|
o << "a symbol";
|
||||||
|
break;
|
||||||
|
case PNamedItem::PARAM:
|
||||||
|
o << "a parameter";
|
||||||
|
break;
|
||||||
|
case PNamedItem::NET:
|
||||||
|
o << "a net";
|
||||||
|
break;
|
||||||
|
case PNamedItem::VAR:
|
||||||
|
o << "a variable";
|
||||||
|
break;
|
||||||
|
case PNamedItem::GENVAR:
|
||||||
|
o << "a genvar";
|
||||||
|
break;
|
||||||
|
case PNamedItem::EVENT:
|
||||||
|
o << "an event";
|
||||||
|
break;
|
||||||
|
case PNamedItem::TYPE:
|
||||||
|
o << "a type";
|
||||||
|
break;
|
||||||
|
case PNamedItem::ENUM:
|
||||||
|
o << "an enum type or value";
|
||||||
|
break;
|
||||||
|
case PNamedItem::CLASS:
|
||||||
|
o << "a class";
|
||||||
|
break;
|
||||||
|
case PNamedItem::FUNCTION:
|
||||||
|
o << "a function";
|
||||||
|
break;
|
||||||
|
case PNamedItem::TASK:
|
||||||
|
o << "a task";
|
||||||
|
break;
|
||||||
|
case PNamedItem::BLOCK:
|
||||||
|
o << "a named block";
|
||||||
|
break;
|
||||||
|
case PNamedItem::GENBLOCK:
|
||||||
|
o << "a generate block";
|
||||||
|
break;
|
||||||
|
case PNamedItem::MODPORT:
|
||||||
|
o << "a modport";
|
||||||
|
break;
|
||||||
|
case PNamedItem::PACKAGE:
|
||||||
|
o << "a package";
|
||||||
|
break;
|
||||||
|
case PNamedItem::MODULE:
|
||||||
|
o << "a module";
|
||||||
|
break;
|
||||||
|
case PNamedItem::PROGRAM:
|
||||||
|
o << "a program";
|
||||||
|
break;
|
||||||
|
case PNamedItem::INTERFACE:
|
||||||
|
o << "an interface";
|
||||||
|
break;
|
||||||
|
case PNamedItem::PRIMITIVE:
|
||||||
|
o << "a primitive";
|
||||||
|
break;
|
||||||
|
case PNamedItem::INSTANCE:
|
||||||
|
o << "an instance name";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
PGenvar::PGenvar()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PGenvar::~PGenvar()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType PGenvar::symbol_type() const
|
||||||
|
{
|
||||||
|
return GENVAR;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
#ifndef IVL_PNamedItem_H
|
||||||
|
#define IVL_PNamedItem_H
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Martin Whitaker (icarus@martin-whitaker.me.uk)
|
||||||
|
*
|
||||||
|
* 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 "LineInfo.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The PNamedItem class is the base class for all items that can be added
|
||||||
|
* to a scope's local symbol map.
|
||||||
|
*/
|
||||||
|
class PNamedItem : virtual public LineInfo {
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum SymbolType { ANY, PARAM, NET, VAR, GENVAR, EVENT, TYPE, ENUM,
|
||||||
|
CLASS, FUNCTION, TASK, BLOCK, GENBLOCK, MODPORT,
|
||||||
|
PACKAGE, MODULE, PROGRAM, INTERFACE, PRIMITIVE,
|
||||||
|
INSTANCE };
|
||||||
|
|
||||||
|
explicit PNamedItem();
|
||||||
|
virtual ~PNamedItem();
|
||||||
|
|
||||||
|
virtual SymbolType symbol_type() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::ostream& operator << (std::ostream&, PNamedItem::SymbolType);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The PGenvar class represents a genvar. This is only used to represent
|
||||||
|
* genvar in a scope's local symbol map.
|
||||||
|
*/
|
||||||
|
class PGenvar : public PNamedItem {
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PGenvar();
|
||||||
|
virtual ~PGenvar();
|
||||||
|
|
||||||
|
SymbolType symbol_type() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* IVL_PNamedItem_H */
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2008-2019 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
|
||||||
|
|
@ -33,6 +33,11 @@ PWire* LexicalScope::wires_find(perm_string name)
|
||||||
return (*cur).second;
|
return (*cur).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType LexicalScope::param_expr_t::symbol_type() const
|
||||||
|
{
|
||||||
|
return PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
PScope::PScope(perm_string n, LexicalScope*parent)
|
PScope::PScope(perm_string n, LexicalScope*parent)
|
||||||
: LexicalScope(parent), name_(n)
|
: LexicalScope(parent), name_(n)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
34
PScope.h
34
PScope.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_PScope_H
|
#ifndef IVL_PScope_H
|
||||||
#define IVL_PScope_H
|
#define IVL_PScope_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2008-2019 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
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "LineInfo.h"
|
# include "PNamedItem.h"
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
# include "pform_types.h"
|
# include "pform_types.h"
|
||||||
# include "ivl_target.h"
|
# include "ivl_target.h"
|
||||||
|
|
@ -61,6 +61,24 @@ class LexicalScope {
|
||||||
|
|
||||||
lifetime_t default_lifetime;
|
lifetime_t default_lifetime;
|
||||||
|
|
||||||
|
// Symbols that are defined or declared in this scope.
|
||||||
|
std::map<perm_string,PNamedItem*>local_symbols;
|
||||||
|
|
||||||
|
// Symbols that are explicitly imported. Bind the imported name
|
||||||
|
// to the package from which the name is imported.
|
||||||
|
std::map<perm_string,PPackage*>explicit_imports;
|
||||||
|
|
||||||
|
// Packages that are wildcard imported. When identifiers from
|
||||||
|
// these packages are referenced, they will be added to the
|
||||||
|
// explicit imports (IEEE 1800-2012 26.3).
|
||||||
|
std::set<PPackage*>potential_imports;
|
||||||
|
|
||||||
|
// A task or function call may reference a task or function defined
|
||||||
|
// later in the scope. So here we stash the potential imports for
|
||||||
|
// task and function calls. They will be added to the explicit
|
||||||
|
// imports if we don't find a local definition.
|
||||||
|
std::map<perm_string,PPackage*>possible_imports;
|
||||||
|
|
||||||
struct range_t {
|
struct range_t {
|
||||||
// True if this is an exclude
|
// True if this is an exclude
|
||||||
bool exclude_flag;
|
bool exclude_flag;
|
||||||
|
|
@ -79,7 +97,7 @@ class LexicalScope {
|
||||||
/* The scope has parameters that are evaluated when the scope
|
/* The scope has parameters that are evaluated when the scope
|
||||||
is elaborated. During parsing, I put the parameters into
|
is elaborated. During parsing, I put the parameters into
|
||||||
this map. */
|
this map. */
|
||||||
struct param_expr_t : public LineInfo {
|
struct param_expr_t : public PNamedItem {
|
||||||
param_expr_t() : type(IVL_VT_NO_TYPE), msb(0), lsb(0), signed_flag(false), expr(0), range(0) { }
|
param_expr_t() : type(IVL_VT_NO_TYPE), msb(0), lsb(0), signed_flag(false), expr(0), range(0) { }
|
||||||
// Type information
|
// Type information
|
||||||
ivl_variable_type_t type;
|
ivl_variable_type_t type;
|
||||||
|
|
@ -90,9 +108,11 @@ class LexicalScope {
|
||||||
PExpr*expr;
|
PExpr*expr;
|
||||||
// If there are range constraints, list them here
|
// If there are range constraints, list them here
|
||||||
range_t*range;
|
range_t*range;
|
||||||
|
|
||||||
|
SymbolType symbol_type() const;
|
||||||
};
|
};
|
||||||
map<perm_string,param_expr_t>parameters;
|
map<perm_string,param_expr_t*>parameters;
|
||||||
map<perm_string,param_expr_t>localparams;
|
map<perm_string,param_expr_t*>localparams;
|
||||||
|
|
||||||
// Defined types in the scope.
|
// Defined types in the scope.
|
||||||
map<perm_string,data_type_t*>typedefs;
|
map<perm_string,data_type_t*>typedefs;
|
||||||
|
|
@ -100,10 +120,6 @@ class LexicalScope {
|
||||||
// Named events in the scope.
|
// Named events in the scope.
|
||||||
map<perm_string,PEvent*>events;
|
map<perm_string,PEvent*>events;
|
||||||
|
|
||||||
// Symbols that are imported. Bind the imported name to the
|
|
||||||
// package from which the name is imported.
|
|
||||||
std::map<perm_string,PPackage*>imports;
|
|
||||||
|
|
||||||
// Nets and variables (wires) in the scope
|
// Nets and variables (wires) in the scope
|
||||||
map<perm_string,PWire*>wires;
|
map<perm_string,PWire*>wires;
|
||||||
PWire* wires_find(perm_string name);
|
PWire* wires_find(perm_string name);
|
||||||
|
|
|
||||||
7
PTask.cc
7
PTask.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008,2010 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1999-2019 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
|
||||||
|
|
@ -73,3 +73,8 @@ void PTask::set_statement(Statement*s)
|
||||||
assert(statement_ == 0);
|
assert(statement_ == 0);
|
||||||
statement_ = s;
|
statement_ = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType PTask::symbol_type() const
|
||||||
|
{
|
||||||
|
return TASK;
|
||||||
|
}
|
||||||
|
|
|
||||||
10
PTask.h
10
PTask.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_PTask_H
|
#ifndef IVL_PTask_H
|
||||||
#define IVL_PTask_H
|
#define IVL_PTask_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1999-2019 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
|
||||||
|
|
@ -19,8 +19,8 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "LineInfo.h"
|
|
||||||
# include "PScope.h"
|
# include "PScope.h"
|
||||||
|
# include "PNamedItem.h"
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
# include <string>
|
# include <string>
|
||||||
# include <vector>
|
# include <vector>
|
||||||
|
|
@ -35,7 +35,7 @@ class Statement;
|
||||||
class PExpr;
|
class PExpr;
|
||||||
|
|
||||||
|
|
||||||
class PTaskFunc : public PScope, public LineInfo {
|
class PTaskFunc : public PScope, public PNamedItem {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PTaskFunc(perm_string name, LexicalScope*parent);
|
PTaskFunc(perm_string name, LexicalScope*parent);
|
||||||
|
|
@ -99,6 +99,8 @@ class PTask : public PTaskFunc {
|
||||||
|
|
||||||
void dump(ostream&, unsigned) const;
|
void dump(ostream&, unsigned) const;
|
||||||
|
|
||||||
|
SymbolType symbol_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Statement*statement_;
|
Statement*statement_;
|
||||||
bool is_auto_;
|
bool is_auto_;
|
||||||
|
|
@ -148,6 +150,8 @@ class PFunction : public PTaskFunc {
|
||||||
|
|
||||||
void dump(ostream&, unsigned) const;
|
void dump(ostream&, unsigned) const;
|
||||||
|
|
||||||
|
SymbolType symbol_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
data_type_t* return_type_;
|
data_type_t* return_type_;
|
||||||
Statement *statement_;
|
Statement *statement_;
|
||||||
|
|
|
||||||
14
PWire.cc
14
PWire.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2012 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1999-2019 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
|
||||||
|
|
@ -283,3 +283,15 @@ ivl_discipline_t PWire::get_discipline(void) const
|
||||||
{
|
{
|
||||||
return discipline_;
|
return discipline_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType PWire::symbol_type() const
|
||||||
|
{
|
||||||
|
switch (type_) {
|
||||||
|
case NetNet::IMPLICIT_REG:
|
||||||
|
case NetNet::INTEGER:
|
||||||
|
case NetNet::REG:
|
||||||
|
return VAR;
|
||||||
|
default:
|
||||||
|
return NET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
8
PWire.h
8
PWire.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_PWire_H
|
#ifndef IVL_PWire_H
|
||||||
#define IVL_PWire_H
|
#define IVL_PWire_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2019 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
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "LineInfo.h"
|
# include "PNamedItem.h"
|
||||||
# include <list>
|
# include <list>
|
||||||
# include <map>
|
# include <map>
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
|
|
@ -51,7 +51,7 @@ enum PWSRType {SR_PORT, SR_NET, SR_BOTH};
|
||||||
* from that perspective, sub-scopes within the module are a part of
|
* from that perspective, sub-scopes within the module are a part of
|
||||||
* the wire name.
|
* the wire name.
|
||||||
*/
|
*/
|
||||||
class PWire : public LineInfo {
|
class PWire : public PNamedItem {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PWire(perm_string name,
|
PWire(perm_string name,
|
||||||
|
|
@ -93,6 +93,8 @@ class PWire : public LineInfo {
|
||||||
|
|
||||||
NetNet* elaborate_sig(Design*, NetScope*scope) const;
|
NetNet* elaborate_sig(Design*, NetScope*scope) const;
|
||||||
|
|
||||||
|
SymbolType symbol_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
NetNet::Type type_;
|
NetNet::Type type_;
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,11 @@ void PBlock::push_statement_front(Statement*that)
|
||||||
list_[0] = that;
|
list_[0] = that;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType PBlock::symbol_type() const
|
||||||
|
{
|
||||||
|
return BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p)
|
PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p)
|
||||||
: package_(0), path_(n), parms_(p.size())
|
: package_(0), path_(n), parms_(p.size())
|
||||||
{
|
{
|
||||||
|
|
@ -411,8 +416,8 @@ PReturn::~PReturn()
|
||||||
delete expr_;
|
delete expr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTrigger::PTrigger(const pform_name_t&e)
|
PTrigger::PTrigger(PPackage*pkg, const pform_name_t&e)
|
||||||
: event_(e)
|
: package_(pkg), event_(e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ class PProcess : public LineInfo {
|
||||||
* fact, the Statement class is abstract and represents all the
|
* fact, the Statement class is abstract and represents all the
|
||||||
* possible kinds of statements that exist in Verilog.
|
* possible kinds of statements that exist in Verilog.
|
||||||
*/
|
*/
|
||||||
class Statement : public LineInfo {
|
class Statement : virtual public LineInfo {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Statement() { }
|
Statement() { }
|
||||||
|
|
@ -170,7 +170,7 @@ class PAssignNB : public PAssign_ {
|
||||||
* statements before constructing this object, so it knows a priori
|
* statements before constructing this object, so it knows a priori
|
||||||
* what is contained.
|
* what is contained.
|
||||||
*/
|
*/
|
||||||
class PBlock : public PScope, public Statement {
|
class PBlock : public PScope, public Statement, public PNamedItem {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum BL_TYPE { BL_SEQ, BL_PAR, BL_JOIN_NONE, BL_JOIN_ANY };
|
enum BL_TYPE { BL_SEQ, BL_PAR, BL_JOIN_NONE, BL_JOIN_ANY };
|
||||||
|
|
@ -205,6 +205,8 @@ class PBlock : public PScope, public Statement {
|
||||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
|
SymbolType symbol_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BL_TYPE bl_type_;
|
BL_TYPE bl_type_;
|
||||||
std::vector<Statement*>list_;
|
std::vector<Statement*>list_;
|
||||||
|
|
@ -561,13 +563,14 @@ class PReturn : public Statement {
|
||||||
class PTrigger : public Statement {
|
class PTrigger : public Statement {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PTrigger(const pform_name_t&ev);
|
explicit PTrigger(PPackage*pkg, const pform_name_t&ev);
|
||||||
~PTrigger();
|
~PTrigger();
|
||||||
|
|
||||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
virtual void dump(ostream&out, unsigned ind) const;
|
virtual void dump(ostream&out, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PPackage*package_;
|
||||||
pform_name_t event_;
|
pform_name_t event_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
380
elab_scope.cc
380
elab_scope.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2019 Stephen Williams (steve@icarus.com)
|
||||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
* Copyright CERN 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
|
||||||
|
|
@ -63,7 +63,7 @@ void set_scope_timescale(Design*des, NetScope*scope, PScope*pscope)
|
||||||
des->set_precision(pscope->time_precision);
|
des->set_precision(pscope->time_precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef map<perm_string,LexicalScope::param_expr_t>::const_iterator mparm_it_t;
|
typedef map<perm_string,LexicalScope::param_expr_t*>::const_iterator mparm_it_t;
|
||||||
|
|
||||||
static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
|
static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
|
||||||
const LexicalScope::param_expr_t&cur,
|
const LexicalScope::param_expr_t&cur,
|
||||||
|
|
@ -110,59 +110,32 @@ static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void collect_scope_parameters_(Design*des, NetScope*scope,
|
static void collect_scope_parameters_(Design*des, NetScope*scope,
|
||||||
const map<perm_string,LexicalScope::param_expr_t>¶meters)
|
const map<perm_string,LexicalScope::param_expr_t*>¶meters)
|
||||||
{
|
{
|
||||||
for (mparm_it_t cur = parameters.begin()
|
for (mparm_it_t cur = parameters.begin()
|
||||||
; cur != parameters.end() ; ++ cur ) {
|
; cur != parameters.end() ; ++ cur ) {
|
||||||
|
|
||||||
// A parameter can not have the same name as a genvar.
|
collect_parm_item_(des, scope, cur->first, *(cur->second), false, false);
|
||||||
if (scope->find_genvar((*cur).first)) {
|
|
||||||
cerr << cur->second.get_fileline()
|
|
||||||
<< ": error: parameter and genvar in '"
|
|
||||||
<< scope->fullname() << "' have the same name '"
|
|
||||||
<< (*cur).first << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, false, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void collect_scope_localparams_(Design*des, NetScope*scope,
|
static void collect_scope_localparams_(Design*des, NetScope*scope,
|
||||||
const map<perm_string,LexicalScope::param_expr_t>&localparams)
|
const map<perm_string,LexicalScope::param_expr_t*>&localparams)
|
||||||
{
|
{
|
||||||
for (mparm_it_t cur = localparams.begin()
|
for (mparm_it_t cur = localparams.begin()
|
||||||
; cur != localparams.end() ; ++ cur ) {
|
; cur != localparams.end() ; ++ cur ) {
|
||||||
|
|
||||||
// A localparam can not have the same name as a genvar.
|
collect_parm_item_(des, scope, cur->first, *(cur->second), false, true);
|
||||||
if (scope->find_genvar((*cur).first)) {
|
|
||||||
cerr << cur->second.get_fileline()
|
|
||||||
<< ": error: localparam and genvar in '"
|
|
||||||
<< scope->fullname() << "' have the same name '"
|
|
||||||
<< (*cur).first << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, false, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void collect_scope_specparams_(Design*des, NetScope*scope,
|
static void collect_scope_specparams_(Design*des, NetScope*scope,
|
||||||
const map<perm_string,LexicalScope::param_expr_t>&specparams)
|
const map<perm_string,LexicalScope::param_expr_t*>&specparams)
|
||||||
{
|
{
|
||||||
for (mparm_it_t cur = specparams.begin()
|
for (mparm_it_t cur = specparams.begin()
|
||||||
; cur != specparams.end() ; ++ cur ) {
|
; cur != specparams.end() ; ++ cur ) {
|
||||||
|
|
||||||
// A specparam can not have the same name as a genvar.
|
collect_parm_item_(des, scope, cur->first, *(cur->second), true, false);
|
||||||
if (scope->find_genvar((*cur).first)) {
|
|
||||||
cerr << cur->second.get_fileline()
|
|
||||||
<< ": error: specparam and genvar in '"
|
|
||||||
<< scope->fullname() << "' have the same name '"
|
|
||||||
<< (*cur).first << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, true, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -556,6 +529,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||||
// Task methods are always automatic...
|
// Task methods are always automatic...
|
||||||
method_scope->is_auto(true);
|
method_scope->is_auto(true);
|
||||||
method_scope->set_line(cur->second);
|
method_scope->set_line(cur->second);
|
||||||
|
method_scope->add_imports(&cur->second->explicit_imports);
|
||||||
|
|
||||||
if (debug_scopes) {
|
if (debug_scopes) {
|
||||||
cerr << cur->second->get_fileline() << ": elaborate_scope_class: "
|
cerr << cur->second->get_fileline() << ": elaborate_scope_class: "
|
||||||
|
|
@ -574,6 +548,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||||
// Function methods are always automatic...
|
// Function methods are always automatic...
|
||||||
method_scope->is_auto(true);
|
method_scope->is_auto(true);
|
||||||
method_scope->set_line(cur->second);
|
method_scope->set_line(cur->second);
|
||||||
|
method_scope->add_imports(&cur->second->explicit_imports);
|
||||||
|
|
||||||
if (debug_scopes) {
|
if (debug_scopes) {
|
||||||
cerr << cur->second->get_fileline() << ": elaborate_scope_class: "
|
cerr << cur->second->get_fileline() << ": elaborate_scope_class: "
|
||||||
|
|
@ -644,6 +619,7 @@ static void elaborate_scope_task(Design*des, NetScope*scope, PTask*task)
|
||||||
NetScope*task_scope = new NetScope(scope, use_name, NetScope::TASK);
|
NetScope*task_scope = new NetScope(scope, use_name, NetScope::TASK);
|
||||||
task_scope->is_auto(task->is_auto());
|
task_scope->is_auto(task->is_auto());
|
||||||
task_scope->set_line(task);
|
task_scope->set_line(task);
|
||||||
|
task_scope->add_imports(&task->explicit_imports);
|
||||||
|
|
||||||
if (debug_scopes) {
|
if (debug_scopes) {
|
||||||
cerr << task->get_fileline() << ": elaborate_scope_task: "
|
cerr << task->get_fileline() << ": elaborate_scope_task: "
|
||||||
|
|
@ -661,39 +637,6 @@ static void elaborate_scope_tasks(Design*des, NetScope*scope,
|
||||||
for (tasks_it_t cur = tasks.begin()
|
for (tasks_it_t cur = tasks.begin()
|
||||||
; cur != tasks.end() ; ++ cur ) {
|
; cur != tasks.end() ; ++ cur ) {
|
||||||
|
|
||||||
hname_t use_name( (*cur).first );
|
|
||||||
// A task can not have the same name as another scope object.
|
|
||||||
const NetScope *child = scope->child(use_name);
|
|
||||||
if (child) {
|
|
||||||
cerr << cur->second->get_fileline() << ": error: task and ";
|
|
||||||
child->print_type(cerr);
|
|
||||||
cerr << " in '" << scope->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A task can not have the same name as a genvar.
|
|
||||||
if (scope->find_genvar((*cur).first)) {
|
|
||||||
cerr << cur->second->get_fileline()
|
|
||||||
<< ": error: task and genvar in '"
|
|
||||||
<< scope->fullname() << "' have the same name '"
|
|
||||||
<< (*cur).first << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A task can not have the same name as a parameter.
|
|
||||||
const NetExpr *ex_msb, *ex_lsb;
|
|
||||||
const NetExpr *parm = scope->get_parameter(des, (*cur).first,
|
|
||||||
ex_msb, ex_lsb);
|
|
||||||
if (parm) {
|
|
||||||
cerr << cur->second->get_fileline()
|
|
||||||
<< ": error: task and parameter in '"
|
|
||||||
<< scope->fullname() << "' have the same name '"
|
|
||||||
<< (*cur).first << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
elaborate_scope_task(des, scope, cur->second);
|
elaborate_scope_task(des, scope, cur->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -706,6 +649,7 @@ static void elaborate_scope_func(Design*des, NetScope*scope, PFunction*task)
|
||||||
NetScope*task_scope = new NetScope(scope, use_name, NetScope::FUNC);
|
NetScope*task_scope = new NetScope(scope, use_name, NetScope::FUNC);
|
||||||
task_scope->is_auto(task->is_auto());
|
task_scope->is_auto(task->is_auto());
|
||||||
task_scope->set_line(task);
|
task_scope->set_line(task);
|
||||||
|
task_scope->add_imports(&task->explicit_imports);
|
||||||
|
|
||||||
if (debug_scopes) {
|
if (debug_scopes) {
|
||||||
cerr << task->get_fileline() << ": elaborate_scope_func: "
|
cerr << task->get_fileline() << ": elaborate_scope_func: "
|
||||||
|
|
@ -723,40 +667,6 @@ static void elaborate_scope_funcs(Design*des, NetScope*scope,
|
||||||
for (funcs_it_t cur = funcs.begin()
|
for (funcs_it_t cur = funcs.begin()
|
||||||
; cur != funcs.end() ; ++ cur ) {
|
; cur != funcs.end() ; ++ cur ) {
|
||||||
|
|
||||||
hname_t use_name( (*cur).first );
|
|
||||||
// A function can not have the same name as another scope object.
|
|
||||||
const NetScope *child = scope->child(use_name);
|
|
||||||
if (child) {
|
|
||||||
cerr << cur->second->get_fileline()
|
|
||||||
<< ": error: function and ";
|
|
||||||
child->print_type(cerr);
|
|
||||||
cerr << " in '" << scope->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A function can not have the same name as a genvar.
|
|
||||||
if (scope->find_genvar((*cur).first)) {
|
|
||||||
cerr << cur->second->get_fileline()
|
|
||||||
<< ": error: function and genvar in '"
|
|
||||||
<< scope->fullname() << "' have the same name '"
|
|
||||||
<< (*cur).first << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A function can not have the same name as a parameter.
|
|
||||||
const NetExpr *ex_msb, *ex_lsb;
|
|
||||||
const NetExpr *parm = scope->get_parameter(des, (*cur).first,
|
|
||||||
ex_msb, ex_lsb);
|
|
||||||
if (parm) {
|
|
||||||
cerr << cur->second->get_fileline()
|
|
||||||
<< ": error: function and parameter in '"
|
|
||||||
<< scope->fullname() << "' have the same name '"
|
|
||||||
<< (*cur).first << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
elaborate_scope_func(des, scope, cur->second);
|
elaborate_scope_func(des, scope, cur->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -815,6 +725,7 @@ bool PPackage::elaborate_scope(Design*des, NetScope*scope)
|
||||||
elaborate_scope_classes(des, scope, classes_lexical);
|
elaborate_scope_classes(des, scope, classes_lexical);
|
||||||
elaborate_scope_funcs(des, scope, funcs);
|
elaborate_scope_funcs(des, scope, funcs);
|
||||||
elaborate_scope_tasks(des, scope, tasks);
|
elaborate_scope_tasks(des, scope, tasks);
|
||||||
|
elaborate_scope_events_(des, scope, events);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1013,56 +924,6 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the generate block name.
|
|
||||||
|
|
||||||
// A generate "loop" can not have the same name as another
|
|
||||||
// scope object. Find any scope with this name, not just an
|
|
||||||
// exact match scope.
|
|
||||||
const NetScope *child = container->child_byname(scope_name);
|
|
||||||
if (child) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"loop\" and ";
|
|
||||||
child->print_type(cerr);
|
|
||||||
cerr << " in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << scope_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A generate "loop" can not have the same name as a genvar.
|
|
||||||
if (container->find_genvar(scope_name)) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"loop\" and "
|
|
||||||
"genvar in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << scope_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A generate "loop" can not have the same name as a named event.
|
|
||||||
const NetEvent *event = container->find_event(scope_name);
|
|
||||||
if (event) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"loop\" and "
|
|
||||||
"named event in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << scope_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A generate "loop" can not have the same name as a parameter.
|
|
||||||
const NetExpr*tmsb;
|
|
||||||
const NetExpr*tlsb;
|
|
||||||
const NetExpr*texpr = container->get_parameter(des, scope_name,
|
|
||||||
tmsb, tlsb);
|
|
||||||
if (texpr != 0) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"loop\" and "
|
|
||||||
"parameter in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << scope_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// These have all been checked so we just need to skip the actual
|
|
||||||
// generation for these name conflicts. Not skipping these two will
|
|
||||||
// cause the compiler to have problems (assert, inf. loop, etc.).
|
|
||||||
if (container->get_parameter(des, loop_index, tmsb, tlsb)) return false;
|
|
||||||
if (container->find_event(loop_index)) return false;
|
|
||||||
|
|
||||||
genvar = init->value().as_long();
|
genvar = init->value().as_long();
|
||||||
delete init_ex;
|
delete init_ex;
|
||||||
|
|
||||||
|
|
@ -1093,6 +954,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||||
NetScope*scope = new NetScope(container, use_name,
|
NetScope*scope = new NetScope(container, use_name,
|
||||||
NetScope::GENBLOCK);
|
NetScope::GENBLOCK);
|
||||||
scope->set_line(get_file(), get_lineno());
|
scope->set_line(get_file(), get_lineno());
|
||||||
|
scope->add_imports(&explicit_imports);
|
||||||
|
|
||||||
// Set in the scope a localparam for the value of the
|
// Set in the scope a localparam for the value of the
|
||||||
// genvar within this instance of the generate
|
// genvar within this instance of the generate
|
||||||
|
|
@ -1169,45 +1031,6 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
|
||||||
}
|
}
|
||||||
|
|
||||||
hname_t use_name (scope_name);
|
hname_t use_name (scope_name);
|
||||||
// A generate "if" can not have the same name as another scope object.
|
|
||||||
const NetScope *child = container->child(use_name);
|
|
||||||
if (child) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"if\" and ";
|
|
||||||
child->print_type(cerr);
|
|
||||||
cerr << " in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A generate "if" can not have the same name as a genvar.
|
|
||||||
if (container->find_genvar(scope_name)) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"if\" and "
|
|
||||||
"genvar in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << scope_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A generate "if" can not have the same name as a named event.
|
|
||||||
const NetEvent *event = container->find_event(scope_name);
|
|
||||||
if (event) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"if\" and "
|
|
||||||
"named event in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A generate "if" can not have the same name as a parameter.
|
|
||||||
const NetExpr *ex_msb, *ex_lsb;
|
|
||||||
const NetExpr *parm = container->get_parameter(des, scope_name,
|
|
||||||
ex_msb, ex_lsb);
|
|
||||||
if (parm) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"if\" and "
|
|
||||||
"parameter in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug_scopes)
|
if (debug_scopes)
|
||||||
cerr << get_fileline() << ": debug: Generate condition "
|
cerr << get_fileline() << ": debug: Generate condition "
|
||||||
<< (else_flag? "(else)" : "(if)")
|
<< (else_flag? "(else)" : "(if)")
|
||||||
|
|
@ -1228,6 +1051,7 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
|
||||||
// for myself. That is what I will pass to the subscope.
|
// for myself. That is what I will pass to the subscope.
|
||||||
NetScope*scope = new NetScope(container, use_name, NetScope::GENBLOCK);
|
NetScope*scope = new NetScope(container, use_name, NetScope::GENBLOCK);
|
||||||
scope->set_line(get_file(), get_lineno());
|
scope->set_line(get_file(), get_lineno());
|
||||||
|
scope->add_imports(&explicit_imports);
|
||||||
|
|
||||||
elaborate_subscope_(des, scope);
|
elaborate_subscope_(des, scope);
|
||||||
|
|
||||||
|
|
@ -1311,44 +1135,6 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
||||||
|
|
||||||
// The name of the scope to generate, whatever that item is.
|
// The name of the scope to generate, whatever that item is.
|
||||||
hname_t use_name (item->scope_name);
|
hname_t use_name (item->scope_name);
|
||||||
// A generate "case" can not have the same name as another scope object.
|
|
||||||
const NetScope *child = container->child(use_name);
|
|
||||||
if (child) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"case\" and ";
|
|
||||||
child->print_type(cerr);
|
|
||||||
cerr << " in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A generate "case" can not have the same name as a genvar.
|
|
||||||
if (container->find_genvar(item->scope_name)) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"case\" and "
|
|
||||||
"genvar in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A generate "case" can not have the same name as a named event.
|
|
||||||
const NetEvent *event = container->find_event(item->scope_name);
|
|
||||||
if (event) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"case\" and "
|
|
||||||
"named event in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A generate "case" can not have the same name as a parameter.
|
|
||||||
const NetExpr *ex_msb, *ex_lsb;
|
|
||||||
const NetExpr *parm = container->get_parameter(des, item->scope_name,
|
|
||||||
ex_msb, ex_lsb);
|
|
||||||
if (parm) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"case\" and "
|
|
||||||
"parameter in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
item->probe_for_direct_nesting_();
|
item->probe_for_direct_nesting_();
|
||||||
if (item->direct_nested_) {
|
if (item->direct_nested_) {
|
||||||
|
|
@ -1368,6 +1154,8 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
||||||
NetScope*scope = new NetScope(container, use_name,
|
NetScope*scope = new NetScope(container, use_name,
|
||||||
NetScope::GENBLOCK);
|
NetScope::GENBLOCK);
|
||||||
scope->set_line(get_file(), get_lineno());
|
scope->set_line(get_file(), get_lineno());
|
||||||
|
scope->add_imports(&explicit_imports);
|
||||||
|
|
||||||
item->elaborate_subscope_(des, scope);
|
item->elaborate_subscope_(des, scope);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1376,46 +1164,6 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
||||||
bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
|
bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
|
||||||
{
|
{
|
||||||
hname_t use_name (scope_name);
|
hname_t use_name (scope_name);
|
||||||
// A generate "block" can not have the same name as another scope
|
|
||||||
// object.
|
|
||||||
const NetScope *child = container->child(use_name);
|
|
||||||
if (child) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"block\" and ";
|
|
||||||
child->print_type(cerr);
|
|
||||||
cerr << " in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A generate "block" can not have the same name as a genvar.
|
|
||||||
if (container->find_genvar(scope_name)) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"block\" and "
|
|
||||||
"genvar in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << scope_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A generate "block" can not have the same name as a named event.
|
|
||||||
const NetEvent *event = container->find_event(scope_name);
|
|
||||||
if (event) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"block\" and "
|
|
||||||
"named event in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A generate "block" can not have the same name as a parameter.
|
|
||||||
const NetExpr *ex_msb, *ex_lsb;
|
|
||||||
const NetExpr *parm = container->get_parameter(des, scope_name,
|
|
||||||
ex_msb, ex_lsb);
|
|
||||||
if (parm) {
|
|
||||||
cerr << get_fileline() << ": error: generate \"block\" and "
|
|
||||||
"parameter in '" << container->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug_scopes)
|
if (debug_scopes)
|
||||||
cerr << get_fileline() << ": debug: Generate named block "
|
cerr << get_fileline() << ": debug: Generate named block "
|
||||||
<< ": Generate scope=" << use_name << endl;
|
<< ": Generate scope=" << use_name << endl;
|
||||||
|
|
@ -1423,6 +1171,7 @@ bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
|
||||||
NetScope*scope = new NetScope(container, use_name,
|
NetScope*scope = new NetScope(container, use_name,
|
||||||
NetScope::GENBLOCK);
|
NetScope::GENBLOCK);
|
||||||
scope->set_line(get_file(), get_lineno());
|
scope->set_line(get_file(), get_lineno());
|
||||||
|
scope->add_imports(&explicit_imports);
|
||||||
|
|
||||||
elaborate_subscope_(des, scope);
|
elaborate_subscope_(des, scope);
|
||||||
|
|
||||||
|
|
@ -1554,36 +1303,6 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||||
// Missing module instance names have already been rejected.
|
// Missing module instance names have already been rejected.
|
||||||
assert(get_name() != "");
|
assert(get_name() != "");
|
||||||
|
|
||||||
// A module instance can not have the same name as another scope object.
|
|
||||||
const NetScope *child = sc->child(hname_t(get_name()));
|
|
||||||
if (child) {
|
|
||||||
cerr << get_fileline() << ": error: module <" << mod->mod_name()
|
|
||||||
<< "> instance and ";
|
|
||||||
child->print_type(cerr);
|
|
||||||
cerr << " in '" << sc->fullname()
|
|
||||||
<< "' have the same name '" << get_name() << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A module instance can not have the same name as a genvar.
|
|
||||||
if (sc->find_genvar(get_name())) {
|
|
||||||
cerr << get_fileline() << ": error: module <" << mod->mod_name()
|
|
||||||
<< "> instance and genvar in '" << sc->fullname()
|
|
||||||
<< "' have the same name '" << get_name() << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A module instance can not have the same name as a parameter.
|
|
||||||
const NetExpr *ex_msb, *ex_lsb;
|
|
||||||
const NetExpr *parm = sc->get_parameter(des, get_name(), ex_msb, ex_lsb);
|
|
||||||
if (parm) {
|
|
||||||
cerr << get_fileline() << ": error: module <" << mod->mod_name()
|
|
||||||
<< "> instance and parameter in '" << sc->fullname()
|
|
||||||
<< "' have the same name '" << get_name() << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for recursive instantiation by scanning the current
|
// check for recursive instantiation by scanning the current
|
||||||
// scope and its parents. Look for a module instantiation of
|
// scope and its parents. Look for a module instantiation of
|
||||||
// the same module, but farther up in the scope.
|
// the same module, but farther up in the scope.
|
||||||
|
|
@ -1728,6 +1447,7 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
||||||
my_scope->set_line(get_file(), mod->get_file(),
|
my_scope->set_line(get_file(), mod->get_file(),
|
||||||
get_lineno(), mod->get_lineno());
|
get_lineno(), mod->get_lineno());
|
||||||
my_scope->set_module_name(mod->mod_name());
|
my_scope->set_module_name(mod->mod_name());
|
||||||
|
my_scope->add_imports(&mod->explicit_imports);
|
||||||
|
|
||||||
for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1)
|
for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1)
|
||||||
my_scope->attribute(attrib_list[adx].key, attrib_list[adx].val);
|
my_scope->attribute(attrib_list[adx].key, attrib_list[adx].val);
|
||||||
|
|
@ -1809,36 +1529,8 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
||||||
* no hierarchy, but neither does the NetEvent, until it is stored in
|
* no hierarchy, but neither does the NetEvent, until it is stored in
|
||||||
* the NetScope object.
|
* the NetScope object.
|
||||||
*/
|
*/
|
||||||
void PEvent::elaborate_scope(Design*des, NetScope*scope) const
|
void PEvent::elaborate_scope(Design*, NetScope*scope) const
|
||||||
{
|
{
|
||||||
// A named event can not have the same name as another scope object.
|
|
||||||
const NetScope *child = scope->child(hname_t(name_));
|
|
||||||
if (child) {
|
|
||||||
cerr << get_fileline() << ": error: named event and ";
|
|
||||||
child->print_type(cerr);
|
|
||||||
cerr << " in '" << scope->fullname()
|
|
||||||
<< "' have the same name '" << name_ << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A named event can not have the same name as a genvar.
|
|
||||||
if (scope->find_genvar(name_)) {
|
|
||||||
cerr << get_fileline() << ": error: named event and "
|
|
||||||
<< "genvar in '" << scope->fullname()
|
|
||||||
<< "' have the same name '" << name_ << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A named event can not have the same name as a parameter.
|
|
||||||
const NetExpr *ex_msb, *ex_lsb;
|
|
||||||
const NetExpr *parm = scope->get_parameter(des, name_, ex_msb, ex_lsb);
|
|
||||||
if (parm) {
|
|
||||||
cerr << get_fileline() << ": error: named event and "
|
|
||||||
<< "parameter in '" << scope->fullname()
|
|
||||||
<< "' have the same name '" << name_ << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEvent*ev = new NetEvent(name_);
|
NetEvent*ev = new NetEvent(name_);
|
||||||
ev->set_line(*this);
|
ev->set_line(*this);
|
||||||
scope->add_event(ev);
|
scope->add_event(ev);
|
||||||
|
|
@ -1909,37 +1601,6 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
if (pscope_name() != 0) {
|
if (pscope_name() != 0) {
|
||||||
hname_t use_name(pscope_name());
|
hname_t use_name(pscope_name());
|
||||||
// A named block can not have the same name as another scope
|
|
||||||
// object.
|
|
||||||
const NetScope *child = scope->child(use_name);
|
|
||||||
if (child) {
|
|
||||||
cerr << get_fileline() << ": error: named block and ";
|
|
||||||
child->print_type(cerr);
|
|
||||||
cerr << " in '" << scope->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A named block can not have the same name as a genvar.
|
|
||||||
if (scope->find_genvar(pscope_name())) {
|
|
||||||
cerr << get_fileline() << ": error: named block and "
|
|
||||||
"genvar in '" << scope->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A named block can not have the same name as a parameter.
|
|
||||||
const NetExpr *ex_msb, *ex_lsb;
|
|
||||||
const NetExpr *parm = scope->get_parameter(des, pscope_name(),
|
|
||||||
ex_msb, ex_lsb);
|
|
||||||
if (parm) {
|
|
||||||
cerr << get_fileline() << ": error: named block and "
|
|
||||||
"parameter in '" << scope->fullname()
|
|
||||||
<< "' have the same name '" << use_name << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug_scopes)
|
if (debug_scopes)
|
||||||
cerr << get_fileline() << ": debug: "
|
cerr << get_fileline() << ": debug: "
|
||||||
<< "Elaborate block scope " << use_name
|
<< "Elaborate block scope " << use_name
|
||||||
|
|
@ -1952,6 +1613,7 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
||||||
: NetScope::BEGIN_END);
|
: NetScope::BEGIN_END);
|
||||||
my_scope->set_line(get_file(), get_lineno());
|
my_scope->set_line(get_file(), get_lineno());
|
||||||
my_scope->is_auto(scope->is_auto());
|
my_scope->is_auto(scope->is_auto());
|
||||||
|
my_scope->add_imports(&explicit_imports);
|
||||||
|
|
||||||
// Scan the parameters in the scope, and store the information
|
// Scan the parameters in the scope, and store the information
|
||||||
// needed to evaluate the parameter expressions.
|
// needed to evaluate the parameter expressions.
|
||||||
|
|
|
||||||
40
elab_sig.cc
40
elab_sig.cc
|
|
@ -942,44 +942,6 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
des->errors += error_cnt_;
|
des->errors += error_cnt_;
|
||||||
|
|
||||||
// A signal can not have the same name as a scope object.
|
|
||||||
const NetScope *child = scope->child_byname(name_);
|
|
||||||
if (child) {
|
|
||||||
cerr << get_fileline() << ": error: signal and ";
|
|
||||||
child->print_type(cerr);
|
|
||||||
cerr << " in '" << scope->fullname()
|
|
||||||
<< "' have the same name '" << name_ << "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
// A signal can not have the same name as a genvar.
|
|
||||||
const LineInfo *genvar = scope->find_genvar(name_);
|
|
||||||
if (genvar) {
|
|
||||||
cerr << get_fileline() << ": error: signal and genvar in '"
|
|
||||||
<< scope->fullname() << "' have the same name '" << name_
|
|
||||||
<< "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
// A signal can not have the same name as a parameter. Note
|
|
||||||
// that we treat enumeration literals similar to parameters,
|
|
||||||
// so if the name matches an enumeration literal, it will be
|
|
||||||
// caught here.
|
|
||||||
const NetExpr *ex_msb, *ex_lsb;
|
|
||||||
const NetExpr *parm = scope->get_parameter(des, name_, ex_msb, ex_lsb);
|
|
||||||
if (parm) {
|
|
||||||
cerr << get_fileline() << ": error: signal and parameter in '"
|
|
||||||
<< scope->fullname() << "' have the same name '" << name_
|
|
||||||
<< "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
// A signal can not have the same name as a named event.
|
|
||||||
const NetEvent *event = scope->find_event(name_);
|
|
||||||
if (event) {
|
|
||||||
cerr << get_fileline() << ": error: signal and named event in '"
|
|
||||||
<< scope->fullname() << "' have the same name '" << name_
|
|
||||||
<< "'." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port_set_ || net_set_) {
|
if (port_set_ || net_set_) {
|
||||||
|
|
||||||
if (warn_implicit_dimensions
|
if (warn_implicit_dimensions
|
||||||
|
|
@ -1214,7 +1176,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
} else if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(set_data_type_)) {
|
} else if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(set_data_type_)) {
|
||||||
list<named_pexpr_t>::const_iterator sample_name = enum_type->names->begin();
|
list<named_pexpr_t>::const_iterator sample_name = enum_type->names->begin();
|
||||||
const netenum_t*use_enum = scope->find_enumeration_for_name(sample_name->name);
|
const netenum_t*use_enum = scope->find_enumeration_for_name(des, sample_name->name);
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": debug: Create signal " << wtype
|
cerr << get_fileline() << ": debug: Create signal " << wtype
|
||||||
|
|
|
||||||
24
elaborate.cc
24
elaborate.cc
|
|
@ -4322,7 +4322,13 @@ cerr << endl;
|
||||||
const NetExpr*par = 0;
|
const NetExpr*par = 0;
|
||||||
NetEvent* eve = 0;
|
NetEvent* eve = 0;
|
||||||
|
|
||||||
NetScope*found_in = symbol_search(this, des, scope,
|
NetScope*use_scope = scope;
|
||||||
|
if (id->package()) {
|
||||||
|
use_scope = des->find_package(id->package()->pscope_name());
|
||||||
|
ivl_assert(*this, use_scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetScope*found_in = symbol_search(this, des, use_scope,
|
||||||
id->path(),
|
id->path(),
|
||||||
sig, par, eve);
|
sig, par, eve);
|
||||||
|
|
||||||
|
|
@ -4368,8 +4374,9 @@ cerr << endl;
|
||||||
|
|
||||||
NetExpr*tmp = elab_and_eval(des, scope, expr_[idx]->expr(), -1);
|
NetExpr*tmp = elab_and_eval(des, scope, expr_[idx]->expr(), -1);
|
||||||
if (tmp == 0) {
|
if (tmp == 0) {
|
||||||
expr_[idx]->dump(cerr);
|
cerr << get_fileline() << ": error: "
|
||||||
cerr << endl;
|
"Failed to evaluate event expression '"
|
||||||
|
<< *expr_[idx] << "'." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -5348,11 +5355,17 @@ NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
assert(scope);
|
assert(scope);
|
||||||
|
|
||||||
|
NetScope*use_scope = scope;
|
||||||
|
if (package_) {
|
||||||
|
use_scope = des->find_package(package_->pscope_name());
|
||||||
|
ivl_assert(*this, use_scope);
|
||||||
|
}
|
||||||
|
|
||||||
NetNet* sig = 0;
|
NetNet* sig = 0;
|
||||||
const NetExpr*par = 0;
|
const NetExpr*par = 0;
|
||||||
NetEvent* eve = 0;
|
NetEvent* eve = 0;
|
||||||
|
|
||||||
NetScope*found_in = symbol_search(this, des, scope, event_,
|
NetScope*found_in = symbol_search(this, des, use_scope, event_,
|
||||||
sig, par, eve);
|
sig, par, eve);
|
||||||
|
|
||||||
if (found_in == 0) {
|
if (found_in == 0) {
|
||||||
|
|
@ -6609,6 +6622,7 @@ Design* elaborate(list<perm_string>roots)
|
||||||
PPackage*unit = pform_units[i];
|
PPackage*unit = pform_units[i];
|
||||||
NetScope*scope = des->make_package_scope(unit->pscope_name(), 0, true);
|
NetScope*scope = des->make_package_scope(unit->pscope_name(), 0, true);
|
||||||
scope->set_line(unit);
|
scope->set_line(unit);
|
||||||
|
scope->add_imports(&unit->explicit_imports);
|
||||||
set_scope_timescale(des, scope, unit);
|
set_scope_timescale(des, scope, unit);
|
||||||
|
|
||||||
elaborator_work_item_t*es = new elaborate_package_t(des, scope, unit);
|
elaborator_work_item_t*es = new elaborate_package_t(des, scope, unit);
|
||||||
|
|
@ -6633,6 +6647,7 @@ Design* elaborate(list<perm_string>roots)
|
||||||
NetScope*unit_scope = unit_scopes[pac->second->parent_scope()];
|
NetScope*unit_scope = unit_scopes[pac->second->parent_scope()];
|
||||||
NetScope*scope = des->make_package_scope(pac->first, unit_scope, false);
|
NetScope*scope = des->make_package_scope(pac->first, unit_scope, false);
|
||||||
scope->set_line(pac->second);
|
scope->set_line(pac->second);
|
||||||
|
scope->add_imports(&pac->second->explicit_imports);
|
||||||
set_scope_timescale(des, scope, pac->second);
|
set_scope_timescale(des, scope, pac->second);
|
||||||
|
|
||||||
elaborator_work_item_t*es = new elaborate_package_t(des, scope, pac->second);
|
elaborator_work_item_t*es = new elaborate_package_t(des, scope, pac->second);
|
||||||
|
|
@ -6674,6 +6689,7 @@ Design* elaborate(list<perm_string>roots)
|
||||||
// Collect some basic properties of this scope from the
|
// Collect some basic properties of this scope from the
|
||||||
// Module definition.
|
// Module definition.
|
||||||
scope->set_line(rmod);
|
scope->set_line(rmod);
|
||||||
|
scope->add_imports(&rmod->explicit_imports);
|
||||||
set_scope_timescale(des, scope, rmod);
|
set_scope_timescale(des, scope, rmod);
|
||||||
|
|
||||||
// Save this scope, along with its definition, in the
|
// Save this scope, along with its definition, in the
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
%{
|
%{
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2019 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
|
||||||
|
|
@ -362,7 +362,7 @@ TU [munpf]
|
||||||
/* If this identifier names a previously declared type, then
|
/* If this identifier names a previously declared type, then
|
||||||
return this as a TYPE_IDENTIFIER instead. */
|
return this as a TYPE_IDENTIFIER instead. */
|
||||||
if (rc == IDENTIFIER && gn_system_verilog()) {
|
if (rc == IDENTIFIER && gn_system_verilog()) {
|
||||||
if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
|
if (data_type_t*type = pform_test_type_identifier(yylloc, yylval.text)) {
|
||||||
yylval.type_identifier.text = yylval.text;
|
yylval.type_identifier.text = yylval.text;
|
||||||
yylval.type_identifier.type = type;
|
yylval.type_identifier.type = type;
|
||||||
rc = TYPE_IDENTIFIER;
|
rc = TYPE_IDENTIFIER;
|
||||||
|
|
@ -383,7 +383,7 @@ TU [munpf]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gn_system_verilog()) {
|
if (gn_system_verilog()) {
|
||||||
if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
|
if (data_type_t*type = pform_test_type_identifier(yylloc, yylval.text)) {
|
||||||
yylval.type_identifier.text = yylval.text;
|
yylval.type_identifier.text = yylval.text;
|
||||||
yylval.type_identifier.type = type;
|
yylval.type_identifier.type = type;
|
||||||
return TYPE_IDENTIFIER;
|
return TYPE_IDENTIFIER;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2019 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
|
||||||
|
|
@ -244,7 +244,13 @@ NetScope* Design::find_scope_(NetScope*scope, const std::list<hname_t>&path,
|
||||||
/* Up references may match module name */
|
/* Up references may match module name */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
scope = scope->child( key );
|
NetScope*found_scope = scope->child(key);
|
||||||
|
if (found_scope == 0) {
|
||||||
|
found_scope = scope->find_import(this, key.peek_name());
|
||||||
|
if (found_scope)
|
||||||
|
found_scope = found_scope->child(key);
|
||||||
|
}
|
||||||
|
scope = found_scope;
|
||||||
if (scope == 0) break;
|
if (scope == 0) break;
|
||||||
}
|
}
|
||||||
tmp.pop_front();
|
tmp.pop_front();
|
||||||
|
|
@ -319,7 +325,13 @@ NetScope* Design::find_scope_(NetScope*scope, const hname_t&path,
|
||||||
/* Up references may match module name */
|
/* Up references may match module name */
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
return scope->child( path );
|
NetScope*found_scope = scope->child(path);
|
||||||
|
if (found_scope == 0) {
|
||||||
|
found_scope = scope->find_import(this, path.peek_name());
|
||||||
|
if (found_scope)
|
||||||
|
found_scope = found_scope->child(path);
|
||||||
|
}
|
||||||
|
return found_scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -864,6 +876,11 @@ NetNet* Design::find_signal(NetScope*scope, pform_name_t path)
|
||||||
if (NetNet*net = scope->find_signal(key))
|
if (NetNet*net = scope->find_signal(key))
|
||||||
return net;
|
return net;
|
||||||
|
|
||||||
|
if (NetScope*import_scope = scope->find_import(this, key)) {
|
||||||
|
scope = import_scope;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (scope->type() == NetScope::MODULE)
|
if (scope->type() == NetScope::MODULE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
30
net_scope.cc
30
net_scope.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2019 Stephen Williams (steve@icarus.com)
|
||||||
* Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch)
|
* Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
# include "netclass.h"
|
# include "netclass.h"
|
||||||
# include "netenum.h"
|
# include "netenum.h"
|
||||||
# include "netvector.h"
|
# include "netvector.h"
|
||||||
|
# include "PPackage.h"
|
||||||
# include <cstring>
|
# include <cstring>
|
||||||
# include <cstdlib>
|
# include <cstdlib>
|
||||||
# include <sstream>
|
# include <sstream>
|
||||||
|
|
@ -117,6 +118,7 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, NetScope*in_u
|
||||||
: type_(t), name_(n), nested_module_(nest), program_block_(program),
|
: type_(t), name_(n), nested_module_(nest), program_block_(program),
|
||||||
is_interface_(interface), is_unit_(compilation_unit), unit_(in_unit), up_(up)
|
is_interface_(interface), is_unit_(compilation_unit), unit_(in_unit), up_(up)
|
||||||
{
|
{
|
||||||
|
imports_ = 0;
|
||||||
events_ = 0;
|
events_ = 0;
|
||||||
lcounter_ = 0;
|
lcounter_ = 0;
|
||||||
is_auto_ = false;
|
is_auto_ = false;
|
||||||
|
|
@ -205,16 +207,38 @@ void NetScope::set_line(perm_string file, perm_string def_file,
|
||||||
def_lineno_ = def_lineno;
|
def_lineno_ = def_lineno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetScope::add_imports(const map<perm_string,PPackage*>*imports)
|
||||||
|
{
|
||||||
|
if (!imports->empty())
|
||||||
|
imports_ = imports;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetScope*NetScope::find_import(const Design*des, perm_string name)
|
||||||
|
{
|
||||||
|
if (imports_ == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
map<perm_string,PPackage*>::const_iterator cur = imports_->find(name);
|
||||||
|
if (cur != imports_->end()) {
|
||||||
|
return des->find_package(cur->second->pscope_name());
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look for the enumeration in the current scope and any parent scopes.
|
* Look for the enumeration in the current scope and any parent scopes.
|
||||||
*/
|
*/
|
||||||
const netenum_t*NetScope::find_enumeration_for_name(perm_string name)
|
const netenum_t*NetScope::find_enumeration_for_name(const Design*des, perm_string name)
|
||||||
{
|
{
|
||||||
NetScope *cur_scope = this;
|
NetScope *cur_scope = this;
|
||||||
while (cur_scope) {
|
while (cur_scope) {
|
||||||
NetEConstEnum*tmp = cur_scope->enum_names_[name];
|
NetEConstEnum*tmp = cur_scope->enum_names_[name];
|
||||||
if (tmp) break;
|
if (tmp) break;
|
||||||
cur_scope = cur_scope->parent();
|
NetScope*import_scope = cur_scope->find_import(des, name);
|
||||||
|
if (import_scope)
|
||||||
|
cur_scope = import_scope;
|
||||||
|
else
|
||||||
|
cur_scope = cur_scope->parent();
|
||||||
if (cur_scope == 0)
|
if (cur_scope == 0)
|
||||||
cur_scope = unit_;
|
cur_scope = unit_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ class NetEvWait;
|
||||||
class PClass;
|
class PClass;
|
||||||
class PExpr;
|
class PExpr;
|
||||||
class PFunction;
|
class PFunction;
|
||||||
|
class PPackage;
|
||||||
class PTaskFunc;
|
class PTaskFunc;
|
||||||
struct enum_type_t;
|
struct enum_type_t;
|
||||||
class netclass_t;
|
class netclass_t;
|
||||||
|
|
@ -942,9 +943,12 @@ class NetScope : public Definitions, public Attrib {
|
||||||
if a unique name couldn't be generated. */
|
if a unique name couldn't be generated. */
|
||||||
bool auto_name(const char* prefix, char pad, const char* suffix);
|
bool auto_name(const char* prefix, char pad, const char* suffix);
|
||||||
|
|
||||||
|
void add_imports(const map<perm_string,PPackage*>*imports);
|
||||||
|
NetScope*find_import(const Design*des, perm_string name);
|
||||||
|
|
||||||
/* Routine to search for the enumeration given a name. It basically
|
/* Routine to search for the enumeration given a name. It basically
|
||||||
* does what enumeration_for_name() does but searched the hierarchy. */
|
* does what enumeration_for_name() does but searched the hierarchy. */
|
||||||
const netenum_t*find_enumeration_for_name(perm_string name);
|
const netenum_t*find_enumeration_for_name(const Design*des, perm_string name);
|
||||||
|
|
||||||
/* Parameters exist within a scope, and these methods allow
|
/* Parameters exist within a scope, and these methods allow
|
||||||
one to manipulate the set. In these cases, the name is the
|
one to manipulate the set. In these cases, the name is the
|
||||||
|
|
@ -1269,6 +1273,8 @@ class NetScope : public Definitions, public Attrib {
|
||||||
signed char time_unit_, time_prec_;
|
signed char time_unit_, time_prec_;
|
||||||
bool time_from_timescale_;
|
bool time_from_timescale_;
|
||||||
|
|
||||||
|
const map<perm_string,PPackage*>*imports_;
|
||||||
|
|
||||||
NetEvent *events_;
|
NetEvent *events_;
|
||||||
|
|
||||||
map<perm_string,LineInfo*> genvars_;
|
map<perm_string,LineInfo*> genvars_;
|
||||||
|
|
|
||||||
86
parse.y
86
parse.y
|
|
@ -819,12 +819,14 @@ class_declaration_endlabel_opt
|
||||||
|
|
||||||
class_declaration_extends_opt /* IEEE1800-2005: A.1.2 */
|
class_declaration_extends_opt /* IEEE1800-2005: A.1.2 */
|
||||||
: K_extends TYPE_IDENTIFIER
|
: K_extends TYPE_IDENTIFIER
|
||||||
{ $$.type = $2.type;
|
{ pform_set_type_referenced(@2, $2.text);
|
||||||
|
$$.type = $2.type;
|
||||||
$$.exprs= 0;
|
$$.exprs= 0;
|
||||||
delete[]$2.text;
|
delete[]$2.text;
|
||||||
}
|
}
|
||||||
| K_extends TYPE_IDENTIFIER '(' expression_list_with_nuls ')'
|
| K_extends TYPE_IDENTIFIER '(' expression_list_with_nuls ')'
|
||||||
{ $$.type = $2.type;
|
{ pform_set_type_referenced(@2, $2.text);
|
||||||
|
$$.type = $2.type;
|
||||||
$$.exprs = $4;
|
$$.exprs = $4;
|
||||||
delete[]$2.text;
|
delete[]$2.text;
|
||||||
}
|
}
|
||||||
|
|
@ -1056,6 +1058,9 @@ data_declaration /* IEEE1800-2005: A.2.1.3 */
|
||||||
}
|
}
|
||||||
pform_makewire(@2, 0, str_strength, $3, NetNet::IMPLICIT_REG, data_type);
|
pform_makewire(@2, 0, str_strength, $3, NetNet::IMPLICIT_REG, data_type);
|
||||||
}
|
}
|
||||||
|
| attribute_list_opt K_event event_variable_list ';'
|
||||||
|
{ if ($3) pform_make_events($3, @2.text, @2.first_line);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
data_type /* IEEE1800-2005: A.2.2.1 */
|
data_type /* IEEE1800-2005: A.2.2.1 */
|
||||||
|
|
@ -1103,7 +1108,8 @@ data_type /* IEEE1800-2005: A.2.2.1 */
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| TYPE_IDENTIFIER dimensions_opt
|
| TYPE_IDENTIFIER dimensions_opt
|
||||||
{ if ($2) {
|
{ pform_set_type_referenced(@1, $1.text);
|
||||||
|
if ($2) {
|
||||||
parray_type_t*tmp = new parray_type_t($1.type, $2);
|
parray_type_t*tmp = new parray_type_t($1.type, $2);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
|
|
@ -1422,8 +1428,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
||||||
char for_block_name [64];
|
char for_block_name [64];
|
||||||
snprintf(for_block_name, sizeof for_block_name, "$ivl_for_loop%u", for_counter);
|
snprintf(for_block_name, sizeof for_block_name, "$ivl_for_loop%u", for_counter);
|
||||||
for_counter += 1;
|
for_counter += 1;
|
||||||
PBlock*tmp = pform_push_block_scope(for_block_name, PBlock::BL_SEQ);
|
PBlock*tmp = pform_push_block_scope(@1, for_block_name, PBlock::BL_SEQ);
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
current_block_stack.push(tmp);
|
current_block_stack.push(tmp);
|
||||||
|
|
||||||
list<decl_assignment_t*>assign_list;
|
list<decl_assignment_t*>assign_list;
|
||||||
|
|
@ -1436,7 +1441,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
||||||
{ pform_name_t tmp_hident;
|
{ pform_name_t tmp_hident;
|
||||||
tmp_hident.push_back(name_component_t(lex_strings.make($4)));
|
tmp_hident.push_back(name_component_t(lex_strings.make($4)));
|
||||||
|
|
||||||
PEIdent*tmp_ident = pform_new_ident(tmp_hident);
|
PEIdent*tmp_ident = pform_new_ident(@4, tmp_hident);
|
||||||
FILE_NAME(tmp_ident, @4);
|
FILE_NAME(tmp_ident, @4);
|
||||||
|
|
||||||
PForStatement*tmp_for = new PForStatement(tmp_ident, $6, $8, $10, $13);
|
PForStatement*tmp_for = new PForStatement(tmp_ident, $6, $8, $10, $13);
|
||||||
|
|
@ -1484,8 +1489,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
||||||
snprintf(for_block_name, sizeof for_block_name, "$ivl_foreach%u", foreach_counter);
|
snprintf(for_block_name, sizeof for_block_name, "$ivl_foreach%u", foreach_counter);
|
||||||
foreach_counter += 1;
|
foreach_counter += 1;
|
||||||
|
|
||||||
PBlock*tmp = pform_push_block_scope(for_block_name, PBlock::BL_SEQ);
|
PBlock*tmp = pform_push_block_scope(@1, for_block_name, PBlock::BL_SEQ);
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
current_block_stack.push(tmp);
|
current_block_stack.push(tmp);
|
||||||
|
|
||||||
pform_make_foreach_declarations(@1, $5);
|
pform_make_foreach_declarations(@1, $5);
|
||||||
|
|
@ -1989,7 +1993,8 @@ simple_type_or_string /* IEEE1800-2005: A.2.2.1 */
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| TYPE_IDENTIFIER
|
| TYPE_IDENTIFIER
|
||||||
{ $$ = $1.type;
|
{ pform_set_type_referenced(@1, $1.text);
|
||||||
|
$$ = $1.type;
|
||||||
delete[]$1.text;
|
delete[]$1.text;
|
||||||
}
|
}
|
||||||
| PACKAGE_IDENTIFIER K_SCOPE_RES
|
| PACKAGE_IDENTIFIER K_SCOPE_RES
|
||||||
|
|
@ -2547,6 +2552,10 @@ block_item_decl
|
||||||
|
|
||||||
| type_declaration
|
| type_declaration
|
||||||
|
|
||||||
|
/* Blocks can have imports. */
|
||||||
|
|
||||||
|
| package_import_declaration
|
||||||
|
|
||||||
/* Recover from errors that happen within variable lists. Use the
|
/* Recover from errors that happen within variable lists. Use the
|
||||||
trailing semi-colon to resync the parser. */
|
trailing semi-colon to resync the parser. */
|
||||||
|
|
||||||
|
|
@ -3176,7 +3185,8 @@ clocking_event_opt /* */
|
||||||
|
|
||||||
event_control /* A.K.A. clocking_event */
|
event_control /* A.K.A. clocking_event */
|
||||||
: '@' hierarchy_identifier
|
: '@' hierarchy_identifier
|
||||||
{ PEIdent*tmpi = new PEIdent(*$2);
|
{ PEIdent*tmpi = pform_new_ident(@2, *$2);
|
||||||
|
FILE_NAME(tmpi, @2);
|
||||||
PEEvent*tmpe = new PEEvent(PEEvent::ANYEDGE, tmpi);
|
PEEvent*tmpe = new PEEvent(PEEvent::ANYEDGE, tmpi);
|
||||||
PEventStatement*tmps = new PEventStatement(tmpe);
|
PEventStatement*tmps = new PEventStatement(tmpe);
|
||||||
FILE_NAME(tmps, @1);
|
FILE_NAME(tmps, @1);
|
||||||
|
|
@ -3559,7 +3569,8 @@ expr_primary_or_typename
|
||||||
/* There are a few special cases (notably $bits argument) where the
|
/* There are a few special cases (notably $bits argument) where the
|
||||||
expression may be a type name. Let the elaborator sort this out. */
|
expression may be a type name. Let the elaborator sort this out. */
|
||||||
| TYPE_IDENTIFIER
|
| TYPE_IDENTIFIER
|
||||||
{ PETypename*tmp = new PETypename($1.type);
|
{ pform_set_type_referenced(@1, $1.text);
|
||||||
|
PETypename*tmp = new PETypename($1.type);
|
||||||
FILE_NAME(tmp,@1);
|
FILE_NAME(tmp,@1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
delete[]$1.text;
|
delete[]$1.text;
|
||||||
|
|
@ -3612,7 +3623,7 @@ expr_primary
|
||||||
indexed arrays and part selects */
|
indexed arrays and part selects */
|
||||||
|
|
||||||
| hierarchy_identifier
|
| hierarchy_identifier
|
||||||
{ PEIdent*tmp = pform_new_ident(*$1);
|
{ PEIdent*tmp = pform_new_ident(@1, *$1);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
delete $1;
|
delete $1;
|
||||||
|
|
@ -4508,7 +4519,7 @@ atom2_type
|
||||||
rule to reflect the rules for assignment l-values. */
|
rule to reflect the rules for assignment l-values. */
|
||||||
lpvalue
|
lpvalue
|
||||||
: hierarchy_identifier
|
: hierarchy_identifier
|
||||||
{ PEIdent*tmp = pform_new_ident(*$1);
|
{ PEIdent*tmp = pform_new_ident(@1, *$1);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
delete $1;
|
delete $1;
|
||||||
|
|
@ -5048,29 +5059,27 @@ module_item
|
||||||
IDENTIFIER '=' expression ')'
|
IDENTIFIER '=' expression ')'
|
||||||
{ pform_start_generate_for(@1, $3, $5, $7, $9, $11); }
|
{ pform_start_generate_for(@1, $3, $5, $7, $9, $11); }
|
||||||
generate_block
|
generate_block
|
||||||
{ pform_endgenerate(); }
|
{ pform_endgenerate(false); }
|
||||||
|
|
||||||
| generate_if
|
| generate_if
|
||||||
generate_block_opt
|
generate_block_opt
|
||||||
K_else
|
K_else
|
||||||
{ pform_start_generate_else(@1); }
|
{ pform_start_generate_else(@1); }
|
||||||
generate_block
|
generate_block
|
||||||
{ pform_endgenerate(); }
|
{ pform_endgenerate(true); }
|
||||||
|
|
||||||
| generate_if
|
| generate_if
|
||||||
generate_block_opt %prec less_than_K_else
|
generate_block_opt %prec less_than_K_else
|
||||||
{ pform_endgenerate(); }
|
{ pform_endgenerate(true); }
|
||||||
|
|
||||||
| K_case '(' expression ')'
|
| K_case '(' expression ')'
|
||||||
{ pform_start_generate_case(@1, $3); }
|
{ pform_start_generate_case(@1, $3); }
|
||||||
generate_case_items
|
generate_case_items
|
||||||
K_endcase
|
K_endcase
|
||||||
{ pform_endgenerate(); }
|
{ pform_endgenerate(true); }
|
||||||
|
|
||||||
| modport_declaration
|
| modport_declaration
|
||||||
|
|
||||||
| package_import_declaration
|
|
||||||
|
|
||||||
/* 1364-2001 and later allow specparam declarations outside specify blocks. */
|
/* 1364-2001 and later allow specparam declarations outside specify blocks. */
|
||||||
|
|
||||||
| attribute_list_opt K_specparam
|
| attribute_list_opt K_specparam
|
||||||
|
|
@ -5162,9 +5171,9 @@ generate_case_items
|
||||||
|
|
||||||
generate_case_item
|
generate_case_item
|
||||||
: expression_list_proper ':' { pform_generate_case_item(@1, $1); } generate_block_opt
|
: expression_list_proper ':' { pform_generate_case_item(@1, $1); } generate_block_opt
|
||||||
{ pform_endgenerate(); }
|
{ pform_endgenerate(false); }
|
||||||
| K_default ':' { pform_generate_case_item(@1, 0); } generate_block_opt
|
| K_default ':' { pform_generate_case_item(@1, 0); } generate_block_opt
|
||||||
{ pform_endgenerate(); }
|
{ pform_endgenerate(false); }
|
||||||
;
|
;
|
||||||
|
|
||||||
generate_item
|
generate_item
|
||||||
|
|
@ -5185,7 +5194,7 @@ generate_item
|
||||||
warn_count += 1;
|
warn_count += 1;
|
||||||
cerr << @1 << ": warning: Anachronistic use of named begin/end to surround generate schemes." << endl;
|
cerr << @1 << ": warning: Anachronistic use of named begin/end to surround generate schemes." << endl;
|
||||||
}
|
}
|
||||||
pform_endgenerate();
|
pform_endgenerate(false);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -5318,7 +5327,8 @@ param_type
|
||||||
param_active_type = IVL_VT_BOOL;
|
param_active_type = IVL_VT_BOOL;
|
||||||
}
|
}
|
||||||
| TYPE_IDENTIFIER
|
| TYPE_IDENTIFIER
|
||||||
{ pform_set_param_from_type(@1, $1.type, $1.text, param_active_range,
|
{ pform_set_type_referenced(@1, $1.text);
|
||||||
|
pform_set_param_from_type(@1, $1.type, $1.text, param_active_range,
|
||||||
param_active_signed, param_active_type);
|
param_active_signed, param_active_type);
|
||||||
delete[]$1.text;
|
delete[]$1.text;
|
||||||
}
|
}
|
||||||
|
|
@ -6260,8 +6270,7 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
}
|
}
|
||||||
/* In SystemVerilog an unnamed block can contain variable declarations. */
|
/* In SystemVerilog an unnamed block can contain variable declarations. */
|
||||||
| K_begin
|
| K_begin
|
||||||
{ PBlock*tmp = pform_push_block_scope(0, PBlock::BL_SEQ);
|
{ PBlock*tmp = pform_push_block_scope(@1, 0, PBlock::BL_SEQ);
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
current_block_stack.push(tmp);
|
current_block_stack.push(tmp);
|
||||||
}
|
}
|
||||||
block_item_decls_opt
|
block_item_decls_opt
|
||||||
|
|
@ -6295,8 +6304,7 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_begin ':' IDENTIFIER
|
| K_begin ':' IDENTIFIER
|
||||||
{ PBlock*tmp = pform_push_block_scope($3, PBlock::BL_SEQ);
|
{ PBlock*tmp = pform_push_block_scope(@1, $3, PBlock::BL_SEQ);
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
current_block_stack.push(tmp);
|
current_block_stack.push(tmp);
|
||||||
}
|
}
|
||||||
block_item_decls_opt
|
block_item_decls_opt
|
||||||
|
|
@ -6333,8 +6341,7 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
}
|
}
|
||||||
/* In SystemVerilog an unnamed block can contain variable declarations. */
|
/* In SystemVerilog an unnamed block can contain variable declarations. */
|
||||||
| K_fork
|
| K_fork
|
||||||
{ PBlock*tmp = pform_push_block_scope(0, PBlock::BL_PAR);
|
{ PBlock*tmp = pform_push_block_scope(@1, 0, PBlock::BL_PAR);
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
current_block_stack.push(tmp);
|
current_block_stack.push(tmp);
|
||||||
}
|
}
|
||||||
block_item_decls_opt
|
block_item_decls_opt
|
||||||
|
|
@ -6369,8 +6376,7 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_fork ':' IDENTIFIER
|
| K_fork ':' IDENTIFIER
|
||||||
{ PBlock*tmp = pform_push_block_scope($3, PBlock::BL_PAR);
|
{ PBlock*tmp = pform_push_block_scope(@1, $3, PBlock::BL_PAR);
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
current_block_stack.push(tmp);
|
current_block_stack.push(tmp);
|
||||||
}
|
}
|
||||||
block_item_decls_opt
|
block_item_decls_opt
|
||||||
|
|
@ -6408,12 +6414,18 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_TRIGGER hierarchy_identifier ';'
|
| K_TRIGGER hierarchy_identifier ';'
|
||||||
{ PTrigger*tmp = new PTrigger(*$2);
|
{ PTrigger*tmp = pform_new_trigger(@2, 0, *$2);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
delete $2;
|
delete $2;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
| K_TRIGGER PACKAGE_IDENTIFIER K_SCOPE_RES hierarchy_identifier
|
||||||
|
{ PTrigger*tmp = pform_new_trigger(@4, $2, *$4);
|
||||||
|
FILE_NAME(tmp, @1);
|
||||||
|
delete $4;
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
| procedural_assertion_statement { $$ = $1; }
|
| procedural_assertion_statement { $$ = $1; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_parse_misc_H
|
#ifndef IVL_parse_misc_H
|
||||||
#define IVL_parse_misc_H
|
#define IVL_parse_misc_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2019 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
|
||||||
|
|
@ -88,7 +88,7 @@ extern void lex_in_package_scope(PPackage*pkg);
|
||||||
* parser detects typedefs and marks the typedef'ed identifiers as
|
* parser detects typedefs and marks the typedef'ed identifiers as
|
||||||
* type names.
|
* type names.
|
||||||
*/
|
*/
|
||||||
extern data_type_t* pform_test_type_identifier(const char*txt);
|
extern data_type_t* pform_test_type_identifier(const YYLTYPE&loc, const char*txt);
|
||||||
extern data_type_t* pform_test_type_identifier(PPackage*pkg, const char*txt);
|
extern data_type_t* pform_test_type_identifier(PPackage*pkg, const char*txt);
|
||||||
|
|
||||||
extern bool pform_test_type_identifier_local(perm_string txt);
|
extern bool pform_test_type_identifier_local(perm_string txt);
|
||||||
|
|
|
||||||
575
pform.cc
575
pform.cc
|
|
@ -349,6 +349,13 @@ static unsigned scope_generate_counter = 1;
|
||||||
always within a module. */
|
always within a module. */
|
||||||
static PGenerate*pform_cur_generate = 0;
|
static PGenerate*pform_cur_generate = 0;
|
||||||
|
|
||||||
|
/* Blocks within the same conditional generate construct may have
|
||||||
|
the same name. Here we collect the set of names used in each
|
||||||
|
construct, so they can be added to the local scope without
|
||||||
|
conflicting with each other. Generate constructs may nest, so
|
||||||
|
we need a stack. */
|
||||||
|
static list<set<perm_string>> conditional_block_names;
|
||||||
|
|
||||||
/* This tracks the current modport list being processed. This is
|
/* This tracks the current modport list being processed. This is
|
||||||
always within an interface. */
|
always within an interface. */
|
||||||
static PModport*pform_cur_modport = 0;
|
static PModport*pform_cur_modport = 0;
|
||||||
|
|
@ -400,8 +407,17 @@ LexicalScope* pform_peek_scope(void)
|
||||||
|
|
||||||
void pform_pop_scope()
|
void pform_pop_scope()
|
||||||
{
|
{
|
||||||
assert(lexical_scope);
|
LexicalScope*scope = lexical_scope;
|
||||||
lexical_scope = lexical_scope->parent_scope();
|
assert(scope);
|
||||||
|
|
||||||
|
map<perm_string,PPackage*>::const_iterator cur;
|
||||||
|
for (cur = scope->possible_imports.begin(); cur != scope->possible_imports.end(); ++cur) {
|
||||||
|
if (scope->local_symbols.find(cur->first) == scope->local_symbols.end())
|
||||||
|
scope->explicit_imports[cur->first] = cur->second;
|
||||||
|
}
|
||||||
|
scope->possible_imports.clear();
|
||||||
|
|
||||||
|
lexical_scope = scope->parent_scope();
|
||||||
assert(lexical_scope);
|
assert(lexical_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -423,6 +439,89 @@ static PScopeExtra* find_nearest_scopex(LexicalScope*scope)
|
||||||
return scopex;
|
return scopex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_local_symbol(LexicalScope*scope, perm_string name, PNamedItem*item)
|
||||||
|
{
|
||||||
|
assert(scope);
|
||||||
|
|
||||||
|
// Check for conflict with another local symbol.
|
||||||
|
map<perm_string,PNamedItem*>::const_iterator cur_sym
|
||||||
|
= scope->local_symbols.find(name);
|
||||||
|
if (cur_sym != scope->local_symbols.end()) {
|
||||||
|
cerr << item->get_fileline() << ": error: "
|
||||||
|
"'" << name << "' has already been declared "
|
||||||
|
"in this scope." << endl;
|
||||||
|
cerr << cur_sym->second->get_fileline() << ": : "
|
||||||
|
"It was declared here as "
|
||||||
|
<< cur_sym->second->symbol_type() << "." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for conflict with an explicit import.
|
||||||
|
map<perm_string,PPackage*>::const_iterator cur_pkg
|
||||||
|
= scope->explicit_imports.find(name);
|
||||||
|
if (cur_pkg != scope->explicit_imports.end()) {
|
||||||
|
cerr << item->get_fileline() << ": error: "
|
||||||
|
"'" << name << "' has already been "
|
||||||
|
"imported into this scope from package '"
|
||||||
|
<< cur_pkg->second->pscope_name() << "'." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scope->local_symbols[name] = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PPackage*find_potential_import(const struct vlltype&loc, LexicalScope*scope,
|
||||||
|
perm_string name, bool tf_call, bool make_explicit)
|
||||||
|
{
|
||||||
|
assert(scope);
|
||||||
|
|
||||||
|
PPackage*found_pkg = 0;
|
||||||
|
for (set<PPackage*>::const_iterator cur_pkg = scope->potential_imports.begin();
|
||||||
|
cur_pkg != scope->potential_imports.end(); ++cur_pkg) {
|
||||||
|
PPackage*search_pkg = *cur_pkg;
|
||||||
|
map<perm_string,PNamedItem*>::const_iterator cur_sym
|
||||||
|
= search_pkg->local_symbols.find(name);
|
||||||
|
if (cur_sym != search_pkg->local_symbols.end()) {
|
||||||
|
if (found_pkg && make_explicit) {
|
||||||
|
cerr << loc.get_fileline() << ": error: "
|
||||||
|
"Ambiguous use of '" << name << "'. "
|
||||||
|
"It is exported by both '"
|
||||||
|
<< found_pkg->pscope_name()
|
||||||
|
<< "' and by '"
|
||||||
|
<< search_pkg->pscope_name()
|
||||||
|
<< "'." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
} else {
|
||||||
|
found_pkg = search_pkg;
|
||||||
|
if (make_explicit) {
|
||||||
|
if (tf_call)
|
||||||
|
scope->possible_imports[name] = found_pkg;
|
||||||
|
else
|
||||||
|
scope->explicit_imports[name] = found_pkg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found_pkg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_potential_imports(const struct vlltype&loc, perm_string name, bool tf_call)
|
||||||
|
{
|
||||||
|
LexicalScope*scope = lexical_scope;
|
||||||
|
while (scope) {
|
||||||
|
if (scope->local_symbols.find(name) != scope->local_symbols.end())
|
||||||
|
return;
|
||||||
|
if (scope->explicit_imports.find(name) != scope->explicit_imports.end())
|
||||||
|
return;
|
||||||
|
if (find_potential_import(loc, scope, name, tf_call, true))
|
||||||
|
return;
|
||||||
|
|
||||||
|
scope = scope->parent_scope();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the local time unit/precision. This version is used for setting
|
* Set the local time unit/precision. This version is used for setting
|
||||||
* the time scale for design elements (modules, packages, etc.) and is
|
* the time scale for design elements (modules, packages, etc.) and is
|
||||||
|
|
@ -516,12 +615,6 @@ PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name,
|
||||||
|
|
||||||
pform_set_scope_timescale(class_scope, scopex);
|
pform_set_scope_timescale(class_scope, scopex);
|
||||||
|
|
||||||
if (scopex->classes.find(name) != scopex->classes.end()) {
|
|
||||||
cerr << class_scope->get_fileline() << ": error: duplicate "
|
|
||||||
"definition for class '" << name << "' in '"
|
|
||||||
<< scopex->pscope_name() << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
scopex->classes[name] = class_scope;
|
scopex->classes[name] = class_scope;
|
||||||
scopex->classes_lexical .push_back(class_scope);
|
scopex->classes_lexical .push_back(class_scope);
|
||||||
|
|
||||||
|
|
@ -566,25 +659,11 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name,
|
||||||
pform_set_scope_timescale(task, scopex);
|
pform_set_scope_timescale(task, scopex);
|
||||||
|
|
||||||
if (pform_cur_generate) {
|
if (pform_cur_generate) {
|
||||||
// Check if the task is already in the dictionary.
|
add_local_symbol(pform_cur_generate, task_name, task);
|
||||||
if (pform_cur_generate->tasks.find(task->pscope_name()) !=
|
pform_cur_generate->tasks[task_name] = task;
|
||||||
pform_cur_generate->tasks.end()) {
|
|
||||||
cerr << task->get_fileline() << ": error: duplicate "
|
|
||||||
"definition for task '" << name << "' in '"
|
|
||||||
<< pform_cur_module.front()->mod_name() << "' (generate)."
|
|
||||||
<< endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
pform_cur_generate->tasks[task->pscope_name()] = task;
|
|
||||||
} else {
|
} else {
|
||||||
// Check if the task is already in the dictionary.
|
add_local_symbol(scopex, task_name, task);
|
||||||
if (scopex->tasks.find(task->pscope_name()) != scopex->tasks.end()) {
|
scopex->tasks[task_name] = task;
|
||||||
cerr << task->get_fileline() << ": error: duplicate "
|
|
||||||
"definition for task '" << name << "' in '"
|
|
||||||
<< scopex->pscope_name() << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
scopex->tasks[task->pscope_name()] = task;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lexical_scope = task;
|
lexical_scope = task;
|
||||||
|
|
@ -615,26 +694,12 @@ PFunction* pform_push_function_scope(const struct vlltype&loc, const char*name,
|
||||||
pform_set_scope_timescale(func, scopex);
|
pform_set_scope_timescale(func, scopex);
|
||||||
|
|
||||||
if (pform_cur_generate) {
|
if (pform_cur_generate) {
|
||||||
// Check if the function is already in the dictionary.
|
add_local_symbol(pform_cur_generate, func_name, func);
|
||||||
if (pform_cur_generate->funcs.find(func->pscope_name()) !=
|
pform_cur_generate->funcs[func_name] = func;
|
||||||
pform_cur_generate->funcs.end()) {
|
|
||||||
cerr << func->get_fileline() << ": error: duplicate "
|
|
||||||
"definition for function '" << name << "' in '"
|
|
||||||
<< pform_cur_module.front()->mod_name() << "' (generate)."
|
|
||||||
<< endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
pform_cur_generate->funcs[func->pscope_name()] = func;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Check if the function is already in the dictionary.
|
add_local_symbol(scopex, func_name, func);
|
||||||
if (scopex->funcs.find(func->pscope_name()) != scopex->funcs.end()) {
|
scopex->funcs[func_name] = func;
|
||||||
cerr << func->get_fileline() << ": error: duplicate "
|
|
||||||
"definition for function '" << name << "' in '"
|
|
||||||
<< scopex->pscope_name() << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
scopex->funcs[func->pscope_name()] = func;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lexical_scope = func;
|
lexical_scope = func;
|
||||||
|
|
@ -642,7 +707,8 @@ PFunction* pform_push_function_scope(const struct vlltype&loc, const char*name,
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt)
|
PBlock* pform_push_block_scope(const struct vlltype&loc, char*name,
|
||||||
|
PBlock::BL_TYPE bt)
|
||||||
{
|
{
|
||||||
perm_string block_name;
|
perm_string block_name;
|
||||||
if (name) block_name = lex_strings.make(name);
|
if (name) block_name = lex_strings.make(name);
|
||||||
|
|
@ -656,26 +722,34 @@ PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt)
|
||||||
}
|
}
|
||||||
|
|
||||||
PBlock*block = new PBlock(block_name, lexical_scope, bt);
|
PBlock*block = new PBlock(block_name, lexical_scope, bt);
|
||||||
|
FILE_NAME(block, loc);
|
||||||
block->default_lifetime = find_lifetime(LexicalScope::INHERITED);
|
block->default_lifetime = find_lifetime(LexicalScope::INHERITED);
|
||||||
|
if (name) add_local_symbol(lexical_scope, block_name, block);
|
||||||
lexical_scope = block;
|
lexical_scope = block;
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a new identifier. Check if this is an imported name.
|
* Create a new identifier.
|
||||||
*/
|
*/
|
||||||
PEIdent* pform_new_ident(const pform_name_t&name)
|
PEIdent* pform_new_ident(const struct vlltype&loc, const pform_name_t&name)
|
||||||
{
|
{
|
||||||
LexicalScope*scope = pform_peek_scope();
|
if (gn_system_verilog())
|
||||||
map<perm_string,PPackage*>::const_iterator pkg = scope->imports.find(name.front().name);
|
check_potential_imports(loc, name.front().name, false);
|
||||||
if (pkg == scope->imports.end())
|
|
||||||
return new PEIdent(name);
|
|
||||||
|
|
||||||
// XXXX For now, do not support indexed imported names.
|
return new PEIdent(name);
|
||||||
assert(name.back().index.size() == 0);
|
}
|
||||||
|
|
||||||
return new PEIdent(pkg->second, name);
|
PTrigger* pform_new_trigger(const struct vlltype&loc, PPackage*pkg,
|
||||||
|
const pform_name_t&name)
|
||||||
|
{
|
||||||
|
if (gn_system_verilog())
|
||||||
|
check_potential_imports(loc, name.front().name, false);
|
||||||
|
|
||||||
|
PTrigger*tmp = new PTrigger(pkg, name);
|
||||||
|
FILE_NAME(tmp, loc);
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
PGenerate* pform_parent_generate(void)
|
PGenerate* pform_parent_generate(void)
|
||||||
|
|
@ -729,15 +803,33 @@ PWire*pform_get_wire_in_scope(perm_string name)
|
||||||
|
|
||||||
static void pform_put_wire_in_scope(perm_string name, PWire*net)
|
static void pform_put_wire_in_scope(perm_string name, PWire*net)
|
||||||
{
|
{
|
||||||
|
add_local_symbol(lexical_scope, name, net);
|
||||||
lexical_scope->wires[name] = net;
|
lexical_scope->wires[name] = net;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pform_put_enum_type_in_scope(enum_type_t*enum_set)
|
static void pform_put_enum_type_in_scope(enum_type_t*enum_set)
|
||||||
{
|
{
|
||||||
|
if (lexical_scope->enum_sets.count(enum_set))
|
||||||
|
return;
|
||||||
|
|
||||||
|
set<perm_string> enum_names;
|
||||||
|
list<named_pexpr_t>::const_iterator cur;
|
||||||
|
for (cur = enum_set->names->begin(); cur != enum_set->names->end(); ++cur) {
|
||||||
|
if (enum_names.count(cur->name)) {
|
||||||
|
cerr << enum_set->get_fileline() << ": error: "
|
||||||
|
"Duplicate enumeration name '"
|
||||||
|
<< cur->name << "'." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
} else {
|
||||||
|
add_local_symbol(lexical_scope, cur->name, enum_set);
|
||||||
|
enum_names.insert(cur->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lexical_scope->enum_sets.insert(enum_set);
|
lexical_scope->enum_sets.insert(enum_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
PWire*pform_get_make_wire_in_scope(const struct vlltype&li, perm_string name,
|
PWire*pform_get_make_wire_in_scope(const struct vlltype&, perm_string name,
|
||||||
NetNet::Type net_type, NetNet::PortType port_type,
|
NetNet::Type net_type, NetNet::PortType port_type,
|
||||||
ivl_variable_type_t vt_type)
|
ivl_variable_type_t vt_type)
|
||||||
{
|
{
|
||||||
|
|
@ -745,15 +837,11 @@ PWire*pform_get_make_wire_in_scope(const struct vlltype&li, perm_string name,
|
||||||
|
|
||||||
// If the wire already exists and is fully defined, this
|
// If the wire already exists and is fully defined, this
|
||||||
// must be a redeclaration. Start again with a new wire.
|
// must be a redeclaration. Start again with a new wire.
|
||||||
if (cur && cur->get_data_type() != IVL_VT_NO_TYPE) {
|
// The error will be reported when we add the new wire
|
||||||
LineInfo tloc;
|
// to the scope. Do not delete the old wire - it will
|
||||||
FILE_NAME(&tloc, li);
|
// remain in the local symbol map.
|
||||||
cerr << tloc.get_fileline() << ": error: duplicate declaration "
|
if (cur && cur->get_data_type() != IVL_VT_NO_TYPE)
|
||||||
"for net or variable '" << name << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
delete cur;
|
|
||||||
cur = 0;
|
cur = 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (cur == 0) {
|
if (cur == 0) {
|
||||||
cur = new PWire(name, net_type, port_type, vt_type);
|
cur = new PWire(name, net_type, port_type, vt_type);
|
||||||
|
|
@ -773,17 +861,24 @@ void pform_set_typedef(perm_string name, data_type_t*data_type, std::list<pform_
|
||||||
if(unp_ranges)
|
if(unp_ranges)
|
||||||
data_type = new uarray_type_t(data_type, unp_ranges);
|
data_type = new uarray_type_t(data_type, unp_ranges);
|
||||||
|
|
||||||
|
add_local_symbol(lexical_scope, name, data_type);
|
||||||
|
|
||||||
data_type_t*&ref = lexical_scope->typedefs[name];
|
data_type_t*&ref = lexical_scope->typedefs[name];
|
||||||
|
|
||||||
ivl_assert(*data_type, ref == 0);
|
ivl_assert(*data_type, ref == 0);
|
||||||
ref = data_type;
|
ref = data_type;
|
||||||
|
|
||||||
if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(data_type)) {
|
if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(data_type))
|
||||||
pform_put_enum_type_in_scope(enum_type);
|
pform_put_enum_type_in_scope(enum_type);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data_type_t* pform_test_type_identifier(const char*txt)
|
void pform_set_type_referenced(const struct vlltype&loc, const char*name)
|
||||||
|
{
|
||||||
|
perm_string lex_name = lex_strings.make(name);
|
||||||
|
check_potential_imports(loc, lex_name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
data_type_t* pform_test_type_identifier(const struct vlltype&loc, const char*txt)
|
||||||
{
|
{
|
||||||
perm_string name = lex_strings.make(txt);
|
perm_string name = lex_strings.make(txt);
|
||||||
|
|
||||||
|
|
@ -798,8 +893,8 @@ data_type_t* pform_test_type_identifier(const char*txt)
|
||||||
// the name has at least shadowed any other possible
|
// the name has at least shadowed any other possible
|
||||||
// meaning for this name.
|
// meaning for this name.
|
||||||
map<perm_string,PPackage*>::iterator cur_pkg;
|
map<perm_string,PPackage*>::iterator cur_pkg;
|
||||||
cur_pkg = cur_scope->imports.find(name);
|
cur_pkg = cur_scope->explicit_imports.find(name);
|
||||||
if (cur_pkg != cur_scope->imports.end()) {
|
if (cur_pkg != cur_scope->explicit_imports.end()) {
|
||||||
PPackage*pkg = cur_pkg->second;
|
PPackage*pkg = cur_pkg->second;
|
||||||
cur = pkg->typedefs.find(name);
|
cur = pkg->typedefs.find(name);
|
||||||
if (cur != pkg->typedefs.end())
|
if (cur != pkg->typedefs.end())
|
||||||
|
|
@ -813,6 +908,16 @@ data_type_t* pform_test_type_identifier(const char*txt)
|
||||||
if (cur != cur_scope->typedefs.end())
|
if (cur != cur_scope->typedefs.end())
|
||||||
return cur->second;
|
return cur->second;
|
||||||
|
|
||||||
|
PPackage*pkg = find_potential_import(loc, cur_scope, name, false, false);
|
||||||
|
if (pkg) {
|
||||||
|
cur = pkg->typedefs.find(name);
|
||||||
|
if (cur != cur_scope->typedefs.end())
|
||||||
|
return cur->second;
|
||||||
|
|
||||||
|
// Not a type. Give up.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
cur_scope = cur_scope->parent_scope();
|
cur_scope = cur_scope->parent_scope();
|
||||||
} while (cur_scope);
|
} while (cur_scope);
|
||||||
|
|
||||||
|
|
@ -841,29 +946,10 @@ PECallFunction* pform_make_call_function(const struct vlltype&loc,
|
||||||
const pform_name_t&name,
|
const pform_name_t&name,
|
||||||
const list<PExpr*>&parms)
|
const list<PExpr*>&parms)
|
||||||
{
|
{
|
||||||
PECallFunction*tmp = 0;
|
if (gn_system_verilog())
|
||||||
|
check_potential_imports(loc, name.front().name, true);
|
||||||
// First try to get the function name from a package. Check
|
|
||||||
// the imports, and if the name is there, make the function as
|
|
||||||
// a package member.
|
|
||||||
do {
|
|
||||||
if (name.size() != 1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
perm_string use_name = peek_tail_name(name);
|
|
||||||
|
|
||||||
map<perm_string,PPackage*>::iterator cur_pkg;
|
|
||||||
cur_pkg = lexical_scope->imports.find(use_name);
|
|
||||||
if (cur_pkg == lexical_scope->imports.end())
|
|
||||||
break;
|
|
||||||
|
|
||||||
tmp = new PECallFunction(cur_pkg->second, use_name, parms);
|
|
||||||
} while(0);
|
|
||||||
|
|
||||||
if (tmp == 0) {
|
|
||||||
tmp = new PECallFunction(name, parms);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
PECallFunction*tmp = new PECallFunction(name, parms);
|
||||||
FILE_NAME(tmp, loc);
|
FILE_NAME(tmp, loc);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -872,26 +958,10 @@ PCallTask* pform_make_call_task(const struct vlltype&loc,
|
||||||
const pform_name_t&name,
|
const pform_name_t&name,
|
||||||
const list<PExpr*>&parms)
|
const list<PExpr*>&parms)
|
||||||
{
|
{
|
||||||
PCallTask*tmp = 0;
|
if (gn_system_verilog())
|
||||||
|
check_potential_imports(loc, name.front().name, true);
|
||||||
do {
|
|
||||||
if (name.size() != 1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
perm_string use_name = peek_tail_name(name);
|
|
||||||
|
|
||||||
map<perm_string,PPackage*>::iterator cur_pkg;
|
|
||||||
cur_pkg = lexical_scope->imports.find(use_name);
|
|
||||||
if (cur_pkg == lexical_scope->imports.end())
|
|
||||||
break;
|
|
||||||
|
|
||||||
tmp = new PCallTask(cur_pkg->second, name, parms);
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
if (tmp == 0) {
|
|
||||||
tmp = new PCallTask(name, parms);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
PCallTask*tmp = new PCallTask(name, parms);
|
||||||
FILE_NAME(tmp, loc);
|
FILE_NAME(tmp, loc);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -1273,6 +1343,8 @@ void pform_startmodule(const struct vlltype&loc, const char*name,
|
||||||
allow_timeunit_decl = true;
|
allow_timeunit_decl = true;
|
||||||
allow_timeprec_decl = true;
|
allow_timeprec_decl = true;
|
||||||
|
|
||||||
|
add_local_symbol(lexical_scope, lex_name, cur_module);
|
||||||
|
|
||||||
lexical_scope = cur_module;
|
lexical_scope = cur_module;
|
||||||
|
|
||||||
/* The generate scheme numbering starts with *1*, not
|
/* The generate scheme numbering starts with *1*, not
|
||||||
|
|
@ -1356,31 +1428,20 @@ void pform_endmodule(const char*name, bool inside_celldefine,
|
||||||
pform_pop_scope();
|
pform_pop_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pform_add_genvar(const struct vlltype&li, const perm_string&name,
|
|
||||||
map<perm_string,LineInfo*>&genvars)
|
|
||||||
{
|
|
||||||
LineInfo*lni = new LineInfo();
|
|
||||||
FILE_NAME(lni, li);
|
|
||||||
if (genvars.find(name) != genvars.end()) {
|
|
||||||
cerr << lni->get_fileline() << ": error: genvar '"
|
|
||||||
<< name << "' has already been declared." << endl;
|
|
||||||
cerr << genvars[name]->get_fileline()
|
|
||||||
<< ": the previous declaration is here." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
delete lni;
|
|
||||||
} else {
|
|
||||||
genvars[name] = lni;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void pform_genvars(const struct vlltype&li, list<perm_string>*names)
|
void pform_genvars(const struct vlltype&li, list<perm_string>*names)
|
||||||
{
|
{
|
||||||
list<perm_string>::const_iterator cur;
|
list<perm_string>::const_iterator cur;
|
||||||
for (cur = names->begin(); cur != names->end() ; *cur++) {
|
for (cur = names->begin(); cur != names->end() ; *cur++) {
|
||||||
if (pform_cur_generate)
|
PGenvar*genvar = new PGenvar();
|
||||||
pform_add_genvar(li, *cur, pform_cur_generate->genvars);
|
FILE_NAME(genvar, li);
|
||||||
else
|
|
||||||
pform_add_genvar(li, *cur, pform_cur_module.front()->genvars);
|
if (pform_cur_generate) {
|
||||||
|
add_local_symbol(pform_cur_generate, *cur, genvar);
|
||||||
|
pform_cur_generate->genvars[*cur] = genvar;
|
||||||
|
} else {
|
||||||
|
add_local_symbol(pform_cur_module.front(), *cur, genvar);
|
||||||
|
pform_cur_module.front()->genvars[*cur] = genvar;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete names;
|
delete names;
|
||||||
|
|
@ -1423,6 +1484,8 @@ void pform_start_generate_if(const struct vlltype&li, PExpr*test)
|
||||||
pform_cur_generate->loop_init = 0;
|
pform_cur_generate->loop_init = 0;
|
||||||
pform_cur_generate->loop_test = test;
|
pform_cur_generate->loop_test = test;
|
||||||
pform_cur_generate->loop_step = 0;
|
pform_cur_generate->loop_step = 0;
|
||||||
|
|
||||||
|
conditional_block_names.push_front(set<perm_string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_start_generate_else(const struct vlltype&li)
|
void pform_start_generate_else(const struct vlltype&li)
|
||||||
|
|
@ -1431,7 +1494,7 @@ void pform_start_generate_else(const struct vlltype&li)
|
||||||
assert(pform_cur_generate->scheme_type == PGenerate::GS_CONDIT);
|
assert(pform_cur_generate->scheme_type == PGenerate::GS_CONDIT);
|
||||||
|
|
||||||
PGenerate*cur = pform_cur_generate;
|
PGenerate*cur = pform_cur_generate;
|
||||||
pform_endgenerate();
|
pform_endgenerate(false);
|
||||||
|
|
||||||
PGenerate*gen = new PGenerate(lexical_scope, scope_generate_counter++);
|
PGenerate*gen = new PGenerate(lexical_scope, scope_generate_counter++);
|
||||||
lexical_scope = gen;
|
lexical_scope = gen;
|
||||||
|
|
@ -1465,6 +1528,8 @@ void pform_start_generate_case(const struct vlltype&li, PExpr*expr)
|
||||||
pform_cur_generate->loop_init = 0;
|
pform_cur_generate->loop_init = 0;
|
||||||
pform_cur_generate->loop_test = expr;
|
pform_cur_generate->loop_test = expr;
|
||||||
pform_cur_generate->loop_step = 0;
|
pform_cur_generate->loop_step = 0;
|
||||||
|
|
||||||
|
conditional_block_names.push_front(set<perm_string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1487,6 +1552,10 @@ void pform_start_generate_nblock(const struct vlltype&li, char*name)
|
||||||
|
|
||||||
pform_cur_generate->scope_name = lex_strings.make(name);
|
pform_cur_generate->scope_name = lex_strings.make(name);
|
||||||
delete[]name;
|
delete[]name;
|
||||||
|
|
||||||
|
add_local_symbol(pform_cur_generate->parent_scope(),
|
||||||
|
pform_cur_generate->scope_name,
|
||||||
|
pform_cur_generate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1528,14 +1597,36 @@ void pform_generate_block_name(char*name)
|
||||||
{
|
{
|
||||||
assert(pform_cur_generate != 0);
|
assert(pform_cur_generate != 0);
|
||||||
assert(pform_cur_generate->scope_name == 0);
|
assert(pform_cur_generate->scope_name == 0);
|
||||||
pform_cur_generate->scope_name = lex_strings.make(name);
|
perm_string scope_name = lex_strings.make(name);
|
||||||
|
pform_cur_generate->scope_name = scope_name;
|
||||||
|
|
||||||
|
if (pform_cur_generate->scheme_type == PGenerate::GS_CONDIT
|
||||||
|
|| pform_cur_generate->scheme_type == PGenerate::GS_ELSE
|
||||||
|
|| pform_cur_generate->scheme_type == PGenerate::GS_CASE_ITEM) {
|
||||||
|
|
||||||
|
if (conditional_block_names.front().count(scope_name))
|
||||||
|
return;
|
||||||
|
|
||||||
|
conditional_block_names.front().insert(scope_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
LexicalScope*parent_scope = pform_cur_generate->parent_scope();
|
||||||
|
assert(parent_scope);
|
||||||
|
if (pform_cur_generate->scheme_type == PGenerate::GS_CASE_ITEM)
|
||||||
|
// Skip over the PGenerate::GS_CASE container.
|
||||||
|
parent_scope = parent_scope->parent_scope();
|
||||||
|
|
||||||
|
add_local_symbol(parent_scope, scope_name, pform_cur_generate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_endgenerate()
|
void pform_endgenerate(bool end_conditional)
|
||||||
{
|
{
|
||||||
assert(pform_cur_generate != 0);
|
assert(pform_cur_generate != 0);
|
||||||
assert(! pform_cur_module.empty());
|
assert(! pform_cur_module.empty());
|
||||||
|
|
||||||
|
if (end_conditional)
|
||||||
|
conditional_block_names.pop_front();
|
||||||
|
|
||||||
// If there is no explicit block name then generate a temporary
|
// If there is no explicit block name then generate a temporary
|
||||||
// name. This will be replaced by the correct name later, once
|
// name. This will be replaced by the correct name later, once
|
||||||
// we know all the explicit names in the surrounding scope. If
|
// we know all the explicit names in the surrounding scope. If
|
||||||
|
|
@ -2024,18 +2115,10 @@ static void pform_set_net_range(list<perm_string>*names,
|
||||||
*/
|
*/
|
||||||
static void pform_make_event(perm_string name, const char*fn, unsigned ln)
|
static void pform_make_event(perm_string name, const char*fn, unsigned ln)
|
||||||
{
|
{
|
||||||
// Check if the named event is already in the dictionary.
|
|
||||||
if (lexical_scope->events.find(name) != lexical_scope->events.end()) {
|
|
||||||
LineInfo tloc;
|
|
||||||
FILE_NAME(&tloc, fn, ln);
|
|
||||||
cerr << tloc.get_fileline() << ": error: duplicate definition "
|
|
||||||
"for named event '" << name << "' in '"
|
|
||||||
<< pform_cur_module.front()->mod_name() << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
PEvent*event = new PEvent(name);
|
PEvent*event = new PEvent(name);
|
||||||
FILE_NAME(event, fn, ln);
|
FILE_NAME(event, fn, ln);
|
||||||
|
|
||||||
|
add_local_symbol(lexical_scope, name, event);
|
||||||
lexical_scope->events[name] = event;
|
lexical_scope->events[name] = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2089,10 +2172,13 @@ static void pform_makegate(PGBuiltin::Type type,
|
||||||
cur->strength1(str.str1);
|
cur->strength1(str.str1);
|
||||||
FILE_NAME(cur, info.file, info.lineno);
|
FILE_NAME(cur, info.file, info.lineno);
|
||||||
|
|
||||||
if (pform_cur_generate)
|
if (pform_cur_generate) {
|
||||||
|
if (dev_name != "") add_local_symbol(pform_cur_generate, dev_name, cur);
|
||||||
pform_cur_generate->add_gate(cur);
|
pform_cur_generate->add_gate(cur);
|
||||||
else
|
} else {
|
||||||
|
if (dev_name != "") add_local_symbol(pform_cur_module.front(), dev_name, cur);
|
||||||
pform_cur_module.front()->add_gate(cur);
|
pform_cur_module.front()->add_gate(cur);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_makegates(const struct vlltype&loc,
|
void pform_makegates(const struct vlltype&loc,
|
||||||
|
|
@ -2169,10 +2255,13 @@ static void pform_make_modgate(perm_string type,
|
||||||
cur->set_parameters(overrides->by_order);
|
cur->set_parameters(overrides->by_order);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pform_cur_generate)
|
if (pform_cur_generate) {
|
||||||
|
if (name != "") add_local_symbol(pform_cur_generate, name, cur);
|
||||||
pform_cur_generate->add_gate(cur);
|
pform_cur_generate->add_gate(cur);
|
||||||
else
|
} else {
|
||||||
|
if (name != "") add_local_symbol(pform_cur_module.front(), name, cur);
|
||||||
pform_cur_module.front()->add_gate(cur);
|
pform_cur_module.front()->add_gate(cur);
|
||||||
|
}
|
||||||
pform_bind_attributes(cur->attributes, attr);
|
pform_bind_attributes(cur->attributes, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2214,11 +2303,13 @@ static void pform_make_modgate(perm_string type,
|
||||||
cur->set_parameters(overrides->by_order);
|
cur->set_parameters(overrides->by_order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pform_cur_generate) {
|
||||||
if (pform_cur_generate)
|
add_local_symbol(pform_cur_generate, name, cur);
|
||||||
pform_cur_generate->add_gate(cur);
|
pform_cur_generate->add_gate(cur);
|
||||||
else
|
} else {
|
||||||
|
add_local_symbol(pform_cur_module.front(), name, cur);
|
||||||
pform_cur_module.front()->add_gate(cur);
|
pform_cur_module.front()->add_gate(cur);
|
||||||
|
}
|
||||||
pform_bind_attributes(cur->attributes, attr);
|
pform_bind_attributes(cur->attributes, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2554,20 +2645,15 @@ static PWire* pform_get_or_make_wire(const vlltype&li, perm_string name,
|
||||||
|
|
||||||
// If the wire already exists and is fully defined, this
|
// If the wire already exists and is fully defined, this
|
||||||
// must be a redeclaration. Start again with a new wire.
|
// must be a redeclaration. Start again with a new wire.
|
||||||
if (cur) {
|
// The error will be reported when we add the new wire
|
||||||
LineInfo tloc;
|
// to the scope. Do not delete the old wire - it will
|
||||||
FILE_NAME(&tloc, li);
|
// remain in the local symbol map.
|
||||||
cerr << tloc.get_fileline() << ": error: duplicate declaration "
|
|
||||||
"for net or variable '" << name << "' in '"
|
|
||||||
<< pform_cur_module.front()->mod_name() << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
delete cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur = new PWire(name, type, ptype, dtype);
|
cur = new PWire(name, type, ptype, dtype);
|
||||||
FILE_NAME(cur, li.text, li.first_line);
|
FILE_NAME(cur, li.text, li.first_line);
|
||||||
|
|
||||||
pform_put_wire_in_scope(name, cur);
|
pform_put_wire_in_scope(name, cur);
|
||||||
|
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3021,63 +3107,33 @@ void pform_set_parameter(const struct vlltype&loc,
|
||||||
VLerror("parameter declarations are not permitted in generate blocks");
|
VLerror("parameter declarations are not permitted in generate blocks");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PScopeExtra*scopex = find_nearest_scopex(lexical_scope);
|
|
||||||
assert(scopex);
|
|
||||||
|
|
||||||
// Check if the parameter name is already in the dictionary.
|
|
||||||
if (scope->parameters.find(name) != scope->parameters.end()) {
|
|
||||||
LineInfo tloc;
|
|
||||||
FILE_NAME(&tloc, loc);
|
|
||||||
cerr << tloc.get_fileline() << ": error: duplicate definition "
|
|
||||||
"for parameter '" << name << "' in '"
|
|
||||||
<< scopex->pscope_name() << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
if (scope->localparams.find(name) != scope->localparams.end()) {
|
|
||||||
LineInfo tloc;
|
|
||||||
FILE_NAME(&tloc, loc);
|
|
||||||
cerr << tloc.get_fileline() << ": error: localparam and "
|
|
||||||
<< "parameter in '" << scopex->pscope_name()
|
|
||||||
<< "' have the same name '" << name << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
// Only a Module scope has specparams.
|
|
||||||
if ((dynamic_cast<Module*> (scope)) &&
|
|
||||||
(scope == pform_cur_module.front()) &&
|
|
||||||
(pform_cur_module.front()->specparams.find(name) !=
|
|
||||||
pform_cur_module.front()->specparams.end())) {
|
|
||||||
LineInfo tloc;
|
|
||||||
FILE_NAME(&tloc, loc);
|
|
||||||
cerr << tloc.get_fileline() << ": error: specparam and "
|
|
||||||
"parameter in '" << scopex->pscope_name()
|
|
||||||
<< "' have the same name '" << name << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(expr);
|
assert(expr);
|
||||||
Module::param_expr_t&parm = scope->parameters[name];
|
Module::param_expr_t*parm = new Module::param_expr_t();
|
||||||
FILE_NAME(&parm, loc);
|
FILE_NAME(parm, loc);
|
||||||
|
|
||||||
parm.expr = expr;
|
add_local_symbol(scope, name, parm);
|
||||||
|
scope->parameters[name] = parm;
|
||||||
|
|
||||||
parm.type = type;
|
parm->expr = expr;
|
||||||
|
|
||||||
|
parm->type = type;
|
||||||
if (range) {
|
if (range) {
|
||||||
assert(range->size() == 1);
|
assert(range->size() == 1);
|
||||||
pform_range_t&rng = range->front();
|
pform_range_t&rng = range->front();
|
||||||
assert(rng.first);
|
assert(rng.first);
|
||||||
assert(rng.second);
|
assert(rng.second);
|
||||||
parm.msb = rng.first;
|
parm->msb = rng.first;
|
||||||
parm.lsb = rng.second;
|
parm->lsb = rng.second;
|
||||||
} else {
|
} else {
|
||||||
parm.msb = 0;
|
parm->msb = 0;
|
||||||
parm.lsb = 0;
|
parm->lsb = 0;
|
||||||
}
|
}
|
||||||
parm.signed_flag = signed_flag;
|
parm->signed_flag = signed_flag;
|
||||||
parm.range = value_range;
|
parm->range = value_range;
|
||||||
|
|
||||||
// Only a Module keeps the position of the parameter.
|
// Only a Module keeps the position of the parameter.
|
||||||
if ((dynamic_cast<Module*> (scope)) &&
|
if ((dynamic_cast<Module*>(scope)) && (scope == pform_cur_module.front()))
|
||||||
(scope == pform_cur_module.front()))
|
|
||||||
pform_cur_module.front()->param_names.push_back(name);
|
pform_cur_module.front()->param_names.push_back(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3090,58 +3146,30 @@ void pform_set_localparam(const struct vlltype&loc,
|
||||||
VLerror(loc, "error: localparam declarations must be contained within a module.");
|
VLerror(loc, "error: localparam declarations must be contained within a module.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PScopeExtra*scopex = find_nearest_scopex(lexical_scope);
|
|
||||||
assert(scopex);
|
|
||||||
|
|
||||||
// Check if the localparam name is already in the dictionary.
|
|
||||||
if (scope->localparams.find(name) != scope->localparams.end()) {
|
|
||||||
LineInfo tloc;
|
|
||||||
FILE_NAME(&tloc, loc);
|
|
||||||
cerr << tloc.get_fileline() << ": error: duplicate definition "
|
|
||||||
"for localparam '" << name << "' in '"
|
|
||||||
<< scopex->pscope_name() << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
if (scope->parameters.find(name) != scope->parameters.end()) {
|
|
||||||
LineInfo tloc;
|
|
||||||
FILE_NAME(&tloc, loc);
|
|
||||||
cerr << tloc.get_fileline() << ": error: parameter and "
|
|
||||||
<< "localparam in '" << scopex->pscope_name()
|
|
||||||
<< "' have the same name '" << name << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((! pform_cur_module.empty()) &&
|
|
||||||
(scope == pform_cur_module.front()) &&
|
|
||||||
(pform_cur_module.front()->specparams.find(name) != pform_cur_module.front()->specparams.end())) {
|
|
||||||
LineInfo tloc;
|
|
||||||
FILE_NAME(&tloc, loc);
|
|
||||||
cerr << tloc.get_fileline() << ": error: specparam and "
|
|
||||||
"localparam in '" << scopex->pscope_name()
|
|
||||||
<< "' have the same name '" << name << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(expr);
|
assert(expr);
|
||||||
Module::param_expr_t&parm = scope->localparams[name];
|
Module::param_expr_t*parm = new Module::param_expr_t();
|
||||||
FILE_NAME(&parm, loc);
|
FILE_NAME(parm, loc);
|
||||||
|
|
||||||
parm.expr = expr;
|
add_local_symbol(scope, name, parm);
|
||||||
|
scope->localparams[name] = parm;
|
||||||
|
|
||||||
parm.type = type;
|
parm->expr = expr;
|
||||||
|
|
||||||
|
parm->type = type;
|
||||||
if (range) {
|
if (range) {
|
||||||
assert(range->size() == 1);
|
assert(range->size() == 1);
|
||||||
pform_range_t&rng = range->front();
|
pform_range_t&rng = range->front();
|
||||||
assert(rng.first);
|
assert(rng.first);
|
||||||
assert(rng.second);
|
assert(rng.second);
|
||||||
parm.msb = rng.first;
|
parm->msb = rng.first;
|
||||||
parm.lsb = rng.second;
|
parm->lsb = rng.second;
|
||||||
} else {
|
} else {
|
||||||
parm.msb = 0;
|
parm->msb = 0;
|
||||||
parm.lsb = 0;
|
parm->lsb = 0;
|
||||||
}
|
}
|
||||||
parm.signed_flag = signed_flag;
|
parm->signed_flag = signed_flag;
|
||||||
parm.range = 0;
|
parm->range = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_specparam(const struct vlltype&loc, perm_string name,
|
void pform_set_specparam(const struct vlltype&loc, perm_string name,
|
||||||
|
|
@ -3151,55 +3179,30 @@ void pform_set_specparam(const struct vlltype&loc, perm_string name,
|
||||||
Module*scope = pform_cur_module.front();
|
Module*scope = pform_cur_module.front();
|
||||||
assert(scope == lexical_scope);
|
assert(scope == lexical_scope);
|
||||||
|
|
||||||
// Check if the specparam name is already in the dictionary.
|
|
||||||
if (pform_cur_module.front()->specparams.find(name) !=
|
|
||||||
pform_cur_module.front()->specparams.end()) {
|
|
||||||
LineInfo tloc;
|
|
||||||
FILE_NAME(&tloc, loc);
|
|
||||||
cerr << tloc.get_fileline() << ": error: duplicate definition "
|
|
||||||
"for specparam '" << name << "' in '"
|
|
||||||
<< pform_cur_module.front()->mod_name() << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
if (scope->parameters.find(name) != scope->parameters.end()) {
|
|
||||||
LineInfo tloc;
|
|
||||||
FILE_NAME(&tloc, loc);
|
|
||||||
cerr << tloc.get_fileline() << ": error: parameter and "
|
|
||||||
"specparam in '" << pform_cur_module.front()->mod_name()
|
|
||||||
<< "' have the same name '" << name << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
if (scope->localparams.find(name) != scope->localparams.end()) {
|
|
||||||
LineInfo tloc;
|
|
||||||
FILE_NAME(&tloc, loc);
|
|
||||||
cerr << tloc.get_fileline() << ": error: localparam and "
|
|
||||||
"specparam in '" << pform_cur_module.front()->mod_name()
|
|
||||||
<< "' have the same name '" << name << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(expr);
|
assert(expr);
|
||||||
|
Module::param_expr_t*parm = new Module::param_expr_t();
|
||||||
|
FILE_NAME(parm, loc);
|
||||||
|
|
||||||
Module::param_expr_t&parm = pform_cur_module.front()->specparams[name];
|
add_local_symbol(scope, name, parm);
|
||||||
FILE_NAME(&parm, loc);
|
pform_cur_module.front()->specparams[name] = parm;
|
||||||
|
|
||||||
parm.expr = expr;
|
parm->expr = expr;
|
||||||
|
|
||||||
if (range) {
|
if (range) {
|
||||||
assert(range->size() == 1);
|
assert(range->size() == 1);
|
||||||
pform_range_t&rng = range->front();
|
pform_range_t&rng = range->front();
|
||||||
assert(rng.first);
|
assert(rng.first);
|
||||||
assert(rng.second);
|
assert(rng.second);
|
||||||
parm.type = IVL_VT_LOGIC;
|
parm->type = IVL_VT_LOGIC;
|
||||||
parm.msb = rng.first;
|
parm->msb = rng.first;
|
||||||
parm.lsb = rng.second;
|
parm->lsb = rng.second;
|
||||||
} else {
|
} else {
|
||||||
parm.type = IVL_VT_NO_TYPE;
|
parm->type = IVL_VT_NO_TYPE;
|
||||||
parm.msb = 0;
|
parm->msb = 0;
|
||||||
parm.lsb = 0;
|
parm->lsb = 0;
|
||||||
}
|
}
|
||||||
parm.signed_flag = false;
|
parm->signed_flag = false;
|
||||||
parm.range = 0;
|
parm->range = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_defparam(const pform_name_t&name, PExpr*expr)
|
void pform_set_defparam(const pform_name_t&name, PExpr*expr)
|
||||||
|
|
@ -3621,12 +3624,10 @@ void pform_start_modport_item(const struct vlltype&loc, const char*name)
|
||||||
perm_string use_name = lex_strings.make(name);
|
perm_string use_name = lex_strings.make(name);
|
||||||
pform_cur_modport = new PModport(use_name);
|
pform_cur_modport = new PModport(use_name);
|
||||||
FILE_NAME(pform_cur_modport, loc);
|
FILE_NAME(pform_cur_modport, loc);
|
||||||
if (scope->modports.find(use_name) != scope->modports.end()) {
|
|
||||||
cerr << loc << ": error: duplicate declaration for modport '"
|
add_local_symbol(scope, use_name, pform_cur_modport);
|
||||||
<< name << "' in '" << scope->mod_name() << "'." << endl;
|
|
||||||
error_count += 1;
|
|
||||||
}
|
|
||||||
scope->modports[use_name] = pform_cur_modport;
|
scope->modports[use_name] = pform_cur_modport;
|
||||||
|
|
||||||
delete[] name;
|
delete[] name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
17
pform.h
17
pform.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_pform_H
|
#ifndef IVL_pform_H
|
||||||
#define IVL_pform_H
|
#define IVL_pform_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2019 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
|
||||||
|
|
@ -246,7 +246,10 @@ extern void pform_add_modport_port(const struct vlltype&loc,
|
||||||
* This creates an identifier aware of names that may have been
|
* This creates an identifier aware of names that may have been
|
||||||
* imported from other packages.
|
* imported from other packages.
|
||||||
*/
|
*/
|
||||||
extern PEIdent* pform_new_ident(const pform_name_t&name);
|
extern PEIdent* pform_new_ident(const struct vlltype&loc, const pform_name_t&name);
|
||||||
|
|
||||||
|
extern PTrigger* pform_new_trigger(const struct vlltype&loc, PPackage*pkg,
|
||||||
|
const pform_name_t&name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enter/exit name scopes. The push_scope function pushes the scope
|
* Enter/exit name scopes. The push_scope function pushes the scope
|
||||||
|
|
@ -274,7 +277,8 @@ extern PTask*pform_push_task_scope(const struct vlltype&loc, char*name,
|
||||||
extern PFunction*pform_push_function_scope(const struct vlltype&loc, const char*name,
|
extern PFunction*pform_push_function_scope(const struct vlltype&loc, const char*name,
|
||||||
LexicalScope::lifetime_t lifetime);
|
LexicalScope::lifetime_t lifetime);
|
||||||
|
|
||||||
extern PBlock*pform_push_block_scope(char*name, PBlock::BL_TYPE tt);
|
extern PBlock*pform_push_block_scope(const struct vlltype&loc, char*name,
|
||||||
|
PBlock::BL_TYPE tt);
|
||||||
|
|
||||||
extern void pform_put_behavior_in_scope(AProcess*proc);
|
extern void pform_put_behavior_in_scope(AProcess*proc);
|
||||||
|
|
||||||
|
|
@ -299,7 +303,7 @@ extern void pform_start_generate_case(const struct vlltype&lp, PExpr*test);
|
||||||
extern void pform_start_generate_nblock(const struct vlltype&lp, char*name);
|
extern void pform_start_generate_nblock(const struct vlltype&lp, char*name);
|
||||||
extern void pform_generate_case_item(const struct vlltype&lp, list<PExpr*>*test);
|
extern void pform_generate_case_item(const struct vlltype&lp, list<PExpr*>*test);
|
||||||
extern void pform_generate_block_name(char*name);
|
extern void pform_generate_block_name(char*name);
|
||||||
extern void pform_endgenerate();
|
extern void pform_endgenerate(bool end_conditional);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function returns the lexically containing generate scheme, if
|
* This function returns the lexically containing generate scheme, if
|
||||||
|
|
@ -311,9 +315,10 @@ extern PGenerate* pform_parent_generate(void);
|
||||||
extern void pform_set_typedef(perm_string name, data_type_t*data_type,
|
extern void pform_set_typedef(perm_string name, data_type_t*data_type,
|
||||||
std::list<pform_range_t>*unp_ranges);
|
std::list<pform_range_t>*unp_ranges);
|
||||||
|
|
||||||
|
extern void pform_set_type_referenced(const struct vlltype&loc, const char*name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function makes a PECallFunction of the named function. Decide
|
* This function makes a PECallFunction of the named function.
|
||||||
* if this function is in the scope or is imported from a package.
|
|
||||||
*/
|
*/
|
||||||
extern PECallFunction* pform_make_call_function(const struct vlltype&loc,
|
extern PECallFunction* pform_make_call_function(const struct vlltype&loc,
|
||||||
const pform_name_t&name,
|
const pform_name_t&name,
|
||||||
|
|
|
||||||
|
|
@ -1359,22 +1359,22 @@ void LexicalScope::dump_typedefs_(ostream&out, unsigned indent) const
|
||||||
|
|
||||||
void LexicalScope::dump_parameters_(ostream&out, unsigned indent) const
|
void LexicalScope::dump_parameters_(ostream&out, unsigned indent) const
|
||||||
{
|
{
|
||||||
typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t;
|
typedef map<perm_string,param_expr_t*>::const_iterator parm_iter_t;
|
||||||
for (parm_iter_t cur = parameters.begin()
|
for (parm_iter_t cur = parameters.begin()
|
||||||
; cur != parameters.end() ; ++ cur ) {
|
; cur != parameters.end() ; ++ cur ) {
|
||||||
out << setw(indent) << "" << "parameter "
|
out << setw(indent) << "" << "parameter "
|
||||||
<< (*cur).second.type << " ";
|
<< (*cur).second->type << " ";
|
||||||
if ((*cur).second.signed_flag)
|
if ((*cur).second->signed_flag)
|
||||||
out << "signed ";
|
out << "signed ";
|
||||||
if ((*cur).second.msb)
|
if ((*cur).second->msb)
|
||||||
out << "[" << *(*cur).second.msb << ":"
|
out << "[" << *(*cur).second->msb << ":"
|
||||||
<< *(*cur).second.lsb << "] ";
|
<< *(*cur).second->lsb << "] ";
|
||||||
out << (*cur).first << " = ";
|
out << (*cur).first << " = ";
|
||||||
if ((*cur).second.expr)
|
if ((*cur).second->expr)
|
||||||
out << *(*cur).second.expr;
|
out << *(*cur).second->expr;
|
||||||
else
|
else
|
||||||
out << "/* ERROR */";
|
out << "/* ERROR */";
|
||||||
for (LexicalScope::range_t*tmp = (*cur).second.range
|
for (LexicalScope::range_t*tmp = (*cur).second->range
|
||||||
; tmp ; tmp = tmp->next) {
|
; tmp ; tmp = tmp->next) {
|
||||||
if (tmp->exclude_flag)
|
if (tmp->exclude_flag)
|
||||||
out << " exclude ";
|
out << " exclude ";
|
||||||
|
|
@ -1408,16 +1408,16 @@ void LexicalScope::dump_parameters_(ostream&out, unsigned indent) const
|
||||||
|
|
||||||
void LexicalScope::dump_localparams_(ostream&out, unsigned indent) const
|
void LexicalScope::dump_localparams_(ostream&out, unsigned indent) const
|
||||||
{
|
{
|
||||||
typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t;
|
typedef map<perm_string,param_expr_t*>::const_iterator parm_iter_t;
|
||||||
for (parm_iter_t cur = localparams.begin()
|
for (parm_iter_t cur = localparams.begin()
|
||||||
; cur != localparams.end() ; ++ cur ) {
|
; cur != localparams.end() ; ++ cur ) {
|
||||||
out << setw(indent) << "" << "localparam ";
|
out << setw(indent) << "" << "localparam ";
|
||||||
if ((*cur).second.msb)
|
if ((*cur).second->msb)
|
||||||
out << "[" << *(*cur).second.msb << ":"
|
out << "[" << *(*cur).second->msb << ":"
|
||||||
<< *(*cur).second.lsb << "] ";
|
<< *(*cur).second->lsb << "] ";
|
||||||
out << (*cur).first << " = ";
|
out << (*cur).first << " = ";
|
||||||
if ((*cur).second.expr)
|
if ((*cur).second->expr)
|
||||||
out << *(*cur).second.expr << ";" << endl;
|
out << *(*cur).second->expr << ";" << endl;
|
||||||
else
|
else
|
||||||
out << "/* ERROR */;" << endl;
|
out << "/* ERROR */;" << endl;
|
||||||
}
|
}
|
||||||
|
|
@ -1513,16 +1513,16 @@ void PClass::dump(ostream&out, unsigned indent) const
|
||||||
|
|
||||||
void Module::dump_specparams_(ostream&out, unsigned indent) const
|
void Module::dump_specparams_(ostream&out, unsigned indent) const
|
||||||
{
|
{
|
||||||
typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t;
|
typedef map<perm_string,param_expr_t*>::const_iterator parm_iter_t;
|
||||||
for (parm_iter_t cur = specparams.begin()
|
for (parm_iter_t cur = specparams.begin()
|
||||||
; cur != specparams.end() ; ++ cur ) {
|
; cur != specparams.end() ; ++ cur ) {
|
||||||
out << setw(indent) << "" << "specparam ";
|
out << setw(indent) << "" << "specparam ";
|
||||||
if ((*cur).second.msb)
|
if ((*cur).second->msb)
|
||||||
out << "[" << *(*cur).second.msb << ":"
|
out << "[" << *(*cur).second->msb << ":"
|
||||||
<< *(*cur).second.lsb << "] ";
|
<< *(*cur).second->lsb << "] ";
|
||||||
out << (*cur).first << " = ";
|
out << (*cur).first << " = ";
|
||||||
if ((*cur).second.expr)
|
if ((*cur).second->expr)
|
||||||
out << *(*cur).second.expr << ";" << endl;
|
out << *(*cur).second->expr << ";" << endl;
|
||||||
else
|
else
|
||||||
out << "/* ERROR */;" << endl;
|
out << "/* ERROR */;" << endl;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
112
pform_package.cc
112
pform_package.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012-2016 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2012-2019 Stephen Williams (steve@icarus.com)
|
||||||
* Copyright CERN 2013 Stephen Williams (steve@icarus.com)
|
* Copyright CERN 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
|
||||||
|
|
@ -72,98 +72,58 @@ void pform_end_package_declaration(const struct vlltype&loc)
|
||||||
* package is declared in pform ahead of time (it is) and that we can
|
* package is declared in pform ahead of time (it is) and that we can
|
||||||
* simply transfer definitions to the current scope (we can).
|
* simply transfer definitions to the current scope (we can).
|
||||||
*/
|
*/
|
||||||
void pform_package_import(const struct vlltype&, PPackage*pkg, const char*ident)
|
void pform_package_import(const struct vlltype&loc, PPackage*pkg, const char*ident)
|
||||||
{
|
{
|
||||||
LexicalScope*scope = pform_peek_scope();
|
LexicalScope*scope = pform_peek_scope();
|
||||||
|
|
||||||
if (ident) {
|
if (ident) {
|
||||||
perm_string use_ident = lex_strings.make(ident);
|
perm_string use_ident = lex_strings.make(ident);
|
||||||
|
|
||||||
map<perm_string,LexicalScope::param_expr_t>::const_iterator cur
|
// Check that the requested symbol is available.
|
||||||
= pkg->parameters.find(use_ident);
|
map<perm_string,PNamedItem*>::const_iterator cur_sym
|
||||||
if (cur != pkg->parameters.end()) {
|
= pkg->local_symbols.find(use_ident);
|
||||||
scope->imports[cur->first] = pkg;
|
if (cur_sym == pkg->local_symbols.end()) {
|
||||||
|
cerr << loc.get_fileline() << ": error: "
|
||||||
|
"'" << use_ident << "' is not exported by '"
|
||||||
|
<< pkg->pscope_name() << "'." << endl;
|
||||||
|
error_count += 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur = pkg->localparams.find(use_ident);
|
// Check for conflict with local symbol.
|
||||||
if (cur != pkg->localparams.end()) {
|
cur_sym = scope->local_symbols.find(use_ident);
|
||||||
scope->imports[cur->first] = pkg;
|
if (cur_sym != scope->local_symbols.end()) {
|
||||||
|
cerr << loc.get_fileline() << ": error: "
|
||||||
|
"'" << use_ident << "' has already been declared "
|
||||||
|
"in this scope." << endl;
|
||||||
|
cerr << cur_sym->second->get_fileline() << ": : "
|
||||||
|
"It was declared here as "
|
||||||
|
<< cur_sym->second->symbol_type() << "." << endl;
|
||||||
|
error_count += 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
map<perm_string,data_type_t*>::const_iterator tcur;
|
// Check for conflict with previous import.
|
||||||
tcur = pkg->typedefs.find(use_ident);
|
map<perm_string,PPackage*>::const_iterator cur_pkg
|
||||||
if (tcur != pkg->typedefs.end()) {
|
= scope->explicit_imports.find(use_ident);
|
||||||
scope->imports[tcur->first] = pkg;
|
if (cur_pkg != scope->explicit_imports.end()) {
|
||||||
|
if (cur_pkg->second != pkg) {
|
||||||
|
cerr << loc.get_fileline() << ": error: "
|
||||||
|
"'" << use_ident << "' has already been "
|
||||||
|
"imported into this scope from package '"
|
||||||
|
<< cur_pkg->second->pscope_name() << "'." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
map<perm_string,PFunction*>::const_iterator fcur;
|
scope->explicit_imports[use_ident] = pkg;
|
||||||
fcur = pkg->funcs.find(use_ident);
|
|
||||||
if (fcur != pkg->funcs.end()) {
|
|
||||||
scope->imports[fcur->first] = pkg;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
map<perm_string,PTask*>::const_iterator ttcur;
|
|
||||||
ttcur = pkg->tasks.find(use_ident);
|
|
||||||
if (ttcur != pkg->tasks.end()) {
|
|
||||||
scope->imports[ttcur->first] = pkg;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
map<perm_string,PWire*>::const_iterator wcur;
|
|
||||||
wcur = pkg->wires.find(use_ident);
|
|
||||||
if (wcur != pkg->wires.end()) {
|
|
||||||
scope->imports[wcur->first] = pkg;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ostringstream msg;
|
|
||||||
msg << "Symbol " << use_ident
|
|
||||||
<< " not found in package " << pkg->pscope_name() << "." << ends;
|
|
||||||
VLerror(msg.str().c_str());
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
set<PPackage*>::const_iterator cur_pkg
|
||||||
// Handle the pkg::* case by importing everything from
|
= scope->potential_imports.find(pkg);
|
||||||
// the package.
|
if (cur_pkg == scope->potential_imports.end())
|
||||||
for (map<perm_string,LexicalScope::param_expr_t>::const_iterator cur = pkg->parameters.begin()
|
scope->potential_imports.insert(pkg);
|
||||||
; cur != pkg->parameters.end() ; ++cur) {
|
|
||||||
|
|
||||||
scope->imports[cur->first] = pkg;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (map<perm_string,LexicalScope::param_expr_t>::const_iterator cur = pkg->localparams.begin()
|
|
||||||
; cur != pkg->localparams.end() ; ++cur) {
|
|
||||||
|
|
||||||
scope->imports[cur->first] = pkg;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (map<perm_string,data_type_t*>::const_iterator cur = pkg->typedefs.begin()
|
|
||||||
; cur != pkg->typedefs.end() ; ++cur) {
|
|
||||||
|
|
||||||
scope->imports[cur->first] = pkg;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (map<perm_string,PFunction*>::const_iterator cur = pkg->funcs.begin()
|
|
||||||
; cur != pkg->funcs.end() ; ++cur) {
|
|
||||||
|
|
||||||
scope->imports[cur->first] = pkg;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (map<perm_string,PWire*>::const_iterator cur = pkg->wires.begin()
|
|
||||||
; cur != pkg->wires.end() ; ++cur) {
|
|
||||||
|
|
||||||
scope->imports[cur->first] = pkg;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (set<enum_type_t*>::const_iterator cur = pkg->enum_sets.begin()
|
|
||||||
; cur != pkg->enum_sets.end() ; ++ cur) {
|
|
||||||
scope->enum_sets.insert(*cur);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2008 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2007-2019 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
|
||||||
|
|
@ -24,6 +24,11 @@ data_type_t::~data_type_t()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType data_type_t::symbol_type() const
|
||||||
|
{
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
string_type_t::~string_type_t()
|
string_type_t::~string_type_t()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -44,3 +49,13 @@ ivl_variable_type_t vector_type_t::figure_packed_base_type(void) const
|
||||||
}
|
}
|
||||||
|
|
||||||
atom2_type_t size_type (32, true);
|
atom2_type_t size_type (32, true);
|
||||||
|
|
||||||
|
PNamedItem::SymbolType enum_type_t::symbol_type() const
|
||||||
|
{
|
||||||
|
return ENUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
PNamedItem::SymbolType class_type_t::symbol_type() const
|
||||||
|
{
|
||||||
|
return CLASS;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_pform_types_H
|
#ifndef IVL_pform_types_H
|
||||||
#define IVL_pform_types_H
|
#define IVL_pform_types_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2018 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2007-2019 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
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
// This for the perm_string type.
|
// This for the perm_string type.
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
# include "LineInfo.h"
|
# include "PNamedItem.h"
|
||||||
# include "verinum.h"
|
# include "verinum.h"
|
||||||
# include "named.h"
|
# include "named.h"
|
||||||
# include "netstruct.h"
|
# include "netstruct.h"
|
||||||
|
|
@ -137,7 +137,7 @@ struct pform_tf_port_t {
|
||||||
* "data_type" rule in the parse rule. We make the type virtual so
|
* "data_type" rule in the parse rule. We make the type virtual so
|
||||||
* that dynamic types will work.
|
* that dynamic types will work.
|
||||||
*/
|
*/
|
||||||
class data_type_t : public LineInfo {
|
class data_type_t : public PNamedItem {
|
||||||
public:
|
public:
|
||||||
inline explicit data_type_t() { }
|
inline explicit data_type_t() { }
|
||||||
virtual ~data_type_t() = 0;
|
virtual ~data_type_t() = 0;
|
||||||
|
|
@ -149,6 +149,8 @@ class data_type_t : public LineInfo {
|
||||||
|
|
||||||
ivl_type_s* elaborate_type(Design*des, NetScope*scope);
|
ivl_type_s* elaborate_type(Design*des, NetScope*scope);
|
||||||
|
|
||||||
|
virtual SymbolType symbol_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Elaborate the type to an ivl_type_s type.
|
// Elaborate the type to an ivl_type_s type.
|
||||||
virtual ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
|
virtual ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
|
||||||
|
|
@ -171,6 +173,8 @@ struct enum_type_t : public data_type_t {
|
||||||
// Return the elaborated version of the type.
|
// Return the elaborated version of the type.
|
||||||
virtual ivl_type_s*elaborate_type_raw(Design*des, NetScope*scope) const;
|
virtual ivl_type_s*elaborate_type_raw(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
|
SymbolType symbol_type() const;
|
||||||
|
|
||||||
ivl_variable_type_t base_type;
|
ivl_variable_type_t base_type;
|
||||||
bool signed_flag;
|
bool signed_flag;
|
||||||
bool integer_flag; // True if "integer" was used
|
bool integer_flag; // True if "integer" was used
|
||||||
|
|
@ -335,6 +339,8 @@ struct class_type_t : public data_type_t {
|
||||||
// type. The elaborate_type_raw() method uses this pointer,
|
// type. The elaborate_type_raw() method uses this pointer,
|
||||||
// and it is used in some other situations as well.
|
// and it is used in some other situations as well.
|
||||||
netclass_t* save_elaborated_type;
|
netclass_t* save_elaborated_type;
|
||||||
|
|
||||||
|
virtual SymbolType symbol_type() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2003-2019 Stephen Williams (steve@icarus.com)
|
||||||
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
* Copyright CERN 2012 / 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
|
||||||
|
|
@ -132,6 +132,11 @@ static bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NetScope*import_scope = scope->find_import(des, path_tail.name)) {
|
||||||
|
scope = import_scope;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (recurse_flag) {
|
if (recurse_flag) {
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
hname_t path_item = eval_path_component(des, start_scope, path_tail, flag);
|
hname_t path_item = eval_path_component(des, start_scope, path_tail, flag);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue