-
Notifications
You must be signed in to change notification settings - Fork 0
Description
(Summary of this Slack discussion)
To evaluate the expressivity of our language, we can build a compiler from Filament type signatures that only mention one single event to straight-line protocols. Examples:
Note that we use DontCare assignments to indicate when a DUT input port is no longer available (i.e. the time has exceed its availability interval the Filament type for the port).
Implementation sketch:
cdinto the Filament repo and runcargo run <prog> --dump-interface, which extracts themainFilament module's type signature into a JSON object.- In a separate package within the existing Protocols cargo workspace, parse the JSON and use the latency / delay information from the Filament type to determine how many
step()s to insert and where to insert thefork(), following the images above. Also insert DUT port assignments /DontCareassignments accordingly. - We will want to check that the generated Protocols program behaves the same as the original Filament program. I think we can do this by running the Protocols interpreter with the generated Protocols spec against the Verilog that the Filament program compiles to, and seeing if the Protocols interpreter succeeds. (This checks if the generated spec faithfully models the Filament program.)
- We can build up a test suite of Filament programs that compile to straight-line Protocols. For each source Filament program, we will want two Turnt snapshot tests:
- One which checks that the generated straight-line protocol remains the same (given the same JSON representation of a Filament type)
- One which checks that the Protocols interpreter accepts the generated protocol as a spec for the Verilog that the Filament compiles to
What remains to be done:
This model only works for Filament types that have one single event. We need to think about how to handle Filament types that mention two events (e.g. the following Filament type for a combinational adder, which mentions two events G and L):
comp Add<G: L-G, L: 1>(@[G, L] l: 32, @[G, L] r: 32) -> (@[G, L] o: 32) where L > G
This type signature means if the inputs are provided for multiple cycles, then outputs will be provided for the same amount of cycles.
Rachit mentioned that this should result in some Protocols program which behaves the same as a Filament module which triggers the @interface signal for G before L. In other words, the target Protocols program should find some way of ensuring that event G happens before L. Maybe this can be done by including some extra control pins in the compiled Protocols program which are modified at the right times? (e.g. one for G and one for L) Need to think a bit more about this.
Alternatively, perhaps we could express this range of timing behaviors if our language adopted the non-deterministic loop / fixed loop-iteration operators mentioned in #167.
Rachit also mentioned there is a test case in the Filament repo which contains 3 events -- might be good to look into that.
Assuming we find a work around to handle multiple events, we should be able to handle all Filament types (including ones in the follow-up language Lilac, since all Lilac types compile to base Filament via elaboration and are type-checked again).