circt/test/Dialect/FIRRTL/parse-basic.fir

1989 lines
77 KiB
Plaintext

; RUN: circt-translate -import-firrtl -verify-diagnostics -split-input-file %s | circt-opt | FileCheck %s
FIRRTL version 4.0.0
circuit MyModule : ; CHECK: firrtl.circuit "MyModule" {
; CHECK-LABEL: firrtl.module @MyModule(in %in: !firrtl.uint<8>, out %out: !firrtl.uint<8>) {
public module MyModule : @[FooBar.scala 369:27]
input in: UInt<8>
output out: UInt<8>
; CHECK: firrtl.matchingconnect %out, %in : !firrtl.uint<8>
connect out, in
; CHECK: }
; CHECK-LABEL: firrtl.module private @circuit(in %in: !firrtl.uint<80>) {
module circuit : ; Module with a keyword id.
input in: UInt<80>
; CHECK: }
; CHECK-LABEL: firrtl.extmodule private @MyExtModule(in in: !firrtl.uint<8>, out out: !firrtl.uint<8>)
; CHECK: attributes {defname = "myextmodule"}
; CHECK-NOT: {
extmodule MyExtModule :
input in: UInt<8>
output out : UInt<8>
defname = myextmodule
; CHECK-LABEL: firrtl.extmodule private @MyParameterizedExtModule
; CHECK-SAME: <FORMAT: none = "xyz_timeout=%d\0A",
; CHECK-SAME: DEFAULT: ui32 = 0,
; CHECK-SAME: WIDTH: ui32 = 32,
; CHECK-SAME: DEPTH: f64 = 3.242000e+01>
; CHECK-SAME: (in in: !firrtl.uint<8>,
; CHECK-SAME: out out: !firrtl.uint<8>)
; CHECK-SAME: attributes {defname = "name_thing"}
; CHECK-NOT: {
extmodule MyParameterizedExtModule :
input in: UInt<8>
output out: UInt<8>
defname = name_thing
parameter FORMAT = "xyz_timeout=%d\n"
parameter DEFAULT = 0
parameter WIDTH = 32
parameter DEPTH = 32.42
; Check that integers are extended to 32 bits if they are smaller.
; CHECK-LABEL: firrtl.extmodule private @IntegerParamsModule
extmodule IntegerParamsModule :
; CHECK-SAME: a: ui32 = 1
parameter a = 1
; CHECK-SAME: b: ui40 = 4294967296
parameter b = 4294967296
; Module to test type parsing.
; CHECK-LABEL: firrtl.module private @types(
module types :
input c: Clock ; CHECK: %c: !firrtl.clock,
input r: Reset ; CHECK: %r: !firrtl.reset,
input ar: AsyncReset ; CHECK: %ar: !firrtl.asyncreset,
input a: Analog ; CHECK: %a: !firrtl.analog,
input a8: Analog<8> ; CHECK: %a8: !firrtl.analog<8>,
input s: SInt ; CHECK: %s: !firrtl.sint,
input s4: SInt<4> ; CHECK: %s4: !firrtl.sint<4>,
input u: UInt ; CHECK: %u: !firrtl.uint,
input bf: { flip int_1 : UInt<1>, int_out : UInt<2>}
; CHECK: %bf: !firrtl.bundle<int_1 flip: uint<1>, int_out: uint<2>>
input vec: UInt<1>[4] ; CHECK: %vec: !firrtl.vector<uint<1>, 4>) {
; CHECK-LABEL: firrtl.module private @stmts(
module stmts :
input reset : UInt<1> ; CHECK: in %reset: !firrtl.uint<1>,
input reset_async: AsyncReset ; CHECK: in %reset_async: !firrtl.asyncreset,
input reset_abstract: Reset ; CHECK: in %reset_abstract: !firrtl.reset,
input clock : Clock ; CHECK: in %clock: !firrtl.clock,
output auto : UInt<1> ; CHECK: out %auto: !firrtl.uint<1>,
output auto11 : UInt<11> ; CHECK: out %auto11: !firrtl.uint<11>,
output sauto : SInt<9> ; CHECK: out %sauto: !firrtl.sint<9>,
input i8 : UInt<8> ; CHECK: in %i8: !firrtl.uint<8>,
input s1 : SInt<1> ; CHECK: in %s1: !firrtl.sint<1>,
input s8 : SInt<8> ; CHECK: in %s8: !firrtl.sint<8>,
input a1 : Analog<1> ; CHECK: in %a1: !firrtl.analog<1>,
input a8 : Analog<8> ; CHECK: in %a8: !firrtl.analog<8>,
input ab : {x : Analog<1>} ; CHECK: in %ab: !firrtl.bundle<x: analog<1>>)
; CHECK: %_t = firrtl.wire interesting_name : !firrtl.vector<uint<1>, 12>
wire _t : UInt<1>[12] @[Nodes.scala 370:76]
; CHECK: %_t_2 = firrtl.wire interesting_name : !firrtl.vector<uint<1>, 12>
wire _t_2 : UInt<1>[12]
; CHECK: firrtl.matchingconnect %_t, %_t_2 : !firrtl.vector<uint<1>, 12>
connect _t, _t_2
; CHECK: [[INV:%.+]] = firrtl.invalidvalue : !firrtl.uint<1>
; CHECK-NEXT: firrtl.matchingconnect %auto, [[INV]] : !firrtl.uint<1>
invalidate auto
; CHECK-NOT: firrtl.attach %a1
invalidate a1
; CHECK-NOT: firrtl.attach %ab
invalidate ab
; CHECK: firrtl.skip
skip @[SKipLoc.scala 42:24]
; CHECK: [[INV:%.+]] = firrtl.invalidvalue : !firrtl.uint<1>
; CHECK-NEXT: firrtl.matchingconnect %auto, [[INV]] : !firrtl.uint<1>
invalidate auto
; CHECK-NOT: firrtl.connect %reset
; CHECK-NOT: firrtl.matchingconnect %reset
invalidate reset
; CHECK: %out_0 = firrtl.wire interesting_name : !firrtl.bundle<member: bundle<"0": bundle<clock: clock, reset: uint<1>>>>
wire out_0 : { member : { 0 : { clock : Clock, reset : UInt<1>}}}
; CHECK: %_t_3 = firrtl.wire interesting_name : !firrtl.vector<uint<1>, 12>
; CHECK: [[A:%.+]] = firrtl.subindex %_t_3[0] : !firrtl.vector<uint<1>, 12>
; CHECK: %_t_4 = firrtl.wire interesting_name : !firrtl.vector<uint<1>, 12>
; CHECK: [[B:%.+]] = firrtl.subindex %_t_4[0] : !firrtl.vector<uint<1>, 12>
; CHECK: firrtl.matchingconnect [[A]], [[B]]
wire _t_3 : UInt<1>[12] @[Nodes.scala 370:76]
wire _t_4 : UInt<1>[12]
connect _t_3[0], _t_4[0] @[Xbar.scala 21:44]
; CHECK: %n1 = firrtl.node interesting_name %i8 : !firrtl.uint<8>
node n1 = i8
; CHECK: firrtl.add %reset, %reset : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<2>
node n2 = add(reset, reset)
; CHECK: firrtl.asClock %reset : (!firrtl.uint<1>) -> !firrtl.clock
node n3 = asClock(reset)
; CHECK: firrtl.asUInt %clock : (!firrtl.clock) -> !firrtl.uint<1>
node check_u0 = asUInt(clock)
; CHECK: firrtl.asUInt %i8 : (!firrtl.uint<8>) -> !firrtl.uint<8>
node check_u1 = asUInt(i8)
; CHECK: firrtl.asUInt %s8 : (!firrtl.sint<8>) -> !firrtl.uint<8>
node check_u2 = asUInt(s8)
; CHECK: firrtl.asUInt %a8 : (!firrtl.analog<8>) -> !firrtl.uint<8>
node check_u3 = asUInt(a8)
; CHECK: firrtl.asUInt %reset_abstract : (!firrtl.reset) -> !firrtl.uint<1>
node check_u5 = asUInt(reset_abstract)
; CHECK: firrtl.asUInt %reset_async : (!firrtl.asyncreset) -> !firrtl.uint<1>
node check_u6 = asUInt(reset_async)
; CHECK: firrtl.asSInt %clock : (!firrtl.clock) -> !firrtl.sint<1>
node check_s0 = asSInt(clock)
; CHECK: firrtl.asSInt %i8 : (!firrtl.uint<8>) -> !firrtl.sint<8>
node check_s1 = asSInt(i8)
; CHECK: firrtl.asSInt %s8 : (!firrtl.sint<8>) -> !firrtl.sint<8>
node check_s2 = asSInt(s8)
; CHECK: firrtl.asSInt %a8 : (!firrtl.analog<8>) -> !firrtl.sint<8>
node check_s3 = asSInt(a8)
; CHECK: firrtl.asSInt %reset_abstract : (!firrtl.reset) -> !firrtl.sint<1>
node check_s5 = asSInt(reset_abstract)
; CHECK: firrtl.asSInt %reset_async : (!firrtl.asyncreset) -> !firrtl.sint<1>
node check_s6 = asSInt(reset_async)
; CHECK: firrtl.asAsyncReset %clock : (!firrtl.clock) -> !firrtl.asyncreset
node check_ar0 = asAsyncReset(clock)
; CHECK: firrtl.asAsyncReset %reset : (!firrtl.uint<1>) -> !firrtl.asyncreset
node check_ar1 = asAsyncReset(reset)
; CHECK: firrtl.asAsyncReset %s1 : (!firrtl.sint<1>) -> !firrtl.asyncreset
node check_ar2 = asAsyncReset(s1)
; CHECK: firrtl.asAsyncReset %a1 : (!firrtl.analog<1>) -> !firrtl.asyncreset
node check_ar3 = asAsyncReset(a1)
; CHECK: firrtl.asAsyncReset %reset_abstract : (!firrtl.reset) -> !firrtl.asyncreset
node check_ar4 = asAsyncReset(reset_abstract)
; CHECK: firrtl.asAsyncReset %reset_async : (!firrtl.asyncreset) -> !firrtl.asyncreset
node check_ar5 = asAsyncReset(reset_async)
; CHECK: firrtl.asClock %clock : (!firrtl.clock) -> !firrtl.clock
node check_c0 = asClock(clock)
; CHECK: firrtl.asClock %reset : (!firrtl.uint<1>) -> !firrtl.clock
node check_c1 = asClock(reset)
; CHECK: firrtl.asClock %s1 : (!firrtl.sint<1>) -> !firrtl.clock
node check_c2 = asClock(s1)
; CHECK: firrtl.asClock %a1 : (!firrtl.analog<1>) -> !firrtl.clock
node check_c3 = asClock(a1)
; CHECK: firrtl.asClock %reset_abstract : (!firrtl.reset) -> !firrtl.clock
node check_c4 = asClock(reset_abstract)
; CHECK: firrtl.asClock %reset_async : (!firrtl.asyncreset) -> !firrtl.clock
node check_c5 = asClock(reset_async)
; CHECK: firrtl.node interesting_name %auto : !firrtl.uint<1>
node check_output = auto
; CHECK: %c42_ui10 = firrtl.constant 42 : !firrtl.const.uint<10>
; CHECK: %c171_ui8 = firrtl.constant 171 : !firrtl.const.uint<8>
; CHECK: firrtl.add %c42_ui10, %c171_ui8
; CHECK: firrtl.constCast
; CHECK: firrtl.matchingconnect %auto
connect auto11, add(UInt<10>(42), UInt<8>(0hAB))
; CHECK: %c-85_si8 = firrtl.constant -85 : !firrtl.const.sint<8>
connect sauto, add(s8, SInt<8>(-85))
; CHECK: firrtl.when %reset : !firrtl.uint<1> {
; CHECK: firrtl.matchingconnect %_t, %_t_2
; CHECK: } else {
; CHECK: firrtl.matchingconnect %_t, %_t_2
; CHECK: }
when reset : connect _t, _t_2 else : connect _t, _t_2
; CHECK: firrtl.when %reset : !firrtl.uint<1> {
; CHECK: [[N4A:%.+]] = firrtl.node interesting_name %_t_2
; CHECK: firrtl.matchingconnect %_t, [[N4A]]
; CHECK: } else {
; CHECK: [[N4B:%.+]] = firrtl.node interesting_name %_t_2
; CHECK: firrtl.matchingconnect %_t, [[N4B]]
; CHECK: }
when reset :
node n4 = _t_2
connect _t, n4
else :
node n4 = _t_2 ; 'n4' name is in unique scopes.
connect _t, n4
; CHECK: [[TMP:%.+]] = firrtl.constant 4
; CHECK: [[COND:%.+]] = firrtl.lt %reset, [[TMP]]
; CHECK: firrtl.when [[COND]] : !firrtl.uint<1> {
; CHECK: firrtl.matchingconnect %_t, %_t_2
; CHECK: }
; CHECK-NOT: else
when lt(reset, UInt(4)) : ;; When with no else.
connect _t, _t_2
; CHECK: firrtl.when %reset : !firrtl.uint<1> {
; CHECK: firrtl.matchingconnect %_t, %_t_2
; CHECK: } else {
; CHECK: [[COND:%.+]] = firrtl.not %reset
; CHECK: firrtl.when [[COND]] : !firrtl.uint<1> {
; CHECK: firrtl.matchingconnect %_t, %_t_2
; CHECK: }
; CHECK: }
when reset :
connect _t, _t_2
else when not(reset) :
connect _t, _t_2
; CHECK: firrtl.when %reset : !firrtl.uint<1> {
; CHECK: firrtl.matchingconnect %_t, %_t
; CHECK: } else {
; CHECK: [[COND:%.+]] = firrtl.not %reset
; CHECK: firrtl.when [[COND]] : !firrtl.uint<1> {
; CHECK: firrtl.matchingconnect %_t, %_t_2
; CHECK: } else {
; CHECK: firrtl.matchingconnect %_t, %_t_2
; CHECK: }
; CHECK: }
when reset:
connect _t, _t_2
else when not(reset) :
connect _t, _t_2
else :
connect _t, _t_2
; CHECK: firrtl.printf %clock, %reset, "Something interesting!\0A %x %x" (%_t, %_t_2) : !firrtl.clock, !firrtl.uint<1>, !firrtl.vector<uint<1>, 12>, !firrtl.vector<uint<1>, 12>
printf(clock, reset, "Something interesting!\n %x %x", _t, _t_2)
; CHECK: firrtl.printf %clock, %reset, "Something interesting!\0A %x %x" {name = "printf_0"} (%_t, %_t_2) : !firrtl.clock, !firrtl.uint<1>, !firrtl.vector<uint<1>, 12>, !firrtl.vector<uint<1>, 12>
printf(clock, reset, "Something interesting!\n %x %x", _t, _t_2) : printf_0
; CHECK: firrtl.stop %clock, %reset, 42 : !firrtl.clock, !firrtl.uint<1>
stop(clock, reset, 42)
; CHECK: firrtl.stop %clock, %reset, 42 {name = "stop_0"} : !firrtl.clock, !firrtl.uint<1>
stop(clock, reset, 42) : stop_0
; CHECK: firrtl.bits %i8 4 to 2 : (!firrtl.uint<8>) -> !firrtl.uint<3>
node n4 = bits(i8, 4, 2)
; CHECK: firrtl.shl %i8, 4 : (!firrtl.uint<8>) -> !firrtl.uint<12>
; CHECK: firrtl.shr %i8, 8 : (!firrtl.uint<8>) -> !firrtl.uint<0>
node n5 = or(shl(i8, 4), shr(i8, 8))
; CHECK: firrtl.dshl %i8, %{{.*}} : (!firrtl.uint<8>, !firrtl.const.uint<4>) -> !firrtl.uint<23>
node n6 = dshl(i8, UInt<4>(7))
; CHECK: firrtl.dshlw %i8, %{{.*}} : (!firrtl.uint<8>, !firrtl.const.uint<4>) -> !firrtl.uint<8>
node n6s = dshlw(i8, UInt<4>(7))
; CHECK: firrtl.cat %{{.*}}, %{{.*}} : (!firrtl.uint<12>, !firrtl.uint<23>) -> !firrtl.uint<35>
node n7 = cat(n5, n6)
; CHECK: firrtl.mux(%reset, %i8, %{{.*}}) : (!firrtl.uint<1>, !firrtl.uint<8>, !firrtl.const.uint) -> !firrtl.uint
node n8 = mux(reset, i8, UInt(4))
; CHECK: %_t_2621 = firrtl.regreset interesting_name %clock, %reset, %{{.*}} : !firrtl.clock, !firrtl.uint<1>, !firrtl.const.uint<4>, !firrtl.uint<4>
regreset _t_2621 : UInt<4>, clock, reset, UInt<4>(0h0) @[Edges.scala 230:27]
; CHECK: %_t_1601 = firrtl.regreset interesting_name %clock, %reset, %{{.*}} : !firrtl.clock, !firrtl.uint<1>, !firrtl.const.uint<2>, !firrtl.uint<2>
regreset _t_1601 : UInt<2>, clock, reset, UInt<2>(0h00) @[Edges.scala 230:27]
; CHECK: firrtl.div %i8, %{{.*}} : (!firrtl.uint<8>, !firrtl.const.uint<4>) -> !firrtl.uint<8>
node n9 = div(i8, UInt<4>(4))
; CHECK: firrtl.tail %i8, 7 : (!firrtl.uint<8>) -> !firrtl.uint<1>
; CHECK: firrtl.tail %i8, 0 : (!firrtl.uint<8>) -> !firrtl.uint<8>
; CHECK: firrtl.head %i8, 4 : (!firrtl.uint<8>) -> !firrtl.uint<4>
node n10 = add(add(tail(i8, 7), tail(i8, 0)), head(i8, 4))
; CHECK: firrtl.tail %{{.*}}, 3 : (!firrtl.sint<8>) -> !firrtl.uint<5>
node n10s = tail(asSInt(i8), 3)
; CHECK: %_t_2622 = firrtl.reg interesting_name %clock : !firrtl.clock, !firrtl.uint<4>
reg _t_2622 : UInt<4>, clock
; CHECK: %xyz_in = firrtl.instance xyz interesting_name @circuit(in in: !firrtl.uint<80>)
inst xyz of circuit
; CHECK: [[PAD:%.*]] = firrtl.pad %i8, 80 : (!firrtl.uint<8>) -> !firrtl.uint<80>
; CHECK: firrtl.matchingconnect %xyz_in, [[PAD]] : !firrtl.uint<80>
connect xyz.in, i8
; CHECK: %myext_in, %myext_out = firrtl.instance myext interesting_name @MyExtModule(in in: !firrtl.uint<8>, out out: !firrtl.uint<8>)
inst myext of MyExtModule
connect myext.in, i8
printf(clock, reset, "Something interesting! %x", myext.out)
; CHECK: firrtl.when %reset : !firrtl.uint<1> {
when reset :
; CHECK: %reset_myext_in, %reset_myext_out = firrtl.instance reset_myext interesting_name @MyExtModule(in in: !firrtl.uint<8>, out out: !firrtl.uint<8>)
inst reset_myext of MyExtModule
connect reset_myext.in, i8
; CHECK: }
; CHECK: firrtl.subaccess %_t[%i8] : !firrtl.vector<uint<1>, 12>, !firrtl.uint<8>
connect auto, _t[i8]
; CHECK: firrtl.subaccess %_t[%auto] : !firrtl.vector<uint<1>, 12>, !firrtl.uint<1>
connect auto, _t[auto]
; CHECK: %myMem = chirrtl.combmem interesting_name : !chirrtl.cmemory<bundle<id: uint<4>, resp: uint<2>>, 8>
cmem myMem : { id : UInt<4>, resp : UInt<2>} [8] @[Decoupled.scala 209:24]
; CHECK: %memValue_data, %memValue_port = chirrtl.memoryport Infer %myMem {name = "memValue"} : (!chirrtl.cmemory<bundle<id: uint<4>, resp: uint<2>>, 8>) -> (!firrtl.bundle<id: uint<4>, resp: uint<2>>, !chirrtl.cmemoryport)
; CHECK: chirrtl.memoryport.access %memValue_port[%i8], %clock : !chirrtl.cmemoryport, !firrtl.uint<8>, !firrtl.clock
infer mport memValue = myMem[i8], clock
connect auto11, memValue.id
; CHECK: %base_table_0 = chirrtl.seqmem interesting_name Undefined : !chirrtl.cmemory<vector<uint<1>, 9>, 256>
smem base_table_0 : UInt<1>[9] [256]
; CHECK: %base_table_1 = chirrtl.seqmem interesting_name Old : !chirrtl.cmemory<vector<uint<1>, 9>, 256>
smem base_table_1 : UInt<1>[9] [256], old
; CHECK: %tableValue_data, %tableValue_port = chirrtl.memoryport Read %base_table_1 {name = "tableValue"} : (!chirrtl.cmemory<vector<uint<1>, 9>, 256>) -> (!firrtl.vector<uint<1>, 9>, !chirrtl.cmemoryport)
; CHECK: chirrtl.memoryport.access %tableValue_port[%i8], %clock : !chirrtl.cmemoryport, !firrtl.uint<8>, !firrtl.clock
read mport tableValue = base_table_1[i8], clock
; Check that we can handle large memory sizes.
; CHECK: %testharness = chirrtl.seqmem interesting_name Undefined : !chirrtl.cmemory<vector<uint<8>, 16>, 2147483648>
smem testharness : UInt<8>[16][2147483648], undefined
; CHECK: firrtl.pad %i8, 10 : (!firrtl.uint<8>) -> !firrtl.uint<10>
node n11 = pad(i8, 10)
; CHECK: firrtl.andr %n11 : (!firrtl.uint<10>) -> !firrtl.uint<1>
node n12 = andr(n11)
; CHECK: = firrtl.not %auto : (!firrtl.uint<1>) -> !firrtl.uint<1>
node n13 = not(auto)
; CHECK: %_M__T_10, %_M__T_11, %_M__T_18 = firrtl.mem interesting_name Undefined {depth = 8 : i64, name = "_M", portNames = ["_T_10", "_T_11", "_T_18"]
; CHECK-SAME: readLatency = 0 : i32, writeLatency = 1 : i32} :
; CHECK-SAME: !firrtl.bundle<addr: uint<3>, en: uint<1>, clk: clock, data: bundle<id: uint<4>>, mask: bundle<id: uint<1>>>,
; CHECK-SAME: !firrtl.bundle<addr: uint<3>, en: uint<1>, clk: clock, data: bundle<id: uint<4>>, mask: bundle<id: uint<1>>>,
; CHECK-SAME: !firrtl.bundle<addr: uint<3>, en: uint<1>, clk: clock, data flip: bundle<id: uint<4>>
mem _M : @[Decoupled.scala 209:24]
data-type => { id : UInt<4> }
depth => 8
read-latency => 0
write-latency => 1
reader => _T_18
writer => _T_10 _T_11
read-under-write => undefined
invalidate _M._T_18.addr @[Decoupled.scala 209:24]
invalidate _M._T_18.clk @[Decoupled.scala 209:24]
connect _M._T_18.en, UInt<1>(0h0) @[Decoupled.scala 209:24]
invalidate _M._T_10.addr @[Decoupled.scala 209:24]
invalidate _M._T_10.clk @[Decoupled.scala 209:24]
connect _M._T_10.en, UInt<1>(0h0) @[Decoupled.scala 209:24]
invalidate _M._T_10.data @[Decoupled.scala 209:24]
invalidate _M._T_10.mask @[Decoupled.scala 209:24]
; CHECK: firrtl.attach %a8, %a8, %a8 :
attach (a8, a8, a8)
wire pred: UInt <1>
wire en: UInt <1>
connect pred, eq(i8, i8)
connect en, not(reset)
; CHECK: firrtl.assert %clock, %pred, %en, "X equals Y when Z is valid" : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<1> {eventControl = 0 : i32, isConcurrent = false}
assert(clock, pred, en, "X equals Y when Z is valid")
; CHECK: firrtl.assert %clock, %pred, %en, "X equals Y when Z is valid" : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<1> {eventControl = 0 : i32, isConcurrent = false, name = "assert_0"}
assert(clock, pred, en, "X equals Y when Z is valid") : assert_0
; CHECK: firrtl.assert %clock, %pred, %en, "pred=%d, en=%d"(%pred, %en) : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<1>, !firrtl.uint<1>, !firrtl.uint<1> {eventControl = 0 : i32, isConcurrent = false, name = "assert_1"}
assert(clock, pred, en, "pred=%d, en=%d", pred, en) : assert_1
; CHECK: firrtl.assume %clock, %pred, %en, "X equals Y when Z is valid" : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<1> {eventControl = 0 : i32, isConcurrent = false}
assume(clock, pred, en, "X equals Y when Z is valid")
; CHECK: firrtl.assume %clock, %pred, %en, "X equals Y when Z is valid" : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<1> {eventControl = 0 : i32, isConcurrent = false, name = "assume_0"}
assume(clock, pred, en, "X equals Y when Z is valid") : assume_0
; CHECK: firrtl.assume %clock, %pred, %en, "pred=%d, en=%d"(%pred, %en) : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<1>, !firrtl.uint<1>, !firrtl.uint<1> {eventControl = 0 : i32, isConcurrent = false, name = "assume_1"}
assume(clock, pred, en, "pred=%d, en=%d", pred, en) : assume_1
; CHECK: firrtl.cover %clock, %pred, %en, "X equals Y when Z is valid" : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<1> {eventControl = 0 : i32, isConcurrent = false}
cover(clock, pred, en, "X equals Y when Z is valid")
; CHECK: firrtl.cover %clock, %pred, %en, "X equals Y when Z is valid" : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<1> {eventControl = 0 : i32, isConcurrent = false, name = "cover_0"}
cover(clock, pred, en, "X equals Y when Z is valid") : cover_0
; CHECK-LABEL: firrtl.module private @type_handling(
module type_handling :
wire _t_6 : { flip b : { bits : { source : UInt<7> } } }
node _t_8 = bits(_t_6.b.bits.source, 5, 0)
; CHECK: %flip1 = firrtl.wire interesting_name : !firrtl.bundle<x flip: bundle<a flip: uint>>
wire flip1 : { flip x : { flip a : UInt } }
; CHECK: %flip2 = firrtl.wire interesting_name : !firrtl.bundle<x flip: bundle<a flip: uint, b: analog>>
wire flip2 : { flip x : { flip a : UInt, b: Analog } }
; CHECK: %flip3 = firrtl.wire interesting_name : !firrtl.bundle<x flip: bundle<a flip: uint, b flip: analog>>
wire flip3 : { flip x : { flip a : UInt, flip b: Analog } }
; CHECK: %flip4 = firrtl.wire interesting_name : !firrtl.bundle<x flip: vector<bundle<a flip: uint>, 4>>
wire flip4 : { flip x : { flip a : UInt }[4] }
; CHECK-LABEL: firrtl.module private @expr_stmt_ambiguity(
module expr_stmt_ambiguity :
; CHECK: %reg = firrtl.wire interesting_name : !firrtl.uint
wire reg : UInt
; CHECK: firrtl.connect %reg,
connect reg, UInt(42)
; CHECK: %write = firrtl.wire
wire write : { id : UInt<4>, resp : UInt<2>}
; CHECK: firrtl.subfield %write[id]
connect write.id, UInt(1)
; CHECK-LABEL: firrtl.module private @expr_stmt_ambiguity2(
module expr_stmt_ambiguity2 :
; CHECK: firrtl.instance write interesting_name @circuit
inst write of circuit
; CHECK: firrtl.connect %write_in
connect write.in, UInt(1)
; CHECK-LABEL: firrtl.module private @oversize_shift(
module oversize_shift :
wire value : UInt<2>
; CHECK: firrtl.shr %value, 5 : (!firrtl.uint<2>) -> !firrtl.uint<0>
node n = shr(value, 5)
; CHECK-LABEL: firrtl.module private @when_else_ambiguity(
module when_else_ambiguity :
output out : UInt
input in : UInt
wire reset : UInt<1>
; CHECK: firrtl.when {{.*}} : !firrtl.uint<1> {
when reset : @[Debug.scala 1176:37]
; CHECK: firrtl.when {{.*}} : !firrtl.uint<1> {
when reset :
connect out, in
; CHECK: }
; CHECK: } else {
else :
; CHECK: firrtl.when {{.*}} : !firrtl.uint<1> {
when reset : @[Debug.scala 1180:39]
connect out, in
; CHECK: }
; CHECK: }
; CHECK-LABEL: firrtl.module private @chisel_when_mport_bug(
module chisel_when_mport_bug :
input cond : UInt<1>
input addr : UInt
input clock : Clock
; Memory ports should be declared in the scope of the cmemory, but should
; be enabled at the location of the mport.
; CHECK: %memory = chirrtl.seqmem interesting_name Undefined : !chirrtl.cmemory<vector<uint<1>, 9>, 256>
smem memory : UInt<1>[9] [256]
; CHECK: %xyz0_data, %xyz0_port = chirrtl.memoryport Read %memory {name = "xyz0"} : (!chirrtl.cmemory<vector<uint<1>, 9>, 256>) -> (!firrtl.vector<uint<1>, 9>, !chirrtl.cmemoryport)
; CHECK: firrtl.when %cond : !firrtl.uint<1> {
; CHECK: chirrtl.memoryport.access %xyz0_port[%addr], %clock : !chirrtl.cmemoryport, !firrtl.uint, !firrtl.clock
; CHECK: }
when cond :
read mport xyz0 = memory[addr], clock
; CHECK: firrtl.when %cond : !firrtl.uint<1> {
; CHECK: %n0 = firrtl.node interesting_name %xyz0_data : !firrtl.vector<uint<1>, 9>
; CHECK: }
when cond :
node n0 = xyz0
; CHECK: %n1 = firrtl.node interesting_name %xyz0_data : !firrtl.vector<uint<1>, 9>
node n1 = xyz0
; CHECK-LABEL: firrtl.module private @constant_implicit_cse(
module constant_implicit_cse :
input cond : UInt<1>
; CHECK: [[CST15:%.+]] = firrtl.constant 15 : !firrtl.const.uint<4>
; CHECK: %a = firrtl.node interesting_name [[CST15]]
node a = UInt<4>(15)
; CHECK: %b = firrtl.node interesting_name [[CST15]]
node b = UInt<4>(15)
;; Constants always get emitted to the top level.
; CHECK: [[CST7:%.+]] = firrtl.constant 7 : !firrtl.const.uint<4>
; CHECK: firrtl.when %cond : !firrtl.uint<1> {
when cond :
; CHECK: %c = firrtl.node interesting_name [[CST15]]
node c = UInt<4>(15)
; CHECK: %d = firrtl.node interesting_name [[CST7]]
node d = UInt<4>(7)
; CHECK: firrtl.when %cond : !firrtl.uint<1> {
when cond :
; CHECK: %e = firrtl.node interesting_name [[CST7]]
node e = UInt<4>(7)
; CHECK: }
; CHECK: }
; CHECK: %f = firrtl.node interesting_name [[CST15]]
node f = UInt<4>(15)
node g = UInt<4>(7)
; CHECK-LABEL: firrtl.module private @subfield_implicit_cse
module subfield_implicit_cse :
input i: {x: UInt<1>}
input cond: UInt<1>
output o: UInt<1>
; Subfields always get emitted by their declarations.
; CHECK: [[SUB:%.+]] = firrtl.subfield %i[x]
; CHECK: %n3 = firrtl.node interesting_name [[SUB]]
node n3 = i.x
; CHECK: firrtl.when %cond : !firrtl.uint<1> {
when cond:
; CHECK: %n4 = firrtl.node interesting_name [[SUB]]
node n4 = i.x
; CHECK: }
; Check that invalidation reuses subfields
wire w: {a: UInt<1>}[1]
; CHECK: %invalid = firrtl.invalidvalue : !firrtl.vector<bundle<a: uint<1>>, 1>
; CHECK: firrtl.matchingconnect %w, %invalid
invalidate w
; CHECK: %invalid_0 = firrtl.invalidvalue : !firrtl.vector<bundle<a: uint<1>>, 1>
; CHECK: firrtl.matchingconnect %w, %invalid_0
invalidate w
; CHECK-LABEL: firrtl.module private @flip_one
module flip_one :
input bf: { flip int_1 : UInt<1>, int_out : UInt<2>}
; CHECK: %0 = firrtl.subfield %bf[int_1]
; CHECK: %_T = firrtl.node interesting_name %0
node _T = bf.int_1
; CHECK: firrtl.when %_T : !firrtl.uint<1> {
when _T :
skip
; CHECK-LABEL: firrtl.module private @mem_depth_1
module mem_depth_1 :
input clock : Clock
input reset : UInt<1>
mem bar : @[Decoupled.scala 218:16]
data-type => UInt<3>
depth => 1
read-latency => 0
write-latency => 1
reader => io_deq_bits_MPORT
writer => MPORT
read-under-write => undefined
; CHECK: %bar_MPORT, %bar_io_deq_bits_MPORT = firrtl.mem interesting_name Undefined {depth = 1 : i64, name = "bar", portNames = ["MPORT", "io_deq_bits_MPORT"], readLatency = 0 : i32, writeLatency = 1 : i32} :
; CHECK: !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data: uint<3>, mask: uint<1>>,
; CHECK: !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data flip: uint<3>>
; CHECK-LABEL: firrtl.module private @mem_no_ports() {
; CHECK-NEXT: }
; https://github.com/llvm/circt/issues/531
module mem_no_ports :
mem bar : @[Decoupled.scala 218:16]
data-type => UInt<3>
depth => 1
read-latency => 0
write-latency => 1
read-under-write => undefined
; CHECK-LABEL: firrtl.module private @issue354(out %tmp5: !firrtl.sint<19>) {
module issue354 :
output tmp5: SInt<19>
connect tmp5, SInt<19>(8)
; CHECK: %c8_si19 = firrtl.constant 8 : !firrtl.const.sint<19>
; CHECK: [[VAL:%.*]] = firrtl.constCast %c8_si19 : (!firrtl.const.sint<19>) -> !firrtl.sint<19>
; CHECK: firrtl.matchingconnect %tmp5, [[VAL]] : !firrtl.sint<19>
; CHECK-LABEL: firrtl.module private @issue347
module issue347 :
output tmp12: SInt<4>
connect tmp12, SInt<4>(-4)
; CHECK: %c-4_si4 = firrtl.constant -4 : !firrtl.const.sint<4>
; CHECK-LABEL: firrtl.extmodule private @issue183<A: si32 = -1>()
extmodule issue183:
parameter A = -1
; The Scala FIRRTL Compiler allows this for an aggregate node with an internal
; analog.
; CHECK-LABEL: firrtl.module private @analog_in_aggregate_node
module analog_in_aggregate_node:
input a: { a: UInt<1>, b: Analog<1>}
; CHECK: %b = firrtl.node interesting_name %a : !firrtl.bundle<a: uint<1>, b: analog<1>>
node b = a
; Check that a register clock sink is converted to passive
; CHECK-LABEL: firrtl.module private @register_clock_passive
module register_clock_passive:
input clkIn: Clock
output clkOut: Clock
connect clkOut, clkIn
; CHECK: firrtl.reg interesting_name %clkOut
reg r: UInt<1>, clkOut
; Check that a register reset sink is converted to passive
; CHECK-LABEL: firrtl.module private @register_reset_passive
module register_reset_passive:
input clk: Clock
output rst: UInt<1>
invalidate rst
; CHECK: firrtl.regreset interesting_name %clk, %rst
regreset r: UInt<1>, clk, rst, UInt<1>(0)
; Check that a register init sink is converted to passive
; CHECK-LABEL: firrtl.module private @register_init_passive
module register_init_passive:
input clk: Clock
input rst: UInt<1>
output init: UInt<1>
invalidate init
; CHECK: firrtl.regreset interesting_name %clk, %rst, %init
regreset r: UInt<1>, clk, rst, init
; https://github.com/llvm/circt/issues/492
; CHECK-LABEL: firrtl.module private @WriteOnlyMemIssue492
module WriteOnlyMemIssue492 :
input clock: Clock
input wAddr: UInt<4>
input wEn: UInt<1>
input wMask: UInt<1>
input wData: UInt<8>
mem memory:
data-type => UInt<8>
depth => 16
writer => w
read-latency => 0
write-latency => 1
read-under-write => undefined
connect memory.w.clk, clock
connect memory.w.en, wEn
connect memory.w.addr, wAddr
connect memory.w.mask, wMask
connect memory.w.data, wData
; https://github.com/llvm/circt/issues/559
; CHECK-LABEL: firrtl.module private @TrickyIssue559
module TrickyIssue559:
input input: UInt<1>
output output: UInt<1>
; CHECK: firrtl.matchingconnect %output, %input
connect output, input
; CHECK-LABEL: firrtl.module private @CheckInvalids
module CheckInvalids_in0 :
input in0 : UInt<1>
; CHECK-NOT: firrtl.connect %in0
; CHECK-NOT: firrtl.matchingconnect %in0
invalidate in0
module CheckInvalids_in1 :
input in1 : { a : UInt<1>, b : UInt<1> }
; CHECK-NOT: firrtl.connect %in1
; CHECK-NOT: firrtl.matchingconnect %in1
invalidate in1
module CheckInvalids_in2 :
input in2 : { a : UInt<1>, flip b : UInt<1>}
; CHECK: [[IN2_B:%.+]] = firrtl.subfield %in2[b]
; CHECK: [[INV:%.+]] = firrtl.invalidvalue
; CHECK: firrtl.matchingconnect [[IN2_B]], [[INV]]
invalidate in2
module CheckInvalids_in3 :
input in3 : {a : { b : UInt<1>, flip c : UInt<1>}}
; CHECK: [[IN3_A:%.+]] = firrtl.subfield %in3[a]
; CHECK: [[IN3_A_C:%.+]] = firrtl.subfield [[IN3_A]][c]
; CHECK: [[INV:%.+]] = firrtl.invalidvalue
; CHECK: firrtl.matchingconnect [[IN3_A_C]], [[INV]]
invalidate in3
module CheckInvalids_out0 :
output out0 : UInt<1>
; CHECK: [[INV:%.+]] = firrtl.invalidvalue
; CHECK: firrtl.matchingconnect %out0, [[INV]]
invalidate out0
module CheckInvalids_out1 :
output out1 : { a : UInt<1>, b : UInt<1> }
; CHECK: [[INV:%.+]] = firrtl.invalidvalue : !firrtl.bundle<a: uint<1>, b: uint<1>>
; CHECK: firrtl.matchingconnect %out1, [[INV]]
invalidate out1
module CheckInvalids_out2 :
output out2 : { a : UInt<1>, flip b : UInt<1>}
; CHECK: [[OUT2_A:%.+]] = firrtl.subfield %out2[a]
; CHECK: [[INV:%.+]] = firrtl.invalidvalue
; CHECK: firrtl.matchingconnect [[OUT2_A]], [[INV]]
invalidate out2
module CheckInvalids_out3 :
output out3 : {a : { b : UInt<1>, flip c : UInt<1>}}
; CHECK: [[OUT3_A:%.+]] = firrtl.subfield %out3[a]
; CHECK: [[OUT3_A_B:%.+]] = firrtl.subfield [[OUT3_A]][b]
; CHECK: [[INV:%.+]] = firrtl.invalidvalue
; CHECK: firrtl.matchingconnect [[OUT3_A_B]], [[INV]]
invalidate out3
module CheckInvalids_wires :
; CHECK: %wire0 = firrtl.wire
; CHECK: [[INV:%.+]] = firrtl.invalidvalue
; CHECK: firrtl.matchingconnect %wire0, [[INV]]
wire wire0 : UInt<1>
invalidate wire0
; CHECK: %wire1 = firrtl.wire
; CHECK: [[WIRE1_B:%.+]] = firrtl.subfield %wire1[b]
; CHECK: [[WIRE1_A:%.+]] = firrtl.subfield %wire1[a]
; CHECK: [[INV:%.+]] = firrtl.invalidvalue
; CHECK: firrtl.matchingconnect [[WIRE1_A]], [[INV]]
; CHECK: [[INV:%.+]] = firrtl.invalidvalue
; CHECK: firrtl.matchingconnect [[WIRE1_B]], [[INV]]
wire wire1 : {a : UInt<1>, flip b : UInt<1> }
invalidate wire1
; An analog in the leaf of a wire should be attached not connected.
; CHECK: %wire2 = firrtl.wire
; CHECK: [[WIRE2_X:%.+]] = firrtl.subfield %wire2[x]
; CHECK: [[WIRE2_X_B:%.+]] = firrtl.subfield [[WIRE2_X]][b]
; CHECK: [[WIRE2_X_A:%.+]] = firrtl.subfield [[WIRE2_X]][a]
; CHECK: [[INV:%.+]] = firrtl.invalidvalue
; CHECK: firrtl.matchingconnect [[WIRE2_X_A]], [[INV]]
; CHECK-NOT: firrtl.attach [[WIRE2_X_B]], [[INV]]
wire wire2 : {x : {flip a : UInt<1>, flip b: Analog<1> } }
invalidate wire2
; https://github.com/llvm/circt/issues/563
; CHECK: %U0_in0, %U0_in1, %U0_out0, %U0_out1 = firrtl.instance U0 interesting_name @mod_0_563
inst U0 of mod_0_563
; CHECK: [[INV:%.+]] = firrtl.invalidvalue
; CHECK: firrtl.matchingconnect %U0_in0, [[INV]]
; CHECK: [[INV:%.+]] = firrtl.invalidvalue : !firrtl.bundle<a: uint<5>>
; CHECK: firrtl.matchingconnect %U0_in1, [[INV]]
invalidate U0
; This reference is declared after its first use.
; https://github.com/llvm/circt/issues/163
module mod_0_563 :
input in0: UInt<5>
input in1: { a : UInt<5> }
output out0: UInt<5>
output out1: { a : UInt<5> }
connect out0, in0
connect out1, in1
; https://github.com/llvm/circt/issues/606
; CHECK-LABEL: firrtl.module private @mutableSubIndex606
module mutableSubIndex606 :
output io : UInt<1>[8]
; CHECK: %0 = firrtl.subindex %io[0] : !firrtl.vector<uint<1>, 8>
; CHECK: [[VAL:%.*]] = firrtl.constCast %c0_ui1 : (!firrtl.const.uint<1>) -> !firrtl.uint<1>
; CHECK: firrtl.matchingconnect %0, [[VAL]] : !firrtl.uint<1>
connect io[0], UInt<1>(0h00)
; https://github.com/llvm/circt/issues/782
; CHECK-LABEL: mem_madness782
module mem_madness782:
input clock: Clock
input rAddr: UInt<4>
input rEn: UInt<1>
output rData: UInt<8>
; CHECK: %mem_r = firrtl.mem interesting_name Undefined {depth = 16 : i64, name = "mem", portNames = ["r"], readLatency = 2 : i32, writeLatency = 1 : i32} : !firrtl.bundle<addr: uint<4>, en: uint<1>, clk: clock, data flip: uint<8>>
mem mem:
data-type => UInt<8>
depth => 16
reader => r
read-latency => 2
write-latency => 1
read-under-write => undefined
connect mem.r.clk, clock
connect mem.r.en, rEn
connect mem.r.addr, rAddr
connect rData, mem.r.data
; Test that behavioral memory reads and writes both work and that flow checks
; don't fail here. (A memory port should have duplex flow.)
; See: https://github.com/llvm/circt/issues/1058
; CHECK-LABEL: firrtl.module private @BehavioralMemory
module BehavioralMemory:
input clock: Clock
input rAddr: UInt<3>
output rData: UInt<1>
input wAddr: UInt<3>
input wData: UInt<1>
cmem a: UInt<1>[8]
; CHECK: firrtl.matchingconnect %rData, %r
infer mport r = a[rAddr], clock
connect rData, r
; CHECK: firrtl.matchingconnect %w_data, %wData
infer mport w = a[wAddr], clock
connect w, wData
; Test that a mux with an unknown width select line parses. This is a check
; of the predicate enforced on UInt1Type.
; CHECK-LABEL: firrtl.module private @MuxUnknownWidthSelect_Issue1108
module MuxUnknownWidthSelect_Issue1108:
input a: UInt<1>
input b: UInt<1>
input sel: UInt
output c: UInt<8>
connect c, mux(sel, a, b)
; Test that a mux with aggregate type is still compatible even if the leaf
; types disagree in their width.
; CHECK-LABEL: firrtl.module private @MuxAggregateWidthMismatch_Issue2806
module MuxAggregateWidthMismatch_Issue2806:
input a: UInt<1>[1]
input b: UInt<32>[1]
input x: {u: UInt<1>, v: UInt<2>}
input y: {u: UInt<32>, v: UInt<2>}
input sel: UInt<1>
output c: UInt[1]
output z: {u: UInt, v: UInt}
; CHECK: firrtl.mux(%sel, %a, %b)
; CHECK-SAME: -> !firrtl.vector<uint<32>, 1>
; CHECK: firrtl.mux(%sel, %x, %y)
; CHECK-SAME: -> !firrtl.bundle<u: uint<32>, v: uint<2>>
connect c, mux(sel, a, b)
connect z, mux(sel, x, y)
; CHECK-LABEL: firrtl.extmodule private @VerbatimStringParam
; CHECK-SAME: <TYPE: none = #hw.param.verbatim<"bit">,
; CHECK-SAME: FORMAT: none = #hw.param.verbatim<"xyz_timeout=%d\\n">,
; CHECK-SAME: MIXED_QUOTES: none = #hw.param.verbatim<"\22'\\\22">>
extmodule VerbatimStringParam :
parameter TYPE = 'bit'
parameter FORMAT = 'xyz_timeout=%d\n'
parameter MIXED_QUOTES = '"\'\"'
; "
; CHECK-LABEL: firrtl.module private @issue1303
module issue1303:
output out: Reset
connect out, UInt(1)
; CHECK: %[[c1:.*]] = firrtl.constant 1 : !firrtl.const.uint
; CHECK-NEXT: %[[c2:.*]] = firrtl.resetCast %[[c1]]
; CHECK-NEXT: %[[c3:.*]] = firrtl.constCast %[[c2]]
; CHECK-NEXT: firrtl.matchingconnect %out, %[[c3]] : !firrtl.reset
; CHECK-LABEL: @resetBundle
module resetBundle:
input a: {a: UInt<1>, b: AsyncReset}
output b: {a: Reset, b: Reset}
connect b, a
; CHECK: %1 = firrtl.subfield %a[a] : !firrtl.bundle<a: uint<1>, b: asyncreset>
; CHECK: %[[r1:.*]] = firrtl.resetCast %1
; CHECK: firrtl.matchingconnect %0, %[[r1]] : !firrtl.reset
; CHECK: %3 = firrtl.subfield %b[b] : !firrtl.bundle<a: reset, b: reset>
; CHECK: %4 = firrtl.subfield %a[b] : !firrtl.bundle<a: uint<1>, b: asyncreset>
; CHECK: %[[r4:.*]] = firrtl.resetCast %4
; CHECK: firrtl.matchingconnect %3, %[[r4]] : !firrtl.reset
module LargeMem :
input clock : Clock
input reset : Reset
; CHECK: !chirrtl.cmemory<vector<uint<8>, 16>, 34359738368>
smem testharness : UInt<8>[16] [34359738368]
node w_addr = UInt<36>(42) @[Cat.scala 31:58]
write mport MPORT = testharness[w_addr], clock
; Module as identifier
; Test parsing of "module" as an identifier for instance and module names
extmodule SomeModule:
input in: UInt<8>
module ModuleAsIdentifier:
inst module of SomeModule
; CHECK: firrtl.instance module interesting_name @SomeModule
connect module.in, UInt(1)
; CHECK-LABEL: firrtl.module private @EnumTypes
module EnumTypes:
; CHECK-SAME: in %i: !firrtl.enum<Some: uint<8>, None: uint<0>>
input i : {| Some : UInt<8>, None |}
output o : UInt<8>
; CHECK: %c0_ui8 = firrtl.constant 0 : !firrtl.const.uint<8>
; CHECK: %0 = firrtl.enumcreate Some(%c0_ui8) : (!firrtl.const.uint<8>) -> !firrtl.enum<Some: uint<8>, None: uint<0>>
; CHECK: %some = firrtl.node interesting_name %0 : !firrtl.enum<Some: uint<8>, None: uint<0>>
node some = {|Some : UInt<8>, None|}(Some, UInt<8>(0))
; CHECK: %c0_ui0 = firrtl.constant 0 : !firrtl.const.uint<0>
; CHECK: %1 = firrtl.enumcreate None(%c0_ui0) : (!firrtl.const.uint<0>) -> !firrtl.enum<Some: uint<8>, None: uint<0>>
; CHECK: %none = firrtl.node {{.*}} %1 : !firrtl.enum<Some: uint<8>, None: uint<0>>
node none = {|Some : UInt<8>, None|}(None)
; CHECK: firrtl.match %i : !firrtl.enum<Some: uint<8>, None: uint<0>> {
match i:
; CHECK: case Some(%arg0) {
; CHECK: firrtl.matchingconnect %o, %arg0 : !firrtl.uint<8>
; CHECK: }
Some(x):
connect o, x
; CHECK: case None(%arg0) {
; CHECK: %invalid_ui8 = firrtl.invalidvalue : !firrtl.uint<8>
; CHECK: firrtl.matchingconnect %o, %invalid_ui8 : !firrtl.uint<8>
; CHECK: }
None:
invalidate o
; CHECK-LABEL: firrtl.module private @EnumInfer(
module EnumInfer:
input i : {| A: UInt<8>, None |}
output o : {| A: UInt, None |}
; CHECK: connect %o, %i
connect o, i
; CHECK-LABEL: module private @RefsChild(
; CHECK-SAME: out %r: !firrtl.probe<uint<1>>
; CHECK-SAME: out %rw: !firrtl.rwprobe<uint<1>>
module RefsChild :
input in : UInt<1>
output r : Probe<UInt<1>>
output rw : RWProbe<UInt<1>>
; CHECK-NEXT: %[[NODE:.+]] = firrtl.node sym @[[NODE_RW_SYM:[^ ]+]]
node n = in
; CHECK-NEXT: %[[REF:.+]] = firrtl.ref.send %[[NODE]]
; CHECK-NEXT: ref.define %r, %[[REF]]
define r = probe(n)
; CHECK: %[[NODE_RWREF:.+]] = firrtl.ref.rwprobe <@RefsChild::@[[NODE_RW_SYM]]>
; CHECK-NEXT: ref.define %rw, %[[NODE_RWREF]]
define rw = rwprobe(n)
; CHECK-LABEL: module private @RefsChildOpenAgg(
; CHECK-SAME: in %in: !firrtl.openbundle<a: uint<1>, rw flip: rwprobe<uint<1>>> sym [<@[[SYM:[^,]+]],1,
module RefsChildOpenAgg :
input in : { a : UInt<1>, flip rw: RWProbe<UInt<1>> }
; CHECK-NEXT: %[[IN_RW:[^ ]+]] = firrtl.opensubfield %in[rw]
; CHECK-NEXT: %[[RWPROBE_IN_A:[^ ]+]] = firrtl.ref.rwprobe <@RefsChildOpenAgg::@[[SYM]]>
; CHECK-NEXT: firrtl.ref.define %[[IN_RW]], %[[RWPROBE_IN_A]]
define in.rw = rwprobe(in.a)
; CHECK-LABEL: module private @Refs(
module Refs :
input in : const UInt<1>
output r : Probe<const UInt>
output rw : RWProbe<UInt>
output notrw : Probe<UInt>
output out : UInt<1>
output out2 : UInt<1>
output outconst : const UInt<1>
; CHECK-SAME: out %agg_out: !firrtl.probe<bundle<a: uint<1>, b: const.uint>>
output agg_out : Probe<{a: UInt<1>, b: const UInt}>
output field_rw : RWProbe<UInt<1>>
; CHECK-NEXT: %[[RC_IN:.+]], %[[RC_R:.+]], %[[RC_RW:.+]] = firrtl.instance rc
inst rc of RefsChild
connect rc.in, in
; CHECK: %[[OUTREF:.+]] = firrtl.ref.send %outconst
; CHECK-NEXT: %[[OUTREF_CAST:.+]] = firrtl.ref.cast %[[OUTREF]] : (!firrtl.probe<const.uint<1>>) -> !firrtl.probe<const.uint>
; CHECK-NEXT: ref.define %r, %[[OUTREF_CAST]]
define r = probe(outconst)
; CHECK-NEXT: %[[RC_RW_CAST:.+]] = firrtl.ref.cast %[[RC_RW]] : (!firrtl.rwprobe<uint<1>>) -> !firrtl.rwprobe<uint>
; CHECK-NEXT: ref.define %rw, %[[RC_RW_CAST]]
; CHECK-SAME: rwprobe<uint>
define rw = rc.rw
; CHECK-NEXT: %[[RC_RW_CAST_PROBE:.+]] = firrtl.ref.cast %[[RC_RW]] : (!firrtl.rwprobe<uint<1>>) -> !firrtl.probe<uint>
; CHECK-NEXT: ref.define %notrw, %[[RC_RW_CAST_PROBE]]
; CHECK-SAME: firrtl.probe
define notrw = rc.rw
; CHECK-NEXT: %[[READ_RC_R:.+]] = firrtl.ref.resolve %[[RC_R]]
; CHECK-NEXT: connect %out, %[[READ_RC_R]]
connect out, read(rc.r)
; CHECK-NEXT: %[[READ_RC_RW:.+]] = firrtl.ref.resolve %[[RC_RW]]
; CHECK-NEXT: connect %out, %[[READ_RC_RW]]
connect out, read(rc.rw)
; ref.sub parsing
; CHECK-DAG: %[[AGG:.+]] = firrtl.wire interesting_name : !firrtl.bundle<a flip: const.uint<1>, b: uint>
; CHECK-DAG: %[[AGG2:.+]] = firrtl.wire interesting_name : !firrtl.bundle<a: uint, b flip: uint<1>>
wire agg : { flip a : const UInt<1>, b : UInt }
wire agg2 : { a : UInt, flip b : UInt<1> }
; CHECK-DAG: %[[AGG_B:.+]] = firrtl.subfield %[[AGG]][b]
; CHECK-DAG: %[[AGG_B_PROBE:.+]] = firrtl.ref.send %[[AGG_B]]
; CHECK-DAG: %[[READ_AGG_B_PROBE:.+]] = firrtl.ref.resolve %[[AGG_B_PROBE]]
; CHECK-DAG: connect %out2, %[[READ_AGG_B_PROBE]]
connect out2, read(probe(agg.b))
; CHECK-DAG: %[[AGG2_PROBE:.+]] = firrtl.ref.send %[[AGG2]]
; CHECK-DAG: %[[READ_AGG2_PROBE:.+]] = firrtl.ref.resolve %[[AGG2_PROBE]]
; CHECK-DAG: %[[READ_AGG2_PROBE__B:.+]] = firrtl.subfield %[[READ_AGG2_PROBE]][b]
; CHECK-DAG: connect %out2, %[[READ_AGG2_PROBE__B]]
connect out2, read(probe(agg2)).b
; CHECK: %[[AGG3:.+]] = firrtl.wire
wire agg3 : const { a : UInt<1>, b : UInt }
; CHECK-NEXT: %[[AGG3_PROBE:.+]] = firrtl.ref.send %[[AGG3]]
; CHECK-NEXT: %[[AGG3_PROBE_CAST:.+]] = firrtl.ref.cast %[[AGG3_PROBE]] : (!firrtl.probe<const.bundle<a: uint<1>, b: uint>>) -> !firrtl.probe<bundle<a: uint<1>, b: const.uint>>
; CHECK-NEXT: ref.define %agg_out, %[[AGG3_PROBE_CAST]]
define agg_out = probe(agg3)
; CHECK: %[[PROBE_IN:.+]] = firrtl.ref.send %in
; CHECK-DAG: %[[READ_PROBE_IN:.+]] = firrtl.ref.resolve %[[PROBE_IN]]
; CHECK-DAG: %[[SUM:.+]] = firrtl.and %[[READ_PROBE_IN]],
connect outconst, and(read(probe(in)), UInt(1))
; CHECK: %[[AGG4:.+]] = firrtl.wire sym [<@[[AGG4_0_b_x_SYM:[^ ]+]],4,public>]
wire agg4 : { a : UInt, flip b : {x : UInt<1>} }[2]
; (static ref expr creates dead subfield accesses, skip)
; CHECK: %[[AGG4_RW_0_b_x:.+]] = firrtl.ref.rwprobe <@Refs::@[[AGG4_0_b_x_SYM]]>
; CHECK-NEXT: firrtl.ref.define %field_rw, %[[AGG4_RW_0_b_x]]
define field_rw = rwprobe(agg4[0].b.x)
; CHECK: %inst_rw = firrtl.wire : !firrtl.rwprobe<uint<1>>
; CHECK-NEXT: %inst_rw2 = firrtl.wire : !firrtl.rwprobe<uint<1>>
; CHECK-NEXT: %rc2_in_bounce = firrtl.wire sym @[[RC2_IN_BOUNCE_SYM:[^ ]+]]
; CHECK-NEXT: %rc2_in, %rc2_r, %rc2_rw = firrtl.instance rc2
; CHECK-NEXT: firrtl.matchingconnect %rc2_in, %rc2_in_bounce
wire inst_rw : RWProbe<UInt<1>>
wire inst_rw2 : RWProbe<UInt<1>>
inst rc2 of RefsChild
; CHECK: %[[IN_CAST:[^ ]+]] = firrtl.constCast %in :
; CHECK: firrtl.matchingconnect %rc2_in_bounce, %[[IN_CAST]]
connect rc2.in, in
; CHECK-NEXT: firrtl.when %rc2_in_bounce :
; CHECK-NEXT: %[[RWPROBE_RC2_IN_BOUNCE_1:[^ ]+]] = firrtl.ref.rwprobe <@Refs::@[[RC2_IN_BOUNCE_SYM]]>
; CHECK-NEXT: firrtl.ref.define %inst_rw, %[[RWPROBE_RC2_IN_BOUNCE_1]]
; CHECK-NEXT: }
when rc2.in:
define inst_rw = rwprobe(rc2.in)
; CHECK-NEXT: firrtl.matchingconnect %rc2_in_bounce,
connect rc2.in, rc.in
; CHECK-NEXT: %[[RWPROBE_RC2_IN_BOUNCE_2:[^ ]+]] = firrtl.ref.rwprobe <@Refs::@[[RC2_IN_BOUNCE_SYM]]>
; CHECK-NEXT: firrtl.ref.define %inst_rw2, %[[RWPROBE_RC2_IN_BOUNCE_2]]
define inst_rw2 = rwprobe(rc2.in)
; CHECK-LABEL: module private @ForceRelease(
module ForceRelease :
input in : UInt<1>
input clock : Clock
input cond : UInt<1>
; CHECK-NEXT: %{{.+}}, %{{.+}}, %[[RC_RW:.+]] = firrtl.instance rc
inst rc of RefsChild
connect rc.in, in
; Check (const) literal works, even if uninferred width.
; Cast reference to more general form as needed.
; CHECK: %[[RC_RW_CAST:.+]] = firrtl.ref.cast %[[RC_RW]] : (!firrtl.rwprobe<uint<1>>) -> !firrtl.rwprobe<uint>
; CHECK: firrtl.ref.force_initial %[[TRUE:.+]], %[[RC_RW_CAST]], %{{.+}} : !firrtl.uint<1>, !firrtl.rwprobe<uint>, !firrtl.const.uint
force_initial(rc.rw, UInt(0))
; CHECK: firrtl.ref.force %clock, %cond, %[[RC_RW]], %{{.+}} : !firrtl.clock, !firrtl.uint<1>, !firrtl.rwprobe<uint<1>>, !firrtl.const.uint<1>
force(clock, cond, rc.rw, UInt<1>(1))
; CHECK: %[[NOT_COND:.+]] = firrtl.not %cond
; CHECK: firrtl.ref.release %clock, %[[NOT_COND]], %[[RC_RW]] : !firrtl.clock, !firrtl.uint<1>, !firrtl.rwprobe<uint<1>>
release(clock, not(cond), rc.rw)
; CHECK-NEXT: %{{.+}}, %{{.+}}, %[[RC2_RW:.+]] = firrtl.instance rc2
inst rc2 of RefsChild
connect rc2.in, in
; CHECK: firrtl.ref.release_initial %[[TRUE]], %[[RC2_RW]] : !firrtl.uint<1>, !firrtl.rwprobe<uint<1>>
release_initial(rc2.rw)
; CHECK-LABEL: extmodule private @RefExtABI
; CHECK-NOT: internalPaths
extmodule RefExtABI :
input in : UInt<1>
output r : Probe<UInt<1>>
output data : UInt<3>
output r2 : Probe<{a : UInt<3>}[3]>
; CHECK-LABEL: @RWProbePort(
module RWProbePort:
; CHECK: in %in: !firrtl.vector<uint<1>, 2> sym [<@[[IN_SYM:.+]],2,public>],
input in : UInt<1>[2]
output p : RWProbe<UInt<1>>
; CHECK: firrtl.ref.rwprobe <@RWProbePort::@[[IN_SYM]]> : !firrtl.rwprobe<uint<1>>
define p = rwprobe(in[1])
; CHECK-LABEL: @RWProbeUninferredPort(
module RWProbeUninferredPort:
; CHECK: in %in: !firrtl.vector<uint, 2> sym [<@[[IN_SYM:.+]],2,public>],
input in : UInt[2]
output p : RWProbe<UInt>
; CHECK: firrtl.ref.rwprobe <@RWProbeUninferredPort::@[[IN_SYM]]> : !firrtl.rwprobe<uint>
define p = rwprobe(in[1])
; CHECK-LABEL: @RWProbeUninferredReset(
module RWProbeUninferredReset:
; CHECK: in %in: !firrtl.bundle<a: reset> sym [<@[[IN_SYM:.+]],1,public>],
input in : {a : Reset}
output p : RWProbe<Reset>
; CHECK: firrtl.ref.rwprobe <@RWProbeUninferredReset::@[[IN_SYM]]> : !firrtl.rwprobe<reset>
define p = rwprobe(in.a)
; CHECK-LABEL: module private @ProbeInvalidate
; CHECK-NEXT: }
module ProbeInvalidate:
output p : Probe<UInt<1>>
invalidate p
; CHECK-LABEL: module private @NumericFields
; See: https://github.com/llvm/circt/issues/5110
module NumericFields:
input a: {0: {0: {bar: UInt<1>}}}
output b: UInt<1>
input c: {0: {0: {0: {bar: UInt<1>}}}}
output d: UInt<1>
; CHECK: %0 = firrtl.subfield %c["0"]
; CHECK-NEXT: %1 = firrtl.subfield %0["0"]
; CHECK-NEXT: %2 = firrtl.subfield %1["0"]
; CHECK-NEXT: %3 = firrtl.subfield %2[bar]
; CHECK-NEXT: %4 = firrtl.subfield %a["0"]
; CHECK-NEXT: %5 = firrtl.subfield %4["0"]
; CHECK-NEXT: %6 = firrtl.subfield %5[bar]
connect b, a.0.0.bar
connect d, c.0.0.0.bar
; CHECK-NEXT: firrtl.matchingconnect %b, %6
; CHECK-NEXT: firrtl.matchingconnect %d, %3
; CHECK-LABEL: firrtl.module private @ConstTypes(
module ConstTypes:
input c: const Clock ; CHECK: %c: !firrtl.const.clock,
input r: const Reset ; CHECK: %r: !firrtl.const.reset,
input ar: const AsyncReset ; CHECK: %ar: !firrtl.const.asyncreset,
input a: const Analog ; CHECK: %a: !firrtl.const.analog,
input a8: const Analog<8> ; CHECK: %a8: !firrtl.const.analog<8>,
input s: const SInt ; CHECK: %s: !firrtl.const.sint,
input s4: const SInt<4> ; CHECK: %s4: !firrtl.const.sint<4>,
input u: const UInt ; CHECK: %u: !firrtl.const.uint,
; CHECK: %b: !firrtl.const.bundle<int_1 flip: uint<1>, int_out: uint<2>>
input b: const {flip int_1 : UInt<1>, int_out : UInt<2>}
; CHECK: %b_constfields: !firrtl.bundle<int_1 flip: const.uint<1>, int_out: const.uint<2>>
input b_constfields: {flip int_1 : const UInt<1>, int_out : const UInt<2>}
; CHECK: %mixedb: !firrtl.bundle<a: sint<1>, b: const.uint<2>>
input mixedb: {a: SInt<1>, b: const UInt<2>}
; CHECK: %vec: !firrtl.const.vector<uint<1>, 4>) {
input vec: const UInt<1>[4]
; CHECK-NEXT: %w = firrtl.wire interesting_name : !firrtl.const.sint<4>
wire w: const SInt<4>
; CHECK-NEXT: firrtl.matchingconnect %w, %s4 : !firrtl.const.sint<4>
connect w, s4
; CHECK-NEXT: %nonconst_w = firrtl.wire interesting_name : !firrtl.sint<4>
wire nonconst_w: SInt<4>
; CHECK-NEXT: [[CAST:%.+]] = firrtl.constCast %s4 : (!firrtl.const.sint<4>) -> !firrtl.sint<4>
; CHECK-NEXT: firrtl.matchingconnect %nonconst_w, [[CAST]] : !firrtl.sint<4>
connect nonconst_w, s4
;// -----
; CHECK-LABEL: firrtl.circuit "Foo_v3p0p0"
FIRRTL version 3.0.0
circuit Foo_v3p0p0:
module Foo_v3p0p0:
input clock: Clock
input reset: UInt<1>
input a: UInt<1>
output b: UInt<1>
; CHECK: firrtl.matchingconnect %b, %a
connect b, a
; CHECK: [[INV:%.+]] = firrtl.invalidvalue : !firrtl.uint<1>
; CHECK-NEXT: firrtl.matchingconnect %b, [[INV]] : !firrtl.uint<1>
invalidate b
; CHECK: %[[zero:[0-9A-Za-z_]+]] = firrtl.constant 0
; CHECK-NEXT: %r = firrtl.regreset interesting_name %clock, %reset, %[[zero]]
regreset r: UInt<1>, clock, reset, UInt<1>(0)
; CHECK: module private @LiteralIdentifiers
; CHECK-SAME: in %_0: !firrtl.bundle<"1": uint<1>>
; CHECK-SAME: out %_2: !firrtl.bundle<"3": uint<1>>
; CHECK-SAME: portNames = ["0", "2"]
module LiteralIdentifiers:
input `0`: {`1`: UInt<1>}
output `2`: {`3`: UInt<1>}
; CHECK-NEXT: %0 = firrtl.subfield %_0["1"] : !firrtl.bundle<"1": uint<1>>
; CHECK-NEXT: %1 = firrtl.subfield %_2["3"] : !firrtl.bundle<"3": uint<1>>
; CHECK-NEXT: firrtl.matchingconnect %1, %0 : !firrtl.uint<1>
connect `2`.`3`, `0`.`1`
; Ensure that `a` is equivalent to a.
; CHECK-NEXT: %a = firrtl.node {{.+}}%_0
node `a` = `0`
; CHECK-NEXT: %b = firrtl.node {{.+}}%a
node b = a
;// -----
; Check reference expressions using literal identifiers or keywords.
; CHECK-LABEL: firrtl.circuit "Probes_refexprs"
FIRRTL version 3.0.0
circuit Probes_refexprs:
extmodule refs:
output `0`: {`1`: Probe<{`2`: UInt<1>}>, rwprobe: RWProbe<UInt<1>>}
output ref: {module: Probe<{when: UInt<1>}>}
module Probes_refexprs:
output `0`: {`1`: Probe<{`2`: UInt<1>}>}
output out: UInt<1>
inst `9` of refs
inst ref of refs
; CHECK: firrtl.ref.define
define `0`.`1` = `9`.`0`.`1`
; CHECK-COUNT-4: firrtl.ref.resolve
node a = read(`9`.`0`.`1`).`2`
node b = read(`9`.`0`.`1`.`2`)
node c = read(`9`.ref.module).when
; Keyword as leading part of static ref expression:
node d = read(ref.`0`.`1`.`2`)
connect out, and(and(a, b), and(c, d))
; CHECK: %[[TEST:.+]] = firrtl.wire sym @[[TEST_SYM:[^ ]+]]
wire `test`: {`0`: UInt<1>, `b`: UInt<1>}
connect `test`.`0`, a
connect `test`.`b`, b
; CHECK: %[[TEST_REF:.+]] = firrtl.ref.rwprobe <@Probes_refexprs::@[[TEST_SYM]]>
; CHECK: force_initial %{{.+}}, %[[TEST_REF]], %[[TEST]]
force_initial(rwprobe(`test`), `test`)
; CHECK: force_initial
force_initial(`9`.`0`.rwprobe, `test`.`0`)
;// -----
; CHECK-LABEL: firrtl.circuit "RadixEncodedIntegerLiterals"
FIRRTL version 2.4.0
circuit RadixEncodedIntegerLiterals:
module RadixEncodedIntegerLiterals:
output bu: UInt<8>
output ou: UInt<8>
output du0: UInt<8>
output du1: UInt<8>
output hu: UInt<8>
output bs: SInt<8>
output os: SInt<8>
output dus0: SInt<8>
output dus1: SInt<8>
output hs: SInt<8>
; CHECK: %[[c42_ui7:[-a-zA-Z_0-9]+]] = firrtl.constant 42
; CHECK-NEXT: %[[c_constCast:[-a-zA-Z_0-9]+]] = firrtl.constCast %[[c42_ui7]]
; CHECK-NEXT: firrtl.connect %bu, %[[c_constCast]]
bu <= UInt(0b101010)
; CHECK-NEXT: %[[c_constCast:[-a-zA-Z_0-9]+]] = firrtl.constCast %[[c42_ui7]]
; CHECK-NEXT: firrtl.connect %ou, %[[c_constCast]]
ou <= UInt(0o052)
; Note: this creates a second constant because the width of a parsed
; constant is dependent on the overestimation of LLVM::StringRef.
;
; CHECK: %[[c42_ui8:[-a-zA-Z_0-9]+]] = firrtl.constant 42
; CHECK-NEXT: %[[c_constCast:[-a-zA-Z_0-9]+]] = firrtl.constCast %[[c42_ui8]]
; CHECK-NEXT: firrtl.connect %du0, %[[c_constCast]]
du0 <= UInt(42)
; CHECK-NEXT: %[[c_constCast:[-a-zA-Z_0-9]+]] = firrtl.constCast %[[c42_ui8]]
; CHECK-NEXT: firrtl.connect %du1, %[[c_constCast]]
du1 <= UInt(0d42)
; CHECK-NEXT: %[[c_constCast:[-a-zA-Z_0-9]+]] = firrtl.constCast %[[c42_ui7]]
; CHECK-NEXT: firrtl.connect %hu, %[[c_constCast]]
hu <= UInt(0h2a)
; CHECK: %[[cn42_si7:[-a-zA-Z_0-9]+]] = firrtl.constant -42
; CHECK-NEXT: %[[c_constCast:[-a-zA-Z_0-9]+]] = firrtl.constCast %[[cn42_si7]]
; CHECK-NEXT: firrtl.connect %bs, %[[c_constCast]]
bs <= SInt(-0b101010)
; CHECK-NEXT: %[[c_constCast:[-a-zA-Z_0-9]+]] = firrtl.constCast %[[cn42_si7]]
; CHECK-NEXT: firrtl.connect %os, %[[c_constCast]]
os <= SInt(-0o52)
; Note: this creates a second constant because the width of a parsed
; constant is dependent on the overestimation of LLVM::StringRef.
;
; CHECK: %[[cn42_si8:[-a-zA-Z_0-9]+]] = firrtl.constant -42
; CHECK-NEXT: %[[c_constCast:[-a-zA-Z_0-9]+]] = firrtl.constCast %[[cn42_si8]]
; CHECK-NEXT: firrtl.connect %dus0, %[[c_constCast]]
dus0 <= SInt(-42)
; CHECK-NEXT: %[[c_constCast:[-a-zA-Z_0-9]+]] = firrtl.constCast %[[cn42_si8]]
; CHECK-NEXT: firrtl.connect %dus1, %[[c_constCast]]
dus1 <= SInt(-0d42)
; CHECK-NEXT: %[[c_constCast:[-a-zA-Z_0-9]+]] = firrtl.constCast %[[cn42_si7]]
; CHECK-NEXT: firrtl.connect %hs, %[[c_constCast]]
hs <= SInt(-0h2a)
;// -----
; Tests for type alias
FIRRTL version 4.0.0
circuit Top:
type WordType = const UInt<32>
type ValidType = UInt<1>
type Data = {w: const WordType[2], valid: ValidType, flip ready: UInt<1>}
type Complex = { real: SInt<10>, imag: SInt<10> }
type Complex_id = Complex
; expected-warning @+1 {{type alias for non-base type '!firrtl.probe<alias<Complex, bundle<real: sint<10>, imag: sint<10>>>>' is currently not supported. Type alias is stripped immediately}}
type ProbeComplex = Probe<Complex>
; CHECK: @Top
; CHECK-SAME: in %in_data: !firrtl.alias<Data, bundle<w: const.vector<const.alias<WordType, const.uint<32>>, 2>,
; CHECK-SAME: valid: alias<ValidType, uint<1>>, ready flip: uint<1>>>,
; CHECK-SAME: in %in_complex: !firrtl.alias<Complex, bundle<real: sint<10>, imag: sint<10>>>
; CHECK-SAME: out %out: !firrtl.probe<alias<Complex, bundle<real: sint<10>, imag: sint<10>>>>
; CHECK-SAME: out %out_valid: !firrtl.alias<ValidType, uint<1>>
; CHECK-NEXT: %[[RESULT:.+]] = firrtl.subfield %in_data[valid] : !firrtl.alias<Data, bundle<w: const.vector<const.alias<WordType, const.uint<32>>, 2>, valid: alias<ValidType, uint<1>>, ready flip: uint<1>>>
; CHECK-NEXT: %c = firrtl.wire interesting_name : !firrtl.alias<Complex_id, alias<Complex, bundle<real: sint<10>, imag: sint<10>>>>
; CHECK-NEXT: firrtl.matchingconnect %out_valid, %[[RESULT]] : !firrtl.alias<ValidType, uint<1>>
public module Top:
input in_data: Data
input in_complex: Complex
output out: ProbeComplex
output out_valid: ValidType
wire c: Complex_id
connect out_valid, in_data.valid
; CHECK-LABEL: firrtl.module private @Const
; CHECK-SAME: (in %a: !firrtl.const.alias<ConstI1, const.uint<1>>)
type ConstI1 = const UInt<1>
module Const :
input a: ConstI1
;// -----
; CHECK-LABEL: firrtl.circuit "Layers"
FIRRTL version 4.0.0
circuit Layers:
layer A, bind:
layer B, bind:
layer C, bind:
layer D, bind:
layer E, inline:
layer F, bind:
; CHECK-NEXT: firrtl.layer @A bind {
; CHECK-NEXT: firrtl.layer @B bind {
; CHECK-NEXT: firrtl.layer @C bind {
; CHECK-NEXT: }
; CHECK-NEXT: firrtl.layer @D bind {
; CHECK-NEXT: firrtl.layer @E inline {
; CHECK-NEXT: }
; CHECK-NEXT: }
; CHECK-NEXT: }
; CHECK-NEXT: firrtl.layer @F bind {
; CHECK-NEXT: }
; CHECK-NEXT: }
; CHECK: firrtl.module @Layers
; CHECK-SAME: out %b: !firrtl.probe<uint<1>, @A>
; CHECK-SAME: out %c: !firrtl.rwprobe<uint<1>, @A::@B>
public module Layers:
input a: UInt<1>
output b: Probe<UInt<1>, A>
output c: RWProbe<UInt<1>, A.B>
layerblock A:
node A_a = a
layerblock B:
node B_a = a
layerblock C:
node C_a = a
layerblock D:
node D_a = a
layerblock E:
node E_a = a
layerblock F:
node F_a = a
; CHECK-NEXT: firrtl.layerblock @A {
; CHECK-NEXT: %A_a = firrtl.node{{.*}} %a
; CHECK-NEXT: firrtl.layerblock @A::@B {
; CHECK-NEXT: %B_a = firrtl.node{{.*}} %a
; CHECK-NEXT: firrtl.layerblock @A::@B::@C {
; CHECK-NEXT: %C_a = firrtl.node{{.*}} %a
; CHECK-NEXT: }
; CHECK-NEXT: firrtl.layerblock @A::@B::@D {
; CHECK-NEXT: %D_a = firrtl.node{{.*}} %a
; CHECK-NEXT: firrtl.layerblock @A::@B::@D::@E {
; CHECK-NEXT: %E_a = firrtl.node{{.*}} %a
; CHECK-NEXT: }
; CHECK-NEXT: }
; CHECK-NEXT: }
; CHECK-NEXT: firrtl.layerblock @A::@F {
; CHECK-NEXT: %F_a = firrtl.node{{.*}} %a
; CHECK-NEXT: }
; CHECK-NEXT: }
; CHECK: firrtl.layer @WithDirectory1 bind attributes {output_file = #hw.output_file<"foo{{/|\\\\}}">}
layer WithDirectory1, bind, "foo":
; CHECK: firrtl.layer @WithDirectory2 bind attributes {output_file = #hw.output_file<"foo{{/|\\\\}}">}
layer WithDirectory2, bind, "foo/":
;// -----
; CHECK-LABEL: firrtl.circuit "BasicProps"
FIRRTL version 3.3.0
circuit BasicProps :
module BasicProps :
; CHECK-LABEL: module private @Integer
module Integer :
; CHECK-SAME: out %a: !firrtl.integer
output a : Integer
; CHECK: %0 = firrtl.integer -10
; CHECK: firrtl.propassign %a, %0 : !firrtl.integer
propassign a, Integer(-10)
; CHECK-LABEL: module private @Bool
module Bool :
; CHECK-SAME: out %true: !firrtl.bool
; CHECK-SAME: out %false: !firrtl.bool
output true : Bool
output false : Bool
; CHECK-NEXT: %0 = firrtl.bool true
; CHECK-NEXT: firrtl.propassign %true, %0 : !firrtl.bool
; CHECK-NEXT: %1 = firrtl.bool false
; CHECK-NEXT: firrtl.propassign %false, %1 : !firrtl.bool
propassign true, Bool(true)
propassign false, Bool(false)
; CHECK-LABEL: module private @Double
module Double :
; CHECK-SAME: out %x: !firrtl.double
; CHECK-SAME: out %y: !firrtl.double
; CHECK-SAME: out %negzero: !firrtl.double
; CHECK-SAME: out %twoTo64: !firrtl.double
; CHECK-SAME: out %exp: !firrtl.double
output x : Double
output y : Double
output negzero : Double
output twoTo64 : Double
output exp : Double
; Try not to overly rely on double printing/rounding/precision.
; CHECK-NEXT: firrtl.double 0.1111111111111111 : f64
; CHECK: propassign
propassign x, Double(0.1111111111111111111111111111111111111111)
; CHECK: firrtl.double 1.{{0*[eE]}}+00
propassign y, Double(1.0)
; CHECK: firrtl.double -0.{{0+[eE]}}+00
propassign negzero, Double(-0.0)
; CHECK: firrtl.double 1.844674407370955{{[0-9]*[eE]}}+
propassign twoTo64, Double(18446744073709551616.0)
; CHECK: firrtl.double 1.2{{.+[eE]}}+30
propassign exp, Double(1.2E+30)
; CHECK-LABEL: module private @String
module String :
; CHECK-SAME: out %a: !firrtl.string
output a : String
; CHECK: %0 = firrtl.string "hello"
; CHECK: firrtl.propassign %a, %0 : !firrtl.string
propassign a, String("hello")
; CHECK-LABEL: module private @Path
module Path :
; CHECK-SAME: out %path: !firrtl.path
output path : Path
; CHECK: firrtl.unresolved_path "OMDeleted:"
; CHECK: firrtl.propassign %path, %0 : !firrtl.path
propassign path, path("OMDeleted:")
; CHECK-LABEL: firrtl.class private @SimpleClass(in %a: !firrtl.string, out %b: !firrtl.string) {
; CHECK-NEXT: firrtl.propassign %b, %a : !firrtl.string
; CHECK-NEXT: }
class SimpleClass:
input a: String
output b: String
propassign b, a
; CHECK-LABEL: firrtl.class private @Client(out %a: !firrtl.class<@SimpleClass(in a: !firrtl.string, out b: !firrtl.string)>)
class Client:
output a: Inst<SimpleClass>
; CHECK-NEXT: %b = firrtl.object @SimpleClass(in a: !firrtl.string, out b: !firrtl.string)
object b of SimpleClass
; CHECK-NEXT: firrtl.propassign %a, %b : !firrtl.class<@SimpleClass(in a: !firrtl.string, out b: !firrtl.string)>
propassign a, b
; CHECK-LABEL firrtl.class private @OtherClient(in %a: !firrtl.string, out %b: !firrtl.string)
class OtherClient:
input a : String
output b : String
object o of SimpleClass
; TODO: This test needs to be fixed up once flow-checking for objects is implemented correctly.
propassign b, o.b
; CHECK-LABEL firrtl.extclass private @ExtClass(in in: !firrtl.string, out out: !firrtl.string)
extclass ExtClass:
input in : String
output out : String
; CHECK-LABEL: firrtl.class private @UserOfExtClass(in %ext_object: !firrtl.class<@ExtClass(in in: !firrtl.string, out out: !firrtl.string)>, out %out: !firrtl.string)
class UserOfExtClass:
input ext_object : Inst<ExtClass>
output out : String
; CHECK-NEXT: %0 = firrtl.object.subfield %ext_object[out] : !firrtl.class<@ExtClass(in in: !firrtl.string, out out: !firrtl.string)
; CHECK-NEXT: firrtl.propassign %out, %0 : !firrtl.string
propassign out, ext_object.out
; CHECK-LABEL: module private @List
module List :
; CHECK-SAME: out %strings: !firrtl.list<string>
; CHECK-SAME: out %objs: !firrtl.list<class<@SimpleClass({{.*}})>>
; CHECK-SAME: out %nested: !firrtl.list<list<string>>
output strings : List<String>
output objs : List<Inst<SimpleClass>>
output nested : List<List<String>>
; CHECK-NEXT: %[[HELLO:.+]] = firrtl.string "hello"
; CHECK-NEXT: %[[WORLD:.+]] = firrtl.string "world"
; CHECK-NEXT: %[[STRINGS:.+]] = firrtl.list.create %[[HELLO]], %[[WORLD]] : !firrtl.list<string>
; CHECK-NEXT: firrtl.propassign %strings, %[[STRINGS]] : !firrtl.list<string>
propassign strings, List<String>(String("hello"), String("world"))
; CHECK-NEXT: %[[OBJ:.+]] = firrtl.object
; CHECK-NEXT: %[[OBJS:.+]] = firrtl.list.create %[[OBJ]], %[[OBJ]] : !firrtl.list<class<@SimpleClass({{.*}})>>
; CHECK-NEXT: firrtl.propassign %objs, %[[OBJS]] : !firrtl.list<class
object obj of SimpleClass
propassign objs, List<Inst<SimpleClass>>(obj, obj)
; CHECK-NEXT: %[[EMPTY1:.+]] = firrtl.list.create : !firrtl.list<string>
; CHECK-NEXT: %[[TEST:.+]] = firrtl.string "test"
; CHECK-NEXT: %[[TESTLIST:.+]] = firrtl.list.create %[[TEST]] : !firrtl.list<string>
; CHECK-NEXT: %[[EMPTY2:.+]] = firrtl.list.create : !firrtl.list<string>
; CHECK-NEXT: %[[NESTED:.+]] = firrtl.list.create %[[EMPTY1]], %[[TESTLIST]], %[[EMPTY2]] : !firrtl.list<list<string>>
; CHECK-NEXT: firrtl.propassign %nested, %[[NESTED]]
propassign nested, List<List<String>>(List<String>(), List<String>(String("test")), List<String>())
;// -----
FIRRTL version 4.0.0
; CHECK-LABEL: firrtl.circuit "IntegerArithmetic"
circuit IntegerArithmetic :
public module IntegerArithmetic :
input a : Integer
input b : Integer
output c : Integer
output d : Integer
output e : Integer
output f : Integer
; CHECK: [[C:%.+]] = firrtl.integer.add %a, %b
; CHECK: firrtl.propassign %c, [[C]]
propassign c, integer_add(a, b)
; CHECK: [[D:%.+]] = firrtl.integer.mul %a, %b
; CHECK: firrtl.propassign %d, [[D]]
propassign d, integer_mul(a, b)
; CHECK: [[E:%.+]] = firrtl.integer.shr %a, %b
; CHECK: firrtl.propassign %e, [[E]]
propassign e, integer_shr(a, b)
; CHECK: [[F:%.+]] = firrtl.integer.shl %a, %b
; CHECK: firrtl.propassign %f, [[F]]
propassign f, integer_shl(a, b)
;// -----
FIRRTL version 4.0.0
; CHECK-LABEL: firrtl.circuit "PropertyListOps"
circuit PropertyListOps :
public module PropertyListOps :
input a : List<Integer>
input b : List<Integer>
output c : List<Integer>
; CHECK: [[C:%.+]] = firrtl.list.concat %a, %b
; CHECK: firrtl.propassign %c, [[C]]
propassign c, list_concat(a, b)
;// -----
FIRRTL version 3.1.0
; CHECK-LABEL: circuit "BundleOfProps"
circuit BundleOfProps:
module BundleOfProps:
input x : {a : String}
wire y : {a: String}
; CHECK-COUNT-2: !firrtl.openbundle<a: string>
;// -----
FIRRTL version 3.1.0
; CHECK-LABEL: circuit "VecOfProps"
circuit VecOfProps:
module VecOfProps:
input x : String[2]
wire y : String[2]
; CHECK-COUNT-2: openvector<string, 2>
;// -----
; Test parsing of wires of probes, wires of agg of probes, and namekinds.
; CHECK-LABEL: circuit "WireOfProbesAndNames"
FIRRTL version 4.0.0
circuit WireOfProbesAndNames:
public module WireOfProbesAndNames:
; CHECK: %mixed = firrtl.wire interesting_name : !firrtl.openbundle
wire mixed : { a : UInt<3>, b : Probe<UInt<3>> }
; CHECK: %probe = firrtl.wire : !firrtl.probe
wire probe : Probe<UInt<1>>
;// -----
FIRRTL version 3.3.0
; CHECK-LABEL: circuit "AnyRef"
circuit AnyRef:
class Foo:
skip
module AnyRef:
input x : AnyRef
; CHECK: !firrtl.anyref
output y : AnyRef
; CHECK: !firrtl.anyref
output listOfAny : List<AnyRef>
; CHECK: !firrtl.list<anyref>
object foo of Foo
propassign y, foo
; CHECK: %[[OBJ:.+]] = firrtl.object
; CHECK: %[[CAST:.+]] = firrtl.object.anyref_cast %[[OBJ]]
; CHECK: firrtl.propassign %y, %[[CAST]]
propassign listOfAny, List<AnyRef>(foo, x)
; CHECK-NEXT: %[[CAST:.+]] = firrtl.object.anyref_cast %[[OBJ]]
; CHECK-NEXT: %[[LIST:.+]] = firrtl.list.create %[[CAST]], %x
; CHECK-NEXT: propassign %listOfAny, %[[LIST]]
;// -----
FIRRTL version 4.0.0
; CHECK-LABEL: circuit "PublicModules"
circuit PublicModules:
; CHECK: firrtl.module @Foo
public module Foo:
; CHECK: firrtl.module private @Bar
module Bar:
; CHECK: firrtl.module @PublicModules
public module PublicModules:
;// -----
FIRRTL version 4.0.0
; CHECK-LABEL: firrtl.circuit "LayerEnabledModule"
circuit LayerEnabledModule:
layer A, bind:
layer B, bind:
layer C, bind:
; CHECK: firrtl.module @LayerEnabledModule
; CHECK-SAME: layers = [@A, @B::@C]
public module LayerEnabledModule enablelayer A enablelayer B.C:
; CHECK: firrtl.module private @UserOfLayerEnabledModule
; CHECK-SAME: layers = [@A, @B::@C]
module UserOfLayerEnabledModule enablelayer A enablelayer B.C:
; CHECK: firrtl.instance i interesting_name {layers = [@A, @B::@C]} @LayerEnabledModule()
inst i of LayerEnabledModule
;// -----
FIRRTL version 3.3.0
; CHECK-LABEL: circuit "StaticShiftRight"
circuit StaticShiftRight:
; CHECK: firrtl.module @StaticShiftRight
module StaticShiftRight:
input a : UInt<8>
input b : UInt<0>
input c : SInt<8>
input d : SInt<0>
wire w : UInt
connect w, a
wire x : SInt
connect x, c
; CHECK: %0 = firrtl.shr %a, 1
; CHECK: %1 = firrtl.pad %0, 1
; CHECK: %a_1 = firrtl.node {{.*}} %1 : !firrtl.uint<7>
node a_1 = shr(a, 1)
; CHECK: %2 = firrtl.shr %a, 8
; CHECK: %3 = firrtl.pad %2, 1
; CHECK: %a_2 = firrtl.node {{.*}} %3 : !firrtl.uint<1>
node a_2 = shr(a, 8)
; CHECK: %4 = firrtl.shr %a, 10
; CHECK: %5 = firrtl.pad %4, 1
; CHECK: %a_3 = firrtl.node {{.*}} %5 : !firrtl.uint<1>
node a_3 = shr(a, 10)
; CHECK: %6 = firrtl.shr %b, 0
; CHECK: %7 = firrtl.pad %6, 1
; CHECK: %b_1 = firrtl.node {{.*}} %7 : !firrtl.uint<1>
node b_1 = shr(b, 0)
; CHECK: %8 = firrtl.shr %b, 1
; CHECK: %9 = firrtl.pad %8, 1
; CHECK: %b_2 = firrtl.node {{.*}} %9 : !firrtl.uint<1>
node b_2 = shr(b, 1)
; CHECK: %10 = firrtl.shr %w, 10
; CHECK: %11 = firrtl.pad %10, 1
; CHECK: %w_1 = firrtl.node {{.*}} %11 : !firrtl.uint
node w_1 = shr(w, 10)
; CHECK: %12 = firrtl.shr %c, 1
; CHECK: %c_1 = firrtl.node {{.*}} %12 : !firrtl.sint<7>
node c_1 = shr(c, 1)
; CHECK: %13 = firrtl.shr %c, 8
; CHECK: %c_2 = firrtl.node {{.*}} %13 : !firrtl.sint<1>
node c_2 = shr(c, 8)
; CHECK: %14 = firrtl.shr %c, 10
; CHECK: %c_3 = firrtl.node {{.*}} %14 : !firrtl.sint<1>
node c_3 = shr(c, 10)
; CHECK: %15 = firrtl.shr %d, 0
; CHECK: %d_1 = firrtl.node {{.*}} %15 : !firrtl.sint<1>
node d_1 = shr(d, 0)
; CHECK: %16 = firrtl.shr %d, 1
; CHECK: %d_2 = firrtl.node {{.*}} %16 : !firrtl.sint<1>
node d_2 = shr(d, 1)
; CHECK: %17 = firrtl.shr %x, 10
; CHECK: %x_1 = firrtl.node {{.*}} %17 : !firrtl.sint
node x_1 = shr(x, 10)
;// -----
FIRRTL version 4.0.0
; CHECK-LABEL: circuit "StaticShiftRight"
circuit StaticShiftRight:
; CHECK: firrtl.module @StaticShiftRight
public module StaticShiftRight:
input a : UInt<8>
input b : UInt<0>
input c : SInt<8>
input d : SInt<0>
wire w : UInt
connect w, a
wire x : SInt
connect x, c
; CHECK: %0 = firrtl.shr %a, 1
; CHECK: %a_1 = firrtl.node {{.*}} %0 : !firrtl.uint<7>
node a_1 = shr(a, 1)
; CHECK: %1 = firrtl.shr %a, 8
; CHECK: %a_2 = firrtl.node {{.*}} %1 : !firrtl.uint<0>
node a_2 = shr(a, 8)
; CHECK: %2 = firrtl.shr %a, 10
; CHECK: %a_3 = firrtl.node {{.*}} %2 : !firrtl.uint<0>
node a_3 = shr(a, 10)
; CHECK: %3 = firrtl.shr %b, 0
; CHECK: %b_1 = firrtl.node {{.*}} %3 : !firrtl.uint<0>
node b_1 = shr(b, 0)
; CHECK: %4 = firrtl.shr %b, 1
; CHECK: %b_2 = firrtl.node {{.*}} %4 : !firrtl.uint<0>
node b_2 = shr(b, 1)
; CHECK: %5 = firrtl.shr %w, 10
; CHECK: %w_1 = firrtl.node {{.*}} %5 : !firrtl.uint
node w_1 = shr(w, 10)
; CHECK: %6 = firrtl.shr %c, 1
; CHECK: %c_1 = firrtl.node {{.*}} %6 : !firrtl.sint<7>
node c_1 = shr(c, 1)
; CHECK: %7 = firrtl.shr %c, 8
; CHECK: %c_2 = firrtl.node {{.*}} %7 : !firrtl.sint<1>
node c_2 = shr(c, 8)
; CHECK: %8 = firrtl.shr %c, 10
; CHECK: %c_3 = firrtl.node {{.*}} %8 : !firrtl.sint<1>
node c_3 = shr(c, 10)
; CHECK: %9 = firrtl.shr %d, 0
; CHECK: %d_1 = firrtl.node {{.*}} %9 : !firrtl.sint<1>
node d_1 = shr(d, 0)
; CHECK: %10 = firrtl.shr %d, 1
; CHECK: %d_2 = firrtl.node {{.*}} %10 : !firrtl.sint<1>
node d_2 = shr(d, 1)
; CHECK: %11 = firrtl.shr %x, 10
; CHECK: %x_1 = firrtl.node {{.*}} %11 : !firrtl.sint
node x_1 = shr(x, 10)
;// -----
FIRRTL version 4.0.0
; CHECK-LABEL: circuit "GenericIntrinsics"
circuit GenericIntrinsics:
; CHECK: firrtl.module @GenericIntrinsics
public module GenericIntrinsics:
input clock : Clock
input data : UInt<32>
input c : UInt<1>
; Statements
; CHECK-NEXT: firrtl.int.generic "circt_verif_assert" %c : (!firrtl.uint<1>) -> ()
intrinsic(circt_verif_assert, c)
; CHECK-NEXT: firrtl.int.generic "circt_fpga_probe" %data, %clock : (!firrtl.uint<32>, !firrtl.clock) -> ()
intrinsic(circt_fpga_probe, data, clock)
; Expressions
; CHECK-NEXT: %[[PAV:.+]] = firrtl.int.generic "circt_plusargs_value" <FORMAT: none = "foo"> : () -> !firrtl.bundle<found: uint<1>, result: uint<5>>
; CHECK-NEXT: %n = firrtl.node interesting_name %[[PAV]]
node n = intrinsic(circt_plusargs_value<FORMAT = "foo"> : { found : UInt<1>, result : UInt<5> })
; CHECK-NEXT: %[[PAT:.+]] = firrtl.int.generic "circt_plusargs_test" <FORMAT: none = "bar"> : () -> !firrtl.uint<1>
; CHECK-NEXT: %n2 = firrtl.node interesting_name %[[PAT]]
node n2 = intrinsic(circt_plusargs_test<FORMAT = "bar"> : UInt<1>)
; Statement with unused return value.
; CHECK-NEXT: firrtl.int.generic "circt_clock_gate" %clock, %c : (!firrtl.clock, !firrtl.uint<1>) -> !firrtl.clock
intrinsic(circt_clock_gate : Clock, clock, c)
; CHECK-NEXT: %[[SZ:.+]] = firrtl.int.generic "circt_isX"
; CHECK-NEXT: "circt_verif_assert" %[[SZ]]
intrinsic(circt_verif_assert, intrinsic(circt_isX: UInt<1>, data))
;// -----
FIRRTL version 4.0.0
; CHECK-LABEL: circuit "Foo"
circuit Foo:
; CHECK-LABEL: firrtl.module @Foo(in %data: !firrtl.uint<32>, in %c: !firrtl.uint<1>, out %out: !firrtl.uint<32>)
public module Foo:
input data : UInt<32>
input c : UInt<1>
output out : UInt<32>
when c:
node add1 = add(data, UInt<32>(1))
connect out, add1
else:
connect out, data
; CHECK-LABEL: firrtl.module @FooTest(in %s_foo_c: !firrtl.uint<1>, in %s_foo_data: !firrtl.uint<32>)
public module FooTest:
input s_foo_c : UInt<1>
input s_foo_data : UInt<32>
; CHECK-NEXT: %foo_data, %foo_c, %foo_out = firrtl.instance foo interesting_name @Foo(in data: !firrtl.uint<32>, in c: !firrtl.uint<1>, out out: !firrtl.uint<32>)
inst foo of Foo
; CHECK-NEXT: firrtl.matchingconnect %foo_c, %s_foo_c : !firrtl.uint<1>
connect foo.c, s_foo_c
; CHECK-NEXT: firrtl.matchingconnect %foo_data, %s_foo_data : !firrtl.uint<32>
connect foo.data, s_foo_data
; CHECK-NEXT: %0 = firrtl.eq %foo_out, %s_foo_data : (!firrtl.uint<32>, !firrtl.uint<32>) -> !firrtl.uint<1>
; CHECK-NEXT: %1 = firrtl.int.generic "circt_ltl_implication" %s_foo_c, %0 : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
; CHECK-NEXT: firrtl.int.generic "circt_verif_assert" %1 : (!firrtl.uint<1>) -> ()
intrinsic(circt_verif_assert, intrinsic(circt_ltl_implication : UInt<1>, s_foo_c, eq(foo.out, s_foo_data)))
; CHECK: firrtl.formal @testFormal of @FooTest bound 20
formal testFormal of FooTest, bound = 20
;// -----
FIRRTL version 3.9.0
circuit Foo:
; CHECK-LABEL: firrtl.extmodule private @Bar(in in: !firrtl.uint)
extmodule Bar:
input in: UInt
; CHECK-LABEL: firrtl.intmodule private @MyIntModule(in in: !firrtl.uint, out out: !firrtl.uint<8>)
; CHECK: attributes {intrinsic = "testIntrinsic1"}
; CHECK-NOT: {
intmodule MyIntModule :
input in: UInt
output out: UInt<8>
intrinsic = testIntrinsic1
; CHECK-LABEL: firrtl.intmodule private @MyParameterizedIntModule
; CHECK-SAME: <FORMAT: none = "xyz_timeout=%d\0A",
; CHECK-SAME: DEFAULT: ui32 = 0,
; CHECK-SAME: WIDTH: ui32 = 32,
; CHECK-SAME: DEPTH: f64 = 3.242000e+01>
; CHECK-SAME: (in in: !firrtl.uint,
; CHECK-SAME: out out: !firrtl.uint<8>)
; CHECK-SAME: attributes {intrinsic = "testIntrinsic2"}
; CHECK-NOT: {
intmodule MyParameterizedIntModule :
input in: UInt
output out: UInt<8>
intrinsic = testIntrinsic2
parameter FORMAT = "xyz_timeout=%d\n"
parameter DEFAULT = 0
parameter WIDTH = 32
parameter DEPTH = 32.42
; CHECK-LABEL: extmodule private @RefExt(
; CHECK-SAME: in in: !firrtl.uint<1>, out r: !firrtl.probe<uint<1>>
; CHECK-SAME: internalPaths = [#firrtl.internalpath, #firrtl.internalpath<"in">]
extmodule RefExt :
input in : UInt<1>
output r : Probe<UInt<1>>
ref r is "in"
; CHECK-LABEL: extmodule private @RefExtMore(
; CHECK-SAME: in in: !firrtl.uint<1>
; CHECK-SAME: out r: !firrtl.probe<uint<1>>
; CHECK-SAME: out data: !firrtl.uint<3>
; CHECK-SAME: out r2: !firrtl.probe<vector<bundle<a: uint<3>>, 3>>
; CHECK-SAME: internalPaths = [#firrtl.internalpath, #firrtl.internalpath<"path.to.internal.signal">, #firrtl.internalpath, #firrtl.internalpath<"in">]
extmodule RefExtMore :
input in : UInt<1>
output r : Probe<UInt<1>>
output data : UInt<3>
output r2 : Probe<{a : UInt<3>}[3]>
ref r2 is "in"
ref r is "path.to.internal.signal"
; CHECK-LABEL: module @Foo(
; CHECK-SAME: out %out: !firrtl.uint,
module Foo:
output out: UInt
output out3 : UInt<3>
; CHECK: %{{.+}}, %[[REM_R:.+]], %{{.+}}, %[[REM_R2:.+]] = firrtl.instance rem
; CHECK-NEXT: %[[REM_R2_1:.+]] = firrtl.ref.sub %[[REM_R2]][1]
; CHECK-NEXT: %[[REM_R2_1_A:.+]] = firrtl.ref.sub %[[REM_R2_1]][0]
; CHECK-NEXT: %[[READ_REM_R2_1_A:.+]] = firrtl.ref.resolve %[[REM_R2_1_A]]
; CHECK-NEXT: connect %out3, %[[READ_REM_R2_1_A]]
inst rem of RefExtMore
connect out3, read(rem.r2[1].a)
;// -----
FIRRTL version 2.9.0
circuit Foo:
module Bar:
input a: UInt<1>
module Foo:
input a: UInt<1>
output b: UInt<1>
node binary = UInt<4>("b1010")
node octal = UInt<4>("o12")
node decimal = UInt<4>(10)
node hexadecimal = UInt<4>("ha")
inst bar of Bar
bar is invalid
b <= a