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] Move Extmodule Params to Instantiation #46

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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: 2 additions & 0 deletions include/firrtl.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<item>Clock</item>
<item>Reset</item>
<item>AsyncReset</item>
<item>Param</item>
Copy link
Member

@dtzSiFive dtzSiFive Jan 26, 2023

Choose a reason for hiding this comment

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

Nit/FWIW: Param is special as it wraps other types. I ran into this for Ref and wanted the inner types formatted so handled it like this: dtzSiFive/firrtl-spec@dtzSiFive:0190aba...dtzSiFive:abdbca8#diff-fc53c821ad3e7a3caa0a87f0f46f48202fca3bc55dbb9e56fc34cb0c6ec3ead3 . I think same would work for Param, as another "outertype", and while I think that could be narrowed a bit regardless we can probably use same approach here.

(Not sure about the other grammar changes)

</list>
<list name="conditionals">
<item>when</item>
Expand Down Expand Up @@ -78,6 +79,7 @@
<item>assert</item>
<item>assume</item>
<item>cover</item>
<item>paramAdd</item>
</list>
<contexts>
<context name="Normal Text" attribute="ID" lineEndContext="#pop">
Expand Down
110 changes: 95 additions & 15 deletions spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,9 @@ instance statement for details on how to instantiate a module
## Externally Defined Modules

Externally defined modules are modules whose implementation is not provided in
the current circuit. Only the ports and name of the externally defined module
are specified in the circuit. An externally defined module may include, in
order, an optional _defname_ which sets the name of the external module in the
resulting Verilog and zero or more name--value _parameter_ statements. Each
name--value parameter statement will result in a value being passed to the named
parameter in the resulting Verilog.
the current circuit. Only the ports of the externally defined module are
specified in the circuit. No other statements may exist in the external module
body.

An example of an externally defined module is:

Expand All @@ -231,15 +228,40 @@ extmodule MyExternalModule :
input foo: UInt<2>
output bar: UInt<4>
output baz: SInt<8>
defname = VerilogName
parameter x = "hello"
parameter y = 42
```

The widths of all externally defined module ports must be specified. Width
inference, described in [@sec:width-inference], is not supported for module
ports.

Externally defined modules may have zero or more parameters. Parameters may be
of known-width `UInt`{.firrtl} or `SInt`{.firrtl} types or `String`{.firrtl}
type. The value of a parameter is set at each instantiation of an external
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we mention that they must be passed in declaration order (there is no name-specified parameter passing syntax)

module using a literal value.

An example of a parametric externally defined module and its instantiation is:

``` firrtl
extmodule MyExternalModule2<
parameter x: Param<String>,
parameter y: Param<UInt<8>>,
parameter z: Param<SInt<4>>
> :
; ...
mwachs5 marked this conversation as resolved.
Show resolved Hide resolved
module Top:
inst foo of MyExternalModule2<Param<"foo">, Param<UInt<8>(42)>, Param<SInt<4>(-1)>>
inst bar of MyExternalModule2<Param<"bar">, Param<UInt(0)>, Param<SInt(-2)>>
node _x = Param<"baz">
node _y = Param<UInt(1)>
node _z = Param<SInt(-1)>
inst baz of MyExternalModule2<_x, _y, _z>
```

As shown above, it is allowable to use a smaller, unknown width integer type
literal to set a parameter value so long as the width of the underlying
parameter value is large enough to store the literal type. A literal that is
too large for a given parameter type is illegal.

A common use of an externally defined module is to represent a Verilog module
that will be written separately and provided together with FIRRTL-generated
Verilog to downstream tools.
Expand Down Expand Up @@ -563,6 +585,37 @@ flipped orientations. Thus all ground types are passive types. Vector types are
passive if their element type is passive. And bundle types are passive if no
fields are flipped and if all field types are passive.

## Parameter Types

A `UInt`{.firrtl}, `SInt`{.firrtl}, or `String`{.firrtl} type may be boxed with
a `Param`{.firrtl}` type. This indicates that this is a type that is used to
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
a `Param`{.firrtl}` type. This indicates that this is a type that is used to
a `Param`{.firrtl} type. This indicates that this is a type that is used to

express parameterization. Parameter types may be used to express
parameterization on externally defined modules. Parameter types may be used as
nodes. Parameter types may be used in passive aggregates. All other uses of
Copy link
Collaborator

Choose a reason for hiding this comment

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

can you show an example of "Parameter types may be used in passive aggregates"? what does that mean?

parameter types are explicitly illegal. E.g., parameter types may not appear in
wires, registers, ports, or connections.

The following shows the creation of two parameter types, an expression involving
these parameter types, and the use of the result of the expression in an
external module instantiation.

``` firrtl
extmodule Foo<parameter a: Param<UInt<8>> :
input a : UInt<a>
module Bar:
input a: UInt<8>

node x = Param(UInt<7>(1))
node y = Param(UInt<7>(2))
node z = paramAdd(x, y)

inst foo of Foo<z>
```

Certain operations are supported on parameter types. See Section
[@sec:parameter-primitive-operations] for a listing of all parameter primitive
operations.

## Type Equivalence

The type equivalence relation is used to determine whether a connection between
Expand Down Expand Up @@ -2379,6 +2432,18 @@ fixed-point number. This will cause the binary point and consequently the total
width of the fixed-point result type to differ from those of the fixed-point
argument type. See [@sec:fixed-point-math] for more detail.

# Parameter Primitive Operations

Operations are defined for manipulating parameter types. For operations which
have overlapping functionality with normal primitive operations (see Section
[@sec:primitive-operations]), the result width expressions are intentionally
kept the same.

| Name | Arguments | Arg Types | Result Type | Result Width |
|----------|-----------|-------------------------------|---------------|--------------------|
| paramAdd | (e1,e2) | (Param\<UInt\>,Param\<UInt\>) | Param\<UInt\> | max(w~e1~,w~e2~)+1 |
| | | (Param\<SInt\>,Param\<SInt\>) | Param\<SInt\> | max(w~e1~,w~e2~)+1 |

# Flows

An expression's flow partially determines the legality of connecting to and from
Expand Down Expand Up @@ -2872,6 +2937,7 @@ type_aggregate = "{" , field , { field } , "}"
| type , "[" , int , "]" ;
field = [ "flip" ] , id , ":" , type ;
type = type_ground | type_aggregate ;
type_param = "Param<" , ( ( "UInt" | "SInt" ) , width | "String" ) , ">"

(* Primitive operations *)
primop_2expr_keyword =
Expand Down Expand Up @@ -2899,8 +2965,8 @@ primop_1expr2int =
primop = primop_2expr | primop_1expr | primop_1expr1int | primop_1expr2int ;

(* Expression definitions *)
expr =
( "UInt" | "SInt" ) , [ width ] , "(" , ( int ) , ")"
int_lit = ( "UInt" | "SInt" ) , [ width ] , "(" , int , ")"
expr = int_lit
| reference
| "mux" , "(" , expr , "," , expr , "," , expr , ")"
| "validif" , "(" , expr , "," , expr , ")"
Expand All @@ -2910,6 +2976,17 @@ reference = id
| reference , "[" , int , "]"
| reference , "[" , expr , "]" ;

(* Parameter primitive operations *)
primop_param_2expr_keyword = "add" ;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
primop_param_2expr_keyword = "add" ;
primop_param_2expr_keyword = "paramAdd" ;

if I am reading this right?

primop_param_2expr =
primop_param_2expr_keyword , "(" , parm_expr , "," , parm_expr ")" ;
param_primop = primop_param_2expr ;

(* Parameter expression definitions *)
param_expr = int_lit ;
| reference
| param_primop ;

(* Memory *)
ruw = ( "old" | "new" | "undefined" ) ;
memory = "mem" , id , ":" , [ info ] , newline , indent ,
Expand All @@ -2924,11 +3001,13 @@ memory = "mem" , id , ":" , [ info ] , newline , indent ,
dedent ;

(* Statements *)
parameter = int_lit | string ;
parameter_seq = parameter | parameter , "," , parameter_seq ;
statement = "wire" , id , ":" , type , [ info ]
| "reg" , id , ":" , type , expr ,
[ "(with: {reset => (" , expr , "," , expr ")})" ] , [ info ]
| memory
| "inst" , id , "of" , id , [ info ]
| "inst" , id , "of" , id , [ "<" , parameter_seq , ">" ] , [ info ]
| "node" , id , "=" , expr , [ info ]
| reference , "<=" , expr , [ info ]
| reference , "<-" , expr , [ info ]
Expand All @@ -2948,10 +3027,11 @@ module = "module" , id , ":" , [ info ] , newline , indent ,
{ port , newline } ,
{ statement , newline } ,
dedent ;
extmodule = "extmodule" , id , ":" , [ info ] , newline , indent ,
parameter_decl = "parameter" , id , ":" , type_param ;
parameter_decl_seq = parameter_decl | parameter_decl , "," , parameter_decl_seq ;
extmodule = "extmodule" , id , [ "<" , parameter_decl_seq , ">" ] , ":" ,
[ info ] , newline , indent ,
{ port , newline } ,
[ "defname" , "=" , id , newline ] ,
{ "parameter" , "=" , ( string | int ) , newline } ,
dedent ;

(* Version definition *)
Expand Down