Add translation support for case.
Hi, and I'm using PyMTL to design hardware where we need to generate different case statements according to the given arguments. I have searched for anything about "case" in the source code but I don't think the case statement is supported at present? Do you have plan for it? Thanks!
Hi Xusine1131,
Thanks for your interest. We are always aware of the absence of case statements and have discussed how to implement them. However, we haven't found any good solution to implement that as of now, unfortunately.
There is no Python syntax for statement that we can take advantage of. I would imagine we could desing some new description primitive for case statements like a function, but it might be pretty difficult to make it succinct, Pythonic and work for both simulation and translation. Also people use wildcard casez statements using question marks like 4'b1??? which is not very easy to support in Python either.
Shunning
You might want to checkout what nmigen did. Sorry on my phone otherwise would provide a direct link.
You might want to checkout what nmigen did. Sorry on my phone otherwise would provide a direct link.
Well if the framework lets the user write code to construct AST node then we can support them too but that's not going to be behavioral code.
Thanks for your response @jsn1993. And here is my idea:
- A normal case is that sometimes we need to build a LUT with the case statement, and I think we can convert an array in Python to a case statement in Verilog?
- For general cases, the case statement is somehow a mapping logic, which is quite similar to a dictionary in Python? Or can we just create a calss and override the
__getitem__? In fact, I'm not sure these will be feasible. Thanks again!
Thanks for your response @jsn1993. And here is my idea:
- A normal case is that sometimes we need to build a LUT with the case statement, and I think we can convert an array in Python to a case statement in Verilog?
- For general cases, the case statement is somehow a mapping logic, which is quite similar to a dictionary in Python? Or can we just create a calss and override the
__getitem__? In fact, I'm not sure these will be feasible. Thanks again!
Thanks for the ideas. I guess you are suggesting predicated execution in an update block which can work but might not be general enough for all kinds of case statements. We will keep you posted. @cbatten thoughts?
If the cases are mutually exclusive you can just use a series of independent if statements. Might be interesting to see how much of an impact that has on post-synthesis QOR?
nMigen is a completely different approach. PyMTL3 uses real pythonic constructs to represent behavioral constructs. This enables us to really use the power of regular Python when doing higher level and lower level modeling. nMigen has their own syntax for constructing behavioral constructs like if/else/loops etc ... this makes nMigen pure-python simulation very painful, while pure-python PyMTL3 sim can be very fast ... but the trade-off is PyMTL3 is more pythonic so some HDL features like case statements don't have direct mappings.
One thing that would be neat to explore is automatic case inference from if-then-else structures. This is what MyHDL does: http://docs.myhdl.org/en/stable/manual/conversion.html
"Python does not provide a case statement. However, the converter recognizes if-then-else structures in which a variable is sequentially compared to items of an enumeration type, and maps such a structure to a Verilog or VHDL case statement with the appropriate synthesis attributes."
That should be very much doable for regular case statements. casez statements are another ball game that would need some kind of syntatic sugar like @jsn1993 is hinting at ...
What might be really neat is to see apples-to-apples post synthesis QOR comparisons of if/then/else vs case ... that would help motivate work on this issue.
FYI, here is how nMigen encodes a case statement
- https://github.com/m-labs/nmigen/blob/3d04122d55699fb4dfee146995239596a0e64c8a/examples/basic/pmux.py#L15-L23
Thank you! @cbatten But I think for users, there might be a difference between the case statement and the if-else statement. Sometimes we just want to convert an array or a dictionary, (apparently it's possible to write a script from scratch to do so.) and in that case, a series of if-else is not concise?
For the PPA difference of the case statement and the if-else statement, I can help. I think I can start from two Verilog files where the same LUT is implemented in two different ways. Then we can compare the result from the Design Compiler. Do you have any suggestions?
I actually don’t think a series of if statements would be all that bad syntactically. This is actually exactly how we implement LUTs in PyMTL and it has never been a huge issue. Note that if you really really want a case statement for PPA you can always write it in Verilog and import it into PyMTL3 as a black box.
@cbatten Thanks! I get the point.