Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIRRTL] LowerLayers RefSend could be Canonicalized Away #7896

Open
seldridge opened this issue Nov 26, 2024 · 0 comments
Open

[FIRRTL] LowerLayers RefSend could be Canonicalized Away #7896

seldridge opened this issue Nov 26, 2024 · 0 comments
Labels
FIRRTL Involving the `firrtl` dialect

Comments

@seldridge
Copy link
Member

The LowerLayers pass can create some trivial canonicalization opportunities. These can be removed with the canonicalizer. However, it may be better to handle these specially in the pass.

I specifically noticed that when you have a ref.resolve user of a captured value in a layerblock, this will create an input port and a ref.send. The ref.resolve(ref.send(block-arg)) can be trivially converted to block-arg. However, it doesn't fit a nice createOrFold pattern and would require special tracking. As I've been moving LowerLayers later and later, this has started to show up in small end-to-end firtool changes.

Consider:

firrtl.circuit "TestHarness" {
  firrtl.layer @Verification bind {
  }
  firrtl.module private @DUT(in %clock: !firrtl.clock, in %a: !firrtl.uint<32>, out %b: !firrtl.uint<32>, out %trace: !firrtl.probe<uint<32>, @Verification>) {
    %pc = firrtl.reg %clock : !firrtl.clock, !firrtl.uint<32>
    firrtl.matchingconnect %pc, %a : !firrtl.uint<32>
    firrtl.matchingconnect %b, %pc : !firrtl.uint<32>
    firrtl.layerblock @Verification {
      %x = firrtl.wire : !firrtl.probe<uint<32>, @Verification>
      %pc_d = firrtl.reg %clock : !firrtl.clock, !firrtl.uint<32>
      firrtl.matchingconnect %pc_d, %a : !firrtl.uint<32>
      %0 = firrtl.ref.send %pc_d : !firrtl.uint<32>
      %1 = firrtl.ref.cast %0 : (!firrtl.probe<uint<32>>) -> !firrtl.probe<uint<32>, @Verification>
      firrtl.ref.define %x, %1 : !firrtl.probe<uint<32>, @Verification>
      firrtl.ref.define %trace, %x : !firrtl.probe<uint<32>, @Verification>
    }
  }
  firrtl.module @TestHarness(in %clock: !firrtl.clock, in %reset: !firrtl.uint<1>, in %a: !firrtl.uint<32>, out %b: !firrtl.uint<32>) attributes {convention = #firrtl<convention scalarized>} {
    %dut_clock, %dut_a, %dut_b, %dut_trace = firrtl.instance dut @DUT(in clock: !firrtl.clock, in a: !firrtl.uint<32>, out b: !firrtl.uint<32>, out trace: !firrtl.probe<uint<32>, @Verification>)
    firrtl.matchingconnect %dut_clock, %clock : !firrtl.clock
    firrtl.matchingconnect %dut_a, %a : !firrtl.uint<32>
    firrtl.matchingconnect %b, %dut_b : !firrtl.uint<32>
    firrtl.layerblock @Verification {
      %0 = firrtl.ref.resolve %dut_trace : !firrtl.probe<uint<32>, @Verification>
      firrtl.printf %clock, %reset, "The last PC was: %x" (%0) : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<32>
    }
  }
}

This will be compiled to:

    firrtl.module private @TestHarness_Verification(in %dut_trace: !firrtl.uint<32>, in %clock: !firrtl.clock, in %reset: !firrtl.uint<1>) {
      %0 = firrtl.ref.send %dut_trace : !firrtl.uint<32>
      %1 = firrtl.ref.resolve %0 : !firrtl.probe<uint<32>>
      firrtl.printf %clock, %reset, "The last PC was: %x" (%1) : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<32>
    }
@seldridge seldridge added the FIRRTL Involving the `firrtl` dialect label Nov 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FIRRTL Involving the `firrtl` dialect
Projects
None yet
Development

No branches or pull requests

1 participant