-
Notifications
You must be signed in to change notification settings - Fork 211
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
Migen outputs incorrect verilog in specific use-case #119
Comments
Yes it's a bug; can you patch it, test it carefully, and send a PR? |
Sure, let me give it a try. |
…) blocks, as reg instead of wire Fixes m-labs#119 Currently, the migen code assumes that all outputs from specials must be wire, which is true logically. But wires can also be assigned inside always(*) blocks, which then should be declared as regs. Solution: We find out all the output signals from specials (set special_outs_only). Then we make a list which has comb statements grouped-by-target signals. We look whether signals in this list are present in `special_outs_only` set or not. If they are , we remove those signals from the wires set. Signed-off-by: Rohit Singh <rohit91.2008@gmail.com>
@sbourdeauducq, @jordens and @whitequark: Could you please review this commit: rohitk-singh@b3206e2 It seems to solve the above issue. |
If the way to solve it is to allow special outputs to be |
sort-of related question: in general, it is considered "good verilog" to use only blocking assignments in combinational (e.g., "always @(*)" blocks, and I noticed that migen uses nonblocking "<=" throughout all such blocks. I wonder if simply generating "="s instead of "<="s for combinational (note: NOT synchronous) blocks wouldn't be a better fix? |
Triage: fixed in nMigen. |
I wrote a Migen code which used MultiReg for signal synchronization across clock domains and the relevant section is similar to the test code below:
The verilog output of this code is:
Incorrect Code Section
Complete generated verilog file (cleaned up) :Issue
The problem with above generated verilog is that
done[1:0]
is declared aswire
instead of being declared asreg
since it is being assigned inside thealways
block.It might be fault of the coding style used in the above test code, but creating object with Test(1) instead of Test(2) gives correct output: https://hastebin.com/jiwomizawe.scala
Also, if I refactor the code to this:
then I get correct verilog output -> https://hastebin.com/bujarijeqe.scala
I can definitely use the refactored code to get intended output but just wanted to confirm whether this is a bug or not.
The text was updated successfully, but these errors were encountered: