-
Notifications
You must be signed in to change notification settings - Fork 53
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
Precise go/done interface #405
Comments
Thanks for writing this up, @rachitnigam; it certainly is odd! I don't exactly know how to proceed, but I thought I'd just add a tad more color to the problem as it stands (if I understand correctly): As a base assumption, this would be a nice property to have: The go/done interface looks the same to from the perspective of a given group, regardless of its invoking context. In other words, a group knows what its "job" is when interacting with the outside world—and this job doesn't change for different settings the group might appear in. In practice, Calyx currently only has two ways that it creates "invoking contexts" for groups: latency-insensitive FSMs (from CompileControl) and latency-sensitive FSMs (from Sensitive). @rachitnigam's argument above tries to show that a go/done interface actually behaves differently in these two settings. The consequence is that we either need a flexible definition of the go/done interface that will capture both settings, or we need to rectify the two so they behave exactly the same (and hence a simpler, less flexible go/done definition will suffice). Concretely, the latency-sensitive case is pretty straightforward; |
The current resolution for this is generating latency-insensitive FSM transitions like this when compiling
|
At many points, we have informally stated the go/done interface as "
go
must be kept high for the duration of the execution of the component anddone
is set to high in the cycle after the component is finished executing."Stated formally, we can ask: Given a component with latency
L
, does thego
signal stay active forL
cycles orL+1
cycles?The implementation of this interface in the compiler provides two potentially* contradicting answers to this:
Structurally Invoking Components
The canonical "correct" way of structurally invoking a component is:
In this program, the
go
signal is set to1
forL + 1
cycles. The following sequence of events happen:comp.go
is set to high sincehas_run.out = 0
.comp.done
becomes high andhas_run.out
andhas_run.write_en
are set to 1.has_run.out
becomes 1 andcomp.go
is set to0
.Latency-Sensitive Compilation
A
static
annotation of a group provides the latencyL
of the group or the component. We use this information to transition the controller FSM without waiting for thedone
signal in the group.In this program,
comp.go
is kept high for exactlyL
cycles.Potentially Conflicting
These implementation are only potentially conflicting: it might be reasonable to say that the
go
signal can be0
or1
in the cycle when thedone
signal is high. After all, this extra cycle represents the coordination required for latency-insensitive compilation.However, we need to be precise about one thing: when does setting the
go
signal start a "new" invocationThe text was updated successfully, but these errors were encountered: