amaranth
amaranth copied to clipboard
Conditional assignment to a slice can generate invalid Verilog
The following code
from amaranth import *
import amaranth.back.verilog
m = Module()
output = Signal(2)
enable = Signal()
with m.If(enable):
m.d.comb += output[0].eq(1)
with open('test.v', 'w') as f:
f.write(amaranth.back.verilog.convert(
m, ports=[enable, output],
emit_src=False))
generates this Verilog
/* Generated by Yosys 0.21+18 (git sha1 0ab726e20, clang 10.0.0-4ubuntu1 -fPIC -Os) */
(* \amaranth.hierarchy = "top" *)
(* top = 1 *)
(* generator = "Amaranth" *)
module top(\output , enable);
reg \$auto$verilog_backend.cc:2083:dump_module$1 = 0;
input enable;
wire enable;
output [1:0] \output ;
reg [1:0] \output ;
always @* begin
if (\$auto$verilog_backend.cc:2083:dump_module$1 ) begin end
\output [0] = 1'h0;
casez (enable)
/* src = "/home/user/test.py:9" */
1'h1:
\output [0] = 1'h1;
endcase
end
assign \output [1] = 1'h0;
endmodule
I think that this is invalid, because \output is a reg but there is a continuous assignment for \output[1] (Vivado rejects this code).
As a workaround, we can add
with m.If(enable):
m.d.comb += output[1].eq(0)
which doesn't change the behaviour (because the reset value of output is zero) but makes the assign disappear from the Verilog output.
This is unfortunately an upstream Yosys bug that is quite difficult to address. I do have a plan for it but it's more long-term than anything.
Triage: still an issue with NIR on a586df89ad43bfe55dcad207bae9f7c8106046fe.
Will be fixed by https://github.com/YosysHQ/yosys/pull/4314.