Skip to content

Probed constants moved out of layerblocks #8560

@rwy7

Description

@rwy7

The following example has bad output. A node, defined and probed under a layerblock, is lifted out of the layerblock and into the body of the module.

FIRRTL version 5.0.0

circuit Example:
  layer Verification, bind:

  public module Example:
    output p: Probe<UInt<1>, Verification>
    layerblock Verification:
      node n = UInt<1>(0)
      define p = probe(n)

Goes to:

// Generated by CIRCT unknown git version
module Example_Verification();
endmodule

module Example();
  wire _GEN = 1'h0;
endmodule


// ----- 8< ----- FILE "ref_Example.sv" ----- 8< -----

// Generated by CIRCT unknown git version
`define ref_Example_p _GEN

// ----- 8< ----- FILE "layers-Example-Verification.sv" ----- 8< -----

// Generated by CIRCT unknown git version
`ifndef layers_Example_Verification
  `define layers_Example_Verification
  bind Example Example_Verification verification ();
`endif // not def layers_Example_Verificatio

If I "donttouch" the node, we get much better output:

FIRRTL version 5.0.0

circuit Example: %[[
  {
    "class": "firrtl.transforms.DontTouchAnnotation",
    "target": "~Example|Example>n"
  }
]]
  layer Verification, bind:

  public module Example:
    output p: Probe<UInt<1>, Verification>
    layerblock Verification:
      node n = UInt<1>(0)
      define p = probe(n)

Goes to:

// Generated by CIRCT unknown git version
module Example_Verification();
  wire n = 1'h0;
  wire n_probe = n;
endmodule

module Example();
endmodule


// ----- 8< ----- FILE "ref_Example.sv" ----- 8< -----

// Generated by CIRCT unknown git version
`define ref_Example_p verification.n_probe

// ----- 8< ----- FILE "layers-Example-Verification.sv" ----- 8< -----

// Generated by CIRCT unknown git version
`ifndef layers_Example_Verification
  `define layers_Example_Verification
  bind Example Example_Verification verification ();
`endif // not def layers_Example_Verification

The cause of this seems to be that the initial node, located under the layerblock, is canonicalized away, and references to the node are replaced with references to the constant. Due to constant-pooling, the constant is located in the front of the body module. When the probes are lowered to XMRs, a new node is created for the XMR, which is co-located with the constant in the module body.

Here is a snippet of the IR output right before and after lower-XMR, which shows how the node has been erased:

// -----// IR Dump Before LowerXMR (firrtl-lower-xmr) //----- //
firrtl.circuit "Example" {
  firrtl.layer @Verification bind {
  }
  firrtl.module @Example(out %p: !firrtl.probe<uint<1>, @Verification>) attributes {convention = #firrtl<convention scalarized>} {
    %c0_ui1 = firrtl.constant 0 : !firrtl.uint<1>
    %0 = firrtl.ref.send %c0_ui1 : !firrtl.uint<1>
    firrtl.layerblock @Verification {
      %1 = firrtl.ref.cast %0 : (!firrtl.probe<uint<1>>) -> !firrtl.probe<uint<1>, @Verification>
      firrtl.ref.define %p, %1 : !firrtl.probe<uint<1>, @Verification>
    }
  }
}

// -----// IR Dump Before LayerSink (firrtl-layer-sink) //----- //
firrtl.module @Example() attributes {convention = #firrtl<convention scalarized>} {
  %c0_ui1 = firrtl.constant 0 : !firrtl.uint<1>
  %0 = firrtl.node sym @sym %c0_ui1 : !firrtl.uint<1>
  firrtl.layerblock @Verification {
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    FIRRTLInvolving the `firrtl` dialectbugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions