Open alanvgreen opened 2 years ago
with m.If(self.edge_detect(m, self.up)):
The use of m
both in a calling function and in a callee in this way is not supported. This is true even if you are not using self.edge_detect(m, ...)
inside of a conditional expression (see below), but when used in a conditional expression it just breaks.
The reason it's not supported is that the following code (still using your edge_detect
function):
is_down = self.edge_detect(m, self.down)
with m.If(...):
m.d.sync += self.output.eq(is_down)
has very different semantics from the code below:
with m.If(...):
is_down = self.edge_detect(m, self.down)
m.d.sync += self.output.eq(is_down)
which does not match how Python functions, variables, and scoping normally work, and is very likely to be a source of obscure bugs, as the edge detector circuit will gain an additional enable input that will no longer make it work like an edge detector.
That said, the error it's currently raising is nonsensical, and the rule I'm talking about should be a warning (or an error), rather than something that is silently accepted.
I also have some ideas on letting people use functions without the scoping hazard I described, though that would need an RFC.
Thanks for taking the time to write such a complete response. I learned something new.
The use of m both in a calling function and in a callee in this way is not supported.
I think I see the problem I created: by calling edge_detect()
inside the Elif
condition, perhaps the inverse condition of the If
applies to it. If that is so, then it the code snippet created by edge_detect()
has an extra enable input, and last
created by edge_detect()
is only updated when the If condition is false. In short, that code is ambiguous and hard to understand, and I ought to write it differently.
I tend to lean into using Python as a macro language for Amaranth, which is convenient, but m
gets passed around a lot. Some guidance (as an error message or extra documentation) around when functions that use m
can be called and when not would be very helpful.
Some guidance (as an error message or extra documentation) around when functions that use
m
can be called and when not would be very helpful.
I agree. Let's keep ths open, since at the very least the error you're hitting is wrong.
I'm getting a syntax error when using a function call that creates a signal inside an Elif.
I can understand why this kind of function call might be problematic in a Python DSL, however I'm raising a bug because this code looks like it ought to be valid. If it's breaking a rule, I'm not sure what the rule is.
fails with:
However, when the condition is calculated outside the Elif, it works