If/Else for combinational assignment generates `always @*` that doesn't initialize
bugupstreambackend:verilog
I think I've found a problem in the verilog generation. I've created a playground example [here](https://amaranth-lang.org/play/#eyJhdiI6InYwLjUuNiIsInMiOiJmcm9tIGFtYXJhbnRoIGltcG9ydCAqXG5mcm9tIGFtYXJhbnRoLnNpbSBpbXBvcnQgU2ltdWxhdG9yXG5mcm9tIGFtYXJhbnRoLmJhY2sgaW1wb3J0IHZlcmlsb2dcbmZyb20gYW1hcmFudGgubGliIGltcG9ydCB3aXJpbmdcbmZyb20gYW1hcmFudGgubGliLndpcmluZyBpbXBvcnQgSW4sIE91dFxuaW1wb3J0IGFtYXJhbnRoX3BsYXlncm91bmRcblxuXG5jbGFzcyBUZXN0TW9kdWxlKHdpcmluZy5Db21wb25lbnQpOlxuICAgIGRhdGFfaW46IEluKDEpXG4gICAgZGF0YV9vdXQ6IE91dCgzKVxuXG4gICAgZGVmIGVsYWJvcmF0ZShzZWxmLCBwbGF0Zm9ybSk6XG4gICAgICAgIG0gPSBNb2R1bGUoKVxuXG4gICAgICAgIGRhdGFfaW5fcmVnID0gU2lnbmFsKClcbiAgICAgICAgbS5kLnN5bmMgKz0gZGF0YV9pbl9yZWcuZXEoc2VsZi5kYXRhX2luKVxuXG4gICAgICAgIHdpdGggbS5JZihkYXRhX2luX3JlZyk6XG4gICAgICAgICAgICBtLmQuY29tYiArPSBzZWxmLmRhdGFfb3V0LmVxKDIpXG4gICAgICAgIHdpdGggbS5FbHNlKCk6XG4gICAgICAgICAgICBtLmQuY29tYiArPSBzZWxmLmRhdGFfb3V0LmVxKDcpXG5cbiAgICAgICAgIyBtLmQuY29tYiArPSBzZWxmLmRhdGFfb3V0LmVxKE11eChkYXRhX2luX3JlZywgMiwgNykpXG5cbiAgICAgICAgcmV0dXJuIG1cblxubSA9IFRlc3RNb2R1bGUoKVxuXG5hc3luYyBkZWYgdGVzdGJlbmNoKGN0eCk6XG4gICAgYXdhaXQgY3R4LnRpY2soKVxuICAgIGN0eC5zZXQobS5kYXRhX2luLCAwKVxuICAgIGF3YWl0IGN0eC50aWNrKClcbiAgICBjdHguc2V0KG0uZGF0YV9pbiwgMSlcbiAgICBhd2FpdCBjdHgudGljaygpXG4gICAgYXdhaXQgY3R4LnRpY2soKVxuXG5zaW0gPSBTaW11bGF0b3IobSlcbnNpbS5hZGRfY2xvY2soMWUtNilcbnNpbS5hZGRfdGVzdGJlbmNoKHRlc3RiZW5jaClcbndpdGggYW1hcmFudGhfcGxheWdyb3VuZC5zaG93X3dhdmVmb3JtcyhzaW0pOlxuICAgIHNpbS5ydW4oKVxuXG5hbWFyYW50aF9wbGF5Z3JvdW5kLnNob3dfdmVyaWxvZyh2ZXJpbG9nLmNvbnZlcnQobSkpXG4ifQ==).
When you use an `m.If(...)`/`m.Else()` for a combinational assignment, an `always @*` block is generated. Now if one of the signals in the (automatically generated) sensitivity list changes, the block will be reevaluated - but it won't be evaluated at the start of the simulation.
That is one of the pitfalls that was fixed with `always_comb` in SystemVerilog. But as it is, this can lead to differences between the Amaranth simulation and other simulators. Even doing a reset does not "fix" this, as the signals in the sensitivity list will just be reset to the value that they already have because they were initialized to it, thus not triggering the `always @*` block.
You can of course work around this issue by just using a `Mux(...)`, which will generate an `assign` statement. When creating multiple assignments that depend on the same conditions, using one `m.If(...)`/`m.Else()` is much cleaner though.
3 条评论