circt/test/Dialect/FIRRTL/emit-basic.mlir

872 lines
42 KiB
MLIR

// RUN: circt-translate --export-firrtl --verify-diagnostics %s -o %t
// RUN: cat %t | FileCheck %s --strict-whitespace
// RUN: circt-translate --import-firrtl %t --mlir-print-debuginfo | circt-translate --export-firrtl | diff - %t
// Check emission at various widths, ensuring still parses and round-trips back to same FIRRTL as default width (inc debug info).
// RUN: circt-translate --export-firrtl %s --target-line-length=10 | circt-translate --import-firrtl --mlir-print-debuginfo | circt-translate --export-firrtl | diff - %t
// RUN: circt-translate --export-firrtl %s --target-line-length=1000 | circt-translate --import-firrtl --mlir-print-debuginfo | circt-translate --export-firrtl | diff - %t
// Sanity-check line length control:
// Check if printing with very long line length, no line ends with a comma.
// RUN: circt-translate --export-firrtl %s --target-line-length=1000 | FileCheck %s --implicit-check-not "{{,$}}" --check-prefix PRETTY
// Check if printing with very short line length, removing info locators (@[...]), no line is longer than 5x line length.
// RUN: circt-translate --export-firrtl %s --target-line-length=10 | sed -e 's/ @\[.*\]//' | FileCheck %s --implicit-check-not "{{^(.{50})}}" --check-prefix PRETTY
// CHECK-LABEL: FIRRTL version 4.0.0
// CHECK-LABEL: circuit Foo :
// PRETTY-LABEL: circuit Foo :
firrtl.circuit "Foo" {
// CHECK-LABEL: public module Foo :
firrtl.module @Foo() {}
// CHECK-LABEL: {{^ *}} module PrivateModule :
firrtl.module private @PrivateModule() {}
// CHECK-LABEL: module PortsAndTypes :
firrtl.module private @PortsAndTypes(
// CHECK-NEXT: input a00 : Clock
// CHECK-NEXT: input a01 : Reset
// CHECK-NEXT: input a02 : AsyncReset
// CHECK-NEXT: input a03 : UInt
// CHECK-NEXT: input a04 : SInt
// CHECK-NEXT: input a05 : Analog
// CHECK-NEXT: input a06 : UInt<42>
// CHECK-NEXT: input a07 : SInt<42>
// CHECK-NEXT: input a08 : Analog<42>
// CHECK-NEXT: input a09 : { a : UInt, flip b : UInt }
// CHECK-NEXT: input a10 : UInt[42]
// CHECK-NEXT: output b0 : UInt
// CHECK-NEXT: output b1 : Probe<UInt<1>>
// CHECK-NEXT: output b2 : RWProbe<UInt<1>>
// CHECK-NEXT: input anyref : AnyRef
// CHECK-NEXT: input string : String
// CHECK-NEXT: input integer : Integer
// CHECK-NEXT: input bool : Bool
// CHECK-NEXT: input double : Double
// CHECK-NEXT: input path : Path
// CHECK-NEXT: input list : List<List<Path>>
in %a00: !firrtl.clock,
in %a01: !firrtl.reset,
in %a02: !firrtl.asyncreset,
in %a03: !firrtl.uint,
in %a04: !firrtl.sint,
in %a05: !firrtl.analog,
in %a06: !firrtl.uint<42>,
in %a07: !firrtl.sint<42>,
in %a08: !firrtl.analog<42>,
in %a09: !firrtl.bundle<a: uint, b flip: uint>,
in %a10: !firrtl.vector<uint, 42>,
out %b0: !firrtl.uint,
out %b1: !firrtl.probe<uint<1>>,
out %b2: !firrtl.rwprobe<uint<1>>,
in %anyref: !firrtl.anyref,
in %string: !firrtl.string,
in %integer: !firrtl.integer,
in %bool : !firrtl.bool,
in %double : !firrtl.double,
in %path : !firrtl.path,
in %list : !firrtl.list<list<path>>
) {}
// CHECK-LABEL: module Simple :
// CHECK: input someIn : UInt<1>
// CHECK: output someOut : UInt<1>
firrtl.module @Simple(in %someIn: !firrtl.uint<1>, out %someOut: !firrtl.uint<1>) {
firrtl.skip
}
// CHECK-LABEL: module Statements :
firrtl.module private @Statements(in %ui1: !firrtl.uint<1>, in %someAddr: !firrtl.uint<8>, in %someClock: !firrtl.clock, in %someReset: !firrtl.reset, out %someOut: !firrtl.uint<1>, out %ref: !firrtl.probe<uint<1>>) {
// CHECK: when ui1 :
// CHECK: skip
firrtl.when %ui1 : !firrtl.uint<1> {
firrtl.skip
}
// CHECK: when ui1 :
// CHECK: skip
// CHECK: else :
// CHECK: skip
firrtl.when %ui1 : !firrtl.uint<1> {
firrtl.skip
} else {
firrtl.skip
}
// CHECK: when ui1 :
// CHECK: skip
// CHECK: else when ui1 :
// CHECK: skip
firrtl.when %ui1 : !firrtl.uint<1> {
firrtl.skip
} else {
firrtl.when %ui1 : !firrtl.uint<1> {
firrtl.skip
}
}
// CHECK: wire someWire : UInt<1>
%someWire = firrtl.wire : !firrtl.uint<1>
// CHECK: reg someReg : UInt<1>, someClock
%someReg = firrtl.reg %someClock : !firrtl.clock, !firrtl.uint<1>
// CHECK: regreset someReg2 : UInt<1>, someClock, someReset, ui1
%someReg2 = firrtl.regreset %someClock, %someReset, %ui1 : !firrtl.clock, !firrtl.reset, !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: node someNode = ui1
%someNode = firrtl.node %ui1 : !firrtl.uint<1>
// CHECK: stop(someClock, ui1, 42) : foo
firrtl.stop %someClock, %ui1, 42 {name = "foo"} : !firrtl.clock, !firrtl.uint<1>
// CHECK: skip
firrtl.skip
// CHECK: printf(someClock, ui1, "some\n magic\"stuff\"", ui1, someReset) : foo
firrtl.printf %someClock, %ui1, "some\n magic\"stuff\"" {name = "foo"} (%ui1, %someReset) : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<1>, !firrtl.reset
// CHECK: assert(someClock, ui1, ui1, "msg") : foo
// CHECK: assume(someClock, ui1, ui1, "msg") : foo
// CHECK: cover(someClock, ui1, ui1, "msg") : foo
firrtl.assert %someClock, %ui1, %ui1, "msg" : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<1> {name = "foo"}
firrtl.assume %someClock, %ui1, %ui1, "msg" : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<1> {name = "foo"}
firrtl.cover %someClock, %ui1, %ui1, "msg" : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<1> {name = "foo"}
// CHECK: connect someOut, ui1
firrtl.connect %someOut, %ui1 : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK: inst someInst of Simple
// CHECK: connect someInst.someIn, ui1
// CHECK: connect someOut, someInst.someOut
%someInst_someIn, %someInst_someOut = firrtl.instance someInst @Simple(in someIn: !firrtl.uint<1>, out someOut: !firrtl.uint<1>)
firrtl.connect %someInst_someIn, %ui1 : !firrtl.uint<1>, !firrtl.uint<1>
firrtl.connect %someOut, %someInst_someOut : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK-NOT: _invalid
// CHECK: invalidate someOut
%invalid_ui1 = firrtl.invalidvalue : !firrtl.uint<1>
firrtl.connect %someOut, %invalid_ui1 : !firrtl.uint<1>, !firrtl.uint<1>
// CHECK-NOT: _invalid
// CHECK: invalidate someOut
%invalid_ui2 = firrtl.invalidvalue : !firrtl.uint<1>
firrtl.matchingconnect %someOut, %invalid_ui2 : !firrtl.uint<1>
// CHECK: connect unknownReset, knownReset
%knownReset = firrtl.wire : !firrtl.asyncreset
%unknownReset = firrtl.wire : !firrtl.reset
%resetCast = firrtl.resetCast %knownReset :
(!firrtl.asyncreset) -> !firrtl.reset
firrtl.matchingconnect %unknownReset, %resetCast : !firrtl.reset
// CHECK: attach(an0, an1)
%an0 = firrtl.wire : !firrtl.analog<1>
%an1 = firrtl.wire : !firrtl.analog<1>
firrtl.attach %an0, %an1 : !firrtl.analog<1>, !firrtl.analog<1>
// CHECK: node k0 = UInt<19>(42)
// CHECK: node k1 = SInt<19>(42)
// CHECK: node k2 = UInt(42)
// CHECK: node k3 = SInt(42)
%0 = firrtl.constant 42 : !firrtl.uint<19>
%1 = firrtl.constant 42 : !firrtl.sint<19>
%2 = firrtl.constant 42 : !firrtl.uint
%3 = firrtl.constant 42 : !firrtl.sint
%k0 = firrtl.node %0 : !firrtl.uint<19>
%k1 = firrtl.node %1 : !firrtl.sint<19>
%k2 = firrtl.node %2 : !firrtl.uint
%k3 = firrtl.node %3 : !firrtl.sint
// CHECK: node k4 = asClock(UInt<1>(0))
// CHECK: node k5 = asAsyncReset(UInt<1>(0))
// CHECK: node k6 = UInt<1>(0)
%4 = firrtl.specialconstant 0 : !firrtl.clock
%5 = firrtl.specialconstant 0 : !firrtl.asyncreset
%6 = firrtl.specialconstant 0 : !firrtl.reset
%k4 = firrtl.node %4 : !firrtl.clock
%k5 = firrtl.node %5 : !firrtl.asyncreset
%k6 = firrtl.node %6 : !firrtl.reset
// CHECK: wire bundle : { a : UInt, flip b : UInt }
// CHECK: wire vector : UInt[42]
// CHECK: node subfield = bundle.a
// CHECK: node subindex = vector[19]
// CHECK: node subaccess = vector[ui1]
%bundle = firrtl.wire : !firrtl.bundle<a: uint, b flip: uint>
%vector = firrtl.wire : !firrtl.vector<uint, 42>
%subfield_tmp = firrtl.subfield %bundle[a] : !firrtl.bundle<a: uint, b flip: uint>
%subindex_tmp = firrtl.subindex %vector[19] : !firrtl.vector<uint, 42>
%subaccess_tmp = firrtl.subaccess %vector[%ui1] : !firrtl.vector<uint, 42>, !firrtl.uint<1>
%subfield = firrtl.node %subfield_tmp : !firrtl.uint
%subindex = firrtl.node %subindex_tmp : !firrtl.uint
%subaccess = firrtl.node %subaccess_tmp : !firrtl.uint
%x = firrtl.node %2 : !firrtl.uint
%y = firrtl.node %2 : !firrtl.uint
// CHECK: node addPrimOp = add(x, y)
// CHECK: node subPrimOp = sub(x, y)
// CHECK: node mulPrimOp = mul(x, y)
// CHECK: node divPrimOp = div(x, y)
// CHECK: node remPrimOp = rem(x, y)
// CHECK: node andPrimOp = and(x, y)
// CHECK: node orPrimOp = or(x, y)
// CHECK: node xorPrimOp = xor(x, y)
// CHECK: node leqPrimOp = leq(x, y)
// CHECK: node ltPrimOp = lt(x, y)
// CHECK: node geqPrimOp = geq(x, y)
// CHECK: node gtPrimOp = gt(x, y)
// CHECK: node eqPrimOp = eq(x, y)
// CHECK: node neqPrimOp = neq(x, y)
// CHECK: node catPrimOp = cat(x, y)
// CHECK: node dShlPrimOp = dshl(x, y)
// CHECK: node dShlwPrimOp = dshlw(x, y)
// CHECK: node dShrPrimOp = dshr(x, y)
%addPrimOp_tmp = firrtl.add %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint
%subPrimOp_tmp = firrtl.sub %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint
%mulPrimOp_tmp = firrtl.mul %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint
%divPrimOp_tmp = firrtl.div %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint
%remPrimOp_tmp = firrtl.rem %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint
%andPrimOp_tmp = firrtl.and %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint
%orPrimOp_tmp = firrtl.or %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint
%xorPrimOp_tmp = firrtl.xor %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint
%leqPrimOp_tmp = firrtl.leq %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint<1>
%ltPrimOp_tmp = firrtl.lt %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint<1>
%geqPrimOp_tmp = firrtl.geq %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint<1>
%gtPrimOp_tmp = firrtl.gt %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint<1>
%eqPrimOp_tmp = firrtl.eq %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint<1>
%neqPrimOp_tmp = firrtl.neq %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint<1>
%catPrimOp_tmp = firrtl.cat %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint
%dShlPrimOp_tmp = firrtl.dshl %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint
%dShlwPrimOp_tmp = firrtl.dshlw %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint
%dShrPrimOp_tmp = firrtl.dshr %x, %y : (!firrtl.uint, !firrtl.uint) -> !firrtl.uint
%addPrimOp = firrtl.node %addPrimOp_tmp : !firrtl.uint
%subPrimOp = firrtl.node %subPrimOp_tmp : !firrtl.uint
%mulPrimOp = firrtl.node %mulPrimOp_tmp : !firrtl.uint
%divPrimOp = firrtl.node %divPrimOp_tmp : !firrtl.uint
%remPrimOp = firrtl.node %remPrimOp_tmp : !firrtl.uint
%andPrimOp = firrtl.node %andPrimOp_tmp : !firrtl.uint
%orPrimOp = firrtl.node %orPrimOp_tmp : !firrtl.uint
%xorPrimOp = firrtl.node %xorPrimOp_tmp : !firrtl.uint
%leqPrimOp = firrtl.node %leqPrimOp_tmp : !firrtl.uint<1>
%ltPrimOp = firrtl.node %ltPrimOp_tmp : !firrtl.uint<1>
%geqPrimOp = firrtl.node %geqPrimOp_tmp : !firrtl.uint<1>
%gtPrimOp = firrtl.node %gtPrimOp_tmp : !firrtl.uint<1>
%eqPrimOp = firrtl.node %eqPrimOp_tmp : !firrtl.uint<1>
%neqPrimOp = firrtl.node %neqPrimOp_tmp : !firrtl.uint<1>
%catPrimOp = firrtl.node %catPrimOp_tmp : !firrtl.uint
%dShlPrimOp = firrtl.node %dShlPrimOp_tmp : !firrtl.uint
%dShlwPrimOp = firrtl.node %dShlwPrimOp_tmp : !firrtl.uint
%dShrPrimOp = firrtl.node %dShrPrimOp_tmp : !firrtl.uint
// CHECK: node asSIntPrimOp = asSInt(x)
// CHECK: node asUIntPrimOp = asUInt(x)
// CHECK: node asAsyncResetPrimOp = asAsyncReset(x)
// CHECK: node asClockPrimOp = asClock(x)
// CHECK: node cvtPrimOp = cvt(x)
// CHECK: node negPrimOp = neg(x)
// CHECK: node notPrimOp = not(x)
// CHECK: node andRPrimOp = andr(x)
// CHECK: node orRPrimOp = orr(x)
// CHECK: node xorRPrimOp = xorr(x)
%asSIntPrimOp_tmp = firrtl.asSInt %x : (!firrtl.uint) -> !firrtl.sint
%asUIntPrimOp_tmp = firrtl.asUInt %x : (!firrtl.uint) -> !firrtl.uint
%asAsyncResetPrimOp_tmp = firrtl.asAsyncReset %x : (!firrtl.uint) -> !firrtl.asyncreset
%asClockPrimOp_tmp = firrtl.asClock %x : (!firrtl.uint) -> !firrtl.clock
%cvtPrimOp_tmp = firrtl.cvt %x : (!firrtl.uint) -> !firrtl.sint
%negPrimOp_tmp = firrtl.neg %x : (!firrtl.uint) -> !firrtl.sint
%notPrimOp_tmp = firrtl.not %x : (!firrtl.uint) -> !firrtl.uint
%andRPrimOp_tmp = firrtl.andr %x : (!firrtl.uint) -> !firrtl.uint<1>
%orRPrimOp_tmp = firrtl.orr %x : (!firrtl.uint) -> !firrtl.uint<1>
%xorRPrimOp_tmp = firrtl.xorr %x : (!firrtl.uint) -> !firrtl.uint<1>
%asSIntPrimOp = firrtl.node %asSIntPrimOp_tmp : !firrtl.sint
%asUIntPrimOp = firrtl.node %asUIntPrimOp_tmp : !firrtl.uint
%asAsyncResetPrimOp = firrtl.node %asAsyncResetPrimOp_tmp : !firrtl.asyncreset
%asClockPrimOp = firrtl.node %asClockPrimOp_tmp : !firrtl.clock
%cvtPrimOp = firrtl.node %cvtPrimOp_tmp : !firrtl.sint
%negPrimOp = firrtl.node %negPrimOp_tmp : !firrtl.sint
%notPrimOp = firrtl.node %notPrimOp_tmp : !firrtl.uint
%andRPrimOp = firrtl.node %andRPrimOp_tmp : !firrtl.uint<1>
%orRPrimOp = firrtl.node %orRPrimOp_tmp : !firrtl.uint<1>
%xorRPrimOp = firrtl.node %xorRPrimOp_tmp : !firrtl.uint<1>
// CHECK: node bitsPrimOp = bits(x, 4, 2)
// CHECK: node headPrimOp = head(x, 4)
// CHECK: node tailPrimOp = tail(x, 4)
// CHECK: node padPrimOp = pad(x, 16)
// CHECK: node muxPrimOp = mux(ui1, x, y)
// CHECK: node shlPrimOp = shl(x, 4)
// CHECK: node shrPrimOp = shr(x, 4)
%bitsPrimOp_tmp = firrtl.bits %x 4 to 2 : (!firrtl.uint) -> !firrtl.uint<3>
%headPrimOp_tmp = firrtl.head %x, 4 : (!firrtl.uint) -> !firrtl.uint<4>
%tailPrimOp_tmp = firrtl.tail %x, 4 : (!firrtl.uint) -> !firrtl.uint
%padPrimOp_tmp = firrtl.pad %x, 16 : (!firrtl.uint) -> !firrtl.uint
%muxPrimOp_tmp = firrtl.mux(%ui1, %x, %y) : (!firrtl.uint<1>, !firrtl.uint, !firrtl.uint) -> !firrtl.uint
%shlPrimOp_tmp = firrtl.shl %x, 4 : (!firrtl.uint) -> !firrtl.uint
%shrPrimOp_tmp = firrtl.shr %x, 4 : (!firrtl.uint) -> !firrtl.uint
%bitsPrimOp = firrtl.node %bitsPrimOp_tmp : !firrtl.uint<3>
%headPrimOp = firrtl.node %headPrimOp_tmp : !firrtl.uint<4>
%tailPrimOp = firrtl.node %tailPrimOp_tmp : !firrtl.uint
%padPrimOp = firrtl.node %padPrimOp_tmp : !firrtl.uint
%muxPrimOp = firrtl.node %muxPrimOp_tmp : !firrtl.uint
%shlPrimOp = firrtl.node %shlPrimOp_tmp : !firrtl.uint
%shrPrimOp = firrtl.node %shrPrimOp_tmp : !firrtl.uint
%MyMem_a, %MyMem_b, %MyMem_c = firrtl.mem Undefined {depth = 8, name = "MyMem", portNames = ["a", "b", "c"], readLatency = 0 : i32, writeLatency = 1 : i32} : !firrtl.bundle<addr: uint<3>, en: uint<1>, clk: clock, data flip: uint<4>>, !firrtl.bundle<addr: uint<3>, en: uint<1>, clk: clock, data: uint<4>, mask: uint<1>>, !firrtl.bundle<addr: uint<3>, en: uint<1>, clk: clock, rdata flip: uint<4>, wmode: uint<1>, wdata: uint<4>, wmask: uint<1>>
%MyMem_a_clk = firrtl.subfield %MyMem_a[clk] : !firrtl.bundle<addr: uint<3>, en: uint<1>, clk: clock, data flip: uint<4>>
%MyMem_b_clk = firrtl.subfield %MyMem_b[clk] : !firrtl.bundle<addr: uint<3>, en: uint<1>, clk: clock, data: uint<4>, mask: uint<1>>
%MyMem_c_clk = firrtl.subfield %MyMem_c[clk] : !firrtl.bundle<addr: uint<3>, en: uint<1>, clk: clock, rdata flip: uint<4>, wmode: uint<1>, wdata: uint<4>, wmask: uint<1>>
firrtl.connect %MyMem_a_clk, %someClock : !firrtl.clock, !firrtl.clock
firrtl.connect %MyMem_b_clk, %someClock : !firrtl.clock, !firrtl.clock
firrtl.connect %MyMem_c_clk, %someClock : !firrtl.clock, !firrtl.clock
// CHECK: mem MyMem :
// CHECK-NEXT: data-type => UInt<4>
// CHECK-NEXT: depth => 8
// CHECK-NEXT: read-latency => 0
// CHECK-NEXT: write-latency => 1
// CHECK-NEXT: reader => a
// CHECK-NEXT: writer => b
// CHECK-NEXT: readwriter => c
// CHECK-NEXT: read-under-write => undefined
// CHECK-NEXT: connect MyMem.a.clk, someClock
// CHECK-NEXT: connect MyMem.b.clk, someClock
// CHECK-NEXT: connect MyMem.c.clk, someClock
%combmem = chirrtl.combmem : !chirrtl.cmemory<uint<3>, 256>
%port0_data, %port0_port = chirrtl.memoryport Infer %combmem {name = "port0"} : (!chirrtl.cmemory<uint<3>, 256>) -> (!firrtl.uint<3>, !chirrtl.cmemoryport)
firrtl.when %ui1 : !firrtl.uint<1> {
chirrtl.memoryport.access %port0_port[%someAddr], %someClock : !chirrtl.cmemoryport, !firrtl.uint<8>, !firrtl.clock
}
// CHECK: cmem combmem : UInt<3>[256]
// CHECK-NEXT: when ui1 :
// CHECK-NEXT: infer mport port0 = combmem[someAddr], someClock
%seqmem = chirrtl.seqmem Undefined : !chirrtl.cmemory<uint<3>, 256>
%port1_data, %port1_port = chirrtl.memoryport Infer %seqmem {name = "port1"} : (!chirrtl.cmemory<uint<3>, 256>) -> (!firrtl.uint<3>, !chirrtl.cmemoryport)
firrtl.when %ui1 : !firrtl.uint<1> {
chirrtl.memoryport.access %port1_port[%someAddr], %someClock : !chirrtl.cmemoryport, !firrtl.uint<8>, !firrtl.clock
}
// CHECK: smem seqmem : UInt<3>[256], undefined
// CHECK-NEXT: when ui1 :
// CHECK-NEXT: infer mport port1 = seqmem[someAddr], someClock
firrtl.connect %port0_data, %port1_data : !firrtl.uint<3>, !firrtl.uint<3>
// CHECK: connect port0, port1
%invalid_clock = firrtl.invalidvalue : !firrtl.clock
%dummyReg = firrtl.reg %invalid_clock : !firrtl.clock, !firrtl.uint<42>
// CHECK: wire [[INV:_invalid.*]] : Clock
// CHECK-NEXT: invalidate [[INV]]
// CHECK-NEXT: reg dummyReg : UInt<42>, [[INV]]
}
// CHECK-LABEL: module RefSource
firrtl.module @RefSource(out %a_ref: !firrtl.probe<uint<1>>,
out %a_rwref: !firrtl.rwprobe<uint<1>>) {
%a, %_a_rwref = firrtl.wire forceable : !firrtl.uint<1>,
!firrtl.rwprobe<uint<1>>
// CHECK: define a_ref = probe(a)
// CHECK: define a_rwref = rwprobe(a)
%a_ref_send = firrtl.ref.send %a : !firrtl.uint<1>
firrtl.ref.define %a_ref, %a_ref_send : !firrtl.probe<uint<1>>
firrtl.ref.define %a_rwref, %_a_rwref : !firrtl.rwprobe<uint<1>>
}
// CHECK-LABEL: module RefSink
firrtl.module @RefSink(
in %clock: !firrtl.clock,
in %enable: !firrtl.uint<1>
) {
%c0_ui1 = firrtl.constant 0 : !firrtl.uint<1>
%c1_ui1 = firrtl.constant 1 : !firrtl.uint<1>
// CHECK: node b = read(refSource.a_ref)
%refSource_a_ref, %refSource_a_rwref =
firrtl.instance refSource @RefSource(
out a_ref: !firrtl.probe<uint<1>>,
out a_rwref: !firrtl.rwprobe<uint<1>>
)
%a_ref_resolve =
firrtl.ref.resolve %refSource_a_ref : !firrtl.probe<uint<1>>
%b = firrtl.node %a_ref_resolve : !firrtl.uint<1>
// CHECK-NEXT: force_initial(refSource.a_rwref, UInt<1>(0))
firrtl.ref.force_initial %c1_ui1, %refSource_a_rwref, %c0_ui1 :
!firrtl.uint<1>, !firrtl.rwprobe<uint<1>>, !firrtl.uint<1>
// CHECK-NEXT: release_initial(refSource.a_rwref)
firrtl.ref.release_initial %c1_ui1, %refSource_a_rwref :
!firrtl.uint<1>, !firrtl.rwprobe<uint<1>>
// CHECK-NEXT: when enable :
// CHECK-NEXT: force_initial(refSource.a_rwref, UInt<1>(0))
firrtl.when %enable : !firrtl.uint<1> {
firrtl.ref.force_initial %c1_ui1, %refSource_a_rwref, %c0_ui1 :
!firrtl.uint<1>, !firrtl.rwprobe<uint<1>>, !firrtl.uint<1>
}
// CHECK-NEXT: when enable :
// CHECK-NEXT: release_initial(refSource.a_rwref)
firrtl.when %enable : !firrtl.uint<1> {
firrtl.ref.release_initial %c1_ui1, %refSource_a_rwref :
!firrtl.uint<1>, !firrtl.rwprobe<uint<1>>
}
// CHECK-NEXT: force(clock, enable, refSource.a_rwref, UInt<1>(1))
firrtl.ref.force %clock, %enable, %refSource_a_rwref, %c1_ui1 :
!firrtl.clock, !firrtl.uint<1>, !firrtl.rwprobe<uint<1>>, !firrtl.uint<1>
// CHECK-NEXT: release(clock, enable, refSource.a_rwref)
firrtl.ref.release %clock, %enable, %refSource_a_rwref :
!firrtl.clock, !firrtl.uint<1>, !firrtl.rwprobe<uint<1>>
}
// CHECK-LABEL: module RefExport
firrtl.module @RefExport(out %a_ref: !firrtl.probe<uint<1>>,
out %a_rwref: !firrtl.rwprobe<uint<1>>) {
// CHECK: define a_ref = refSource.a_ref
// CHECK: define a_rwref = refSource.a_rwref
%refSource_a_ref, %refSource_a_rwref =
firrtl.instance refSource @RefSource(
out a_ref: !firrtl.probe<uint<1>>,
out a_rwref: !firrtl.rwprobe<uint<1>>
)
firrtl.ref.define %a_ref, %refSource_a_ref : !firrtl.probe<uint<1>>
firrtl.ref.define %a_rwref, %refSource_a_rwref : !firrtl.rwprobe<uint<1>>
}
// CHECK-LABEL: extmodule ExtOpenAgg
// CHECK-NEXT: output out : { a : { data : UInt<1> },
// CHECK-NEXT: b : { x : UInt<2>, y : Probe<UInt<2>[3]> }[2] }
firrtl.extmodule @ExtOpenAgg(
out out: !firrtl.openbundle<a: bundle<data: uint<1>>, b: openvector<openbundle<x: uint<2>, y: probe<vector<uint<2>, 3>>>, 2>>)
// CHECK-LABEL: module OpenAggTest
firrtl.module @OpenAggTest(
// CHECK-NEXT: output out_b_0_y_2 : Probe<UInt<2>>
// CHECK-EMPTY:
out %out_b_0_y_2 : !firrtl.probe<uint<2>>) {
// CHECK-NEXT: inst oa of ExtOpenAgg
%oa_out = firrtl.instance oa @ExtOpenAgg(out out: !firrtl.openbundle<a: bundle<data: uint<1>>, b: openvector<openbundle<x: uint<2>, y: probe<vector<uint<2>, 3>>>, 2>>)
%a = firrtl.opensubfield %oa_out[a] : !firrtl.openbundle<a: bundle<data: uint<1>>, b: openvector<openbundle<x: uint<2>, y: probe<vector<uint<2>, 3>>>, 2>>
%data = firrtl.subfield %a[data] : !firrtl.bundle<data: uint<1>>
// CHECK-NEXT: node n_data = oa.out.a.data
%n_data = firrtl.node %data : !firrtl.uint<1>
%b = firrtl.opensubfield %oa_out[b] : !firrtl.openbundle<a: bundle<data: uint<1>>, b: openvector<openbundle<x: uint<2>, y: probe<vector<uint<2>, 3>>>, 2>>
%b_0 = firrtl.opensubindex %b[0] : !firrtl.openvector<openbundle<x: uint<2>, y: probe<vector<uint<2>, 3>>>, 2>
%b_0_y = firrtl.opensubfield %b_0[y] : !firrtl.openbundle<x : uint<2>, y: probe<vector<uint<2>, 3>>>
%b_0_y_2 = firrtl.ref.sub %b_0_y[2] : !firrtl.probe<vector<uint<2>, 3>>
// openagg indexing + ref.sub
// CHECK-NEXT: define out_b_0_y_2 = oa.out.b[0].y[2]
firrtl.ref.define %out_b_0_y_2, %b_0_y_2 : !firrtl.probe<uint<2>>
}
firrtl.extmodule @MyParameterizedExtModule<DEFAULT: i64 = 0, DEPTH: f64 = 3.242000e+01, FORMAT: none = "xyz_timeout=%d\0A", WIDTH: i8 = 32>(in in: !firrtl.uint<1>, out out: !firrtl.uint<8>) attributes {defname = "name_thing"}
// CHECK-LABEL: extmodule MyParameterizedExtModule :
// CHECK-NEXT: input in : UInt<1>
// CHECK-NEXT: output out : UInt<8>
// CHECK-NEXT: defname = name_thing
// CHECK-NEXT: parameter DEFAULT = 0
// CHECK-NEXT: parameter DEPTH = 32.42
// CHECK-NEXT: parameter FORMAT = "xyz_timeout=%d\n"
// CHECK-NEXT: parameter WIDTH = 32
// CHECK-LABEL: module ConstTypes :
firrtl.module private @ConstTypes(
// CHECK-NEXT: input a00 : const Clock
// CHECK-NEXT: input a01 : const Reset
// CHECK-NEXT: input a02 : const AsyncReset
// CHECK-NEXT: input a03 : const UInt
// CHECK-NEXT: input a04 : const SInt
// CHECK-NEXT: input a05 : const Analog
// CHECK-NEXT: input a06 : const UInt<42>
// CHECK-NEXT: input a07 : const SInt<42>
// CHECK-NEXT: input a08 : const Analog<42>
// CHECK-NEXT: input a09 : const { a : UInt, flip b : UInt }
// CHECK-NEXT: input a10 : { a : const UInt, flip b : UInt }
// CHECK-NEXT: input a11 : const UInt[42]
// CHECK-NEXT: output b0 : const UInt<42>
in %a00: !firrtl.const.clock,
in %a01: !firrtl.const.reset,
in %a02: !firrtl.const.asyncreset,
in %a03: !firrtl.const.uint,
in %a04: !firrtl.const.sint,
in %a05: !firrtl.const.analog,
in %a06: !firrtl.const.uint<42>,
in %a07: !firrtl.const.sint<42>,
in %a08: !firrtl.const.analog<42>,
in %a09: !firrtl.const.bundle<a: uint, b flip: uint>,
in %a10: !firrtl.bundle<a: const.uint, b flip: uint>,
in %a11: !firrtl.const.vector<uint, 42>,
out %b0: !firrtl.const.uint<42>
) {
// Make sure literals strip the 'const' prefix
// CHECK: connect b0, UInt<42>(1)
%c = firrtl.constant 1 : !firrtl.const.uint<42>
firrtl.matchingconnect %b0, %c : !firrtl.const.uint<42>
}
// Test that literal identifiers work.
// CHECK-LABEL: module `0Bar` :
firrtl.module @"0Bar"(
// CHECK-NEXT: input `0` : UInt<1>
in %_0: !firrtl.uint<1>
) attributes {portNames = ["0"]} {}
// CHECK-LABEL: module `0Foo` :
firrtl.module private @"0Foo"(
// CHECK-NEXT: input `0` : Clock
// CHECK-NEXT: input `1` : Reset
// CHECK-NEXT: input `2` : AsyncReset
// CHECK-NEXT: input `3` : UInt<1>
// CHECK-NEXT: input `4` : SInt
// CHECK-NEXT: input `5` : Analog
// CHECK-NEXT: input `6` : UInt<42>
// CHECK-NEXT: input `7` : SInt<42>
// CHECK-NEXT: input `8` : Analog<42>
// CHECK-NEXT: input `9` : { `0` : UInt, flip `1` : UInt }
// CHECK-NEXT: input `10` : UInt[42]
// CHECK-NEXT: output `11` : UInt
// CHECK-NEXT: output `12` : Probe<UInt<1>>
// CHECK-NEXT: output `13` : RWProbe<UInt<1>>
in %_0: !firrtl.clock,
in %_1: !firrtl.reset,
in %_2: !firrtl.asyncreset,
in %_3: !firrtl.uint<1>,
in %_4: !firrtl.sint,
in %_5: !firrtl.analog,
in %_6: !firrtl.uint<42>,
in %_7: !firrtl.sint<42>,
in %_8: !firrtl.analog<42>,
in %_9: !firrtl.bundle<"0": uint, "1" flip: uint>,
in %_10: !firrtl.vector<uint, 42>,
out %_11: !firrtl.uint,
out %_12: !firrtl.probe<uint<1>>,
out %_13: !firrtl.rwprobe<uint<1>>
) attributes {
portNames = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"]
} {
%0 = firrtl.subfield %_9["0"] : !firrtl.bundle<"0": uint, "1" flip: uint>
%1 = firrtl.subfield %_9["1"] : !firrtl.bundle<"0": uint, "1" flip: uint>
// CHECK: wire `14` : UInt<1>
// CHECK-NEXT: reg `15` : UInt<1>, `0`
// CHECK-NEXT: regreset `16` : UInt<1>, `0`, `1`, `3`
// CHECK-NEXT: node `17` = `3`
%_14 = firrtl.wire interesting_name {name = "14"} : !firrtl.uint<1>
%_15, %_15_ref = firrtl.reg %_0 forceable {name = "15"} :
!firrtl.clock, !firrtl.uint<1>, !firrtl.rwprobe<uint<1>>
%_16 = firrtl.regreset %_0, %_1, %_3 {name = "16"} :
!firrtl.clock, !firrtl.reset, !firrtl.uint<1>, !firrtl.uint<1>
%_17 = firrtl.node %_3 {name = "17"} : !firrtl.uint<1>
// CHECK: connect `9`.`1`, `9`.`0`
firrtl.connect %1, %0 : !firrtl.uint, !firrtl.uint
// CHECK: invalidate `11`
%invalid_ui = firrtl.invalidvalue : !firrtl.uint
firrtl.connect %_11, %invalid_ui : !firrtl.uint, !firrtl.uint
// CHECK: inst `0bar` of `0Bar`
// CHECK-NEXT: connect `0bar`.`0`, `3`
%_0bar_0 = firrtl.instance "0bar" @"0Bar"(in "0": !firrtl.uint<1>)
firrtl.matchingconnect %_0bar_0, %_3 : !firrtl.uint<1>
// CHECK: mem `18` :
// CHECK-NEXT: data-type => UInt<8>
// CHECK-NEXT: depth => 32
// CHECK-NEXT: read-latency => 1
// CHECK-NEXT: write-latency => 1
// CHECK-NEXT: reader => `0`
// CHECK-NEXT: writer => `1`
// CHECK-NEXT: readwriter => `2`
// CHECK-NEXT: read-under-write => undefined
%_18_0, %_18_1, %_18_2 = firrtl.mem Undefined {
depth = 32 : i64,
name = "18",
portNames = ["0", "1", "2"],
readLatency = 1 : i32,
writeLatency = 1 : i32
} : !firrtl.bundle<addr: uint<5>, en: uint<1>, clk: clock, data flip: uint<8>>,
!firrtl.bundle<addr: uint<5>, en: uint<1>, clk: clock, data: uint<8>, mask: uint<1>>,
!firrtl.bundle<addr: uint<5>, en: uint<1>, clk: clock, rdata flip: uint<8>, wmode: uint<1>, wdata: uint<8>, wmask: uint<1>>
// CHECK: connect `18`.`0`.clk, `0`
// CHECK-NEXT: connect `18`.`0`.en, `3`
// CHECK-NEXT: connect `18`.`0`.addr, pad(`3`, 5)
// CHECK-NEXT: connect `11`, `18`.`0`.data
// CHECK-NEXT: connect `18`.`1`.clk, `0`
// CHECK-NEXT: connect `18`.`1`.en, `3`
// CHECK-NEXT: connect `18`.`1`.data, pad(`3`, 8)
// CHECK-NEXT: connect `18`.`1`.addr, pad(`3`, 5)
// CHECK-NEXT: connect `18`.`1`.mask, `3`
%3 = firrtl.subfield %_18_1[mask] : !firrtl.bundle<addr: uint<5>, en: uint<1>, clk: clock, data: uint<8>, mask: uint<1>>
%4 = firrtl.subfield %_18_1[addr] : !firrtl.bundle<addr: uint<5>, en: uint<1>, clk: clock, data: uint<8>, mask: uint<1>>
%5 = firrtl.subfield %_18_1[data] : !firrtl.bundle<addr: uint<5>, en: uint<1>, clk: clock, data: uint<8>, mask: uint<1>>
%6 = firrtl.subfield %_18_1[en] : !firrtl.bundle<addr: uint<5>, en: uint<1>, clk: clock, data: uint<8>, mask: uint<1>>
%7 = firrtl.subfield %_18_1[clk] : !firrtl.bundle<addr: uint<5>, en: uint<1>, clk: clock, data: uint<8>, mask: uint<1>>
%8 = firrtl.subfield %_18_0[data] : !firrtl.bundle<addr: uint<5>, en: uint<1>, clk: clock, data flip: uint<8>>
%9 = firrtl.subfield %_18_0[addr] : !firrtl.bundle<addr: uint<5>, en: uint<1>, clk: clock, data flip: uint<8>>
%10 = firrtl.subfield %_18_0[en] : !firrtl.bundle<addr: uint<5>, en: uint<1>, clk: clock, data flip: uint<8>>
%11 = firrtl.subfield %_18_0[clk] : !firrtl.bundle<addr: uint<5>, en: uint<1>, clk: clock, data flip: uint<8>>
firrtl.matchingconnect %11, %_0 : !firrtl.clock
firrtl.matchingconnect %10, %_3 : !firrtl.uint<1>
%12 = firrtl.pad %_3, 5 : (!firrtl.uint<1>) -> !firrtl.uint<5>
firrtl.matchingconnect %9, %12 : !firrtl.uint<5>
firrtl.connect %_11, %8 : !firrtl.uint, !firrtl.uint<8>
firrtl.matchingconnect %7, %_0 : !firrtl.clock
firrtl.matchingconnect %6, %_3 : !firrtl.uint<1>
%14 = firrtl.pad %_3, 8 : (!firrtl.uint<1>) -> !firrtl.uint<8>
firrtl.matchingconnect %5, %14 : !firrtl.uint<8>
%15 = firrtl.pad %_3, 5 : (!firrtl.uint<1>) -> !firrtl.uint<5>
firrtl.matchingconnect %4, %15 : !firrtl.uint<5>
firrtl.matchingconnect %3, %_3 : !firrtl.uint<1>
// CHECK-NEXT: cmem `19` : { `0` : UInt<8> }[32]
// CHECK-NEXT: smem `20` : { `0` : UInt<8> }[32]
// CHECK-NEXT: write mport `21` = `19`[UInt<5>(8)], `0`
// CHECK-NEXT: connect `21`.`0`, UInt<8>(0)
%_19 = chirrtl.combmem {name = "19"} : !chirrtl.cmemory<bundle<"0": uint<8>>, 32>
%_21_data, %_21_port = chirrtl.memoryport Write %_19 {name = "21"} : (!chirrtl.cmemory<bundle<"0": uint<8>>, 32>) -> (!firrtl.bundle<"0": uint<8>>, !chirrtl.cmemoryport)
%16 = firrtl.subfield %_21_data["0"] : !firrtl.bundle<"0": uint<8>>
%_20 = chirrtl.seqmem Undefined {name = "20"} : !chirrtl.cmemory<bundle<"0": uint<8>>, 32>
%c8_ui5 = firrtl.constant 8 : !firrtl.const.uint<5>
chirrtl.memoryport.access %_21_port[%c8_ui5], %_0 : !chirrtl.cmemoryport, !firrtl.const.uint<5>, !firrtl.clock
%c0_ui8 = firrtl.constant 0 : !firrtl.const.uint<8>
%17 = firrtl.constCast %c0_ui8 : (!firrtl.const.uint<8>) -> !firrtl.uint<8>
firrtl.matchingconnect %16, %17 : !firrtl.uint<8>
// CHECK-NEXT: stop(`0`, `3`, 1) : `22`
// CHECK-NEXT: assert(`0`, `3`, `3`, "message") : `23`
firrtl.stop %_0, %_3, 1 {name = "22"} : !firrtl.clock, !firrtl.uint<1>
firrtl.assert %_0, %_3, %_3, "message" : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<1> {eventControl = 0 : i32, isConcurrent = false, name = "23"}
// CHECK-NEXT: define `12` = probe(`14`)
// CHECK-NEXT: define `13` = rwprobe(`15`)
%18 = firrtl.ref.send %_14 : !firrtl.uint<1>
firrtl.ref.define %_12, %18 : !firrtl.probe<uint<1>>
firrtl.ref.define %_13, %_15_ref : !firrtl.rwprobe<uint<1>>
}
// CHECK-LABEL: module Properties :
firrtl.module @Properties(out %string : !firrtl.string,
out %integer : !firrtl.integer,
out %bool : !firrtl.bool,
out %double : !firrtl.double,
out %path : !firrtl.path,
out %list : !firrtl.list<list<string>>) {
// CHECK: propassign string, String("hello")
%0 = firrtl.string "hello"
firrtl.propassign %string, %0 : !firrtl.string
// CHECK: propassign integer, Integer(99)
%1 = firrtl.integer 99
firrtl.propassign %integer, %1 : !firrtl.integer
// CHECK: propassign bool, Bool(true)
%true = firrtl.bool true
firrtl.propassign %bool, %true : !firrtl.bool
// CHECK: propassign double, Double(0.3333{{[0-9]*}})
%d = firrtl.double 0.333333333333333333333333333333333333333
firrtl.propassign %double, %d : !firrtl.double
// CHECK: propassign path, path("OMDeleted:")
%p = firrtl.unresolved_path "OMDeleted:"
firrtl.propassign %path, %p : !firrtl.path
// CHECK: propassign list,
// CHECK-NEXT: List<List<String>>(List<String>(String("hello"), String("hello")),
// CHECK-NEXT: List<String>())
%strings = firrtl.list.create %0, %0 : !firrtl.list<string>
%empty = firrtl.list.create : !firrtl.list<string>
%strings_and_empty = firrtl.list.create %strings, %empty : !firrtl.list<list<string>>
firrtl.propassign %list, %strings_and_empty : !firrtl.list<list<string>>
}
// Test optional group declaration and definition emission.
//
// CHECK-LABEL: layer GroupA, bind :
// CHECK-NEXT: layer GroupB, bind :
// CHECK-NEXT: layer GroupC, bind :
// CHECK-NEXT: layer GroupD, bind :
// CHECK-NEXT: layer GroupE, inline :
// CHECK-NEXT: layer GroupF, bind :
// CHECK-NEXT: layer GroupWithOutputDir, bind, "foo{{/|\\\\}}" :
firrtl.layer @GroupA bind {
firrtl.layer @GroupB bind {
firrtl.layer @GroupC bind {
}
firrtl.layer @GroupD bind {
firrtl.layer @GroupE inline {
}
}
}
firrtl.layer @GroupF bind {
}
}
firrtl.layer @GroupWithOutputDir bind attributes {output_file = #hw.output_file<"foo/">} {}
// CHECK: module ModuleWithGroups :
// CHECK-NEXT: output a : Probe<UInt<1>, GroupA>
// CHECK-NEXT: output b : RWProbe<UInt<1>, GroupA.GroupB>
// CHECK: layerblock GroupA :
// CHECK-NEXT: layerblock GroupB :
// CHECK-NEXT: layerblock GroupC :
// CHECK-NEXT: layerblock GroupD :
// CHECK-NEXT: layerblock GroupE :
// CHECK-NEXT: layerblock GroupF :
firrtl.module @ModuleWithGroups(
out %a: !firrtl.probe<uint<1>, @GroupA>,
out %b: !firrtl.rwprobe<uint<1>, @GroupA::@GroupB>
) {
firrtl.layerblock @GroupA {
firrtl.layerblock @GroupA::@GroupB {
firrtl.layerblock @GroupA::@GroupB::@GroupC {
}
firrtl.layerblock @GroupA::@GroupB::@GroupD {
firrtl.layerblock @GroupA::@GroupB::@GroupD::@GroupE {
}
}
}
firrtl.layerblock @GroupA::@GroupF {
}
}
}
// Test line-breaks for very large layer associations.
firrtl.layer @Group1234567890 bind {
firrtl.layer @Group1234567890 bind {
firrtl.layer @Group1234567890 bind {
firrtl.layer @Group1234567890 bind {
firrtl.layer @Group1234567890 bind {
firrtl.layer @Group1234567890 bind {
firrtl.layer @Group1234567890 bind {
firrtl.layer @Group1234567890 bind {}
}
}
}
}
}
}
}
// CHECK: module ModuleWithLongProbeColor
// CHECK-NEXT: output o : Probe<
// CHECK-NEXT: UInt<1>,
// CHECK-NEXT: Group1234567890.Group1234567890.Group1234567890.Group1234567890
// CHECK-NEXT: .Group1234567890.Group1234567890.Group1234567890.Group1234567890
// CHECK-NEXT: >
firrtl.module @ModuleWithLongProbeColor(
out %o: !firrtl.probe<uint<1>, @Group1234567890::@Group1234567890::@Group1234567890::@Group1234567890::@Group1234567890::@Group1234567890::@Group1234567890::@Group1234567890>
) {}
// CHECK: module ModuleWithEnabledLayers enablelayer GroupA enablelayer GroupA.GroupB :
firrtl.module private @ModuleWithEnabledLayers() attributes {
layers = [
@GroupA,
@GroupA::@GroupB
]
} {}
// CHECK: extmodule ExtModuleWithEnabledLayers
// CHECK-NEXT: enablelayer GroupA
// CHECK-NEXT: enablelayer GroupA.GroupB :
firrtl.extmodule @ExtModuleWithEnabledLayers() attributes {
layers = [
@GroupA,
@GroupA::@GroupB
]
}
// CHECK: module ModuleWithLargeEnabledLayers
// CHECK-NEXT: enablelayer Group1234567890.Group1234567890
// CHECK-NEXT: enablelayer
// CHECK-NEXT: Group1234567890.Group1234567890.Group1234567890.Group1234567890
// CHECK-NEXT: enablelayer
// CHECK-NEXT: Group1234567890.Group1234567890.Group1234567890.Group1234567890
// CHECK-NEXT: .Group1234567890.Group1234567890.Group1234567890.Group1234567890 :
firrtl.module @ModuleWithLargeEnabledLayers() attributes {
layers = [
@Group1234567890::@Group1234567890,
@Group1234567890::@Group1234567890::@Group1234567890::@Group1234567890,
@Group1234567890::@Group1234567890::@Group1234567890::@Group1234567890::@Group1234567890::@Group1234567890::@Group1234567890::@Group1234567890
]} {}
// CHECK: module RWProbe :
// CHECK-NEXT: input in : { a : UInt<1> }[2]
// CHECK-NEXT: output p : RWProbe<UInt<1>>
// CHECK-NEXT: output p2 : RWProbe<UInt>
// CHECK-EMPTY:
// CHECK-NEXT: define p = rwprobe(in[1].a)
// CHECK-NEXT: node q = read(p)
// CHECK-NEXT: define p2 = rwprobe(q)
firrtl.module private @RWProbe(in %in: !firrtl.vector<bundle<a: uint<1>>, 2> sym [<@sym,4,public>],
out %p: !firrtl.rwprobe<uint<1>>,
out %p2 : !firrtl.rwprobe<uint>) {
%0 = firrtl.ref.rwprobe <@RWProbe::@sym> : !firrtl.rwprobe<uint<1>>
firrtl.ref.define %p, %0 : !firrtl.rwprobe<uint<1>>
%read = firrtl.ref.resolve %p : !firrtl.rwprobe<uint<1>>
%q, %q_ref = firrtl.node interesting_name %read forceable : !firrtl.uint<1>
%refcast = firrtl.ref.cast %q_ref : (!firrtl.rwprobe<uint<1>>) -> !firrtl.rwprobe<uint>
firrtl.ref.define %p2, %refcast : !firrtl.rwprobe<uint>
}
// CHECK-LABEL: option Platform :
firrtl.option @Platform {
// CHECK-NEXT: FPGA
firrtl.option_case @FPGA
// CHECK-NEXT: ASIC
firrtl.option_case @ASIC
}
// CHECK-LABEL: extmodule DefaultTarget
firrtl.extmodule private @DefaultTarget()
// CHECK-LABEL: extmodule FPGATarget
firrtl.extmodule private @FPGATarget()
// CHECK-LABEL: extmodule ASICTarget
firrtl.extmodule private @ASICTarget()
// CHECK-LABEL: module InstChoice :
firrtl.module public @InstChoice() {
// CHECK: instchoice inst of DefaultTarget, Platform :
// CHECK-NEXT: FPGA => FPGATarget
// CHECK-NEXT: ASIC => ASICTarget
firrtl.instance_choice inst @DefaultTarget alternatives @Platform
{ @FPGA -> @FPGATarget, @ASIC -> @ASICTarget } ()
}
// CHECK-LABEL: public module GenericIntrinsic :
firrtl.module public @GenericIntrinsic(in %clk: !firrtl.clock,
in %c : !firrtl.uint<1>,
out %s: !firrtl.uint<32>,
out %io1: !firrtl.uint<1>,
out %io2: !firrtl.uint<1>,
out %io3: !firrtl.uint<1>,
out %io4: !firrtl.uint<5>) {
// Common case should be emitted inline.
// CHECK: connect s, intrinsic(circt_sizeof : UInt<32>, clk)
%0 = firrtl.int.generic "circt_sizeof" %clk : (!firrtl.clock) -> !firrtl.uint<32>
firrtl.matchingconnect %s, %0 : !firrtl.uint<32>
// CHECK-NEXT: connect io1, intrinsic(circt_isX : UInt<1>, clk)
%1 = firrtl.int.generic "circt_isX" %clk : (!firrtl.clock) -> !firrtl.uint<1>
firrtl.matchingconnect %io1, %1 : !firrtl.uint<1>
// CHECK-NEXT: connect io2, intrinsic(circt_plusargs_test<FORMAT = "foo"> : UInt<1>)
%2 = firrtl.int.generic "circt_plusargs_test" <FORMAT: none = "foo"> : () -> !firrtl.uint<1>
firrtl.matchingconnect %io2, %2 : !firrtl.uint<1>
// CHECK-NOT: =
// CHECK-NEXT: intrinsic(circt_clock_gate : Clock, clk, c)
firrtl.int.generic "circt_clock_gate" %clk, %c : (!firrtl.clock, !firrtl.uint<1>) -> !firrtl.clock
// Materialize node as needed when used multiple times.
// CHECK-NEXT: node [[PAV:.+]]
// CHECK-NEXT: = intrinsic(circt_plusargs_value<FORMAT = "foo">
// CHECK-NEXT: : { found : UInt<1>, result : UInt<5> }
%3 = firrtl.int.generic "circt_plusargs_value" <FORMAT: none = "foo"> : () -> !firrtl.bundle<found: uint<1>, result: uint<5>>
// CHECK-NEXT: connect io3, [[PAV]].found
// CHECK-NEXT: connect io4, [[PAV]].result
%4 = firrtl.subfield %3[found] : !firrtl.bundle<found: uint<1>, result: uint<5>>
%5 = firrtl.subfield %3[result] : !firrtl.bundle<found: uint<1>, result: uint<5>>
firrtl.matchingconnect %io3, %4 : !firrtl.uint<1>
firrtl.matchingconnect %io4, %5 : !firrtl.uint<5>
// Nested once should be inlined.
// CHECK-NEXT: intrinsic(circt_verif_assert, intrinsic(circt_isX : UInt<1>, c))
%6 = firrtl.int.generic "circt_isX" %c : (!firrtl.uint<1>) -> !firrtl.uint<1>
firrtl.int.generic "circt_verif_assert" %6 : (!firrtl.uint<1>) -> ()
// Spill if nested > 1 for simplicity.
// CHECK-NEXT: node [[ISX:.+]] = intrinsic(circt_isX : UInt<1>, c)
// CHECK-NEXT: intrinsic(circt_verif_assert, intrinsic(circt_isX : UInt<1>, [[ISX]]))
%7 = firrtl.int.generic "circt_isX" %c : (!firrtl.uint<1>) -> !firrtl.uint<1>
%8 = firrtl.int.generic "circt_isX" %7 : (!firrtl.uint<1>) -> !firrtl.uint<1>
firrtl.int.generic "circt_verif_assert" %8 : (!firrtl.uint<1>) -> ()
}
}