Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[major] Finalize FIRRTL 4.0.0 Public Modules #167

Merged
merged 5 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion abi.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Both these ABIs may evolve as new FIRRTL constructs are added.

### The Circuit

The circuit is a container of public modules.
The circuit is a container of modules with a single "main module" entry point.
The circuit, by itself, does not have any ABI.

### External Modules
Expand Down
1 change: 0 additions & 1 deletion revision-history.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ revisionHistory:
thisVersion:
spec:
- Add public modules.
Change circuits to support any number of public modules which may have disjoint instance hierarchies.
- Rename a "FIRRTL Language Definition" to "Grammar".
- Rename "Details about Syntax" to "Notes on Syntax".
- Add section "Circuit Components".
Expand Down
46 changes: 25 additions & 21 deletions spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,19 @@ This will not be present on files generated according to versions of this standa

``` firrtl
FIRRTL version 1.1.0
circuit :
circuit Foo :
```

# Circuits and Modules

## Circuits

A FIRRTL circuit is a collection of FIRRTL modules.
A FIRRTL circuit is a named collection of FIRRTL modules.
Each module is a hardware "unit" that has ports, registers, wires, and may instantiate other modules (see: [@sec:modules]).
(This is the same concept as a Verilog `module`{.verilog}.)
Each FIRRTL circuit has one *main module*.
The name of the FIRRTL circuit is the name of the main module.
Modules in a FIRRTL circuit may be public or private.
A public module may be instantiated outside the current circuit.
Public modules are the exported identifiers of a circuit.
Any non-public module may not be instantiated outside the current circuit.
Expand All @@ -79,7 +82,7 @@ Consider the following circuit. This contains two modules, `Bar` and `Baz`.
Module `Baz` is marked public.

``` firrtl
circuit :
circuit Baz :
module Bar :
input a: UInt<1>
output b: UInt<1>
Expand All @@ -101,7 +104,7 @@ Module `Foo` has no common instances with `Bar` or `Baz`.
`Bar` and `Baz` both instantiate `Qux`:

``` firrtl
circuit :
circuit Foo :
public module Foo :

public module Bar :
Expand All @@ -113,8 +116,9 @@ circuit :
module Qux :
```

A circuit that contains no public modules is trivially equivalent to a circuit that contains no modules.
It is not enforced that a circuit has at least one public module, but it is expected that it does.
A circuit that contains no public modules is trivially equivalent to an empty circuit.
It is not enforced that a circuit has at least one public module.
It is not enforced that the main module is public.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines seem strange to me.

How can a circuit be empty if:

  • it requires a name, and
  • the name matches a public module

It feels like we're trying to document a quirk of the implementation. Maybe it would help to comment on the intention of these rules.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe there's a better way of putting this...

The PR is trying to make public mean the same thing for all modules. If a module is public then you get a Verilog module with ports following the port lowering ABI. If a module is private, anything can happen to the module. It may be optimized away, it may get inlined, it may be duplicated a million times, etc.

The main module creates a discontinuity arising from making the main module implicitly public. If it is implicitly public, then either the public keyword has no effect or the public keyword is mandatory (or the public keyword cannot be applied to the main module, but it is implicitly public anyway).

The language in this section is trying to say that a circuit which has no public modules can be optimized to produce no Verilog.

WDYT?

For full clarity, this is an intermediate step to FIRRTL 5. Currently you can get the "bag o' dags" representation in FIRRTL 4 with:

circuit Container :
  public module Foo :
  public module Bar :
  module Container :
    inst foo of Foo
    invalidate foo

    inst bar of Bar
    invalidate Bar

or perhaps the following, though FIRRTL compilers don't really handle this well right now:

circuit Dummy :
  public module Foo :
  public module Bar :
  module Dummy :

In FIRRTL 5 we can drop the circuit entirely and just make this:

public module Foo:
public module Bar:


## Modules

Expand Down Expand Up @@ -191,10 +195,10 @@ The circuit below contains one layer, `Bar`.
Module `Foo` contains a layer block that creates a node computed from a port defined in the scope of `Foo`.

``` firrtl
circuit:
circuit Foo:
layer Bar, bind: ; Declaration of layer Bar with convention "bind"

module Foo:
public module Foo:
input a: UInt<1>

layerblock Bar: ; Declaration of a layer block associated with layer Bar inside module Foo
Expand All @@ -208,10 +212,10 @@ The first layer block may not reference node `c`.
The second layer block may not reference node `b`.

``` firrtl
circuit:
circuit Foo:
layer Bar, bind:

module Foo:
public module Foo:
input a: UInt<1>

layerblock Bar: ; First layer block
Expand All @@ -229,7 +233,7 @@ The circuit below contains four layers, three of which are nested.
`Quz` is nested under `Qux`.

``` firrtl
circuit:
circuit Foo:
layer Bar, bind:
layer Baz, bind:
layer Qux, bind:
Expand Down Expand Up @@ -262,7 +266,7 @@ In module `Foo`, the port may be read from inside the layer block.
*Stated differently, module `Baz` has an additional port `_a` that is only accessible in a layer block associated with `Bar`*.

``` firrtl
circuit:
circuit Foo:
layer Bar, bind:

module Baz:
Expand All @@ -274,7 +278,7 @@ circuit:
node notA = not(a)
define _a = probe(notA)

module Foo:
public module Foo:

inst baz of Baz

Expand All @@ -286,11 +290,11 @@ If a port is associated with a nested layer then a period is used to indicate th
E.g., the following circuit has a port associated with the nested layer `Bar.Baz`:

``` firrtl
circuit:
circuit Foo:
layer Bar, bind:
layer Baz, bind:

module Foo:
public module Foo:
output a: Probe<UInt<1>, Bar.Baz>
```

Expand Down Expand Up @@ -1865,7 +1869,7 @@ FIRRTL modules are instantiated with the instance statement.
The following example demonstrates creating an instance named `myinstance`{.firrtl} of the `MyModule`{.firrtl} module within the top level module `Top`{.firrtl}.

``` firrtl
circuit :
circuit Top :
module MyModule :
input a: UInt
output b: UInt
Expand Down Expand Up @@ -2586,8 +2590,8 @@ To show some examples of what these look like, consider the following example ci
This consists of four instances of module `Baz`{.firrtl}, two instances of module `Bar`{.firrtl}, and one instance of module `Foo`{.firrtl}:

``` firrtl
circuit:
module Foo:
circuit Foo:
public module Foo:
inst a of Bar
inst b of Bar
module Bar:
Expand Down Expand Up @@ -3125,7 +3129,7 @@ As a concrete guide, a few consequences of these rules are summarized below:
As an example illustrating some of these points, the following is a legal FIRRTL circuit:

``` firrtl
circuit :
circuit Foo :
public module Foo :
skip
module Bar :
Expand All @@ -3143,7 +3147,7 @@ The following characters need to be escaped with a leading '`\`': '`\n`' (new li
The following example shows the info tokens included:

``` firrtl
circuit : @[myfile.txt 14:8]
circuit Top : @[myfile.txt 14:8]
public module Top : @[myfile.txt 15:2]
output out: UInt @[myfile.txt 16:3]
input b: UInt<32> @[myfile.txt 17:3]
Expand Down Expand Up @@ -3222,7 +3226,7 @@ Any use in place of an integer is disallowed.
(* Circuit Definition *)
circuit =
version , newline ,
"circuit" , ":" , [ annotations ] , [ info ] , newline , indent ,
"circuit" , id , ":" , [ annotations ] , [ info ] , newline , indent ,
{ decl } ,
dedent ;

Expand Down
Loading