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
|
================================================
========== ADAM's BIG ARSE TODO LIST ============
================================================
======== Current Tasks ========
Add/Update Unit Tests for each pass
Check after each pass
write test that checks instance types are correctly lowered
error on uninitialized wires
ensure module names are unique
add check that limits size of width of dshl
add efficient prefix checker
Change to new low firrtl
add clock type
add clock, reset to reg, mem etc
change parser to accept subword, but error
move width inference earlier
Required for subword assignment, consistent vec width inference, and supporting the new constructs of tobits/frombits
Temp elimination needs to count # uses
Declared references needs to understand scope <= check in high form check
Check for recursively defined instances
Names in bundles must be unique
Fix reset scope
Scaling
Do name-mangling differently, use _xEF or something like that
Add alpha transform pass
======== Verilog Backend Notes ========
* 1) Emit module. No Parameters. Include clk and reset signals
o 2) Emit all declarations (wires,regs)
o 3) Initialize all regs with random values under synthesis
o 4) Emit all connections as assign statements
o 5) Emit assertions under always @ posedge clk, under synthesis
o 6) Emit all register updates:
if(io_update_valid) begin
R4 <= io_update_bits_target;
end
Note: muxes turn into if/else statements within the always@ block
Notes:
For now, emit mems as reg with nothing else.
WritePorts?
Checks:
names in fields should be special renamed
widths are -1 of size
zero width?
======== Update Core ==========
Add bi-accessor
Add RdWrPort
Add SubwordConnect
Add clock, reset to reg
Add clock to cmem, smem
Add clock to Direction, make sure it all works
Remove concrete syntax from EmptyStmt()
======== Check Passes ==========
High-Firrtl
No combinational loops
Clocks are used correctly
Restrictions on subword assignments
After adding dynamic assertions, insert bounds check with accessor expansion
Width inference
No names
No Unknowns
All widths are positive, and nonzero
Pad's width is greater than value's width
pad's width is greater than value's width
connect can connect from big to small?? <- I think this shouldn't be allowed
Width pad check?
======== Other Passes ========
constant folding (partial eval) pass
Get rid of unnecessary pads
push pad into literal
common subexpression elimination pass
deadcode elimination
======== Consultations ========
Andrew: Way to keep Array information for backends to avoid code explosion
======== Think About ========
subword accesses
verilog style guide
annotation system
zero-width wires
expanding mems (consider changing defmem to be size, and element type)
Multi-streams for print statements/asserts (Jack)
Consider def female node. (Patrick)
Add FIFOs to the IR (Palmer)
Union Types
Enums?
Convert to scala
Firrtl interpreter (in scala)
======== Update Spec ========
Add explanation of an instance type, ie converting from input/output to default/reverse
also, can only be used on the right side of :=
Add assert statement explanation
think about printfs
think about subword on accessors, non-ground types
think about mems in lowered form - change ReadPort's reference to mem to be either exp or id
think about ROMS
think about how widths propagate - add section explicitly addressing this
FIRRTL rule: No name can be a prefix of any other name.
Future questions to address in spec:
Introduction – motivation, and intended usage
Philosophical justifications for all constructs
More introduction for types, e.g. what is a ground type?
What is a statement? What is an expression? What is a memory? Difference between vector type and memory? What are accessors for?
Why would I ever write an empty statement? Mainly for use by compiler/passes
What is a structural element? Duplication?
Subtracting two unsigned numbers… Should talk to a math guy to figure it out
What are shift left and shift right operations? HW doesn’t have these concepts. Need justification.
What is lowered form? What is it for?
======== Pass Ideas ==========
Bounds checks for accessors
Overflow checks for add/add-wrap
Check combinational
Fast C++ where wires/register/instances are predicated
Verilog backend - put stuff in posedge clock, not assign statements, for speedup
Annotate mems with location stuff
Coverage tests, such as statespace or specific instances (like asserts, sort of)
check all predicates of whens
Generate a ROM, and index with cycle counter, and dynamically check any wire on a given cycle
======== FIRRTL++ =========
Variable size FIFOs
TruthTable node
Custom types? Parameterized Types?
======== Next Layer Components =======
Accelerator with config registers
Schedulable
Decouple
Nack
Scheduler
======== Notes ========
Which ones
Treat everything as just bits - the only operators that should exist are ones that emit different bits
Go through all primops with Andrew
|