From 64741342fed93d5d9e8902eb101dfeb2adfd5f5d Mon Sep 17 00:00:00 2001 From: Max Korbel Date: Fri, 2 Aug 2024 16:53:28 -0700 Subject: [PATCH] Fix bug in `LogicStructure.getRange` calculations (#499) --- lib/src/signals/logic_structure.dart | 15 +++++-- test/logic_array_test.dart | 66 +++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/lib/src/signals/logic_structure.dart b/lib/src/signals/logic_structure.dart index 6e72dcaca..6fac9d61e 100644 --- a/lib/src/signals/logic_structure.dart +++ b/lib/src/signals/logic_structure.dart @@ -179,10 +179,17 @@ class LogicStructure implements Logic { final elementStart = index; final elementEnd = index + element.width; - final elementInRange = ((elementStart >= modifiedStartIndex) && - (elementStart < modifiedEndIndex)) || - ((elementEnd > modifiedStartIndex) && - (elementEnd <= modifiedEndIndex)); + // if the element is even partially within the range, then include it + // OR, if it is wholly contained within the range, include it + final elementInRange = + // end is within the element + (modifiedEndIndex > elementStart && modifiedEndIndex < elementEnd) || + // start is within the element + (modifiedStartIndex >= elementStart && + modifiedStartIndex < elementEnd) || + //element is fully contained + (modifiedEndIndex >= elementEnd && + modifiedStartIndex <= elementStart); if (elementInRange) { // figure out the subset of `element` that needs to be included diff --git a/test/logic_array_test.dart b/test/logic_array_test.dart index 96ee77035..9d2689c65 100644 --- a/test/logic_array_test.dart +++ b/test/logic_array_test.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2023 Intel Corporation +// Copyright (C) 2023-2024 Intel Corporation // SPDX-License-Identifier: BSD-3-Clause // // logic_array_test.dart @@ -579,6 +579,70 @@ void main() { }); }); + group('access logicarray', () { + test('slice one bit of 1d array', () async { + final la = LogicArray([3], 8); + final slice = la.slice(9, 9); + expect(slice.width, 1); + la.elements[1].put(bin('00000010')); + expect(slice.value.toInt(), 1); + }); + + test('slice 2 bits of one element of 1d array', () async { + final la = LogicArray([3], 8); + final slice = la.slice(10, 9); + expect(slice.width, 2); + la.elements[1].put(bin('00000110')); + expect(slice.value.toInt(), bin('11')); + }); + + test('slice 2 bits spanning two elements of 1d array', () async { + final la = LogicArray([3], 8); + final slice = la.slice(8, 7); + expect(slice.width, 2); + la.elements[1].put(1, fill: true); + la.elements[0].put(0, fill: true); + expect(slice.value.toInt(), bin('10')); + }); + + test('slice 2 bits spanning 2 arrays of 2d array', () async { + final la = LogicArray([3, 2], 8); + final slice = la.slice(16, 15); + expect(slice.width, 2); + la.elements[1].elements[0].put(1, fill: true); + la.elements[0].elements[1].put(0, fill: true); + expect(slice.value.toInt(), bin('10')); + }); + + test('slice more than one element of array', () async { + final la = LogicArray([3], 8); + final slice = la.slice(19, 4); + expect(slice.width, 16); + la.elements[2].put(LogicValue.x); + la.elements[1].put(0); + la.elements[0].put(1, fill: true); + expect(slice.value, LogicValue.of('xxxx000000001111')); + }); + + test('slice more than one element of array at the edges', () async { + final la = LogicArray([3], 8); + final slice = la.slice(16, 7); + expect(slice.width, 10); + la.elements[2].put(LogicValue.x); + la.elements[1].put(0); + la.elements[0].put(1, fill: true); + expect(slice.value, LogicValue.of('x000000001')); + }); + + test('slice exactly one element of array', () async { + final la = LogicArray([3], 8); + final slice = la.slice(15, 8); + expect(slice.width, 8); + la.elements[1].put(1, fill: true); + expect(slice.value, LogicValue.of('11111111')); + }); + }); + group('logicarray passthrough', () { Future testArrayPassthrough(SimpleLAPassthrough mod, {bool checkNoSwizzle = true,