-
Notifications
You must be signed in to change notification settings - Fork 28
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
base: main
Are you sure you want to change the base?
Changes from all commits
8f79a2b
442b8b2
75126fc
48093c7
dbb406b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -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: | ||||||
|
||||||
|
@@ -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 | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||||||
|
@@ -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 | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
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 | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||||||
|
@@ -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 | ||||||
|
@@ -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 = | ||||||
|
@@ -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 , ")" | ||||||
|
@@ -2910,6 +2976,17 @@ reference = id | |||||
| reference , "[" , int , "]" | ||||||
| reference , "[" , expr , "]" ; | ||||||
|
||||||
(* Parameter primitive operations *) | ||||||
primop_param_2expr_keyword = "add" ; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
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 , | ||||||
|
@@ -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 ] | ||||||
|
@@ -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 *) | ||||||
|
There was a problem hiding this comment.
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 forParam
, 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)