mirror of https://github.com/llvm/circt.git
220 lines
9.1 KiB
MLIR
220 lines
9.1 KiB
MLIR
// RUN: circt-opt %s | circt-opt | FileCheck %s
|
|
|
|
// CHECK-LABEL: @basic
|
|
// CHECK-SAME: (in [[IN0:%.+]] : i32, out out0 : i32)
|
|
hw.module @basic(in %in0 : i32, out out0 : i32) {
|
|
// CHECK: %{{.*}} = llhd.delay [[IN0]] by <0ns, 1d, 0e> : i32
|
|
%0 = llhd.delay %in0 by <0ns, 1d, 0e> : i32
|
|
hw.output %0 : i32
|
|
}
|
|
|
|
// CHECK-LABEL: @connect_ports
|
|
// CHECK-SAME: (inout %[[IN:.+]] : [[TYPE:.+]], inout %[[OUT:.+]] : [[TYPE]])
|
|
// CHECK-NEXT: llhd.con %[[IN]], %[[OUT]] : !hw.inout<[[TYPE]]>
|
|
hw.module @connect_ports(inout %in: i32, inout %out: i32) {
|
|
llhd.con %in, %out : !hw.inout<i32>
|
|
}
|
|
|
|
// CHECK-LABEL: @sigExtract
|
|
hw.module @sigExtract(inout %arg0 : i32, in %arg1 : i5) {
|
|
// CHECK-NEXT: %{{.*}} = llhd.sig.extract %arg0 from %arg1 : (!hw.inout<i32>) -> !hw.inout<i5>
|
|
%1 = llhd.sig.extract %arg0 from %arg1 : (!hw.inout<i32>) -> !hw.inout<i5>
|
|
}
|
|
|
|
// CHECK-LABEL: @sigArray
|
|
hw.module @sigArray(inout %arg0 : !hw.array<5xi1>, in %arg1 : i3) {
|
|
// CHECK-NEXT: %{{.*}} = llhd.sig.array_slice %arg0 at %arg1 : (!hw.inout<array<5xi1>>) -> !hw.inout<array<3xi1>>
|
|
%0 = llhd.sig.array_slice %arg0 at %arg1 : (!hw.inout<array<5xi1>>) -> !hw.inout<array<3xi1>>
|
|
// CHECK-NEXT: %{{.*}} = llhd.sig.array_get %arg0[%arg1] : !hw.inout<array<5xi1>>
|
|
%1 = llhd.sig.array_get %arg0[%arg1] : !hw.inout<array<5xi1>>
|
|
}
|
|
|
|
// CHECK-LABEL: @sigStructExtract
|
|
hw.module @sigStructExtract(inout %arg0 : !hw.struct<foo: i1, bar: i2, baz: i3>) {
|
|
// CHECK-NEXT: %{{.*}} = llhd.sig.struct_extract %arg0["foo"] : !hw.inout<struct<foo: i1, bar: i2, baz: i3>>
|
|
%0 = llhd.sig.struct_extract %arg0["foo"] : !hw.inout<struct<foo: i1, bar: i2, baz: i3>>
|
|
// CHECK-NEXT: %{{.*}} = llhd.sig.struct_extract %arg0["baz"] : !hw.inout<struct<foo: i1, bar: i2, baz: i3>>
|
|
%1 = llhd.sig.struct_extract %arg0["baz"] : !hw.inout<struct<foo: i1, bar: i2, baz: i3>>
|
|
}
|
|
|
|
// CHECK-LABEL: @check_var
|
|
// CHECK-SAME: %[[INT:.*]]: i32
|
|
// CHECK-SAME: %[[ARRAY:.*]]: !hw.array<3xi1>
|
|
// CHECK-SAME: %[[TUP:.*]]: !hw.struct<foo: i1, bar: i2, baz: i3>
|
|
func.func @check_var(%int : i32, %array : !hw.array<3xi1>, %tup : !hw.struct<foo: i1, bar: i2, baz: i3>) {
|
|
// CHECK-NEXT: %{{.*}} = llhd.var %[[INT]] : i32
|
|
%0 = llhd.var %int : i32
|
|
// CHECK-NEXT: %{{.*}} = llhd.var %[[ARRAY]] : !hw.array<3xi1>
|
|
%1 = llhd.var %array : !hw.array<3xi1>
|
|
// CHECK-NEXT: %{{.*}} = llhd.var %[[TUP]] : !hw.struct<foo: i1, bar: i2, baz: i3>
|
|
%2 = llhd.var %tup : !hw.struct<foo: i1, bar: i2, baz: i3>
|
|
|
|
return
|
|
}
|
|
|
|
// CHECK-LABEL: @check_load
|
|
// CHECK-SAME: %[[INT:.*]]: !llhd.ptr<i32>
|
|
// CHECK-SAME: %[[ARRAY:.*]]: !llhd.ptr<!hw.array<3xi1>>
|
|
// CHECK-SAME: %[[TUP:.*]]: !llhd.ptr<!hw.struct<foo: i1, bar: i2, baz: i3>>
|
|
func.func @check_load(%int : !llhd.ptr<i32>, %array : !llhd.ptr<!hw.array<3xi1>>, %tup : !llhd.ptr<!hw.struct<foo: i1, bar: i2, baz: i3>>) {
|
|
// CHECK-NEXT: %{{.*}} = llhd.load %[[INT]] : !llhd.ptr<i32>
|
|
%0 = llhd.load %int : !llhd.ptr<i32>
|
|
// CHECK-NEXT: %{{.*}} = llhd.load %[[ARRAY]] : !llhd.ptr<!hw.array<3xi1>>
|
|
%1 = llhd.load %array : !llhd.ptr<!hw.array<3xi1>>
|
|
// CHECK-NEXT: %{{.*}} = llhd.load %[[TUP]] : !llhd.ptr<!hw.struct<foo: i1, bar: i2, baz: i3>>
|
|
%2 = llhd.load %tup : !llhd.ptr<!hw.struct<foo: i1, bar: i2, baz: i3>>
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// CHECK-LABEL: @check_store
|
|
// CHECK-SAME: %[[INT:.*]]: !llhd.ptr<i32>
|
|
// CHECK-SAME: %[[INTC:.*]]: i32
|
|
// CHECK-SAME: %[[ARRAY:.*]]: !llhd.ptr<!hw.array<3xi1>>
|
|
// CHECK-SAME: %[[ARRAYC:.*]]: !hw.array<3xi1>
|
|
// CHECK-SAME: %[[TUP:.*]]: !llhd.ptr<!hw.struct<foo: i1, bar: i2, baz: i3>>
|
|
// CHECK-SAME: %[[TUPC:.*]]: !hw.struct<foo: i1, bar: i2, baz: i3>
|
|
func.func @check_store(%int : !llhd.ptr<i32>, %intC : i32 , %array : !llhd.ptr<!hw.array<3xi1>>, %arrayC : !hw.array<3xi1>, %tup : !llhd.ptr<!hw.struct<foo: i1, bar: i2, baz: i3>>, %tupC : !hw.struct<foo: i1, bar: i2, baz: i3>) {
|
|
// CHECK-NEXT: llhd.store %[[INT]], %[[INTC]] : !llhd.ptr<i32>
|
|
llhd.store %int, %intC : !llhd.ptr<i32>
|
|
// CHECK-NEXT: llhd.store %[[ARRAY]], %[[ARRAYC]] : !llhd.ptr<!hw.array<3xi1>>
|
|
llhd.store %array, %arrayC : !llhd.ptr<!hw.array<3xi1>>
|
|
// CHECK-NEXT: llhd.store %[[TUP]], %[[TUPC]] : !llhd.ptr<!hw.struct<foo: i1, bar: i2, baz: i3>>
|
|
llhd.store %tup, %tupC : !llhd.ptr<!hw.struct<foo: i1, bar: i2, baz: i3>>
|
|
|
|
return
|
|
}
|
|
|
|
// CHECK-LABEL: @checkSigInst
|
|
hw.module @checkSigInst() {
|
|
// CHECK: %[[CI1:.*]] = hw.constant
|
|
%cI1 = hw.constant 0 : i1
|
|
// CHECK-NEXT: %sigI1 = llhd.sig %[[CI1]] : i1
|
|
%sigI1 = llhd.sig %cI1 : i1
|
|
// CHECK-NEXT: %[[CI64:.*]] = hw.constant
|
|
%cI64 = hw.constant 0 : i64
|
|
// CHECK-NEXT: %sigI64 = llhd.sig %[[CI64]] : i64
|
|
%sigI64 = llhd.sig %cI64 : i64
|
|
|
|
// CHECK-NEXT: %[[TUP:.*]] = hw.struct_create
|
|
%tup = hw.struct_create (%cI1, %cI64) : !hw.struct<foo: i1, bar: i64>
|
|
// CHECK-NEXT: %sigTup = llhd.sig %[[TUP]] : !hw.struct<foo: i1, bar: i64>
|
|
%sigTup = llhd.sig %tup : !hw.struct<foo: i1, bar: i64>
|
|
|
|
// CHECK-NEXT: %[[ARRAY:.*]] = hw.array_create
|
|
%array = hw.array_create %cI1, %cI1 : i1
|
|
// CHECK-NEXT: %sigArray = llhd.sig %[[ARRAY]] : !hw.array<2xi1>
|
|
%sigArray = llhd.sig %array : !hw.array<2xi1>
|
|
}
|
|
|
|
// CHECK-LABEL: @checkPrb
|
|
hw.module @checkPrb(inout %arg0 : i1, inout %arg1 : i64, inout %arg2 : !hw.array<3xi8>, inout %arg3 : !hw.struct<foo: i1, bar: i2, baz: i4>) {
|
|
// CHECK: %{{.*}} = llhd.prb %arg0 : !hw.inout<i1>
|
|
%0 = llhd.prb %arg0 : !hw.inout<i1>
|
|
// CHECK-NEXT: %{{.*}} = llhd.prb %arg1 : !hw.inout<i64>
|
|
%1 = llhd.prb %arg1 : !hw.inout<i64>
|
|
// CHECK-NEXT: %{{.*}} = llhd.prb %arg2 : !hw.inout<array<3xi8>>
|
|
%2 = llhd.prb %arg2 : !hw.inout<array<3xi8>>
|
|
// CHECK-NEXT: %{{.*}} = llhd.prb %arg3 : !hw.inout<struct<foo: i1, bar: i2, baz: i4>>
|
|
%3 = llhd.prb %arg3 : !hw.inout<struct<foo: i1, bar: i2, baz: i4>>
|
|
}
|
|
|
|
// CHECK-LABEL: @checkOutput
|
|
hw.module @checkOutput(in %arg0 : i32) {
|
|
%t = llhd.constant_time <0ns, 1d, 0e>
|
|
// CHECK: %{{.+}} = llhd.output %arg0 after %{{.*}} : i32
|
|
%0 = llhd.output %arg0 after %t : i32
|
|
// CHECK-NEXT: %{{.+}} = llhd.output "sigName" %arg0 after %{{.*}} : i32
|
|
%1 = llhd.output "sigName" %arg0 after %t : i32
|
|
}
|
|
|
|
// CHECK-LABEL: @checkDrv
|
|
hw.module @checkDrv(inout %arg0 : i1, inout %arg1 : i64, in %arg2 : i1,
|
|
in %arg3 : i64, inout %arg5 : !hw.array<3xi8>,
|
|
inout %arg6 : !hw.struct<foo: i1, bar: i2, baz: i4>,
|
|
in %arg7 : !hw.array<3xi8>, in %arg8 : !hw.struct<foo: i1, bar: i2, baz: i4>) {
|
|
|
|
%t = llhd.constant_time <0ns, 1d, 0e>
|
|
// CHECK: llhd.drv %arg0, %arg2 after %{{.*}} : !hw.inout<i1>
|
|
llhd.drv %arg0, %arg2 after %t : !hw.inout<i1>
|
|
// CHECK-NEXT: llhd.drv %arg1, %arg3 after %{{.*}} : !hw.inout<i64>
|
|
llhd.drv %arg1, %arg3 after %t : !hw.inout<i64>
|
|
// CHECK-NEXT: llhd.drv %arg1, %arg3 after %{{.*}} if %arg2 : !hw.inout<i64>
|
|
llhd.drv %arg1, %arg3 after %t if %arg2 : !hw.inout<i64>
|
|
// CHECK-NEXT: llhd.drv %arg5, %arg7 after %{{.*}} : !hw.inout<array<3xi8>>
|
|
llhd.drv %arg5, %arg7 after %t : !hw.inout<array<3xi8>>
|
|
// CHECK-NEXT: llhd.drv %arg6, %arg8 after %{{.*}} : !hw.inout<struct<foo: i1, bar: i2, baz: i4>>
|
|
llhd.drv %arg6, %arg8 after %t : !hw.inout<struct<foo: i1, bar: i2, baz: i4>>
|
|
}
|
|
|
|
// CHECK-LABEL: @check_wait_0
|
|
hw.module @check_wait_0 () {
|
|
// CHECK-NEXT: llhd.process
|
|
llhd.process {
|
|
// CHECK: llhd.wait ^[[BB:.*]]
|
|
llhd.wait ^bb1
|
|
// CHECK-NEXT: ^[[BB]]
|
|
^bb1:
|
|
llhd.halt
|
|
}
|
|
}
|
|
|
|
// CHECK-LABEL: @check_wait_1
|
|
hw.module @check_wait_1 () {
|
|
// CHECK-NEXT: llhd.process
|
|
llhd.process {
|
|
// CHECK-NEXT: %[[TIME:.*]] = llhd.constant_time
|
|
%time = llhd.constant_time #llhd.time<0ns, 0d, 0e>
|
|
// CHECK-NEXT: llhd.wait for %[[TIME]], ^[[BB:.*]](%[[TIME]] : !llhd.time)
|
|
llhd.wait for %time, ^bb1(%time: !llhd.time)
|
|
// CHECK-NEXT: ^[[BB]](%[[T:.*]]: !llhd.time):
|
|
^bb1(%t: !llhd.time):
|
|
llhd.halt
|
|
}
|
|
}
|
|
|
|
// CHECK: @check_wait_2(inout %[[ARG0:.*]] : i64, inout %[[ARG1:.*]] : i1) {
|
|
hw.module @check_wait_2 (inout %arg0 : i64, inout %arg1 : i1) {
|
|
// CHECK: [[PRB0:%.+]] = llhd.prb %arg0
|
|
%prb0 = llhd.prb %arg0 : !hw.inout<i64>
|
|
// CHECK: [[PRB1:%.+]] = llhd.prb %arg1
|
|
%prb1 = llhd.prb %arg1 : !hw.inout<i1>
|
|
// CHECK-NEXT: llhd.process
|
|
llhd.process {
|
|
// CHECK-NEXT: llhd.wait ([[PRB0]], [[PRB1]] : i64, i1), ^[[BB:.*]](%[[ARG1]] : !hw.inout<i1>)
|
|
llhd.wait (%prb0, %prb1 : i64, i1), ^bb1(%arg1 : !hw.inout<i1>)
|
|
// CHECK: ^[[BB]](%[[A:.*]]: !hw.inout<i1>):
|
|
^bb1(%a: !hw.inout<i1>):
|
|
llhd.halt
|
|
}
|
|
}
|
|
|
|
// CHECK: hw.module @check_wait_3(inout %[[ARG0:.*]] : i64, inout %[[ARG1:.*]] : i1) {
|
|
hw.module @check_wait_3 (inout %arg0 : i64, inout %arg1 : i1) {
|
|
// CHECK: [[PRB0:%.+]] = llhd.prb %arg0
|
|
%prb0 = llhd.prb %arg0 : !hw.inout<i64>
|
|
// CHECK: [[PRB1:%.+]] = llhd.prb %arg1
|
|
%prb1 = llhd.prb %arg1 : !hw.inout<i1>
|
|
// CHECK-NEXT: llhd.process
|
|
llhd.process {
|
|
// CHECK-NEXT: %[[TIME:.*]] = llhd.constant_time
|
|
%time = llhd.constant_time #llhd.time<0ns, 0d, 0e>
|
|
// CHECK-NEXT: llhd.wait for %[[TIME]], ([[PRB0]], [[PRB1]] : i64, i1), ^[[BB:.*]](%[[ARG1]], %[[ARG0]] : !hw.inout<i1>, !hw.inout<i64>)
|
|
llhd.wait for %time, (%prb0, %prb1 : i64, i1), ^bb1(%arg1, %arg0 : !hw.inout<i1>, !hw.inout<i64>)
|
|
// CHECK: ^[[BB]](%[[A:.*]]: !hw.inout<i1>, %[[B:.*]]: !hw.inout<i64>):
|
|
^bb1(%a: !hw.inout<i1>, %b: !hw.inout<i64>):
|
|
llhd.halt
|
|
}
|
|
}
|
|
|
|
// CHECK-LABEL: @FinalProcess
|
|
hw.module @FinalProcess () {
|
|
// CHECK-NEXT: llhd.final {
|
|
// CHECK-NEXT: llhd.halt
|
|
// CHECK-NEXT: }
|
|
llhd.final {
|
|
llhd.halt
|
|
}
|
|
}
|