From 71302dbd2df1da1c78aeddd71b79e4e46cce3854 Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 14 Sep 2022 15:39:30 -0700 Subject: [PATCH 1/5] Fix slice primitives * Promote int-like values in get_slice/set_slice * Update doc to refer to set_index instead of set_bit * Support set_slice of length 1 for constant values --- docs/primitives.md | 11 +- magma/primitives/slice.py | 25 +- .../test_operators/gold/TestSetSliceInt.mlir | 296 ++++++++++++++++++ .../gold/TestSetSliceWidthOne.mlir | 3 + tests/test_operators/gold/TestSliceInt.mlir | 10 + tests/test_operators/test_slice.py | 48 +++ tests/test_type/test_ndarray.py | 14 + tools/xdl/slice.py | 4 +- 8 files changed, 402 insertions(+), 9 deletions(-) create mode 100644 tests/test_operators/gold/TestSetSliceInt.mlir create mode 100644 tests/test_operators/gold/TestSetSliceWidthOne.mlir create mode 100644 tests/test_operators/gold/TestSliceInt.mlir diff --git a/docs/primitives.md b/docs/primitives.md index 18d20a641..2ec80ca34 100644 --- a/docs/primitives.md +++ b/docs/primitives.md @@ -249,9 +249,9 @@ Slice function interfaces: * width: constant slice width -### set_bit +### set_index Similar to set_slice/get_slice, this function allows you to dynamically set the -value of a bit in a Bits value. Here's an example: +value of one index in an Array. Here's an example: ```python class SetBit(m.Circuit): @@ -259,13 +259,16 @@ class SetBit(m.Circuit): val=m.In(m.Bit), idx=m.In(m.Bits[2]), O=m.Out(m.Bits[4])) - io.O @= m.set_bit(io.I, io.val, io.idx) + io.O @= m.set_index(io.I, io.val, io.idx) ``` Interface: ```python -def set_bit(target: Bits, value: Bit, idx: UInt): +def set_index(target: Array, value, idx: UInt): """ Returns a new value where index `idx` of value `target` is set to `value` + * `target` - a value of type `Array[N, T]` + * `value` - a value of type `T` + * `idx` - a value of type `UInt[clog2(N)]` """ ``` diff --git a/magma/primitives/slice.py b/magma/primitives/slice.py index 95aa07124..d5bfe364e 100644 --- a/magma/primitives/slice.py +++ b/magma/primitives/slice.py @@ -1,3 +1,5 @@ +from typing import Union + from magma.bit import Bit from magma.bits import Bits, UInt from magma.bitutils import clog2 @@ -40,15 +42,32 @@ def slice(*args, **kwargs): return get_slice(*args, **kwargs) -def set_slice(target: Bits, value: Bits, start: UInt, width: int): +def set_slice(target: Bits, value: Bits, start: Union[UInt, int], width: int): """ target: the output with a dynamic slice range replaced by value value: the output driving a slice of target start: dynamic start index of the slice width: constant slice width """ - if not isinstance(start, UInt): - raise TypeError("start should be a UInt") + if not isinstance(start, (UInt, int)): + raise TypeError("start should be a UInt or int") + if len(target) == 1: + if start != 0: + raise ValueError( + "Start must equal 0 for set_slice with value of length 1") + if width != 1: + raise ValueError( + "Width must equal 1 for set_slice with value of length 1") + if not ( + isinstance(value, type(target)) or + isinstance(target, type(value)) + ): + raise ValueError( + "Incompatible types found for target and value") + return value + if isinstance(start, int): + start = uint(start) + T = magma_type(type(target)) output = T.qualify(Direction.Undirected)() orig_start_len = len(start) diff --git a/tests/test_operators/gold/TestSetSliceInt.mlir b/tests/test_operators/gold/TestSetSliceInt.mlir new file mode 100644 index 000000000..a160da979 --- /dev/null +++ b/tests/test_operators/gold/TestSetSliceInt.mlir @@ -0,0 +1,296 @@ +hw.module @TestSetSliceInt(%I: i6) -> (O: i12) { + %0 = hw.constant 1 : i1 + %1 = hw.constant 0 : i4 + %2 = hw.constant 2 : i4 + %3 = comb.sub %1, %2 : i4 + %4 = comb.extract %3 from 0 : (i4) -> i1 + %5 = comb.extract %3 from 1 : (i4) -> i1 + %6 = comb.extract %3 from 2 : (i4) -> i1 + %7 = hw.constant 0 : i1 + %8 = hw.constant 0 : i1 + %9 = hw.constant 0 : i1 + %10 = comb.concat %9, %8, %7, %6, %5, %4 : i1, i1, i1, i1, i1, i1 + %11 = comb.shru %I, %10 : i6 + %12 = comb.extract %11 from 0 : (i6) -> i1 + %13 = hw.constant 1 : i1 + %14 = hw.constant 2 : i4 + %15 = hw.constant 0 : i4 + %16 = comb.icmp ule %14, %15 : i4 + %17 = comb.and %13, %16 : i1 + %19 = hw.array_create %12, %0 : i1 + %18 = hw.array_get %19[%17] : !hw.array<2xi1> + %20 = hw.constant 1 : i1 + %21 = hw.constant 1 : i4 + %22 = hw.constant 2 : i4 + %23 = comb.sub %21, %22 : i4 + %24 = comb.extract %23 from 0 : (i4) -> i1 + %25 = comb.extract %23 from 1 : (i4) -> i1 + %26 = comb.extract %23 from 2 : (i4) -> i1 + %27 = hw.constant 0 : i1 + %28 = hw.constant 0 : i1 + %29 = hw.constant 0 : i1 + %30 = comb.concat %29, %28, %27, %26, %25, %24 : i1, i1, i1, i1, i1, i1 + %31 = comb.shru %I, %30 : i6 + %32 = comb.extract %31 from 0 : (i6) -> i1 + %33 = hw.constant 1 : i1 + %34 = hw.constant 2 : i4 + %35 = hw.constant 1 : i4 + %36 = comb.icmp ule %34, %35 : i4 + %37 = comb.and %33, %36 : i1 + %38 = hw.constant 2 : i4 + %39 = hw.constant 6 : i4 + %40 = comb.add %38, %39 : i4 + %41 = hw.constant 1 : i4 + %42 = comb.sub %40, %41 : i4 + %43 = hw.constant 1 : i4 + %44 = comb.icmp uge %42, %43 : i4 + %45 = comb.and %37, %44 : i1 + %47 = hw.array_create %32, %20 : i1 + %46 = hw.array_get %47[%45] : !hw.array<2xi1> + %48 = hw.constant 1 : i1 + %49 = hw.constant 2 : i4 + %50 = hw.constant 2 : i4 + %51 = comb.sub %49, %50 : i4 + %52 = comb.extract %51 from 0 : (i4) -> i1 + %53 = comb.extract %51 from 1 : (i4) -> i1 + %54 = comb.extract %51 from 2 : (i4) -> i1 + %55 = hw.constant 0 : i1 + %56 = hw.constant 0 : i1 + %57 = hw.constant 0 : i1 + %58 = comb.concat %57, %56, %55, %54, %53, %52 : i1, i1, i1, i1, i1, i1 + %59 = comb.shru %I, %58 : i6 + %60 = comb.extract %59 from 0 : (i6) -> i1 + %61 = hw.constant 1 : i1 + %62 = hw.constant 2 : i4 + %63 = hw.constant 2 : i4 + %64 = comb.icmp ule %62, %63 : i4 + %65 = comb.and %61, %64 : i1 + %66 = hw.constant 2 : i4 + %67 = hw.constant 6 : i4 + %68 = comb.add %66, %67 : i4 + %69 = hw.constant 1 : i4 + %70 = comb.sub %68, %69 : i4 + %71 = hw.constant 2 : i4 + %72 = comb.icmp uge %70, %71 : i4 + %73 = comb.and %65, %72 : i1 + %75 = hw.array_create %60, %48 : i1 + %74 = hw.array_get %75[%73] : !hw.array<2xi1> + %76 = hw.constant 1 : i1 + %77 = hw.constant 3 : i4 + %78 = hw.constant 2 : i4 + %79 = comb.sub %77, %78 : i4 + %80 = comb.extract %79 from 0 : (i4) -> i1 + %81 = comb.extract %79 from 1 : (i4) -> i1 + %82 = comb.extract %79 from 2 : (i4) -> i1 + %83 = hw.constant 0 : i1 + %84 = hw.constant 0 : i1 + %85 = hw.constant 0 : i1 + %86 = comb.concat %85, %84, %83, %82, %81, %80 : i1, i1, i1, i1, i1, i1 + %87 = comb.shru %I, %86 : i6 + %88 = comb.extract %87 from 0 : (i6) -> i1 + %89 = hw.constant 1 : i1 + %90 = hw.constant 2 : i4 + %91 = hw.constant 6 : i4 + %92 = comb.add %90, %91 : i4 + %93 = hw.constant 1 : i4 + %94 = comb.sub %92, %93 : i4 + %95 = hw.constant 3 : i4 + %96 = comb.icmp uge %94, %95 : i4 + %97 = comb.and %89, %96 : i1 + %99 = hw.array_create %88, %76 : i1 + %98 = hw.array_get %99[%97] : !hw.array<2xi1> + %100 = hw.constant 1 : i1 + %101 = hw.constant 4 : i4 + %102 = hw.constant 2 : i4 + %103 = comb.sub %101, %102 : i4 + %104 = comb.extract %103 from 0 : (i4) -> i1 + %105 = comb.extract %103 from 1 : (i4) -> i1 + %106 = comb.extract %103 from 2 : (i4) -> i1 + %107 = hw.constant 0 : i1 + %108 = hw.constant 0 : i1 + %109 = hw.constant 0 : i1 + %110 = comb.concat %109, %108, %107, %106, %105, %104 : i1, i1, i1, i1, i1, i1 + %111 = comb.shru %I, %110 : i6 + %112 = comb.extract %111 from 0 : (i6) -> i1 + %113 = hw.constant 1 : i1 + %114 = hw.constant 2 : i4 + %115 = hw.constant 6 : i4 + %116 = comb.add %114, %115 : i4 + %117 = hw.constant 1 : i4 + %118 = comb.sub %116, %117 : i4 + %119 = hw.constant 4 : i4 + %120 = comb.icmp uge %118, %119 : i4 + %121 = comb.and %113, %120 : i1 + %123 = hw.array_create %112, %100 : i1 + %122 = hw.array_get %123[%121] : !hw.array<2xi1> + %124 = hw.constant 1 : i1 + %125 = hw.constant 5 : i4 + %126 = hw.constant 2 : i4 + %127 = comb.sub %125, %126 : i4 + %128 = comb.extract %127 from 0 : (i4) -> i1 + %129 = comb.extract %127 from 1 : (i4) -> i1 + %130 = comb.extract %127 from 2 : (i4) -> i1 + %131 = hw.constant 0 : i1 + %132 = hw.constant 0 : i1 + %133 = hw.constant 0 : i1 + %134 = comb.concat %133, %132, %131, %130, %129, %128 : i1, i1, i1, i1, i1, i1 + %135 = comb.shru %I, %134 : i6 + %136 = comb.extract %135 from 0 : (i6) -> i1 + %137 = hw.constant 1 : i1 + %138 = hw.constant 2 : i4 + %139 = hw.constant 6 : i4 + %140 = comb.add %138, %139 : i4 + %141 = hw.constant 1 : i4 + %142 = comb.sub %140, %141 : i4 + %143 = hw.constant 5 : i4 + %144 = comb.icmp uge %142, %143 : i4 + %145 = comb.and %137, %144 : i1 + %147 = hw.array_create %136, %124 : i1 + %146 = hw.array_get %147[%145] : !hw.array<2xi1> + %148 = hw.constant 1 : i1 + %149 = hw.constant 6 : i4 + %150 = hw.constant 2 : i4 + %151 = comb.sub %149, %150 : i4 + %152 = comb.extract %151 from 0 : (i4) -> i1 + %153 = comb.extract %151 from 1 : (i4) -> i1 + %154 = comb.extract %151 from 2 : (i4) -> i1 + %155 = hw.constant 0 : i1 + %156 = hw.constant 0 : i1 + %157 = hw.constant 0 : i1 + %158 = comb.concat %157, %156, %155, %154, %153, %152 : i1, i1, i1, i1, i1, i1 + %159 = comb.shru %I, %158 : i6 + %160 = comb.extract %159 from 0 : (i6) -> i1 + %161 = hw.constant 1 : i1 + %162 = hw.constant 2 : i4 + %163 = hw.constant 6 : i4 + %164 = comb.add %162, %163 : i4 + %165 = hw.constant 1 : i4 + %166 = comb.sub %164, %165 : i4 + %167 = hw.constant 6 : i4 + %168 = comb.icmp uge %166, %167 : i4 + %169 = comb.and %161, %168 : i1 + %171 = hw.array_create %160, %148 : i1 + %170 = hw.array_get %171[%169] : !hw.array<2xi1> + %172 = hw.constant 1 : i1 + %173 = hw.constant 7 : i4 + %174 = hw.constant 2 : i4 + %175 = comb.sub %173, %174 : i4 + %176 = comb.extract %175 from 0 : (i4) -> i1 + %177 = comb.extract %175 from 1 : (i4) -> i1 + %178 = comb.extract %175 from 2 : (i4) -> i1 + %179 = hw.constant 0 : i1 + %180 = hw.constant 0 : i1 + %181 = hw.constant 0 : i1 + %182 = comb.concat %181, %180, %179, %178, %177, %176 : i1, i1, i1, i1, i1, i1 + %183 = comb.shru %I, %182 : i6 + %184 = comb.extract %183 from 0 : (i6) -> i1 + %185 = hw.constant 1 : i1 + %186 = hw.constant 2 : i4 + %187 = hw.constant 6 : i4 + %188 = comb.add %186, %187 : i4 + %189 = hw.constant 1 : i4 + %190 = comb.sub %188, %189 : i4 + %191 = hw.constant 7 : i4 + %192 = comb.icmp uge %190, %191 : i4 + %193 = comb.and %185, %192 : i1 + %195 = hw.array_create %184, %172 : i1 + %194 = hw.array_get %195[%193] : !hw.array<2xi1> + %196 = hw.constant 1 : i1 + %197 = hw.constant 8 : i4 + %198 = hw.constant 2 : i4 + %199 = comb.sub %197, %198 : i4 + %200 = comb.extract %199 from 0 : (i4) -> i1 + %201 = comb.extract %199 from 1 : (i4) -> i1 + %202 = comb.extract %199 from 2 : (i4) -> i1 + %203 = hw.constant 0 : i1 + %204 = hw.constant 0 : i1 + %205 = hw.constant 0 : i1 + %206 = comb.concat %205, %204, %203, %202, %201, %200 : i1, i1, i1, i1, i1, i1 + %207 = comb.shru %I, %206 : i6 + %208 = comb.extract %207 from 0 : (i6) -> i1 + %209 = hw.constant 1 : i1 + %210 = hw.constant 2 : i4 + %211 = hw.constant 6 : i4 + %212 = comb.add %210, %211 : i4 + %213 = hw.constant 1 : i4 + %214 = comb.sub %212, %213 : i4 + %215 = hw.constant 8 : i4 + %216 = comb.icmp uge %214, %215 : i4 + %217 = comb.and %209, %216 : i1 + %219 = hw.array_create %208, %196 : i1 + %218 = hw.array_get %219[%217] : !hw.array<2xi1> + %220 = hw.constant 1 : i1 + %221 = hw.constant 9 : i4 + %222 = hw.constant 2 : i4 + %223 = comb.sub %221, %222 : i4 + %224 = comb.extract %223 from 0 : (i4) -> i1 + %225 = comb.extract %223 from 1 : (i4) -> i1 + %226 = comb.extract %223 from 2 : (i4) -> i1 + %227 = hw.constant 0 : i1 + %228 = hw.constant 0 : i1 + %229 = hw.constant 0 : i1 + %230 = comb.concat %229, %228, %227, %226, %225, %224 : i1, i1, i1, i1, i1, i1 + %231 = comb.shru %I, %230 : i6 + %232 = comb.extract %231 from 0 : (i6) -> i1 + %233 = hw.constant 1 : i1 + %234 = hw.constant 2 : i4 + %235 = hw.constant 6 : i4 + %236 = comb.add %234, %235 : i4 + %237 = hw.constant 1 : i4 + %238 = comb.sub %236, %237 : i4 + %239 = hw.constant 9 : i4 + %240 = comb.icmp uge %238, %239 : i4 + %241 = comb.and %233, %240 : i1 + %243 = hw.array_create %232, %220 : i1 + %242 = hw.array_get %243[%241] : !hw.array<2xi1> + %244 = hw.constant 1 : i1 + %245 = hw.constant 10 : i4 + %246 = hw.constant 2 : i4 + %247 = comb.sub %245, %246 : i4 + %248 = comb.extract %247 from 0 : (i4) -> i1 + %249 = comb.extract %247 from 1 : (i4) -> i1 + %250 = comb.extract %247 from 2 : (i4) -> i1 + %251 = hw.constant 0 : i1 + %252 = hw.constant 0 : i1 + %253 = hw.constant 0 : i1 + %254 = comb.concat %253, %252, %251, %250, %249, %248 : i1, i1, i1, i1, i1, i1 + %255 = comb.shru %I, %254 : i6 + %256 = comb.extract %255 from 0 : (i6) -> i1 + %257 = hw.constant 1 : i1 + %258 = hw.constant 2 : i4 + %259 = hw.constant 6 : i4 + %260 = comb.add %258, %259 : i4 + %261 = hw.constant 1 : i4 + %262 = comb.sub %260, %261 : i4 + %263 = hw.constant 10 : i4 + %264 = comb.icmp uge %262, %263 : i4 + %265 = comb.and %257, %264 : i1 + %267 = hw.array_create %256, %244 : i1 + %266 = hw.array_get %267[%265] : !hw.array<2xi1> + %268 = hw.constant 1 : i1 + %269 = hw.constant 11 : i4 + %270 = hw.constant 2 : i4 + %271 = comb.sub %269, %270 : i4 + %272 = comb.extract %271 from 0 : (i4) -> i1 + %273 = comb.extract %271 from 1 : (i4) -> i1 + %274 = comb.extract %271 from 2 : (i4) -> i1 + %275 = hw.constant 0 : i1 + %276 = hw.constant 0 : i1 + %277 = hw.constant 0 : i1 + %278 = comb.concat %277, %276, %275, %274, %273, %272 : i1, i1, i1, i1, i1, i1 + %279 = comb.shru %I, %278 : i6 + %280 = comb.extract %279 from 0 : (i6) -> i1 + %281 = hw.constant 1 : i1 + %282 = hw.constant 2 : i4 + %283 = hw.constant 6 : i4 + %284 = comb.add %282, %283 : i4 + %285 = hw.constant 1 : i4 + %286 = comb.sub %284, %285 : i4 + %287 = hw.constant 11 : i4 + %288 = comb.icmp uge %286, %287 : i4 + %289 = comb.and %281, %288 : i1 + %291 = hw.array_create %280, %268 : i1 + %290 = hw.array_get %291[%289] : !hw.array<2xi1> + %292 = comb.concat %290, %266, %242, %218, %194, %170, %146, %122, %98, %74, %46, %18 : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1 + hw.output %292 : i12 +} diff --git a/tests/test_operators/gold/TestSetSliceWidthOne.mlir b/tests/test_operators/gold/TestSetSliceWidthOne.mlir new file mode 100644 index 000000000..97f7e76ff --- /dev/null +++ b/tests/test_operators/gold/TestSetSliceWidthOne.mlir @@ -0,0 +1,3 @@ +hw.module @TestSetSliceWidthOne(%I: i1) -> (O: i1) { + hw.output %I : i1 +} diff --git a/tests/test_operators/gold/TestSliceInt.mlir b/tests/test_operators/gold/TestSliceInt.mlir new file mode 100644 index 000000000..8328094cf --- /dev/null +++ b/tests/test_operators/gold/TestSliceInt.mlir @@ -0,0 +1,10 @@ +hw.module @TestSliceInt(%I: i10) -> (O: i6) { + %0 = comb.extract %I from 2 : (i10) -> i1 + %1 = comb.extract %I from 3 : (i10) -> i1 + %2 = comb.extract %I from 4 : (i10) -> i1 + %3 = comb.extract %I from 5 : (i10) -> i1 + %4 = comb.extract %I from 6 : (i10) -> i1 + %5 = comb.extract %I from 7 : (i10) -> i1 + %6 = comb.concat %5, %4, %3, %2, %1, %0 : i1, i1, i1, i1, i1, i1 + hw.output %6 : i6 +} diff --git a/tests/test_operators/test_slice.py b/tests/test_operators/test_slice.py index 5200ba760..5818bddd0 100644 --- a/tests/test_operators/test_slice.py +++ b/tests/test_operators/test_slice.py @@ -68,3 +68,51 @@ class TestSetSlice(m.Circuit): ) tester.compile_and_run("verilator", skip_compile=True, directory=build_dir, flags=["-Wno-unused"]) + + +def test_get_slice_int(): + class TestSliceInt(m.Circuit): + io = m.IO( + I=m.In(m.Bits[10]), + O=m.Out(m.Bits[6]) + ) + + io.O @= m.get_slice(io.I, start=2, width=6) + + m.compile("build/TestSliceInt", TestSliceInt, output="mlir") + assert check_files_equal(__file__, + "build/TestSliceInt.mlir", + "gold/TestSliceInt.mlir") + + +def test_set_slice_int(): + class TestSetSliceInt(m.Circuit): + io = m.IO( + I=m.In(m.Bits[6]), + O=m.Out(m.Bits[12]) + ) + + # default value + O = m.Bits[12](0xFFF) + io.O @= m.set_slice(O, io.I, start=2, width=6) + + m.compile("build/TestSetSliceInt", TestSetSliceInt, output="mlir") + assert check_files_equal(__file__, "build/TestSetSliceInt.mlir", + "gold/TestSetSliceInt.mlir") + + +def test_set_slice_width_one(): + class TestSetSliceWidthOne(m.Circuit): + io = m.IO( + I=m.In(m.Bits[1]), + O=m.Out(m.Bits[1]) + ) + + # default value + O = m.Bits[1](1) + io.O @= m.set_slice(O, io.I, start=0, width=1) + + m.compile("build/TestSetSliceWidthOne", TestSetSliceWidthOne, + output="mlir-verilog") + assert check_files_equal(__file__, "build/TestSetSliceWidthOne.mlir", + "gold/TestSetSliceWidthOne.mlir") diff --git a/tests/test_type/test_ndarray.py b/tests/test_type/test_ndarray.py index b9c900faf..f31b5daa1 100644 --- a/tests/test_type/test_ndarray.py +++ b/tests/test_type/test_ndarray.py @@ -114,3 +114,17 @@ class Main(m.Circuit): m.compile("build/test_ndarray_get_slice", Main, inline=True) assert check_files_equal(__file__, f"build/test_ndarray_get_slice.v", f"gold/test_ndarray_get_slice.v") + + +def test_ndarray_get_slice(): + class Main(m.Circuit): + io = m.IO( + I=m.In(m.Array[(2, 3, 6), m.Bit]), + x=m.In(m.UInt[2]), + O=m.Out(m.Array[(2, 3, 2), m.Bit]) + ) + io.O @= m.get_slice(io.I, start=io.x, width=2) + + m.compile("build/test_ndarray_get_slice", Main, inline=True) + assert check_files_equal(__file__, f"build/test_ndarray_get_slice.v", + f"gold/test_ndarray_get_slice.v") diff --git a/tools/xdl/slice.py b/tools/xdl/slice.py index 9419b5d32..e57d036a7 100644 --- a/tools/xdl/slice.py +++ b/tools/xdl/slice.py @@ -3,7 +3,7 @@ fpga = 'xc3s250e.xdlrc' if len(sys.argv) == 2: - fpga = sys.argv[1] + fpga = sys.argv[1] device = Device(fpga) @@ -44,7 +44,7 @@ else: line += '.' print(line) - + From e1b35446815ba0b840082f02de84eeaec6f9aef9 Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 14 Sep 2022 15:41:58 -0700 Subject: [PATCH 2/5] Revert undesired changes --- tests/test_type/test_ndarray.py | 14 -------------- tools/xdl/slice.py | 4 ++-- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/tests/test_type/test_ndarray.py b/tests/test_type/test_ndarray.py index f31b5daa1..b9c900faf 100644 --- a/tests/test_type/test_ndarray.py +++ b/tests/test_type/test_ndarray.py @@ -114,17 +114,3 @@ class Main(m.Circuit): m.compile("build/test_ndarray_get_slice", Main, inline=True) assert check_files_equal(__file__, f"build/test_ndarray_get_slice.v", f"gold/test_ndarray_get_slice.v") - - -def test_ndarray_get_slice(): - class Main(m.Circuit): - io = m.IO( - I=m.In(m.Array[(2, 3, 6), m.Bit]), - x=m.In(m.UInt[2]), - O=m.Out(m.Array[(2, 3, 2), m.Bit]) - ) - io.O @= m.get_slice(io.I, start=io.x, width=2) - - m.compile("build/test_ndarray_get_slice", Main, inline=True) - assert check_files_equal(__file__, f"build/test_ndarray_get_slice.v", - f"gold/test_ndarray_get_slice.v") diff --git a/tools/xdl/slice.py b/tools/xdl/slice.py index e57d036a7..9419b5d32 100644 --- a/tools/xdl/slice.py +++ b/tools/xdl/slice.py @@ -3,7 +3,7 @@ fpga = 'xc3s250e.xdlrc' if len(sys.argv) == 2: - fpga = sys.argv[1] + fpga = sys.argv[1] device = Device(fpga) @@ -44,7 +44,7 @@ else: line += '.' print(line) - + From 52e0e12708c2d2222dd497dd56da665e06ec1edf Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 14 Sep 2022 15:50:25 -0700 Subject: [PATCH 3/5] Use mlir output --- tests/test_operators/test_slice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_operators/test_slice.py b/tests/test_operators/test_slice.py index 5818bddd0..3489b4546 100644 --- a/tests/test_operators/test_slice.py +++ b/tests/test_operators/test_slice.py @@ -113,6 +113,6 @@ class TestSetSliceWidthOne(m.Circuit): io.O @= m.set_slice(O, io.I, start=0, width=1) m.compile("build/TestSetSliceWidthOne", TestSetSliceWidthOne, - output="mlir-verilog") + output="mlir") assert check_files_equal(__file__, "build/TestSetSliceWidthOne.mlir", "gold/TestSetSliceWidthOne.mlir") From e965d3a237a6380078bb61383e42e6cf3ba1ef67 Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Thu, 15 Sep 2022 11:24:51 -0700 Subject: [PATCH 4/5] Update slice width one logic/test --- magma/primitives/slice.py | 27 +++++++------------ .../gold/TestSetSliceWidthOne.mlir | 3 --- tests/test_operators/test_slice.py | 7 ++--- 3 files changed, 13 insertions(+), 24 deletions(-) delete mode 100644 tests/test_operators/gold/TestSetSliceWidthOne.mlir diff --git a/magma/primitives/slice.py b/magma/primitives/slice.py index d5bfe364e..587c5f776 100644 --- a/magma/primitives/slice.py +++ b/magma/primitives/slice.py @@ -51,20 +51,6 @@ def set_slice(target: Bits, value: Bits, start: Union[UInt, int], width: int): """ if not isinstance(start, (UInt, int)): raise TypeError("start should be a UInt or int") - if len(target) == 1: - if start != 0: - raise ValueError( - "Start must equal 0 for set_slice with value of length 1") - if width != 1: - raise ValueError( - "Width must equal 1 for set_slice with value of length 1") - if not ( - isinstance(value, type(target)) or - isinstance(target, type(value)) - ): - raise ValueError( - "Incompatible types found for target and value") - return value if isinstance(start, int): start = uint(start) @@ -80,8 +66,13 @@ def set_slice(target: Bits, value: Bits, start: Union[UInt, int], width: int): in_slice_range &= start <= i if i > 0: in_slice_range &= i <= (start + width - 1) - value_idx = (uint(i, clog2(len(target))) - start)[:clog2(len(value))] - if len(value_idx) == 1: - value_idx = value_idx[0] - output[i] @= in_slice_range.ite(value[value_idx], target[i]) + if width == 1: + curr_value = value[0] + else: + value_idx = uint(i, clog2(len(target))) - start + value_idx = value_idx[:clog2(len(value))] + if len(value_idx) == 1: + value_idx = value_idx[0] + curr_value = value[value_idx] + output[i] @= in_slice_range.ite(curr_value, target[i]) return output diff --git a/tests/test_operators/gold/TestSetSliceWidthOne.mlir b/tests/test_operators/gold/TestSetSliceWidthOne.mlir deleted file mode 100644 index 97f7e76ff..000000000 --- a/tests/test_operators/gold/TestSetSliceWidthOne.mlir +++ /dev/null @@ -1,3 +0,0 @@ -hw.module @TestSetSliceWidthOne(%I: i1) -> (O: i1) { - hw.output %I : i1 -} diff --git a/tests/test_operators/test_slice.py b/tests/test_operators/test_slice.py index 3489b4546..92e56f63a 100644 --- a/tests/test_operators/test_slice.py +++ b/tests/test_operators/test_slice.py @@ -105,12 +105,13 @@ def test_set_slice_width_one(): class TestSetSliceWidthOne(m.Circuit): io = m.IO( I=m.In(m.Bits[1]), - O=m.Out(m.Bits[1]) + x=m.In(m.UInt[2]), + O=m.Out(m.Bits[12]) ) # default value - O = m.Bits[1](1) - io.O @= m.set_slice(O, io.I, start=0, width=1) + O = m.Bits[12](0xFFF) + io.O @= m.set_slice(O, io.I, start=io.x, width=1) m.compile("build/TestSetSliceWidthOne", TestSetSliceWidthOne, output="mlir") From 4edeeaee1a542561a3b569b7f31e69c57de9618e Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Thu, 15 Sep 2022 11:25:38 -0700 Subject: [PATCH 5/5] Add gold --- .../gold/TestSetSliceWidthOne.mlir | 183 ++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 tests/test_operators/gold/TestSetSliceWidthOne.mlir diff --git a/tests/test_operators/gold/TestSetSliceWidthOne.mlir b/tests/test_operators/gold/TestSetSliceWidthOne.mlir new file mode 100644 index 000000000..88a30a203 --- /dev/null +++ b/tests/test_operators/gold/TestSetSliceWidthOne.mlir @@ -0,0 +1,183 @@ +hw.module @TestSetSliceWidthOne(%I: i1, %x: i2) -> (O: i12) { + %0 = hw.constant 1 : i1 + %1 = comb.extract %I from 0 : (i1) -> i1 + %2 = hw.constant 1 : i1 + %3 = comb.extract %x from 0 : (i2) -> i1 + %4 = comb.extract %x from 1 : (i2) -> i1 + %5 = hw.constant 0 : i1 + %6 = hw.constant 0 : i1 + %7 = comb.concat %6, %5, %4, %3 : i1, i1, i1, i1 + %8 = hw.constant 0 : i4 + %9 = comb.icmp ule %7, %8 : i4 + %10 = comb.and %2, %9 : i1 + %12 = hw.array_create %1, %0 : i1 + %11 = hw.array_get %12[%10] : !hw.array<2xi1> + %13 = hw.constant 1 : i1 + %14 = hw.constant 1 : i1 + %15 = hw.constant 0 : i1 + %16 = hw.constant 0 : i1 + %17 = comb.concat %16, %15, %4, %3 : i1, i1, i1, i1 + %18 = hw.constant 1 : i4 + %19 = comb.icmp ule %17, %18 : i4 + %20 = comb.and %14, %19 : i1 + %21 = hw.constant 0 : i1 + %22 = hw.constant 0 : i1 + %23 = comb.concat %22, %21, %4, %3 : i1, i1, i1, i1 + %24 = hw.constant 1 : i4 + %25 = comb.add %23, %24 : i4 + %26 = hw.constant 1 : i4 + %27 = comb.sub %25, %26 : i4 + %28 = hw.constant 1 : i4 + %29 = comb.icmp uge %27, %28 : i4 + %30 = comb.and %20, %29 : i1 + %32 = hw.array_create %1, %13 : i1 + %31 = hw.array_get %32[%30] : !hw.array<2xi1> + %33 = hw.constant 1 : i1 + %34 = hw.constant 1 : i1 + %35 = hw.constant 0 : i1 + %36 = hw.constant 0 : i1 + %37 = comb.concat %36, %35, %4, %3 : i1, i1, i1, i1 + %38 = hw.constant 2 : i4 + %39 = comb.icmp ule %37, %38 : i4 + %40 = comb.and %34, %39 : i1 + %41 = hw.constant 0 : i1 + %42 = hw.constant 0 : i1 + %43 = comb.concat %42, %41, %4, %3 : i1, i1, i1, i1 + %44 = hw.constant 1 : i4 + %45 = comb.add %43, %44 : i4 + %46 = hw.constant 1 : i4 + %47 = comb.sub %45, %46 : i4 + %48 = hw.constant 2 : i4 + %49 = comb.icmp uge %47, %48 : i4 + %50 = comb.and %40, %49 : i1 + %52 = hw.array_create %1, %33 : i1 + %51 = hw.array_get %52[%50] : !hw.array<2xi1> + %53 = hw.constant 1 : i1 + %54 = hw.constant 1 : i1 + %55 = hw.constant 0 : i1 + %56 = hw.constant 0 : i1 + %57 = comb.concat %56, %55, %4, %3 : i1, i1, i1, i1 + %58 = hw.constant 1 : i4 + %59 = comb.add %57, %58 : i4 + %60 = hw.constant 1 : i4 + %61 = comb.sub %59, %60 : i4 + %62 = hw.constant 3 : i4 + %63 = comb.icmp uge %61, %62 : i4 + %64 = comb.and %54, %63 : i1 + %66 = hw.array_create %1, %53 : i1 + %65 = hw.array_get %66[%64] : !hw.array<2xi1> + %67 = hw.constant 1 : i1 + %68 = hw.constant 1 : i1 + %69 = hw.constant 0 : i1 + %70 = hw.constant 0 : i1 + %71 = comb.concat %70, %69, %4, %3 : i1, i1, i1, i1 + %72 = hw.constant 1 : i4 + %73 = comb.add %71, %72 : i4 + %74 = hw.constant 1 : i4 + %75 = comb.sub %73, %74 : i4 + %76 = hw.constant 4 : i4 + %77 = comb.icmp uge %75, %76 : i4 + %78 = comb.and %68, %77 : i1 + %80 = hw.array_create %1, %67 : i1 + %79 = hw.array_get %80[%78] : !hw.array<2xi1> + %81 = hw.constant 1 : i1 + %82 = hw.constant 1 : i1 + %83 = hw.constant 0 : i1 + %84 = hw.constant 0 : i1 + %85 = comb.concat %84, %83, %4, %3 : i1, i1, i1, i1 + %86 = hw.constant 1 : i4 + %87 = comb.add %85, %86 : i4 + %88 = hw.constant 1 : i4 + %89 = comb.sub %87, %88 : i4 + %90 = hw.constant 5 : i4 + %91 = comb.icmp uge %89, %90 : i4 + %92 = comb.and %82, %91 : i1 + %94 = hw.array_create %1, %81 : i1 + %93 = hw.array_get %94[%92] : !hw.array<2xi1> + %95 = hw.constant 1 : i1 + %96 = hw.constant 1 : i1 + %97 = hw.constant 0 : i1 + %98 = hw.constant 0 : i1 + %99 = comb.concat %98, %97, %4, %3 : i1, i1, i1, i1 + %100 = hw.constant 1 : i4 + %101 = comb.add %99, %100 : i4 + %102 = hw.constant 1 : i4 + %103 = comb.sub %101, %102 : i4 + %104 = hw.constant 6 : i4 + %105 = comb.icmp uge %103, %104 : i4 + %106 = comb.and %96, %105 : i1 + %108 = hw.array_create %1, %95 : i1 + %107 = hw.array_get %108[%106] : !hw.array<2xi1> + %109 = hw.constant 1 : i1 + %110 = hw.constant 1 : i1 + %111 = hw.constant 0 : i1 + %112 = hw.constant 0 : i1 + %113 = comb.concat %112, %111, %4, %3 : i1, i1, i1, i1 + %114 = hw.constant 1 : i4 + %115 = comb.add %113, %114 : i4 + %116 = hw.constant 1 : i4 + %117 = comb.sub %115, %116 : i4 + %118 = hw.constant 7 : i4 + %119 = comb.icmp uge %117, %118 : i4 + %120 = comb.and %110, %119 : i1 + %122 = hw.array_create %1, %109 : i1 + %121 = hw.array_get %122[%120] : !hw.array<2xi1> + %123 = hw.constant 1 : i1 + %124 = hw.constant 1 : i1 + %125 = hw.constant 0 : i1 + %126 = hw.constant 0 : i1 + %127 = comb.concat %126, %125, %4, %3 : i1, i1, i1, i1 + %128 = hw.constant 1 : i4 + %129 = comb.add %127, %128 : i4 + %130 = hw.constant 1 : i4 + %131 = comb.sub %129, %130 : i4 + %132 = hw.constant 8 : i4 + %133 = comb.icmp uge %131, %132 : i4 + %134 = comb.and %124, %133 : i1 + %136 = hw.array_create %1, %123 : i1 + %135 = hw.array_get %136[%134] : !hw.array<2xi1> + %137 = hw.constant 1 : i1 + %138 = hw.constant 1 : i1 + %139 = hw.constant 0 : i1 + %140 = hw.constant 0 : i1 + %141 = comb.concat %140, %139, %4, %3 : i1, i1, i1, i1 + %142 = hw.constant 1 : i4 + %143 = comb.add %141, %142 : i4 + %144 = hw.constant 1 : i4 + %145 = comb.sub %143, %144 : i4 + %146 = hw.constant 9 : i4 + %147 = comb.icmp uge %145, %146 : i4 + %148 = comb.and %138, %147 : i1 + %150 = hw.array_create %1, %137 : i1 + %149 = hw.array_get %150[%148] : !hw.array<2xi1> + %151 = hw.constant 1 : i1 + %152 = hw.constant 1 : i1 + %153 = hw.constant 0 : i1 + %154 = hw.constant 0 : i1 + %155 = comb.concat %154, %153, %4, %3 : i1, i1, i1, i1 + %156 = hw.constant 1 : i4 + %157 = comb.add %155, %156 : i4 + %158 = hw.constant 1 : i4 + %159 = comb.sub %157, %158 : i4 + %160 = hw.constant 10 : i4 + %161 = comb.icmp uge %159, %160 : i4 + %162 = comb.and %152, %161 : i1 + %164 = hw.array_create %1, %151 : i1 + %163 = hw.array_get %164[%162] : !hw.array<2xi1> + %165 = hw.constant 1 : i1 + %166 = hw.constant 1 : i1 + %167 = hw.constant 0 : i1 + %168 = hw.constant 0 : i1 + %169 = comb.concat %168, %167, %4, %3 : i1, i1, i1, i1 + %170 = hw.constant 1 : i4 + %171 = comb.add %169, %170 : i4 + %172 = hw.constant 1 : i4 + %173 = comb.sub %171, %172 : i4 + %174 = hw.constant 11 : i4 + %175 = comb.icmp uge %173, %174 : i4 + %176 = comb.and %166, %175 : i1 + %178 = hw.array_create %1, %165 : i1 + %177 = hw.array_get %178[%176] : !hw.array<2xi1> + %179 = comb.concat %177, %163, %149, %135, %121, %107, %93, %79, %65, %51, %31, %11 : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1 + hw.output %179 : i12 +}