Skip to content

ice40_dsp: fix const handling #4992

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

Anhijkt
Copy link
Contributor

@Anhijkt Anhijkt commented Apr 5, 2025

What are the reasons/motivation for this change?
ice40_dsp seems to incorrectly handle unsigned consts. The issue seems to be with unextend function. By searching previous issues I could find this one #2648.
Explain how this is achieved.
Now unextend is called only on non constant inputs.
If applicable, please suggest to reviewers how they can test the change.

read_verilog << EOT
module top(input wire [14:0] a, output wire [31:0] b);
assign b = a*$unsigned(5'b01111);
endmodule
EOT

prep
ice40_dsp
write_rtlil
read_verilog << EOT
module top(input wire signed [14:0] a, output wire signed [31:0] b);
assign b = a*$signed(5'b01111);
endmodule
EOT

prep
ice40_dsp
write_rtlil

Gives two different connect \B values in \SB_MAC16 cell on pre-PR code, and the same value on post-PR code.

@widlarizer
Copy link
Collaborator

Please add a regression test. If you have the time, can you check techlibs/xilinx/xilinx_dsp.pmg too? It seems like either is the copy of the other, and they differ exactly on const handling. Maybe what xilinx_dsp.pmg does is somehow a more correct fix, or the other way around. Thanks for your contributions!

@Anhijkt
Copy link
Contributor Author

Anhijkt commented Apr 9, 2025

I tried to copy xilinx code, but it(and microchip_dsp.pmg) seems to fail on the same issue. Also I mistaken this bug for const-only, turns out this is an issue with handling all unsigned signals (for example a*$unsigned({7'b1110101, b})), so I think there is other way to fix it.

@Anhijkt
Copy link
Contributor Author

Anhijkt commented Apr 10, 2025

Also I want to note that in first example, the issue was not just with ice40_dsp, unextend can handle $unsigned(5'b01111), the problem is with wreduce in prep, that reducing it into $unsigned(4'b1111).

@Anhijkt
Copy link
Contributor Author

Anhijkt commented Apr 11, 2025

The previous commit did not optimize unsigned zero-leading signals unlike the original code. But it also differs from original when handling signals like $unsigned({a[n], a[n], a}) where n is the index of last bit of signal a. If original unextend would optimize it into $unsigned({a}) this code leave it unchanged. I dont know which implementation is more accurate, so I think I need feedback on this one.

Copy link
Collaborator

@widlarizer widlarizer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure the old behavior wasn't right. You can't unextend an unsigned 110 into a 10, for example. The current version looks good. There are other DSP PMG passes where an unextend function is cobbled together but let's consider that out of scope for this PR and moved into #5059

@widlarizer widlarizer added the merge-soon Merge: PR will be merged at the end of the next work day unless concerns are raised label Apr 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge-soon Merge: PR will be merged at the end of the next work day unless concerns are raised
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants