8000 [FIRRTL] More alias copy propagation · Issue #788 · llvm/circt · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
[FIRRTL] More alias copy propagation #788
Closed
@seldridge

Description

@seldridge

This is really just more of #738 and #740.

CIRCT needs to work harder to eliminate or copy-propagate FIRRTL Analog types or Verilog inout types. inout support is extremely spotty and weird across different tooling.

Annoyingly, the typical situation where use of Analog or inout shows up in code is purely passing these from a module's IO to a submodule's IO. Doing the direct assignment is fine and supported by basically all tooling, but anything else is extremely spotty.

Consider something like:

circuit Foo:
  module Bar:
    input a: Analog<1>
  module Foo:
    input a: Analog<1>
    inst bar of Bar

    wire b: Analog<1>

    attach(b, a)
    attach(bar.a, b)

The wire b: Analog<1> is really just a temporary and can be trivially copy propagated through.

The Scala FIRRTL Compiler will get rid of this and produce:

module Bar(
  inout   a
);
endmodule
module Foo(
  inout   a
);
  Bar bar (
    .a(a)
  );
endmodule

However, CIRCT is much less aggressive here and produces:

module Bar(
  inout a);

endmodule

module Foo(
  inout a);

  wire _a_wire;	// Analog.fir:6:5
  wire b;	// Analog.fir:8:5

  Bar bar (	// Analog.fir:6:5
    .a (_a_wire)
  );
  `ifdef SYNTHESIS	// Analog.fir:10:5
    wire _T = b;	// Analog.fir:10:5
    assign b = a;	// Analog.fir:10:5
    assign a = _T;	// Analog.fir:10:5
    assign _a_wire = _T;	// Analog.fir:11:5
    assign b = _a_wire;	// Analog.fir:11:5
  `else
    `ifdef verilator	// Analog.fir:11:5
      `error "Verilator does not support alias and thus cannot arbitrarily connect bidirectional wires and ports"	// Analog.fir:10:5
      `error "Verilator does not support alias and thus cannot arbitrarily connect bidirectional wires and ports"	// Analog.fir:11:5
    `else
      alias b = a;	// Analog.fir:10:5
      alias _a_wire = b;	// Analog.fir:11:5
    `endif
  `endif
endmodule

This has consequences because just about any tool will handle the SFC code, but the CIRCT code is extremely problematic due to spotty tooling support (see below).

Summary of Spotty Tooling

Thanks to @jackkoenig for finding and documenting all this. 👍

Concretely, any tool is happy with:

module Foo(inout bar);
  SubFoo SubFoo(bar);
endmodule

While entirely equivalent, if you introduce a temporary wire for inout bar, you're in trouble.

Synopsys Design Compiler will accept, but VCS will not accept:

module Foo(inout bar);
  wire tmp;
  assign tmp = bar;
  assign bar = tmp;
  SubFoo SubFoo(tmp);
endmodule

VCS will accept this if you express this using alias:

module Foo(inout bar);
  wire tmp;
  alias tmp = bar;
  SubFoo SubFoo(tmp);
endmodule

Verilator accepts neither the double assign nor alias.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FIRRTLInvolving the `firrtl` dialectenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0