-
Notifications
You must be signed in to change notification settings - Fork 147
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
(Optionally) Sequential Black Boxes #2231
base: master
Are you sure you want to change the base?
Conversation
0843269
to
ae8dcbd
Compare
In NetDecl', the type of the decl was either a HWType or raw text. Since only the HWType branch was ever used in Clash, this should be simplified.
The function `id2identifier` is an unsafe version of `fromCoreId` in the netlist identifier module. It makes more sense for it to be defined there, so callers can see it is obviously unsafe.
When producing sequential and concurrent code, there are restrictions for how the same declared signal can be assigned which depend on the HDL being targeted. In short, these are VHDL: A `signal` can be assigned continuously, or procedurally with non-blocking assignment. A `variable` can only be assigned procedurally with blocking assignment. Verilog: A `wire` can only be assigned continuously. A `reg` can only be assigned procedurally, but can be assigned both non-blocking and blocking. When the backend produces HDL, it needs to know the type of a declaration to render it. With the `WireOrReg` type, this was easy for VHDL, but does not help differentiate between if a signal is intended to be a VHDL signal or variable. A more general type is now provided which provides the extra information to make this choice: ```haskell data Blocking = Blocking | NonBlocking data Usage = Cont | Proc Blocking ``` Since a declaration can accept more than one type of assignment, the usage is not tracked with the declaration like `WireOrReg` was, but tracked in the assignments and a usage map is created for every component (tracking declared signals to their most restrictive use). When producing netlist, the current use of a signal should be checked to ensure that generated code only produces assignments that are valid for the backend being targeted.
The environment of the netlist monad now contains the "style" of HDL to generate, i.e. concurrent or sequential. This is just a refactoring to make the information accessible without needing to thread it through every netlist function.
Depending on the current style of HDL being produced, we want to be able to change the template of black boxes. However, this may change the type of assignment to the result signal in the template. Consider a template for an `fmap` implementation. In a concurrent context we may choose to produce a generate statement, which uses continuous assignment to the result variable. In a sequential context we would instead use a for loop with procedural assignment.
There is now a tag to test if the black box is being rendered in a context which is concurrent or sequential. This allows the template to provide a different implementation when a black box can be implemented in both styles. Somewhat annoyingly, templates can currently be rendered in the wrong context with no warning until the HDL is given to a vendor tool. It may be the case that many templates need to be wrapped with something like ``` ~IF ~ISSEQUENTIAL ~THEN ~ERR["no implementation possible"] ~ELSE ... ~FI ``` or vice-versa for templates that do not allow use in concurrent contexts.
ae8dcbd
to
0c7aa3d
Compare
Me and Leon had a discussion about this a while ago, so I think it makes sense to add what I remember from that here.
I think these were the main points. Anything I forgot @leonschoorl? |
This PR adds the ability to define black boxes which can render in concurrent and sequential contexts. A new template tag
~ISSEQUENTIAL
is provided, which templates can use to provide alternative implementations for the two contexts.NOTE: This branch is based off #2230, not
master
, so that should be merged firstStill TODO:
Vector.map
etc. which can be defined in both contexts)