1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
|
\title{Specification for the FIRRTL Language: Version 0.1.1}
\author{Patrick S. Li, Adam M. Izraelevitz, Jonathan Bachrach}
\documentclass[12pt]{article}
\usepackage{listings}
\usepackage{amsmath}
\usepackage{proof}
\usepackage{amsfonts}
\usepackage[pdftex]{graphicx}
\lstset{basicstyle=\footnotesize\ttfamily,breaklines=true}
\begin{document}
\maketitle
%Useful Macros
\newcommand{\id}{\text{id }}
\newcommand{\ids}{\text{id}}
\newcommand{\ints}{\text{int}}
\newcommand{\kw}[1]{\text{\bf #1\ }}
\newcommand{\kws}[1]{\text{\bf #1}}
\newcommand{\pd}[1]{\text{\em #1\ }}
\newcommand{\pds}[1]{\text{\em #1}}
\newcommand{\bundleT}[1]{\{#1\}}
\newcommand{\info}{[\pds{info}]\ }
\section{FIRRTL Language Definition}
\subsection{Abstract Syntax Tree}
\[
\begin{array}{rrll}
\pd{circuit} &= &\kw{circuit} \id \kw{:} (\pd{module*}) &\text{Circuit}\\
\pd{module} &= &\info \kw{module} \id \kw{:} (\pd{port*} \pd{stmt}) &\text{Module}\\
&\vert &\info \kw{exmodule} \id \kw{:} (\pd{port*}) &\text{External Module}\\
\pd{port} &= &\info \pd{dir} \id \kw{:} \pd{type} &\text{Port}\\
\pd{dir} &= &\kws{input} \vert \kws{output} &\text{Input/Output}\\
\pd{type} &= &\kws{UInt}<\pd{width}> &\text{Unsigned Integer}\\
&\vert &\kws{SInt}<\pd{width}> &\text{Signed Integer}\\
&\vert &\bundleT{\pd{field*}} &\text{Bundle}\\
&\vert &\pds{type}[\ints] &\text{Vector}\\
\pd{field} &= &\pd{orientation} \id \kw{:} \pd{type} &\text{Bundle Field}\\
\pd{orientation}&= &\kws{default} \vert \kws{reverse} &\text{Orientation}\\
\pd{width} &= &\ints &\text{Known Integer Width}\\
&\vert &\kw{?} &\text{Unknown Width}\\
\pd{atype} &= &\kws{read} \vert \kws{write} \vert \kws{unknown} &\text{Accessor Type}\\
\pd{stmt} &= &\info \kw{wire} \id \kw{:} \pd{type} &\text{Wire Declaration}\\
&\vert &\info \kw{reg} \id \kw{:} \pd{type} &\text{Register Declaration}\\
&\vert &\info \kw{mem} \id \kw{:} \pd{type} &\text{Memory Declaration}\\
&\vert &\info \kw{inst} \id \kw{:} \id &\text{Instance Declaration}\\
&\vert &\info \kw{node} \id = \pd{exp} &\text{Node Declaration}\\
&\vert &\info \pd{atype} \kw{accessor} \id = \pds{exp}[\pds{exp}] &\text{Accessor Declaration}\\
&\vert &\info \pd{exp} \kw{:=} \pd{exp} &\text{Connect}\\
&\vert &\info \kw{on-reset} \pd{exp} \kw{:=} \pd{exp} &\text{On Reset}\\
&\vert &\info \kw{when} \pd{exp} \kw{:} \pd{stmt} \kw{else :} \pd{stmt} &\text{Conditional}\\
&\vert &\info (\pd{stmt*}) &\text{Statement Group}\\
&\vert &\info \kw{skip} &\text{Empty Statement}\\
\pd{exp} &= &\info \kws{UInt}<\pds{width}>(ints) &\text{Literal Unsigned Integer}\\
&\vert &\info \kws{SInt}<\pds{width}>(ints) &\text{Literal Signed Integer}\\
&\vert &\info \id &\text{Reference}\\
&\vert &\info \pds{exp}.\id &\text{Subfield}\\
&\vert &\info \pds{exp}[\ints] &\text{Subindex}\\
&\vert &\info \kws{Register}(\pds{exp}, \pds{exp}) &\text{Structural Register}\\
&\vert &\info \kws{WritePort}(\id, \pds{exp}, \pds{exp}) &\text{Write Port}\\
&\vert &\info \kws{ReadPort}(\id, \pds{exp}, \pds{exp}) &\text{Read Port}\\
\end{array}
\]
\[
\begin{array}{rrll}
&\vert &\info \pds{primop}(\pds{exp*}, \ints\text{*}) &\text{Primitive Operation}\\
\pd{info} &= &\text{filename } \kw{:} \text{line} . \text{col} &\text{File Location}\\
&\vert &\kw{noinfo} &\text{No File Location}\\
\end{array}
\]
\[
\begin{array}{rll}
\pd{primop} &= \\
&\kws{add} &\text{Unsigned/Signed Add}\\
\vert &\kws{sub} &\text{Unsigned/Signed Subtract}\\
\vert &\kws{mul} &\text{Unsigned/Signed Multiply}\\
\vert &\kws{div} &\text{Unsigned/Signed Divide}\\
\vert &\kws{rem} &\text{Unsigned/Signed Remainder}\\
\vert &\kws{quo} &\text{Unsigned/Signed Quotient}\\
\vert &\kws{mod} &\text{Unsigned/Signed Modulo}\\
\vert &\kws{add-wrap} &\text{Unsigned/Signed Add Wrap}\\
\vert &\kws{sub-wrap} &\text{Unsigned/Signed Subtract Wrap}\\
\vert &\kws{lt} &\text{Unsigned/Signed Less Than}\\
\vert &\kws{leq} &\text{Unsigned/Signed Less or Equal}\\
\vert &\kws{gt} &\text{Unsigned/Signed Greater Than}\\
\vert &\kws{geq} &\text{Unsigned/Signed Greater or Equal}\\
\vert &\kws{eq} &\text{Unsigned/Signed Equal}\\
\vert &\kws{neq} &\text{Unsigned/Signed Not-Equal}\\
\vert &\kws{mux} &\text{Unsigned/Signed Multiplex}\\
\vert &\kws{pad} &\text{Unsigned/Signed Pad to Length}\\
\vert &\kws{asUInt} &\text{Unsigned/Signed Reinterpret Bits as UInt}\\
\vert &\kws{asSInt} &\text{Unsigned/Signed Reinterpret Bits as SInt}\\
\vert &\kws{shl} &\text{Unsigned/Signed Shift Left}\\
\vert &\kws{shr} &\text{Unsigned/Signed Shift Right}\\
\vert &\kws{toSInt} &\text{Unsigned/Signed to Signed Conversion}\\
\vert &\kws{neg} &\text{Unsigned/Signed Negate}\\
\vert &\kws{bit-not} &\text{Unsigned Not}\\
\vert &\kws{bit-and} &\text{Unsigned And}\\
\vert &\kws{bit-or} &\text{Unsigned Or}\\
\vert &\kws{bit-xor} &\text{Unsigned Xor}\\
\vert &\kws{bit-and-reduce} &\text{Unsigned And}\\
\vert &\kws{bit-or-reduce} &\text{Unsigned Or}\\
\vert &\kws{bit-xor-reduce} &\text{Unsigned Xor}\\
\vert &\kws{cat} &\text{Unsigned Concatenation}\\
\vert &\kws{bit} &\text{Single Bit Extraction}\\
\vert &\kws{bits} &\text{Multiple Bit Extraction}\\
\end{array}
\]
\subsection{Notation}
The above definition specifies the structure of the abstract syntax tree corresponding to a FIRRTL circuit. Nodes in the abstract syntax tree are {\em italicized}. Keywords are shown in {\bf bold}. The special productions, id and int, indicates an identifier and an integer literal respectively. Tokens followed by an asterisk, {\em e.g.} \pds{field}*, indicates a list formed from repeated occurences of the token.
Keep in the mind that the above definition is only the {\em abstract} syntax tree, and is a representation of the in-memory FIRRTL datastructure. Readers and writers are provided for converting a FIRRTL datastructure into a purely textual representation, and is defined in section \ref{concrete}.
\section{Circuits and Modules}
\[
\begin{array}{rrl}
\pd{circuit} &= &\kw{circuit} \text{toplevel-module } \kw{:} (\text{modules*}) \\
\pd{module} &= &\kw{module} \text{name } \kw{:} (\text{ports* } \text{body}) \\
&\vert &\kw{exmodule} \text{name } \kw{:} (\text{ports* }) \\
\pd{port} &= &\pd{dir} \id \kw{:} \pd{type} \\
\pd{dir} &= &\kws{input} \vert \kws{output} \\
\end{array}
\]
All FIRRTL circuits are comprised of a flat list of modules, each representing one hardware block.
Each module has a given name, a list of ports, and a statement representing the circuit connections within the module.
Externally defined modules consist of a given name, and a list of ports, whose types must match the types defined in the associated Verilog.
Module names exist in their own namespace, and all modules must have a unique name. The name of the top-level module must be specified for a circuit.
A module port is specified by a direction, which may be input or output, a name, and the data type for the port.
The port names exist in the identifier namespace for the module, and must be unique.
In addition, all references within a module must be unique.
The special port name, {\em reset}, is used to carry the module reset signal for circuit initialization, and has special meaning.
Circuit initialization is described in section \ref{initialization}.
\section{Types}
\subsection{Ground Types}
\[
\begin{array}{rrl}
\pd{type} &= &\kws{UInt}<\pd{width}> \\
&\vert &\kws{SInt}<\pd{width}> \\
\pd{width} &= &\ints \\
&\vert &\kw{?} \\
\end{array}
\]
There are only two ground types in FIRRTL, an unsigned and a signed integer type.
Both of these types require a given bitwidth, which may be some known integer width, which must be non-negative, or an unknown width.
Unknown widths are a declaration for the width to be computed by the FIRRTL width inferencer, instead of manually given by the programmer.
\subsection{Vector Types}
\[
\begin{array}{rrl}
\pd{type} &= &\pds{type}[\ints] \\
\end{array}
\]
Vector types in FIRRTL indicate a structure consisting of multiple elements of some given type.
This is akin to array types in the C programming language.
Note that the number of elements must be known, and non-negative.
As an example, the type $\kws{UInt}<16>[10]$ indicates a ten element vector of 16-bit unsigned integers.
The type $\kws{UInt}<\kws{?}>[10]$ indicates a ten element vector of unsigned integers, with unknown but the same bitwidths.
Vector types may be nested ad infinitum.
The type $\kws{UInt}<16>[10][5]$ indicates a five element vector {\em of} ten element vectors of 16-bit unsigned integers.
\subsection{Bundle Types}
\[
\begin{array}{rrl}
\pd{type} &= &\bundleT{\pd{field*}} \\
\pd{field} &= &\pd{orientation} \text{name } \kw{:} \pd{type} \\
\pd{orientation}&= &\kws{default} \vert \kws{reverse} \\
\end{array}
\]
Bundle types in FIRRTL are composite types formed from an ordered sequence of named, nested types.
All fields in a bundle must have a given direction, name, and type.
The following is an example of a possible type for representing a complex number.
\[
\bundleT{\kw{default} \text{real } \kw{:} \kws{SInt}<10>,
\kw{default} \text{imag } \kw{:} \kws{SInt}<10>}
\]
It has two fields, real, and imag, both 10-bit signed integers.
Here is an example of a possible type for a decoupled port.
\[
\begin{aligned}
\{ \kw{default} &\text{data } \kw{:} \kws{UInt}<10>, \\
\kw{default} &\text{valid } \kw{:} \kws{UInt}<1>, \\
\kw{reverse} &\text{ready } \kw{:} \kws{UInt}<1>\} \\
\end{aligned}
\]
It has a data field that is specified to be a 10-bit unsigned integer, a valid signal that must be a 1-bit unsigned integer, and a flipped ready signal that must be a 1-bit unsigned integer.
By convention, we specify the directions within a bundle type with their relative orientation.
For this reason, the real and imag fields for the complex number bundle type are both specified to be {\em default}.
Similarly, if a module were to output a value using a decoupled protocol, we would declare the module to have an output port, data, which would contain the value itself, a non-flipped field, valid, which would indicate when the value is valid, and accept an {\em reverse} field, ready, from the receiving component, which would indicate when the component is ready to receive the value.
Note that all field names within a bundle type must be unique.
As in the case of vector types, bundle types may also be nested ad infinitum.
I.e., the types of the fields themselves may also be bundle types, which will in turn contain more fields, etc.
\section{Statements}
FIRRTL circuit components are instantiated and connected together using {\em statements}.
\subsection{Wires}
A wire is a named combinational circuit element that can connected to using the connect statement.
A wire with a given name and type can be instantiated with the following statement.
\[
\kw{wire} \text{name } \kw{:} \pd{type} \\
\]
Declared wires are {\em bidirectional}, which means that they can be used as both an input (by being on the left-hand side of a connect statement), or as an output (by being on the right-hand side of a connect statement).
\subsection{Registers}
A register is a named stateful circuit element.
A register with a given name and type can be instantiated with the following statement.
\[
\kw{reg} \text{name } \kw{:} \pd{type} \\
\]
Like wires, registers are also {\em bidirectional}, which means that they can be used as both an input (by being on the left-hand side of a connect statement), or as an output (by being on the right-hand side of a connect statement).
The statement {\em on-reset} is used to specify the initialization value for a register, and is described in section \ref{initialization}.
\subsection{Memories}
A memory is a stateful circuit element containing multiple elements.
Unlike registers, memories can {\em only} be read from or written to through {\em accessors}.
A memory with a given name and type can be instantiated with the following statement.
\[
\begin{aligned}
\kw{mem} \text{name } \kw{:} \pd{type} \\
\end{aligned}
\]
Note that, by definition, memories contain multiple elements, and hence {\em must} be declared with a vector type.
It is an error to specify any other type for a memory.
However, the internal type to the vector type may be a non-ground type, with the caveat that the internal type, if a bundle type, cannot contain any reverse fields.
Additionally, the type for a memory must be completely specified and cannot contain any unknown widths.
\subsection{Nodes}
A node is simply a named intermediate value in a circuit.
A node with a given name and value can be instantiated with the following statement.
\[
\kw{node} \text{name } = \pd{exp} \\
\]
Unlike wires, nodes can only be used in {\em output} directions.
They can be connected from, but not connected to.
Consequentially, their expression cannot be a bundle type with any flipped fields.
\subsection{Accessors}
Accessors are used for either connecting to or from a vector-typed expression, from some {\em variable} index.
An accessor can be instantiated with the following statement.
\[
\begin{aligned}
\pd{atype} \kw{accessor} \text{name} = \pds{exp}[\text{index}] \\
\pd{atype} &= &\kws{read} \vert \kws{write} \vert \kws{unknown} \\
\end{aligned}
\]
Given a name, an expression to access, the index at which to access, and optionally the accessor type, the above statement creates an accessor that may be used for connecting to or from the expression.
The expression must have a vector type, and the index must be an variable with a UInt type.
An untyped (unknown) accessor or a read accessor may be used as outputs, by being on the right-hand side of a connect statement, in which case the accessor acts as a reader from the given expression at the given index.
Or, an untyped accessor or a write accessor may be used as inputs, by being on the left-hand side of a connect statement, in which case the accessor acts as a writer to the given expression at the given index.
An accessor must consistently be used either as an input, or as an output, but not as both.
The following example demonstrates using untyped accessors to read and write to a memory.
The accessor, reader, acts as a memory read port that reads from the index specified by the wire i.
The accessor, writer, acts as a memory write port that writes 42 to the index specified by wire j.
\[
\begin{aligned}
&\kw{wire} i : \kws{UInt}<5> \\
&\kw{wire} j : \kws{UInt}<5> \\
&\kw{mem} m : \kws{UInt}<10>[10] \\
&\kw{accessor} reader = m[i] \\
&\kw{accessor} writer = m[j] \\
&writer := \kws{UInt}<?>(42) \\
&\kw{node} temp = reader \\
\end{aligned}
\]
As mentioned previously, the only way to read from or write to a memory is through an accessor.
But accessors are not restricted to accessing memories.
They can be used to access {\em any} vector-valued type.
\subsection{Instances}
An instance refers to a particular instantiation of a FIRRTL module.
An instance with some given name, of a given module can be created using the following statement.
\[
\begin{aligned}
\kw{inst} \text{name } \kw{of} \text{module}
\end{aligned}
\]
The ports of an instance may be accessed using the subfield expression.
The output ports of an instance may only be used in output positions, e.g. the right-hand side of a connect statement, and the input ports of an instance may only be used in input positions, e.g. the left-hand side of a connect statement.
An instance may be directly connected to a value. However, it can only be used as an input, or on the right side of a connect.
There are restrictions upon which modules the user is allowed to instantiate, so as not to create infinitely recursive hardware.
We define a module with no instances as a {\em level 0} module.
A module containing only instances of {\em level 0} modules is a {\em level 1} module, and a module containing only instances of {\em level 1} or below modules is a {\em level 2} module.
In general, a {\em level n} module is only allowed to contain instances of modules of level $n-1$ or below.
\subsection{The Connect Statement}
The connect statement is used to specify a physical wired connection between one hardware component to another, and is the most important statement in FIRRTL.
The following statement is used to connect the output of some component, to the input of another component.
\[
\text{input } \kw{:=} \text{output}
\]
For a connection to be legal, the types of the two expressions must match exactly, including all field flips if the wires contain bundle types.
The component on the right-hand side must be able to be used as an output, and the component on the left-hand side must be able to be used as an input.
\subsection{The On Reset Statement}
The on-reset statement is used to specify the default value for a register. Its semantics are described in Section \ref{initialization}.
\[
\kw{on-reset} \text{reg } \kw{:=} \text{output}
\]
For a connection to be legal, the types of the two expressions must match exactly, including all field flips if the wires contain bundle types.
The component on the right-hand side must be able to be used as an output, and the component on the left-hand side must be able to be used as an input, and must be a reg.
\subsection{The Conditional Statement}
The conditional statement is used to specify a condition that must be asserted under which a list of statements hold.
The condition must be a 1-bit unsigned integer.
The following statement states that the {\em conseq} statements hold only when {\em condition} is assert high, otherwise the {\em alt} statements hold instead.
\[
\begin{aligned}
\kw{when} \text{condition } \kw{:} \text{conseq } \kw{else :} \text{alt}
\end{aligned}
\]
Notationally, for convenience, we omit the \kws{else} branch if it is an empty statement.
\subsubsection{Initialization Coverage}
Because of the conditional statement, it is possible for wires to be only partially connected to an expression.
In the following example, the wire w is connected to 42 when enable is asserted high, but it is not specified what w is connected to when enable is low.
This is an illegal FIRRTL circuit, and will throw a \kws{wire not initialized} error during compilation.
\[
\begin{aligned}
&\kw{wire} w : \kws{UInt}<\kws{?}> \\
&\kw{when} enable : \\
&\quad w := \kws{UInt}<\kws{?}>(42) \\
\end{aligned}
\]
\subsubsection{Scoping}
The conditional statement creates a new {\em scope} within its consequent and alternative branches.
It is an error to refer to any component declared within a branch after the branch has ended.
Note that there is still only a single identifier namespace in a module.
Thus, there cannot be two components with identical names in the same module, {\em even if} they are in separate scopes.
This is to facilitate writing transformational passes, by ensuring that the component name and module name is sufficient to uniquely identify a component.
\subsection{Statement Groups}
Several statements can be grouped into one using the following construct.
\[
\begin{aligned}
(\pd{stmt*})
\end{aligned}
\]
Ordering is important in a statement group.
Later connect statements take precedence over earlier connect statements, and circuit components cannot be referred to before they are instantiated.
\subsubsection{Last Connect Semantics}
Because of the connect statement, FIRRTL statements are {\em ordering} dependent.
Later connections take precendence over earlier connections.
In the following example, the wire w is connected to 42, not 20.
\[
\begin{aligned}
&\kw{wire} w : \kws{UInt}(\kws{?}) \\
&w := \kws{UInt}<\kws{?}>(20) \\
&w := \kws{UInt}<\kws{?}>(42) \\
\end{aligned}
\]
By coupling the conditional statement with last connect semantics, many circuits can be expressed in a natural style.
In the following example, the wire w is connected to 20 unless the enable expression is asserted high, in which case w is connected to 42.
\[
\begin{aligned}
&\kw{wire} w : \kws{UInt}(\kws{?}) \\
&w := \kws{UInt}<\kws{?}>(20) \\
&\kw{when} enable : \\
&\quad w := \kws{UInt}<\kws{?}>(42) \\
\end{aligned}
\]
\subsection{The Empty Statement}
The empty statement is specified using the following.
\[
\begin{aligned}
\kw{skip}
\end{aligned}
\]
The empty statement does nothing and is used simply as a placeholder where a statement is expected.
It is typically used as the alternative branch in a conditional statement.
In addition, it is useful for transformational pass writers.
\section{Expressions}
FIRRTL expressions are used for creating values corresponding to the ground types, for referring to a declared circuit component, for accessing a nested element within a component, and for performing primitive operations.
\subsection{Unsigned Integers}
A value of type \kws{UInt} can be directly created using the following expression.
\[
\kws{UInt}<\text{width}>(\text{value})
\]
The given value must be non-negative, and the given width, if known, must be large enough to hold the value.
If the width is specified as unknown, then FIRRTL infers the minimum possible width necessary to hold the value.
\subsection{Signed Integers}
A value of type \kws{SInt} can be directly created using the following expression.
\[
\kws{SInt}<\text{width}>(\text{value})
\]
The given width, if known, must be large enough to hold the given value in two's complement format.
If the width is specified as unknown, then FIRRTL infers the minimum possible width necessary to hold the value.
\subsection{References}
\[
\text{name}
\]
A reference is simply a name that refers to some declared circuit component.
A reference may refer to a port, a node, a wire, a register, an instance, a memory, a node, or a structural register.
\subsection{Subfields}
\[
\pds{exp}.\text{name}
\]
The subfield expression may be used for one of three purposes:
\begin{enumerate}
\item To refer to a specific port of an instance, using instance-name.port-name.
\item To refer to a specific field within a bundle-typed expression.
\end{enumerate}
\subsection{Subindex}
\[
\pds{exp}[\text{index}]
\]
The subindex expression is used for referring to a specific element within a vector-valued expression.
It is legal to use the subindex expression on any vector-valued expression, except for memories.
\subsection{Structural Register}
\[
\kws{Register}(\text{value}, \text{enable})
\]
A structural register is an unnamed register specified by the input value for the register and the enable signal for the register.
The type of the input must be a ground type and the enable signal must be a 1-bit unsigned integer.
\subsection{WritePort}
\[
\kws{WritePort}(\text{mem},\text{index},\text{enable})
\]
A write port is specified given the memory it accesses, the index into the memory, and the enable signal determining when to write the value.
The index must be an expression with an unsigned integer type and the enable signal must be a 1-bit unsigned integer.
The type of the WritePort is the inside type of the memory's vector type.
A WritePort can only be used as an output (on the left side of a connect statement).
\subsection{ReadPort}
\[
\kws{ReadPort}(\text{mem},\text{index},\text{enable})
\]
A read port is specified given the memory it accesses, the index into the memory, and the enable signal determining when to read the value.
The index must be an expression with an unsigned integer type and the enable signal must be a 1-bit unsigned integer.
The type of the ReadPort is the inside type of the memory's vector type.
A ReadPort can only be used as an input (on the right side of a connect statement).
\subsection{Primitive Operation}
\[
\pds{primop}(\pds{exp*}, \ints\text{*})
\]
There are a number of different primitive operations supported by FIRRTL.
Each operation takes some number of expressions, along with some number of integer literals.
Section \ref{primitives} will describe the format and semantics of each operation.
\section{Primitive Operations} \label{primitives}
All primitive operations expression operands must be ground types.
In addition, some allow all permutations of operand ground types, while others on allow subsets.
When well defined, input arguments are allowed to be differing widths.
FAQ: Why have generic operations instead of explicit types (e.g. add-uu, where the two inputs are unsigned)
FAQ: Why allow operations to allow inputs of differing widths?
\subsection{Add Operation}
\[
\begin{array}{rll}
\kws{Input Types} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{add}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & max(width(op1),width(op2)) + 1 \\
\kws{add}(\pds{op1}:UInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) + 1 \\
\kws{add}(\pds{op1}:SInt, \pds{op2}:UInt) & SInt & max(width(op1),width(op2)) + 1 \\
\kws{add}(\pds{op1}:SInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) + 1 \\
\end{array}
\]
The resultant's value is 1-bit larger than the wider of the two operands and has a signed type if either operand is signed (otherwise is unsigned).
\subsection{Subtract Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{sub}(\pds{op1}:UInt, \pds{op2}:UInt) & SInt & max(width(op1),width(op2)) + 1 \\
\kws{sub}(\pds{op1}:UInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) + 1 \\
\kws{sub}(\pds{op1}:SInt, \pds{op2}:UInt) & SInt & max(width(op1),width(op2)) + 1 \\
\kws{sub}(\pds{op1}:SInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) + 1 \\
\end{array}
\]
The subtraction operation works similarly to the add operation, but always returns a signed integer with a width that is 1-bit wider than the max of the widths of the two operands.
\subsection{Multiply Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{mul}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & width(op1) + width(op2) \\
\kws{mul}(\pds{op1}:UInt, \pds{op2}:SInt) & SInt & width(op1) + width(op2) \\
\kws{mul}(\pds{op1}:SInt, \pds{op2}:UInt) & SInt & width(op1) + width(op2) \\
\kws{mul}(\pds{op1}:SInt, \pds{op2}:SInt) & SInt & width(op1) + width(op2) \\
\end{array}
\]
The resultant value has width equal to the sum of the widths of its two operands.
\subsection{Divide Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{div}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & width(op1) \\
\kws{div}(\pds{op1}:UInt, \pds{op2}:SInt) & SInt & width(op1) + 1 \\
\kws{div}(\pds{op1}:SInt, \pds{op2}:UInt) & SInt & width(op1) \\
\kws{div}(\pds{op1}:SInt, \pds{op2}:SInt) & SInt & width(op1) + 1 \\
\end{array}
\]
The first argument is the dividend, the second argument is the divisor.
The resultant width of a divide operation is equal to the width of the dividend, plus one if the divisor is an SInt.
The resultant value follows the following formula : div(a,b) = round-towards-zero(a/b) + mod(a,b)
\subsection{Modulus Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{mod}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & width(op2) \\
\kws{mod}(\pds{op1}:UInt, \pds{op2}:SInt) & UInt & width(op2) \\
\kws{mod}(\pds{op1}:SInt, \pds{op2}:UInt) & SInt & width(op2) + 1 \\
\kws{mod}(\pds{op1}:SInt, \pds{op2}:SInt) & SInt & width(op2) \\
\end{array}
\]
The first argument is the dividend, the second argument is the divisor.
The resultant width of a modulus operation is equal to the width of the divisor, except when the modulus is positive and the result can be negative.
The resultant value follows the following formula : div(a,b) = round-towards-zero(a/b) + mod(a,b)
\subsection{Quotient Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{quo}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & width(op1) + 1 \\
\kws{quo}(\pds{op1}:UInt, \pds{op2}:SInt) & SInt & width(op1) \\
\kws{quo}(\pds{op1}:SInt, \pds{op2}:UInt) & SInt & width(op1) + 1 \\
\kws{quo}(\pds{op1}:SInt, \pds{op2}:SInt) & SInt & width(op1) \\
\end{array}
\]
The first argument is the dividend, the second argument is the divisor.
The resultant width of a quotient operation is equal to the width of the dividend, plus one if the divisor is an SInt.
The resultant value follows the following formula : quo(a,b) = floor(a/b) + rem(a,b)
\subsection{Remainder Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{rem}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & width(op2) \\
\kws{rem}(\pds{op1}:UInt, \pds{op2}:SInt) & SInt & width(op2) \\
\kws{rem}(\pds{op1}:SInt, \pds{op2}:UInt) & UInt & width(op2) + 1 \\
\kws{rem}(\pds{op1}:SInt, \pds{op2}:SInt) & SInt & width(op2) \\
\end{array}
\]
The first argument is the dividend, the second argument is the divisor.
The resultant width of a modulus operation is equal to the width of the divisor, except when the divisor is positive and the result can be negative.
The resultant value follows the following formula : quo(a,b) = floor(a/b) + rem(a,b)
\subsection{Add Wrap Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{add-wrap}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & max(width(op1),width(op2)) \\
\kws{add-wrap}(\pds{op1}:UInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) \\
\kws{add-wrap}(\pds{op1}:SInt, \pds{op2}:UInt) & SInt & max(width(op1),width(op2)) \\
\kws{add-wrap}(\pds{op1}:SInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) \\
\end{array}
\]
The add wrap operation works identically to the normal add operation except that the resultant width is the maximum of the width of the two operands, instead of 1 bit greater than the maximum.
In the case of overflow, the result silently rolls over.
\subsection{Subtract Wrap Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{sub-wrap}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & max(width(op1),width(op2)) \\
\kws{sub-wrap}(\pds{op1}:UInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) \\
\kws{sub-wrap}(\pds{op1}:SInt, \pds{op2}:UInt) & SInt & max(width(op1),width(op2)) \\
\kws{sub-wrap}(\pds{op1}:SInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) \\
\end{array}
\]
Similarly to the add wrap operation, the subtract wrap operation works identically to the normal subtract operation except that the resultant width is the maximum of the width of the two operands.
In the case of overflow, the result silently rolls over.
\subsection{Comparison Operations}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{lt} (\pds{op1}:UInt, \pds{op2}:UInt) & UInt & 1 \\
\kws{lt} (\pds{op1}:UInt, \pds{op2}:SInt) & UInt & 1 \\
\kws{lt} (\pds{op1}:SInt, \pds{op2}:UInt) & UInt & 1 \\
\kws{lt} (\pds{op1}:SInt, \pds{op2}:SInt) & UInt & 1 \\
\kws{leq} (\pds{op1}:UInt, \pds{op2}:UInt) & UInt & 1 \\
\kws{leq} (\pds{op1}:UInt, \pds{op2}:SInt) & UInt & 1 \\
\kws{leq} (\pds{op1}:SInt, \pds{op2}:UInt) & UInt & 1 \\
\kws{leq} (\pds{op1}:SInt, \pds{op2}:SInt) & UInt & 1 \\
\kws{gt} (\pds{op1}:UInt, \pds{op2}:UInt) & UInt & 1 \\
\kws{gt} (\pds{op1}:UInt, \pds{op2}:SInt) & UInt & 1 \\
\kws{gt} (\pds{op1}:SInt, \pds{op2}:UInt) & UInt & 1 \\
\kws{gt} (\pds{op1}:SInt, \pds{op2}:SInt) & UInt & 1 \\
\kws{geq} (\pds{op1}:UInt, \pds{op2}:UInt) & UInt & 1 \\
\kws{geq} (\pds{op1}:UInt, \pds{op2}:SInt) & UInt & 1 \\
\kws{geq} (\pds{op1}:SInt, \pds{op2}:UInt) & UInt & 1 \\
\kws{geq} (\pds{op1}:SInt, \pds{op2}:SInt) & UInt & 1 \\
\end{array}
\]
Each operation accept any combination of SInt or UInt input arguements, and always returns a single-bit unsigned integer.
\subsection{Equality Comparison}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{eq}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & 1 \\
\kws{eq}(\pds{op1}:SInt, \pds{op2}:SInt) & UInt & 1 \\
\end{array}
\]
The equality comparison operator accepts either two unsigned or two signed integers and checks whether they are bitwise equivalent.
The resulting value is a 1-bit unsigned integer.
If an arithmetic equals between a signed and unsigned integer is desired, one must first use convert on the unsigned integer, then use the equal primop.
\subsection{Not-Equality Comparison}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{neq}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & 1 \\
\kws{neq}(\pds{op1}:SInt, \pds{op2}:SInt) & UInt & 1 \\
\end{array}
\]
The not-equality comparison operator accepts either two unsigned or two signed integers and checks whether they are not bitwise equivalent.
The resulting value is a 1-bit unsigned integer.
If an arithmetic not-equals between a signed and unsigned integer is desired, one must first use convert on the unsigned integer, then use the not-equal primop.
\subsection{Multiplex}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{mux} (\pds{condition}, \pds{op1}, \pds{op2}) & UInt & width(op1) \\
\kws{mux} (\pds{condition}, \pds{op1}, \pds{op2}) & SInt & width(op1) \\
\end{array}
\]
The multiplex operation accepts three signals, a 1-bit unsigned integer for the condition expression, followed by either two unsigned integers, or two signed integers.
If the condition is high, then the result is equal to the first of the two following operands.
If the condition is low, then the result is the second of the two following operands.
The output is of the same width as the max width of the inputs.
\subsection{Padding Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{pad}(\pds{op}:UInt, \text{num}) & UInt & num \\
\kws{pad}(\pds{op}:SInt, \text{num}) & SInt & num \\
\end{array}
\]
A pad operation is provided which either zero-extends or sign-extends an expression to a specified width.
The given width must be equal to or greater than the existing width of the expression.
\subsection{Reinterpret Bits as UInt}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{asUInt}(\pds{op1}:UInt) & UInt & width(op1) \\
\kws{asUInt}(\pds{op1}:SInt) & UInt & width(op1) \\
\end{array}
\]
Regardless of input type, primop returns a UInt with the same width as the operand.
\subsection{Reinterpret Bits as SInt}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{asSInt}(\pds{op1}:UInt) & SInt & width(op1) \\
\kws{asSInt}(\pds{op1}:SInt) & SInt & width(op1) \\
\end{array}
\]
Regardless of input type, primop returns a SInt with the same width as the operand.
\subsection{Shift Left Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{shl}(\pds{op}:UInt, \text{num}) & UInt & width(op) + num \\
\kws{shl}(\pds{op}:SInt, \text{num}) & SInt & width(op) + num \\
\end{array}
\]
The shift left operation accepts either an unsigned or a signed integer, plus a non-negative integer literal specifying the number of bits to shift.
The resultant value has the same type as the operand.
The output of a shift left operation is equal to the original signal concatenated with $n$ zeros at the end, where $n$ is the shift amount.
\subsection{Shift Right Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{shr}(\pds{op}:UInt, \text{num}) & UInt & width(op) - num \\
\kws{shr}(\pds{op}:SInt, \text{num}) & SInt & width(op) - num \\
\end{array}
\]
The shift right operation accepts either an unsigned or a signed integer, plus a non-negative integer literal specifying the number of bits to shift.
The resultant value has the same type as the operand.
The shift amount must be less than or equal to the width of the operand.
The output of a shift right operation is equal to the original signal with the least significant $num$ bits truncated, where $num$ is the shift amount.
\subsection{Dynamic Shift Left Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{dshl}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & width(op1) + pow(2,width(op2)) \\
\kws{dshl}(\pds{op1}:SInt, \pds{op2}:UInt) & SInt & width(op1) + pow(2,width(op2)) \\
\end{array}
\]
The dynamic shift left operation accepts either an unsigned or a signed integer, plus an unsigned integer dynamically specifying the number of bits to shift.
The resultant value has the same type as the operand.
The output of a dynamic shift left operation is equal to the original signal concatenated with $n$ zeros at the end, where $n$ is the dynamic shift amount.
The output width of a dynamic shift left operation is the width of the original signal plus 2 raised to the width of the dynamic shift amount.
\subsection{Dynamic Shift Right Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{dshr}(\pds{op}:UInt, \pds{op2}:UInt) & UInt & width(op) \\
\kws{dshr}(\pds{op}:SInt, \pds{op2}:UInt) & SInt & width(op) \\
\end{array}
\]
The shift right operation accepts either an unsigned or a signed integer, plus a non-negative integer literal specifying the number of bits to shift.
The resultant value has the same type as the operand.
The shift amount must be less than or equal to the width of the operand.
The output of a shift right operation is equal to the original signal with the least significant $n$ bits truncated, where $n$ is the dynamic shift amount.
The output width of a dynamic shift right operation is the width of the original signal.
\subsection{Convert to Signed}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{toSInt}(\pds{op}:UInt) & SInt & width(op) + 1 \\
\kws{toSInt}(\pds{op}:SInt) & SInt & width(op) \\
\end{array}
\]
The toSInt operation accepts either an unsigned or a signed integer.
The resultant value is always a signed integer.
The output of a toSInt operation will be the same arithmetic value as the input value.
The output width is the same as the input width if the input is signed, and increased by one if the input is unsigned.
\subsection{Negate}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{neg}(\pds{op1}:UInt) & SInt & width(op1) + 1 \\
\kws{neg}(\pds{op1}:SInt) & SInt & width(op1) \\
\end{array}
\]
If the input type is UInt, primop returns the negative value as an SInt with the width of the operand plus one.
If the input type is SInt, primop returns -1 * input value, as an SInt with the same width of the operand.
\subsection{Bitwise Operations}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{bit-not} (\pds{op1:UInt}) & UInt & width(op1) \\
\kws{bit-and} (\pds{op1:UInt}, \pds{op2:UInt}) & UInt & max(width(op1),width(op2)) \\
\kws{bit-or} (\pds{op1:UInt}, \pds{op2:UInt}) & UInt & max(width(op1),width(op2)) \\
\kws{bit-xor} (\pds{op1:UInt}, \pds{op2:UInt}) & UInt & max(width(op1),width(op2)) \\
\end{array}
\]
The above operations correspond to bitwise not, and, or, and exclusive or respectively.
The operands must be unsigned integers, and the resultant width is equal to the width of the wider of the two operands.
\subsection{Reduce Bitwise Operations}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{bit-and-reduce} (\pds{op:UInt}*) & UInt & max(width(op)*) \\
\kws{bit-or-reduce} (\pds{op:UInt}*) & UInt & max(width(op)*) \\
\kws{bit-xor-reduce} (\pds{op:UInt}*) & UInt & max(width(op)*) \\
\end{array}
\]
The above operations correspond to bitwise not, and, or, and exclusive or respectively, reduced over a list of unsigned integers.
The resultant width is equal to the width of the widest operand.
\subsection{Concatenation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{cat}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & width(op1) + width(op2) \\
\end{array}
\]
The concatenation operator accepts two unsigned integers and returns the bitwise concatenation of the two values as an unsigned integer.
The resultant width is the sum of the widths of the two operands.
\subsection{Bit Extraction Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{bit}(\pds{op}:UInt, \text{index}) & UInt & 1 \\
\kws{bit}(\pds{op}:SInt, \text{index}) & UInt & 1 \\
\end{array}
\]
The bit extraction operation accepts either an unsigned or a signed integer, plus an integer literal specifying the index of the bit to extract.
The resultant value is a 1-bit unsigned integer.
The index must be non-negative and less than the width of the operand.
An index of zero indicates the least significant bit in the operand, and an index of one less than the width the operand indicates the most significant bit in the operand.
\subsection{Bit Range Extraction Operation}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
\kws{bits}(\pds{op}:UInt, \text{high}, \text{low}) & UInt & high - low \\
\kws{bits}(\pds{op}:SInt, \text{high}, \text{low}) & UInt & high - low \\
\end{array}
\]
The bit range extraction operation accepts either an unsigned or a signed integer, plus two integer literals that specify the high (inclusive) and low (inclusive) index of the bit range to extract.
Regardless of the type of the operand, the resultant value is a $n$-bit unsigned integer, where $n = \text{high} - \text{low} + 1$.
\section{Circuit Initialization} \label{initialization}
This section describes FIRRTL's facilities for expressing circuit initialization, and how it is customized through the reset port for modules, and the on-reset construct for registers.
\subsection{Module Initialization}
As stated before, all modules must have a port named reset defined.
\subsection{Register Initialization}
By default, a register will not have a initialization value and will not be enabled during reset.
Hence, the default reset behavior for registers is to maintain their current value.
However, an explicit initialization value can be provided for a register by connecting an expression to the register via the on-reset construct.
The following example demonstrates declaring a register, and changing its initialization value to forty two.
\[
\begin{aligned}
& \kw{reg} r : \kws{UInt}<10> \\
& on-reset r := \kws{UInt}<\kws{?}>(42)
\end{aligned}
\]
The type of the initialization value must match the declared type of the register.
In the above example, the register, r, will be set to forty two when the circuit is reset.
Note that structural registers cannot be assigned an initial value because they can only be used on the right side of a connect statement.
\section{Lowered Form}
To simplify the writing of transformation passes, FIRRTL provides a {\em lowering} pass, which rewrites any FIRRTL circuit into an equivalent {\em lowered form}.
The lowered form has the advantage of not having any high-level constructs or composite types, and hence is a minimal representation that is convenient for low-level transforms.
In lowered form, every module has exactly the following form.
\[
\begin{aligned}
&\kw{module} \text{name} : \\
&\quad \pds{port} \ldots \\
&\quad \kw{wire} \ldots \\
&\quad \text{connections to output ports} \ldots \\
\end{aligned}
\]
The body of the module must consist of a list of wire declarations, followed by a series of connect statements.
The following restrictions also hold for modules in lowered form.
\subsection{No Nested Expressions}
In the declaration of the structural elements, the only nested expressions allowed are references, and unsigned and signed literals.
All other nested expressions must be lifted to a named node, and referred to through a reference.
\subsection{No Composite Types}
No module port or wire may be declared with a bundle or vector type.
The lowering pass will recursively expand ports into its constituent elements until all ports are declared with ground types.
\subsection{Single Connect}
Every wire declared can only be assigned to once within a module.
\subsection{No Unknown Widths}
No port or structural element may be declared with unknown width.
The FIRRTL width inferencer will compute the widths for all structural elements and ports.
If a width for some element cannot be calculated, then the lowering pass will fail with an error.
\section{Inlined Lowered Form}
A further (and optional) pass provided by FIRRTL is the inlining pass, which recursively inlines all instances in the top-level module until the top-level module is the only remaining module in the circuit.
Inlined lowered form is essentially a flat netlist which specifies every component used in a circuit and their input connections.
\section{Concrete Syntax}\label{concrete}
This section describes the text format for FIRRTL that is supported by the provided readers and writers.
\subsection*{General Principles}
FIRRTL's text format is human-readable and uses indentation to indicate block structuring.
The following characters are allowed in identifiers: upper and lower case letters, digits, as well as the punctuation characters \verb|~!@#$%^*-_+=?/|.
Identifiers cannot begin with a digit.
Comments begin with a semicolon and extend until the end of the line.
Commas are treated as whitespace, and may be used by the user for clarity if desired.
Statements are grouped into statement groups using parenthesis, however a colon at the end of a line will automatically surround the next indented region with parenthesis.
This mechanism is used for indicating block structuring.
\subsection*{Circuits and Modules}
A circuit is specified the following way.
\begin{verbatim}
circuit name : (modules ...)
\end{verbatim}
Or by taking advantage of indentation structuring:
\begin{verbatim}
circuit name :
modules ...
\end{verbatim}
A module is specified the following way.
\begin{verbatim}
module name : (ports ... stmts ...)
\end{verbatim}
The module body consists of a sequence of ports followed immediately by a sequence of statements.
If there is more than one statement they are grouped into a statement group by the parser.
By using indentation structuring:
\begin{verbatim}
module name :
ports ...
stmts ...
\end{verbatim}
The following shows an example of a simple module.
\begin{verbatim}
module mymodule :
input a: UInt<1>
output b: UInt<1>
b := a
\end{verbatim}
\subsection*{Types}
The unsigned and signed integer types are specified the following way.
The following examples demonstrate a unsigned integer with known bitwidth, signed integer with known bitwidth, an unsigned integer with unknown bitwidth, and signed integer with unknown bitwidth.
\begin{verbatim}
UInt<42>
SInt<42>
UInt<?>
SInt<?>
\end{verbatim}
The bundle type consists of a number of fields surrounded with parenthesis.
The following shows an example of a decoupled bundle type.
Note that the commas are for clarity only and are not necessary.
\begin{verbatim}
{data: UInt<10>,
valid: UInt<1>,
flip ready: UInt<1>}
\end{verbatim}
The vector type is specified by immediately postfixing a type with a bracketed integer literal.
The following example demonstrates a ten-element vector of 16-bit unsigned integers.
\begin{verbatim}
UInt<16>[10]
\end{verbatim}
\subsection*{Statements}
The following examples demonstrate declaring wires, registers, memories, nodes, instances, and accessors.
\begin{verbatim}
wire mywire : UInt<10>
reg myreg : UInt<10>
mem mymem : UInt<10>[16]
inst myinst : MyModule
accessor myaccessor = e[i]
\end{verbatim}
The connect statement is specified using the \verb|:=| operator.
\begin{verbatim}
x := y
\end{verbatim}
The on-reset statement is specified using the on-reset keyword and the \verb|:=| operator.
\begin{verbatim}
on-reset x := y
\end{verbatim}
The conditional statement is specified with the \verb|when| keyword.
\begin{verbatim}
when x : x := y else : x := z
\end{verbatim}
Or by using indentation structuring:
\begin{verbatim}
when x :
x := y
else :
x := z
\end{verbatim}
If there is no alternative branch specified, the parser will automatically insert an empty statement.
\begin{verbatim}
when x :
x := y
\end{verbatim}
Finally, for convenience when expressing nested conditional statements, the colon following the \verb|else| keyword may be elided if the next statement is another conditional statement.
\begin{verbatim}
when x :
x := y
else when y :
x := z
else :
x := w
\end{verbatim}
\subsection*{Expressions}
The UInt and SInt constructors create literal integers from a given value and bitwidth.
The following examples demonstrate creating literal integers of both known and unknown bitwidth.
\begin{verbatim}
UInt<4>(42)
SInt<4>(-42)
UInt<?>(42)
SInt<?>(-42)
\end{verbatim}
References are specified with a identifier.
\begin{verbatim}
x
\end{verbatim}
Subfields are expressed using the dot operator.
\begin{verbatim}
x.data
\end{verbatim}
Subindicies are expressed using the \verb|[]| operator.
\begin{verbatim}
x[10]
\end{verbatim}
Read ports are expressed using the ReadPort constructor.
\begin{verbatim}
ReadPort(m, index, enable)
\end{verbatim}
Write ports are expressed using the WritePort constructor.
\begin{verbatim}
WritePort(m, index, enable)
\end{verbatim}
Primitive operations are expressed by following the name of the primitive with a list containing the operands.
\begin{verbatim}
add(x, y)
add(x, add(x, y))
shl(x, 42)
\end{verbatim}
\end{document}
|