-
Notifications
You must be signed in to change notification settings - Fork 71
copilot-bluespec: Flip direction of interface inputs and outputs in Bluespec. Refs #677.
#678
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
base: master
Are you sure you want to change the base?
copilot-bluespec: Flip direction of interface inputs and outputs in Bluespec. Refs #677.
#678
Conversation
ec63500 to
b7573e4
Compare
|
I'm not quite sure why Travis CI is timing out... any ideas? |
| Nothing | ||
| [] | ||
| (BS.CQType [] (tWire `BS.TAp` transType ty)) | ||
| (BS.CVar (BS.mkId BS.NoPos "mkBypassWire")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change Manager: Does this work with multiple externs and multiple triggers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! When compiling a Copilot specification with multiple externs, mkExtWireDecln is called on each extern, thereby producing a separate Wire value for each extern:
mkExample :: Module ExampleIfc;
mkExample =
module {
extern1_wire :: Wire (UInt 8) <- mkBypassWire;
extern2_wire :: Wire (UInt 8) <- mkBypassWire;
...Where the externs are named extern1, extern2, etc.
Multiple triggers are also supported, although the mkExtWireDecln function doesn't interact directly with the compilation of triggers.
| [ BS.PIPrefixStr "" | ||
| , BS.PIArgNames [BS.mkId BS.NoPos $ fromString $ lowercaseName name] | ||
| ] | ||
| (BS.tArrow `BS.TAp` transType ty `BS.TAp` BS.tAction) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change Manager: What is this?
(BS.tArrow BS.TAptransType tyBS.TAp BS.tAction)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is the Bluespec abstract syntax for the type ty -> Action, which is the type of the generated interface method for an extern.
Like in Haskell, the function type (->) is represented as a type constructor that is applied (using BS.TAp, short for "type application") to two type arguments, the argument type <ty> and the result type Action. As a result, the AST for this type is:
BS.TAp BS.tArrow (BS.TAp (transType ty) BS.tAction)It becomes a bit difficult to read these ASTs when there are a lot of applications (i.e., a lot of BS.TAps) involved, so I usually write the BS.TAp applications as infix to cut down on the amount of parentheses required. This is just a stylistic preference, however—I'm fine with writing using prefix applications (like in the code shown above) if you'd prefer that.
| -- language-bluespec's pretty-printer will error if it | ||
| -- encounters a CSletrec with an empty list of definitions, so | ||
| -- avoid generating a CSletrec if there are no streams. | ||
| [ BS.CMStmt $ BS.CSletrec genFuns | not (null genFuns) ] ++ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change Manager: Is this (map (BS.CMStmt . BS.CSletRec) genFuns)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, they're not the same. Your suggested code wouldn't typecheck, as CSletrec expects [BS.CDefl] as an argument, whereas your code would only typecheck if BS.CSletrec took a single BS.CDefl as an argument.
|
Change Manager:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change Manager: See individual comments.
…luespec. Refs Copilot-Language#677. The current Bluespec backend leads to Verilog code that requires manual manipulations in order to work correctly. Specifically, Copilot externs, which are inputs to the Copilot monitoring system, are treated as _outputs_ in Verilog, and Copilot triggers, which can be considered outputs of the monitoring system, are treated as _inputs_. This order of inputs and outputs is the opposite what we would like users to work with, and of what other backends generate (e.g., C99). This commit updates the internals of `copilot-bluespec` to flip the order in which generated Bluespec module interfaces declare their inputs and outputs. A module interface now represents each Copilot extern as a method of type `<ty> -> Action` (where `<ty>` is the type of the extern), as this type directly translates to a Verilog input. Moreover, a module interface now represents trigger arguments as interface methods of type `<ty>_i`, where each `<ty>_i` is the type of each trigger argument. Each `<ty>_i` directly translates to a Verilog output. In addition to changing the module interface definitions, this commit also changes the generated modules that instantiate the new interfaces. One of the more notable changes is that all extern values are stored as a Bluespec `Wire` in the module internals, as using `Wire`s leads to compact Verilog code without adding any user-visible inputs or outputs. Every time a value is read from an extern, the corresponding `Wire` must be read from, which means that several parts of the module internals have been updated to reference these `Wire`s.
…new input/output order. Refs Copilot-Language#677. The current Bluespec backend leads to Verilog code that requires manual manipulations in order to work correctly. Specifically, Copilot externs, which are inputs to the Copilot monitoring system, are treated as _outputs_ in Verilog, and Copilot triggers, which can be considered outputs of the monitoring system, are treated as _inputs_. This order of inputs and outputs is the opposite what we would like users to work with, and of what other backends generate (e.g., C99). A prior commit has updated the internals of `copilot-bluespec` to invert the order in which Verilog inputs and outputs are declared. This commit adapts the top-level code in `Copilot.Compile.Bluespec.Compile` accordingly. In particular, the `compileWith` function now generates a `<Prefix>.bs` file that defines two module interfaces: one interface that contains the core methods that will comprise the generated Verilog code, and another interface that helps automate the process of defining a `Module Empty` value that is more suitable for software simulation purposes. Previously, `compileWith` generated a separate `<Prefix>Ifc.bs` file that contained nothing but the module interface in isolation so that it could be used separately from the interface's `Module` definition. This distinction no longer makes as much sense, as in the new design, as (1) there are now multiple interfaces, and (2) it is unlikely that the interfaces are not particularly useful without having the `Module` definitions to accompany them. As such, this commit now omits generating a `<Prefix>Ifc.bs` file, instead opting to generate the interfaces as part of `<Prefix>.bs`.
…Refs Copilot-Language#677. The current Bluespec backend leads to Verilog code that requires manual manipulations in order to work correctly. Specifically, Copilot externs, which are inputs to the Copilot monitoring system, are treated as _outputs_ in Verilog, and Copilot triggers, which can be considered outputs of the monitoring system, are treated as _inputs_. This order of inputs and outputs is the opposite what we would like users to work with, and of what other backends generate (e.g., C99). A prior commit has updated the internals of `copilot-bluespec` to invert the order in which Verilog inputs and outputs are declared. This commit updates the test suite to work with the new design. In addition to changing the code to reflect the new order of inputs and outputs, this commit also updates the names of some internal variables from "`input`" to "`input1`". This change is necessary because "`input`" is a reserved keyword in Verilog, and giving a Bluespec interface method the same name as a reserved Verilog keyword becomes an error when the interface is used in the result type of a synthesized module.
… Refs Copilot-Language#677. The current Bluespec backend leads to Verilog code that requires manual manipulations in order to work correctly. Specifically, Copilot externs, which are inputs to the Copilot monitoring system, are treated as _outputs_ in Verilog, and Copilot triggers, which can be considered outputs of the monitoring system, are treated as _inputs_. This order of inputs and outputs is the opposite what we would like users to work with, and of what other backends generate (e.g., C99). A prior commit has updated the internals of `copilot-bluespec` to invert the order in which Verilog inputs and outputs are declared. This commit updates the prose in the `DESIGN.md` document to reflect the new design. The new design is just different enough from the old one that it made sense to completely rewrite certain portions of the document. One of the more notable changes is that there are now separate sections about running the generated Verilog code on hardware versus simulating the generated code in software, as these are distinct use cases that require separate discussion.
b7573e4 to
5577557
Compare
The former. Whenever you run mkMod :: Module <Ifc> -> Module EmptyHere, the result type is After this PR, however, we now compile mkMod :: Module <Ifc>Now Bluespec does check if |
|
Implementor: Fix implemented, review requested. |
The current Bluespec backend leads to Verilog code that requires manual manipulations in order to work correctly. Specifically, Copilot externs, which are inputs to the Copilot monitoring system, are treated as outputs in Verilog, and Copilot triggers, which can be considered outputs of the monitoring system, are treated as inputs. This order of inputs and outputs is the opposite what we would like users to work with, and of what other backends generate (e.g., C99).
This PR updates
copilot-bluespecto flip the order in which generated Bluespec module interfaces declare their inputs and outputs. A module interface now represents each Copilot extern as a method of type<ty> -> Action(where<ty>is the type of the extern), as this type directly translates to a Verilog input. Moreover, a module interface now represents trigger arguments as interface methods of type<ty>_i, where each<ty>_iis the type of each trigger argument. Each<ty>_idirectly translates to a Verilog output.In addition to changing the module interface definitions, this PR also changes the generated modules that instantiate the new interfaces. One of the more notable changes is that all extern values are stored as a Bluespec
Wirein the module internals, as this leads to compact Verilog code without adding any user-visible inputs or outputs. Every time a value is read from an extern, the correspondingWiremust be read from, which means that several parts of the module internals have been updated to reference theseWires.This PR also updates the test suite and
DESIGN.mddocument accordingly.Fixes #677.