Skip to content

Invalid verilog generated on exhaustive switch statements with assert in default clause #1648

@qbojj

Description

@qbojj

When switch is already exhaustive, but we still specify the default clause, the generated verilog will be silently wrong.

Here is my minimal reproduction of the problem with generated verilog - You can see an error in right after (* full_case = 32'd1 *).
From what I understand the verilog attributes must be attached, so at least they need a ; after them.

from amaranth import *
from amaranth.back import verilog
from amaranth.lib.wiring import Component, In, Out


class Bad(Component):
    sig: In(1)

    def elaborate(self, platform) -> Module:
        m = Module()

        with m.Switch(self.sig):
            with m.Case(0):
                pass
            with m.Case(1):
                pass
            with m.Default():
                m.d.sync += Assert(0, "Invalid value of enum")

        return m


with open("bad.v", "w") as f:
    f.write(verilog.convert(Bad()))
/* Generated by Yosys 0.54 (git sha1 db72ec3bd, g++ 15.2.1 -march=x86-64-v3 -mtune=haswell -O3 -fno-plt -fexceptions -fstack-clash-protection -fcf-protection -mpclmul -ffile-prefix-map=/startdir/src=/usr/src/debug/yosys -fPIC -O3) */

(* top =  1  *)
(* src = "/home/kuba/Desktop/test/amaranth_bad/./bad.py:10" *)
(* generator = "Amaranth" *)
module top(clk, rst, sig);
  reg \$auto$verilog_backend.cc:2359:dump_module$1  = 0;
  wire \$1 ;
  (* src = "/home/kuba/Desktop/FPGA/praca/.venv/lib/python3.10/site-packages/amaranth/hdl/_ir.py:283" *)
  input clk;
  wire clk;
  (* src = "/home/kuba/Desktop/FPGA/praca/.venv/lib/python3.10/site-packages/amaranth/hdl/_ir.py:283" *)
  input rst;
  wire rst;
  (* src = "/home/kuba/Desktop/test/amaranth_bad/./bad.py:7" *)
  input sig;
  wire sig;
  always @(posedge clk) begin
    if (1'h0) begin
      if (!1'h0)
        $write("Invalid value of enum");
      assert (1'h0);
    end
  end
  always @* begin
    if (\$auto$verilog_backend.cc:2359:dump_module$1 ) begin end
    (* full_case = 32'd1 *)
    
  end
  assign \$1  = 1'h0;
endmodule

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions