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

Incorrect CSE in multi-drive conflict scenario #5099

Open
mathis-s opened this issue May 3, 2024 · 2 comments
Open

Incorrect CSE in multi-drive conflict scenario #5099

mathis-s opened this issue May 3, 2024 · 2 comments
Labels
status: ready Issue is ready for someone to fix; then goes to 'status: assigned'

Comments

@mathis-s
Copy link

mathis-s commented May 3, 2024

bug.zip

It seems like incorrect CSE occurs in the attached multi-drive conflict scenario. In particular, a multi-driven conflicting wire seems to still be used for CSE even when its actual value is undefined due to the conflict.

In the attached example, two independent 3-input ANDs are implemented via replication of the Bug module (which implements a single 3-input AND). The behavior of these ANDs should be entirely independent of one another. Due to erroneous CSE involving the conflicting output however, this is not the case.

SV files again as snippets:

module Bug
(
    input wire a,
    input wire b,
    input wire c,

    output wire conflicting,
    output wire regular
);

assign conflicting = a & b;
assign regular = a & b & c; // CSE turns this into seemingly correct `conflicting & c`
endmodule
module Top
(
    input wire a[1:0],
    input wire b[1:0],
    input wire c[1:0],
    output wire regular[1:0]
);

wire conflict; // erroneously driven by both instances of mod
Bug bug[1:0](a, b, c, conflict, regular);
endmodule

The bug is also apparent in the generated CPP:

Top__DOT__conflict = (vlSelf->a[1U] & vlSelf->b
                        [1U]);
vlSelf->regular[1U] = ((IData)(Top__DOT__conflict) 
                        & vlSelf->c[1U]);
vlSelf->regular[0U] = ((IData)(Top__DOT__conflict) 
                        & vlSelf->c[0U]);

What 'verilator' command line do we use to run your example?
verilator --cc --exe --build -j 0 Top_tb.cpp Top.sv Bug.sv

What 'verilator --version' are you using? Did you try it with the git master version?
Verilator 5.022 2024-02-24 rev UNKNOWN.REV

What OS and distribution are you using?
6.6.19-1-MANJARO

@mathis-s mathis-s added the new New issue not seen by maintainers label May 3, 2024
@gezalore
Copy link
Member

gezalore commented May 3, 2024

Thanks for the small test case, if you need a workaround -fno-dfg probably would prevent the CSE, but note that multiple driver resolution in this case is not handled well in Verilator in general.

@mathis-s
Copy link
Author

mathis-s commented May 3, 2024

Thanks! This fortunately isn't a real issue for me either. I just stumbled across this while debugging and thought you might want to have a look

@wsnyder wsnyder added status: ready Issue is ready for someone to fix; then goes to 'status: assigned' and removed new New issue not seen by maintainers labels May 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: ready Issue is ready for someone to fix; then goes to 'status: assigned'
Projects
None yet
Development

No branches or pull requests

3 participants