This is an old revision of the document!
Namespaces
Namespaces are used as a mechanism to prevent naming conflicts when
multiple people are working on a design. While ACT can be used
without any namespaces (in which case everything is defined and
created in the default namespace Global
), most large designs
will contain structure that can be used to keep the ACT files
clean and modular.
Creating a namespace
A namespace is created by using the namespace
construct.
namespace lib { ... export defproc buffer (a1of2? l; a1of2! r) { ... } ... }
The process buffer
has been created in the namespace
lib
, and it's fully qualified name is
::lib::buffer
. This syntax is similar to the one used by
C++.
An ACT type or instance is first evaluated in the current namespace; if it doesn't exist in the current namespace, then the global namespace is searched next.
A namespace typically contains user-defined types. By default, these
types are only visible within the current namespace. To allow a type
to be visible in any other namespace, it must be prefaced by the
export
keyword (as above).
A namespace can also contain another namespace. However, these namespaces do not have special privileges. An example of nested namespaces is shown below.
namespace datapath { export defproc bus_interface(...) { ... } namespace adder { export defproc alu(...) { bus_interface b; } } ... }
Nesting does not give a namespace special permissions; if the
bus_interface
definition was not export
ed, then the
namespace adder
within it would not be able to reference
bus_interface
. However, notice that the type
bus_interface
within alu
did not require its fully
qualified name, due to the fact that the definition is in scope due to
nesting.
alu
cannot be referenced from the global namespace using
datapath::adder::alu
. Although alu
is exported from the
namespace datapath::adder
, the export
directive only
exports the definition one level up. To export this another level out,
the entire namespace adder
can be exported as follows:
namespace datapath { export defproc bus_interface(...) { ... } export namespace adder { export defproc alu(...) { bus_interface b; } } ... }
Now datapath::adder::alu
can be accessed from the global
namespace.
Namespace globals are instances that are defined outside any type
definition. While the Global
namespace can have any instances
or other constructs used to construct circuits, other namespaces can
only have global data types or channels—i.e. no circuits.