-
Notifications
You must be signed in to change notification settings - Fork 28
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
stateful declarations shouldn't be allowed in conditions (was: what happens when you read from inactive enum variants) #255
Comments
For registers, this should do what you want. I.e., That example should simulate the same with the register inside or outside the match (just like with a You do bring up a good point about other circuit components, specifically wires and instances. If
CIRCT will take interpretation (1) for reasons that this is what the Scala-based FIRRTL Compiler did. However, I don't actually think that there is a reason why it can't be invalidated other than there is legacy Chisel code that is relying on this behavior. The problematic case is where a user has instantiated a module under a I've toyed with a radical change to the FIRRTL spec which would disallow any statement under a conditional statement other than connects. This avoids all of the ambiguity here. |
afaict that's not right. The spec describes how connects depend only on the conditions in between the destination declaration and the connect: Lines 1908 to 1912 in f3b0034
for the code: FIRRTL version 3.2.0
circuit test:
module test:
input clk: Clock
input a: UInt<1>
input b: UInt<1>
output o: UInt<1>
connect o, UInt<1>(0)
when a:
reg r: UInt<1>, clk
connect r, b
connect o, r the // -----// IR Dump Before ExpandWhens (firrtl-expand-whens) //----- //
firrtl.module @test(in %clk: !firrtl.clock, in %a: !firrtl.uint<1>, in %b: !firrtl.uint<1>, out %o: !firrtl.uint<1>) attributes {convention = #firrtl<convention scalarized>} {
%c0_ui1 = firrtl.constant 0 : !firrtl.uint<1>
firrtl.matchingconnect %o, %c0_ui1 : !firrtl.uint<1>
firrtl.when %a : !firrtl.uint<1> {
%r = firrtl.reg interesting_name %clk : !firrtl.clock, !firrtl.uint<1>
firrtl.matchingconnect %r, %b : !firrtl.uint<1>
firrtl.matchingconnect %o, %r : !firrtl.uint<1>
}
}
// -----// IR Dump After ExpandWhens (firrtl-expand-whens) //----- //
firrtl.module @test(in %clk: !firrtl.clock, in %a: !firrtl.uint<1>, in %b: !firrtl.uint<1>, out %o: !firrtl.uint<1>) attributes {convention = #firrtl<convention scalarized>} {
%c0_ui1 = firrtl.constant 0 : !firrtl.uint<1>
%r = firrtl.reg interesting_name %clk : !firrtl.clock, !firrtl.uint<1>
firrtl.matchingconnect %r, %b : !firrtl.uint<1>
%0 = firrtl.mux(%a, %r, %c0_ui1) : (!firrtl.uint<1>, !firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
firrtl.connect %o, %0 : !firrtl.uint<1>
} |
For wires, and any other stateless constructs, it shouldn't matter what value wires take when the conditionals their declaration is in are not active, since you can't read them then. For any stateful constructs it does matter.
Imo some stuff should still be allowed under conditionals:
|
I noticed that firrtl lets you read from inactive enum variants using code like:
note how if
a
is false, it still writesv
tor
, which you can then read in the next clock cycle.this makes me think that putting stateful logic elements in a conditional block is a misfeature because state changes still occur even when the conditional block is not active.
The text was updated successfully, but these errors were encountered: