mirror of https://github.com/llvm/circt.git
233 lines
9.3 KiB
MLIR
233 lines
9.3 KiB
MLIR
// RUN: circt-opt %s -split-input-file | circt-opt -split-input-file
|
|
// RUN: firtool %s -preserve-values=named -split-input-file
|
|
// These tests are just for demonstrating RefOps, and expected to not error.
|
|
|
|
// Simple 1 level read from wire.
|
|
firrtl.circuit "xmr" {
|
|
firrtl.module private @Test(out %x: !firrtl.probe<uint<2>>) {
|
|
%w = firrtl.wire : !firrtl.uint<2>
|
|
%zero = firrtl.constant 0 : !firrtl.uint<2>
|
|
firrtl.matchingconnect %w, %zero : !firrtl.uint<2>
|
|
%1 = firrtl.ref.send %w : !firrtl.uint<2>
|
|
firrtl.ref.define %x, %1 : !firrtl.probe<uint<2>>
|
|
}
|
|
firrtl.module @xmr() {
|
|
%test_x = firrtl.instance test @Test(out x: !firrtl.probe<uint<2>>)
|
|
%x = firrtl.ref.resolve %test_x : !firrtl.probe<uint<2>>
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
// Simple 1 level read from constant.
|
|
firrtl.circuit "SimpleRead" {
|
|
firrtl.module @Bar(out %_a: !firrtl.probe<uint<1>>) {
|
|
%zero = firrtl.constant 0 : !firrtl.uint<1>
|
|
%1 = firrtl.ref.send %zero : !firrtl.uint<1>
|
|
firrtl.ref.define %_a, %1 : !firrtl.probe<uint<1>>
|
|
}
|
|
firrtl.module @SimpleRead() {
|
|
%bar_a = firrtl.instance bar interesting_name @Bar(out _a: !firrtl.probe<uint<1>>)
|
|
%a = firrtl.wire : !firrtl.uint<1>
|
|
%0 = firrtl.ref.resolve %bar_a : !firrtl.probe<uint<1>>
|
|
firrtl.matchingconnect %a, %0 : !firrtl.uint<1>
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
// Forward module port to instance
|
|
firrtl.circuit "ForwardToInstance" {
|
|
firrtl.module @Bar2(out %_a: !firrtl.probe<uint<1>>) {
|
|
%zero = firrtl.constant 0 : !firrtl.uint<1>
|
|
%1 = firrtl.ref.send %zero : !firrtl.uint<1>
|
|
firrtl.ref.define %_a, %1 : !firrtl.probe<uint<1>>
|
|
}
|
|
firrtl.module @Bar(out %_a: !firrtl.probe<uint<1>>) {
|
|
%bar_2 = firrtl.instance bar @Bar2(out _a: !firrtl.probe<uint<1>>)
|
|
firrtl.ref.define %_a, %bar_2 : !firrtl.probe<uint<1>>
|
|
}
|
|
firrtl.module @ForwardToInstance() {
|
|
%bar_a = firrtl.instance bar interesting_name @Bar(out _a: !firrtl.probe<uint<1>>)
|
|
%a = firrtl.wire : !firrtl.uint<1>
|
|
%0 = firrtl.ref.resolve %bar_a : !firrtl.probe<uint<1>>
|
|
firrtl.matchingconnect %a, %0 : !firrtl.uint<1>
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
// Multiple readers, for a single remote value.
|
|
firrtl.circuit "ForwardToInstance" {
|
|
firrtl.module @Bar2(out %_a: !firrtl.probe<uint<1>>) {
|
|
%zero = firrtl.constant 0 : !firrtl.uint<1>
|
|
%1 = firrtl.ref.send %zero : !firrtl.uint<1>
|
|
firrtl.ref.define %_a, %1 : !firrtl.probe<uint<1>>
|
|
}
|
|
firrtl.module @Bar(out %_a: !firrtl.probe<uint<1>>) {
|
|
%bar_2 = firrtl.instance bar @Bar2(out _a: !firrtl.probe<uint<1>>)
|
|
firrtl.ref.define %_a, %bar_2 : !firrtl.probe<uint<1>>
|
|
// Reader 1
|
|
%0 = firrtl.ref.resolve %bar_2 : !firrtl.probe<uint<1>>
|
|
%a = firrtl.wire : !firrtl.uint<1>
|
|
firrtl.matchingconnect %a, %0 : !firrtl.uint<1>
|
|
}
|
|
firrtl.module @ForwardToInstance() {
|
|
%bar_a = firrtl.instance bar @Bar(out _a: !firrtl.probe<uint<1>>)
|
|
%a = firrtl.wire interesting_name : !firrtl.uint<1>
|
|
// Reader 2
|
|
%0 = firrtl.ref.resolve %bar_a : !firrtl.probe<uint<1>>
|
|
firrtl.matchingconnect %a, %0 : !firrtl.uint<1>
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
// Two references passed by value.
|
|
firrtl.circuit "DUT" {
|
|
firrtl.module private @Submodule (out %ref_out1: !firrtl.probe<uint<1>>, out %ref_out2: !firrtl.probe<uint<4>>) {
|
|
%zero = firrtl.constant 0 : !firrtl.uint<1>
|
|
%w_data1 = firrtl.wire : !firrtl.uint<1>
|
|
firrtl.matchingconnect %w_data1, %zero : !firrtl.uint<1>
|
|
%1 = firrtl.ref.send %w_data1 : !firrtl.uint<1>
|
|
firrtl.ref.define %ref_out1, %1 : !firrtl.probe<uint<1>>
|
|
%w_data2 = firrtl.wire : !firrtl.uint<4>
|
|
%zero4 = firrtl.constant 0 : !firrtl.uint<4>
|
|
firrtl.matchingconnect %w_data2, %zero4 : !firrtl.uint<4>
|
|
%2 = firrtl.ref.send %w_data2 : !firrtl.uint<4>
|
|
firrtl.ref.define %ref_out2, %2 : !firrtl.probe<uint<4>>
|
|
}
|
|
firrtl.module @DUT() {
|
|
%view_out1, %view_out2 = firrtl.instance sub interesting_name @Submodule(out ref_out1: !firrtl.probe<uint<1>>, out ref_out2: !firrtl.probe<uint<4>>)
|
|
%view_in1, %view_in2 = firrtl.instance MyView_companion interesting_name @MyView_companion(in ref_in1: !firrtl.uint<1>, in ref_in2: !firrtl.uint<4>)
|
|
|
|
%1 = firrtl.ref.resolve %view_out1 : !firrtl.probe<uint<1>>
|
|
%2 = firrtl.ref.resolve %view_out2 : !firrtl.probe<uint<4>>
|
|
firrtl.matchingconnect %view_in1, %1 : !firrtl.uint<1>
|
|
firrtl.matchingconnect %view_in2, %2 : !firrtl.uint<4>
|
|
}
|
|
|
|
firrtl.module private @MyView_companion (in %ref_in1: !firrtl.uint<1>, in %ref_in2: !firrtl.uint<4>) {
|
|
%c0_ui1 = firrtl.constant 0 : !firrtl.uint<1>
|
|
%_WIRE = firrtl.wire sym @_WIRE : !firrtl.uint<1>
|
|
firrtl.matchingconnect %_WIRE, %c0_ui1 : !firrtl.uint<1>
|
|
%iface = sv.interface.instance sym @__MyView_MyInterface__ : !sv.interface<@MyInterface>
|
|
}
|
|
|
|
sv.interface @MyInterface {
|
|
sv.verbatim "// a wire called 'bool'" {symbols = []}
|
|
sv.interface.signal @bool : i1
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
// RefType of aggregates and RefSub.
|
|
firrtl.circuit "RefTypeVector" {
|
|
firrtl.module @RefTypeVector(in %bundle : !firrtl.bundle<a: uint<1>, b flip: uint<2>>) {
|
|
%zero = firrtl.constant 0 : !firrtl.uint<4>
|
|
%z = firrtl.bitcast %zero : (!firrtl.uint<4>) -> !firrtl.vector<uint<1>,4>
|
|
%1 = firrtl.ref.send %z : !firrtl.vector<uint<1>,4>
|
|
%10 = firrtl.ref.sub %1[0] : !firrtl.probe<vector<uint<1>,4>>
|
|
%11 = firrtl.ref.sub %1[1] : !firrtl.probe<vector<uint<1>,4>>
|
|
%a = firrtl.ref.resolve %10 : !firrtl.probe<uint<1>>
|
|
%b = firrtl.ref.resolve %11 : !firrtl.probe<uint<1>>
|
|
%b1 = firrtl.ref.send %bundle : !firrtl.bundle<a: uint<1>, b flip: uint<2>>
|
|
%12 = firrtl.ref.sub %b1[1] : !firrtl.probe<bundle<a: uint<1>, b: uint<2>>>
|
|
%rb = firrtl.ref.resolve %12 : !firrtl.probe<uint<2>>
|
|
%bundle_b = firrtl.subfield %bundle[b] : !firrtl.bundle<a: uint<1>, b flip: uint<2>>
|
|
%zero2 = firrtl.constant 0 : !firrtl.uint<2>
|
|
firrtl.matchingconnect %bundle_b, %zero2 : !firrtl.uint<2>
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
// https://github.com/llvm/circt/issues/3715
|
|
firrtl.circuit "Issue3715" {
|
|
firrtl.module private @Test(in %p: !firrtl.uint<1>, out %x: !firrtl.probe<uint<2>>) {
|
|
firrtl.when %p : !firrtl.uint<1> {
|
|
%zero = firrtl.constant 1 : !firrtl.uint<2>
|
|
%w = firrtl.wire : !firrtl.uint<2>
|
|
%1 = firrtl.ref.send %w : !firrtl.uint<2>
|
|
firrtl.ref.define %x, %1 : !firrtl.probe<uint<2>>
|
|
firrtl.matchingconnect %w, %zero : !firrtl.uint<2>
|
|
}
|
|
}
|
|
firrtl.module @Issue3715(in %p: !firrtl.uint<1>) {
|
|
%test_in, %test_x = firrtl.instance test interesting_name @Test(in p: !firrtl.uint<1>, out x: !firrtl.probe<uint<2>>)
|
|
firrtl.matchingconnect %test_in, %p : !firrtl.uint<1>
|
|
%x = firrtl.ref.resolve %test_x : !firrtl.probe<uint<2>>
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
// Support using output port reference locally.
|
|
// https://github.com/llvm/circt/issues/3713
|
|
|
|
firrtl.circuit "UseRefsWithSinkFlow" {
|
|
firrtl.module private @OutChild(in %x: !firrtl.uint, out %y: !firrtl.uint, out %p: !firrtl.probe<uint>) {
|
|
%0 = firrtl.ref.send %x : !firrtl.uint
|
|
firrtl.ref.define %p, %0 : !firrtl.probe<uint>
|
|
%1 = firrtl.ref.resolve %p : !firrtl.probe<uint>
|
|
firrtl.connect %y, %1 : !firrtl.uint, !firrtl.uint
|
|
}
|
|
firrtl.module @UseRefsWithSinkFlow(in %x: !firrtl.uint<1>, out %y: !firrtl.uint<1>, out %zz: !firrtl.uint<1>, out %p: !firrtl.probe<uint<1>>) {
|
|
%0 = firrtl.ref.send %x : !firrtl.uint<1>
|
|
firrtl.ref.define %p, %0 : !firrtl.probe<uint<1>>
|
|
%1 = firrtl.ref.resolve %p : !firrtl.probe<uint<1>>
|
|
firrtl.matchingconnect %y, %1 : !firrtl.uint<1>
|
|
%oc_x, %oc_y, %oc_p = firrtl.instance oc interesting_name @OutChild(in x: !firrtl.uint, out y: !firrtl.uint, out p: !firrtl.probe<uint>)
|
|
firrtl.connect %oc_x, %x : !firrtl.uint, !firrtl.uint<1>
|
|
firrtl.connect %zz, %oc_y : !firrtl.uint<1>, !firrtl.uint
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
firrtl.circuit "ProbeAndRWProbe" {
|
|
// Dead, just check it parses.
|
|
firrtl.extmodule private @Probes(out ro : !firrtl.probe<uint<1>>, out rw : !firrtl.rwprobe<uint<2>>)
|
|
firrtl.module @ProbeAndRWProbe() {}
|
|
}
|
|
|
|
// -----
|
|
|
|
firrtl.circuit "Forceable" {
|
|
// Check forceable declarations
|
|
firrtl.module @Forceable(
|
|
in %clock : !firrtl.clock,
|
|
in %reset : !firrtl.uint<1>,
|
|
in %value : !firrtl.uint<2>,
|
|
out %node_ref : !firrtl.rwprobe<uint<2>>,
|
|
out %wire_ref : !firrtl.rwprobe<uint>,
|
|
out %reg_ref : !firrtl.rwprobe<uint<2>>,
|
|
out %regreset_ref : !firrtl.rwprobe<uint<2>>) {
|
|
|
|
%n, %n_f = firrtl.node %value forceable : !firrtl.uint<2>
|
|
firrtl.ref.define %node_ref, %n_f : !firrtl.rwprobe<uint<2>>
|
|
|
|
// TODO: infer ref result existence + type based on "forceable" or other ref-kind(s) indicator.
|
|
%w, %w_f = firrtl.wire forceable : !firrtl.uint, !firrtl.rwprobe<uint>
|
|
firrtl.ref.define %wire_ref, %w_f : !firrtl.rwprobe<uint>
|
|
firrtl.connect %w, %value : !firrtl.uint, !firrtl.uint<2>
|
|
|
|
%reg, %reg_f = firrtl.reg %clock forceable : !firrtl.clock, !firrtl.uint<2>, !firrtl.rwprobe<uint<2>>
|
|
firrtl.ref.define %reg_ref, %reg_f : !firrtl.rwprobe<uint<2>>
|
|
|
|
%regreset, %regreset_f = firrtl.regreset %clock, %reset, %value forceable : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<2>, !firrtl.uint<2>, !firrtl.rwprobe<uint<2>>
|
|
firrtl.ref.define %regreset_ref, %regreset_f : !firrtl.rwprobe<uint<2>>
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
firrtl.circuit "RefDefineAndCastWidths" {
|
|
firrtl.module @RefDefineAndCastWidths(in %x: !firrtl.uint<2>, out %p : !firrtl.probe<uint>) {
|
|
%ref = firrtl.ref.send %x : !firrtl.uint<2>
|
|
%cast = firrtl.ref.cast %ref : (!firrtl.probe<uint<2>>) -> !firrtl.probe<uint>
|
|
firrtl.ref.define %p, %cast : !firrtl.probe<uint>
|
|
}
|
|
}
|