Skip to content

Commit 05f6cba

Browse files
Issue #377: assign a logic subset to logic (array) (#456)
1 parent a084c03 commit 05f6cba

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed

lib/src/exceptions/logic/signal_width_mismatch_exception.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,12 @@ class SignalWidthMismatchException extends RohdException {
3131
SignalWidthMismatchException.forNull(dynamic val)
3232
: super('Could not infer width of input $val.'
3333
' Please provide a valid width.');
34+
35+
/// Constructs a new [Exception] for when a dynamic has a wrong width.
36+
SignalWidthMismatchException.forWidthOverflow(int actualWidth, int maxWidth,
37+
{String? customMessage})
38+
: super(customMessage ??
39+
'Value has the wrong width.'
40+
' Expected $actualWidth to be less than'
41+
' or equal to $maxWidth.');
3442
}

lib/src/signals/logic_array.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,33 @@ class LogicArray extends LogicStructure {
127127
return LogicArray(dimensions, elementWidth,
128128
numUnpackedDimensions: numUnpackedDimensions, name: name);
129129
}
130+
131+
/// Perform Assign operation on a Logic subset or slice
132+
///
133+
/// Assigns part of this LogicArray with a given [updatedSubset] of type
134+
/// [List<Logic>]. The update is performed from a given [start] position
135+
/// to the length of the [updatedSubset].
136+
///
137+
/// Example:
138+
/// ```
139+
/// LogicArray sampleLogic;
140+
/// // Note: updatedSubset.length < (sampleLogic.length - start)
141+
/// List<Logic> updatedSubset;
142+
/// // Assign part of sampleLogic as [updatedSubset]
143+
/// sampleLogic.assignSubset(updatedSubset); // start = 0 by default
144+
/// // assign updated subset to sampleLogic[10:10+updatedSubset.length]
145+
/// sampleLogic.assignSubset(updatedSubset, 10);
146+
/// ```
147+
///
148+
void assignSubset(List<Logic> updatedSubset, {int start = 0}) {
149+
if (updatedSubset.length > elements.length - start) {
150+
throw SignalWidthMismatchException.forWidthOverflow(
151+
updatedSubset.length, elements.length - start);
152+
}
153+
154+
// Assign Logic array from `start` index to `start+updatedSubset.length`
155+
for (var i = 0; i < updatedSubset.length; i++) {
156+
elements[start + i] <= updatedSubset[i];
157+
}
158+
}
130159
}

test/logic_array_test.dart

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,28 @@ class IndexBitOfArrayModule extends Module {
477477
}
478478
}
479479

480+
class AssignSubsetModule extends Module {
481+
AssignSubsetModule(LogicArray updatedSubset,
482+
{int? start, bool? isError = false}) {
483+
final dim = ((isError != null && isError) ? 10 : 5);
484+
updatedSubset = addInputArray('inputLogicArray', updatedSubset,
485+
dimensions: [dim], elementWidth: 3);
486+
487+
final o =
488+
addOutputArray('outputLogicArray', dimensions: [10], elementWidth: 3);
489+
final error = addOutput('errorBit');
490+
try {
491+
if (start != null) {
492+
o.assignSubset(updatedSubset.elements, start: start);
493+
} else {
494+
o.assignSubset(updatedSubset.elements);
495+
}
496+
} on SignalWidthMismatchException {
497+
error <= Const(1);
498+
}
499+
}
500+
}
501+
480502
void main() {
481503
tearDown(() async {
482504
await Simulator.reset();
@@ -938,5 +960,58 @@ void main() {
938960
await SimCompare.checkFunctionalVector(mod, vectors);
939961
SimCompare.checkIverilogVector(mod, vectors);
940962
});
963+
964+
test('assign subset of logic array without mentioning start', () async {
965+
final updatedSubset = LogicArray([5], 3, name: 'updatedSubset');
966+
final mod = AssignSubsetModule(updatedSubset);
967+
await mod.build();
968+
969+
final vectors = [
970+
Vector({'inputLogicArray': 0},
971+
{'outputLogicArray': LogicValue.ofString(('z' * 15) + ('0' * 15))}),
972+
Vector({'inputLogicArray': bin('101' * 5)},
973+
{'outputLogicArray': LogicValue.ofString(('z' * 15) + ('101' * 5))})
974+
];
975+
976+
await SimCompare.checkFunctionalVector(mod, vectors);
977+
SimCompare.checkIverilogVector(mod, vectors);
978+
});
979+
980+
test('assign subset of logic array with mentioning start', () async {
981+
final updatedSubset = LogicArray([5], 3, name: 'updatedSubset');
982+
final mod = AssignSubsetModule(updatedSubset, start: 3);
983+
await mod.build();
984+
985+
final vectors = [
986+
Vector({
987+
'inputLogicArray': 0
988+
}, {
989+
'outputLogicArray':
990+
LogicValue.ofString(('z' * 3 * 2) + ('0' * 3 * 5) + ('z' * 3 * 3))
991+
}),
992+
Vector({
993+
'inputLogicArray': bin('101' * 5)
994+
}, {
995+
'outputLogicArray':
996+
LogicValue.ofString(('z' * 3 * 2) + ('101' * 5) + ('z' * 3 * 3))
997+
}),
998+
];
999+
1000+
await SimCompare.checkFunctionalVector(mod, vectors);
1001+
SimCompare.checkIverilogVector(mod, vectors);
1002+
});
1003+
1004+
test('error in assign subset of logic array', () async {
1005+
final updatedSubset = LogicArray([10], 3, name: 'updatedSubset');
1006+
final mod = AssignSubsetModule(updatedSubset, start: 3, isError: true);
1007+
await mod.build();
1008+
1009+
final vectors = [
1010+
Vector({'inputLogicArray': bin('101' * 10)}, {'errorBit': 1})
1011+
];
1012+
1013+
await SimCompare.checkFunctionalVector(mod, vectors);
1014+
SimCompare.checkIverilogVector(mod, vectors);
1015+
});
9411016
});
9421017
}

0 commit comments

Comments
 (0)