Skip to content
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

ice40_dsp: fix const handling #4992

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 is 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants