From 87ca92bf285f91c9a7577417577ccbdb0d1c80eb Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Sat, 7 Jun 2025 18:48:34 -0700 Subject: [PATCH 01/19] Add bit reversal component for 1D arrays Signed-off-by: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> --- lib/src/bit_reversal.dart | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 lib/src/bit_reversal.dart diff --git a/lib/src/bit_reversal.dart b/lib/src/bit_reversal.dart new file mode 100644 index 000000000..418bd3a00 --- /dev/null +++ b/lib/src/bit_reversal.dart @@ -0,0 +1,44 @@ +// Copyright (C) 2021-2024 Intel Corporation +// SPDX-License-Identifier: BSD-3-Clause + +import 'package:rohd/rohd.dart'; +import 'package:rohd_hcl/rohd_hcl.dart'; + +int bitReverse(int value, int bits) { + var reversed = 0; + for (var i = 0; i < bits; i++) { + reversed <<= 1; + reversed |= value & 1; + value >>= 1; + } + return reversed; +} + +class BitReversal extends Module { + LogicArray get out => output('out') as LogicArray; + + BitReversal(LogicArray input, {super.name = 'bit_reversal'}) + : assert(input.dimensions.length == 1, 'Can only bit reverse 1D arrays') { + input = addInputArray( + 'input_array', + input, + dimensions: input.dimensions, // it seems like these are needed + elementWidth: input.elementWidth, + numUnpackedDimensions: input.numUnpackedDimensions, + ); + + final out = addOutputArray( + 'out', + dimensions: input.dimensions, + elementWidth: input.elementWidth, + numUnpackedDimensions: input.numUnpackedDimensions, + ); + + final length = input.dimensions[0]; + final bits = log2Ceil(length); + + for (var i = 0; i < length; i++) { + out.elements[bitReverse(i, bits)] <= input.elements[i]; + } + } +} From 492150c207806a6fd761e3b4c0f15f8ec39c32e7 Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Mon, 9 Jun 2025 13:48:10 -0700 Subject: [PATCH 02/19] Add complex floating point module Signed-off-by: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> --- .../floating_point/floating_point_fft.dart | 71 ++++++++++++++++ .../complex_floating_point_logic.dart | 83 +++++++++++++++++++ .../floating_point_logic.dart | 6 ++ .../copmlex_floating_point_test.dart | 65 +++++++++++++++ 4 files changed, 225 insertions(+) create mode 100644 lib/src/arithmetic/floating_point/floating_point_fft.dart create mode 100644 lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart create mode 100644 test/arithmetic/floating_point/copmlex_floating_point_test.dart diff --git a/lib/src/arithmetic/floating_point/floating_point_fft.dart b/lib/src/arithmetic/floating_point/floating_point_fft.dart new file mode 100644 index 000000000..71b2ba298 --- /dev/null +++ b/lib/src/arithmetic/floating_point/floating_point_fft.dart @@ -0,0 +1,71 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: BSD-3-Clause + +import 'package:rohd/rohd.dart'; + +// class FFT extends Module { +// LogicArray get out => output('out') as LogicArray; +// +// FFT(Logic en, Logic clk, Logic reset, LogicArray input, {super.name = 'fft'}) +// : assert(input.dimensions.length == 1) { +// final int length = input.dimensions[0]; +// if ((length & (~(length - 1))) != length) { +// assert(false); +// } +// final int log2Length = log2Ceil(length); +// +// input = addInputArray( +// 'input_array', +// input, +// dimensions: input.dimensions, // it seems like these are needed +// elementWidth: input.elementWidth, +// numUnpackedDimensions: input.numUnpackedDimensions, +// ); +// +// List stageArrays = List.generate( +// log2Length + 1, +// (stage) => LogicArray( +// input.dimensions, +// input.elementWidth, +// name: 'stage${stage}Array', +// numUnpackedDimensions: input.numUnpackedDimensions, +// ), +// ); +// +// LogicArray out = addOutputArray( +// 'out', +// dimensions: input.dimensions, +// elementWidth: input.elementWidth, +// numUnpackedDimensions: input.numUnpackedDimensions, +// ); +// out <= stageArrays[log2Length]; +// +// List Function(PipelineStageInfo)> fftStages = []; +// +// fftStages.add((p) => [stageArrays[0] < BitReverse(input).out]); +// +// for (var s = 1; s <= log2Length; s++) { +// final m = 1 << s; +// final mShift = log2Ceil(m); +// +// Counter i = Counter(en, reset, clk, width: log2Length - 1); +// +// Logic k = (i.val >> (mShift - 1)) << mShift; +// Logic j = (i.val & Const((m >> 1) - 1, width: i.width)); +// } +// +// // ReadyValidPipeline() +// +// // for s = 1 to log(n) do +// // m ← 2s +// // ωm ← exp(−2πi/m) +// // for k = 0 to n-1 by m do +// // ω ← 1 +// // for j = 0 to m/2 – 1 do +// // t ← ω A[k + j + m/2] +// // u ← A[k + j] +// // A[k + j] ← u + t +// // A[k + j + m/2] ← u – t +// // ω ← ω ωm +// } +// } diff --git a/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart b/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart new file mode 100644 index 000000000..279d06ead --- /dev/null +++ b/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart @@ -0,0 +1,83 @@ +// Copyright (C) 2024-2025 Intel Corporation +// SPDX-License-Identifier: BSD-3-Clause + +import 'package:meta/meta.dart'; +import 'package:rohd/rohd.dart'; +import 'package:rohd_hcl/rohd_hcl.dart'; + +class ComplexFloatingPoint extends LogicStructure { + final FloatingPoint realPart; + + final FloatingPoint imaginaryPart; + + static String _nameJoin(String? structName, String signalName) { + if (structName == null) { + return signalName; + } + return '${structName}_$signalName'; + } + + ComplexFloatingPoint({ + required int exponentWidth, + required int mantissaWidth, + String? name, + }) : this._internal( + realPart: FloatingPoint( + exponentWidth: exponentWidth, + mantissaWidth: mantissaWidth, + name: _nameJoin(name, 're'), + ), + imaginaryPart: FloatingPoint( + exponentWidth: exponentWidth, + mantissaWidth: mantissaWidth, + name: _nameJoin(name, 'im'), + ), + name: name, + ); + + ComplexFloatingPoint._internal( + {required this.realPart, required this.imaginaryPart, super.name}) + : assert(realPart.exponent.width == imaginaryPart.exponent.width), + assert(realPart.mantissa.width == imaginaryPart.mantissa.width), + super([realPart, imaginaryPart]); + + @mustBeOverridden + @override + ComplexFloatingPoint clone({String? name}) => ComplexFloatingPoint( + exponentWidth: realPart.exponent.width, + mantissaWidth: realPart.mantissa.width, + name: name, + ); + + ComplexFloatingPoint adder(ComplexFloatingPoint other) => + ComplexFloatingPoint._internal( + realPart: FloatingPointAdderSinglePath(realPart, other.realPart).sum, + imaginaryPart: + FloatingPointAdderSinglePath(imaginaryPart, other.imaginaryPart) + .sum, + name: _nameJoin(name, "adder")); + + ComplexFloatingPoint multiplier(ComplexFloatingPoint other) { + // use only 3 multipliers: https://mathworld.wolfram.com/ComplexMultiplication.html + final ac = FloatingPointMultiplierSimple(realPart, other.realPart).product; + final bd = FloatingPointMultiplierSimple(imaginaryPart, other.imaginaryPart) + .product; + final abcd = FloatingPointMultiplierSimple( + FloatingPointAdderSinglePath(realPart, imaginaryPart).sum, + FloatingPointAdderSinglePath(other.realPart, other.imaginaryPart) + .sum) + .product; + + return ComplexFloatingPoint._internal( + realPart: FloatingPointAdderSinglePath(ac, bd.negated()).sum, + imaginaryPart: FloatingPointAdderSinglePath(abcd, + FloatingPointAdderSinglePath(ac.negated(), bd.negated()).sum) + .sum, + name: _nameJoin(name, "multiplier")); + } + + ComplexFloatingPoint negated() => ComplexFloatingPoint._internal( + realPart: realPart.negated(), + imaginaryPart: imaginaryPart.negated(), + name: _nameJoin(name, "negated")); +} diff --git a/lib/src/arithmetic/signals/floating_point_logics/floating_point_logic.dart b/lib/src/arithmetic/signals/floating_point_logics/floating_point_logic.dart index a8dd6899a..612efe262 100644 --- a/lib/src/arithmetic/signals/floating_point_logics/floating_point_logic.dart +++ b/lib/src/arithmetic/signals/floating_point_logics/floating_point_logic.dart @@ -165,6 +165,12 @@ class FloatingPoint extends LogicStructure { } } + FloatingPoint negated() => FloatingPoint._( + ~sign, + exponent.clone()..gets(exponent), + mantissa.clone()..gets(mantissa), + _explicitJBit); + /// Construct a FloatingPoint that represents infinity. factory FloatingPoint.inf( {required int exponentWidth, diff --git a/test/arithmetic/floating_point/copmlex_floating_point_test.dart b/test/arithmetic/floating_point/copmlex_floating_point_test.dart new file mode 100644 index 000000000..69f23fbf4 --- /dev/null +++ b/test/arithmetic/floating_point/copmlex_floating_point_test.dart @@ -0,0 +1,65 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: BSD-3-Clause +// +// floating_point_test.dart +// Tests of Floating Point basic types +// +// 2024 April 1 +// Authors: +// Max Korbel +// Desmond A Kirkpatrick Date: Mon, 9 Jun 2025 14:06:36 -0700 Subject: [PATCH 03/19] Add butterfly module Signed-off-by: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> --- .../bad_fft.dart} | 0 .../floating_point/fft/butterfly.dart | 31 +++++++++++++ .../complex_floating_point_logic.dart | 2 +- .../floating_point/butterfly_test.dart | 46 +++++++++++++++++++ ....dart => complex_floating_point_test.dart} | 8 ---- 5 files changed, 78 insertions(+), 9 deletions(-) rename lib/src/arithmetic/floating_point/{floating_point_fft.dart => fft/bad_fft.dart} (100%) create mode 100644 lib/src/arithmetic/floating_point/fft/butterfly.dart create mode 100644 test/arithmetic/floating_point/butterfly_test.dart rename test/arithmetic/floating_point/{copmlex_floating_point_test.dart => complex_floating_point_test.dart} (89%) diff --git a/lib/src/arithmetic/floating_point/floating_point_fft.dart b/lib/src/arithmetic/floating_point/fft/bad_fft.dart similarity index 100% rename from lib/src/arithmetic/floating_point/floating_point_fft.dart rename to lib/src/arithmetic/floating_point/fft/bad_fft.dart diff --git a/lib/src/arithmetic/floating_point/fft/butterfly.dart b/lib/src/arithmetic/floating_point/fft/butterfly.dart new file mode 100644 index 000000000..b9cadc199 --- /dev/null +++ b/lib/src/arithmetic/floating_point/fft/butterfly.dart @@ -0,0 +1,31 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: BSD-3-Clause + +import 'package:rohd/rohd.dart'; +import 'package:rohd_hcl/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart'; + +class Butterfly extends Module { + final ComplexFloatingPoint inA; + final ComplexFloatingPoint inB; + final ComplexFloatingPoint twiddleFactor; + + late final outA = inA.clone()..gets(output('outA')); + late final outB = inA.clone()..gets(output('outB')); + + Butterfly( + {required this.inA, + required this.inB, + required this.twiddleFactor, + super.name = 'butterfly'}) { + addInput('inA', inA, width: inA.width); + addInput('inB', inB, width: inA.width); + + final outA = addOutput('outA', width: inA.width); + final outB = addOutput('outB', width: inA.width); + + final temp = twiddleFactor.multiplier(inB); + + outB <= inA.adder(temp.negated); + outA <= inA.adder(temp); + } +} diff --git a/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart b/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart index 279d06ead..790e67c87 100644 --- a/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart +++ b/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart @@ -76,7 +76,7 @@ class ComplexFloatingPoint extends LogicStructure { name: _nameJoin(name, "multiplier")); } - ComplexFloatingPoint negated() => ComplexFloatingPoint._internal( + late final ComplexFloatingPoint negated = ComplexFloatingPoint._internal( realPart: realPart.negated(), imaginaryPart: imaginaryPart.negated(), name: _nameJoin(name, "negated")); diff --git a/test/arithmetic/floating_point/butterfly_test.dart b/test/arithmetic/floating_point/butterfly_test.dart new file mode 100644 index 000000000..d6c980467 --- /dev/null +++ b/test/arithmetic/floating_point/butterfly_test.dart @@ -0,0 +1,46 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: BSD-3-Clause + +import 'package:rohd/rohd.dart'; +import 'package:rohd_hcl/rohd_hcl.dart'; +import 'package:rohd_hcl/src/arithmetic/floating_point/fft/butterfly.dart'; +import 'package:rohd_hcl/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart'; +import 'package:test/test.dart'; + +ComplexFloatingPoint newComplex(double real, double imaginary) { + final realFP = FloatingPoint64(); + final imaginaryFP = FloatingPoint64(); + + final realFPValue = FloatingPoint64Value.populator().ofDouble(real); + final imaginaryFPValue = FloatingPoint64Value.populator().ofDouble(imaginary); + + realFP.put(realFPValue); + imaginaryFP.put(imaginaryFPValue); + + final complex = ComplexFloatingPoint( + exponentWidth: realFP.exponent.width, + mantissaWidth: realFP.mantissa.width); + complex.realPart <= realFP; + complex.imaginaryPart <= imaginaryFP; + + return complex; +} + +void main() { + tearDown(() async { + await Simulator.reset(); + }); + + test('butterfly unit test', () { + final a = newComplex(1.0, 2.0); + final b = newComplex(-3.0, -4.0); + final twiddle = newComplex(1.0, 0.0); + + final butterfly = Butterfly(inA: a, inB: b, twiddleFactor: twiddle); + + expect(butterfly.outA.realPart.floatingPointValue.toDouble(), -2.0); + expect(butterfly.outA.imaginaryPart.floatingPointValue.toDouble(), -2.0); + expect(butterfly.outB.realPart.floatingPointValue.toDouble(), 4.0); + expect(butterfly.outB.imaginaryPart.floatingPointValue.toDouble(), 6.0); + }); +} diff --git a/test/arithmetic/floating_point/copmlex_floating_point_test.dart b/test/arithmetic/floating_point/complex_floating_point_test.dart similarity index 89% rename from test/arithmetic/floating_point/copmlex_floating_point_test.dart rename to test/arithmetic/floating_point/complex_floating_point_test.dart index 69f23fbf4..d2fd85a80 100644 --- a/test/arithmetic/floating_point/copmlex_floating_point_test.dart +++ b/test/arithmetic/floating_point/complex_floating_point_test.dart @@ -1,13 +1,5 @@ // Copyright (C) 2025 Intel Corporation // SPDX-License-Identifier: BSD-3-Clause -// -// floating_point_test.dart -// Tests of Floating Point basic types -// -// 2024 April 1 -// Authors: -// Max Korbel -// Desmond A Kirkpatrick Date: Mon, 9 Jun 2025 16:49:27 -0700 Subject: [PATCH 04/19] WIP butterfly stage Signed-off-by: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> --- .../floating_point/fft/fft_stage.dart | 105 ++++++++++++++++++ .../complex_floating_point_logic.dart | 5 + 2 files changed, 110 insertions(+) create mode 100644 lib/src/arithmetic/floating_point/fft/fft_stage.dart diff --git a/lib/src/arithmetic/floating_point/fft/fft_stage.dart b/lib/src/arithmetic/floating_point/fft/fft_stage.dart new file mode 100644 index 000000000..fb3d1ecee --- /dev/null +++ b/lib/src/arithmetic/floating_point/fft/fft_stage.dart @@ -0,0 +1,105 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: BSD-3-Clause + +import 'package:rohd/rohd.dart'; +import 'package:rohd_hcl/rohd_hcl.dart'; +import 'package:rohd_hcl/src/arithmetic/floating_point/fft/butterfly.dart'; +import 'package:rohd_hcl/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart'; + +class BadFFTStage extends Module { + final int logStage; + final int exponentWidth; + final int mantissaWidth; + final Logic clk; + final Logic reset; + final Logic ready; + final DataPortInterface inputSamplesA; + final DataPortInterface inputSamplesB; + final DataPortInterface twiddleFactorROM; + + Logic get valid => output("valid"); + late final DataPortInterface outputSamples; + + BadFFTStage( + {required this.logStage, + required this.exponentWidth, + required this.mantissaWidth, + required this.clk, + required this.reset, + required this.ready, + required this.inputSamplesA, + required this.inputSamplesB, + required this.twiddleFactorROM, + super.name = 'badfftstage'}) + : assert(ready.width == 1) { + addInput('clk', clk); + addInput('reset', reset); + addInput('ready', ready); + + outputSamples = + DataPortInterface(inputSamplesA.dataWidth, inputSamplesA.addrWidth); + final outputSamplesWritePortA = + DataPortInterface(inputSamplesA.dataWidth, inputSamplesA.addrWidth); + final outputSamplesWritePortB = + DataPortInterface(inputSamplesA.dataWidth, inputSamplesA.addrWidth); + MemoryModel(clk, reset, [outputSamplesWritePortA, outputSamplesWritePortB], + [outputSamples], + readLatency: 0); + + // outputSamplesWritePort.connectIO(this, srcInterface) + + final n = 1 << inputSamplesA.addrWidth; + final log2Length = inputSamplesA.addrWidth; + final m = 1 << logStage; + final mShift = log2Ceil(m); + + final i = Counter.ofLogics([~this.valid], + clk: clk, + reset: reset, + restart: this.ready & this.valid, + width: log2Length - 1, + maxValue: n / 2); + valid <= i.equalsMax; + + final k = (i.count >> (mShift - 1)) << mShift; + final j = (i.count & Const((m >> 1) - 1, width: i.width)); + + // for k = 0 to n-1 by m do + // ω ← 1 + // for j = 0 to m/2 – 1 do + // t ← ω A[k + j + m/2] + // u ← A[k + j] + // A[k + j] ← u + t + // A[k + j + m/2] ← u – t + // ω ← ω ωm + Logic addressA = k + j; + Logic addressB = addressA + n / 2; + inputSamplesA.addr <= addressA; + inputSamplesA.en <= ~this.valid; + inputSamplesB.addr <= addressB; + inputSamplesB.en <= ~this.valid; + twiddleFactorROM.addr <= j; + twiddleFactorROM.en <= ~this.valid; + + final butterfly = Butterfly( + inA: ComplexFloatingPoint.of(inputSamplesA.data, + exponentWidth: exponentWidth, mantissaWidth: mantissaWidth), + inB: ComplexFloatingPoint.of(inputSamplesB.data, + exponentWidth: exponentWidth, mantissaWidth: mantissaWidth), + twiddleFactor: ComplexFloatingPoint.of(twiddleFactorROM.data, + exponentWidth: exponentWidth, mantissaWidth: mantissaWidth)); + + outputSamplesWritePortA.addr <= addressA; + outputSamplesWritePortA.en <= ~this.valid; + outputSamplesWritePortB.addr <= addressB; + outputSamplesWritePortB.en <= ~this.valid; + + Sequential( + clk, + [ + outputSamplesWritePortA.data < butterfly.outA, + outputSamplesWritePortB.data < butterfly.outB + ], + reset: reset); + } +} diff --git a/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart b/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart index 790e67c87..1a0045ea6 100644 --- a/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart +++ b/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart @@ -35,6 +35,11 @@ class ComplexFloatingPoint extends LogicStructure { name: name, ); + ComplexFloatingPoint.of(Logic input, + {required int exponentWidth, required int mantissaWidth, super.name}) { + this <= input; + } + ComplexFloatingPoint._internal( {required this.realPart, required this.imaginaryPart, super.name}) : assert(realPart.exponent.width == imaginaryPart.exponent.width), From e2463a1fa67bd9b65e80a77866326de3c1f9828a Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Tue, 17 Jun 2025 17:11:30 -0700 Subject: [PATCH 05/19] backup Signed-off-by: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> --- .../floating_point/fft/butterfly.dart | 4 +- .../floating_point/fft/fft_stage.dart | 77 ++++++++++------ .../complex_floating_point_logic.dart | 22 ++++- .../floating_point/bad_fft_stage_test.dart | 89 +++++++++++++++++++ 4 files changed, 157 insertions(+), 35 deletions(-) create mode 100644 test/arithmetic/floating_point/bad_fft_stage_test.dart diff --git a/lib/src/arithmetic/floating_point/fft/butterfly.dart b/lib/src/arithmetic/floating_point/fft/butterfly.dart index b9cadc199..a9bb72b90 100644 --- a/lib/src/arithmetic/floating_point/fft/butterfly.dart +++ b/lib/src/arithmetic/floating_point/fft/butterfly.dart @@ -9,8 +9,8 @@ class Butterfly extends Module { final ComplexFloatingPoint inB; final ComplexFloatingPoint twiddleFactor; - late final outA = inA.clone()..gets(output('outA')); - late final outB = inA.clone()..gets(output('outB')); + final outA; + final outB; Butterfly( {required this.inA, diff --git a/lib/src/arithmetic/floating_point/fft/fft_stage.dart b/lib/src/arithmetic/floating_point/fft/fft_stage.dart index fb3d1ecee..ad7872aa6 100644 --- a/lib/src/arithmetic/floating_point/fft/fft_stage.dart +++ b/lib/src/arithmetic/floating_point/fft/fft_stage.dart @@ -1,6 +1,8 @@ // Copyright (C) 2025 Intel Corporation // SPDX-License-Identifier: BSD-3-Clause +import 'dart:math'; + import 'package:rohd/rohd.dart'; import 'package:rohd_hcl/rohd_hcl.dart'; import 'package:rohd_hcl/src/arithmetic/floating_point/fft/butterfly.dart'; @@ -10,14 +12,14 @@ class BadFFTStage extends Module { final int logStage; final int exponentWidth; final int mantissaWidth; - final Logic clk; - final Logic reset; - final Logic ready; - final DataPortInterface inputSamplesA; - final DataPortInterface inputSamplesB; - final DataPortInterface twiddleFactorROM; - - Logic get valid => output("valid"); + Logic clk; + Logic reset; + Logic ready; + DataPortInterface inputSamplesA; + DataPortInterface inputSamplesB; + DataPortInterface twiddleFactorROM; + + late final Logic valid; late final DataPortInterface outputSamples; BadFFTStage( @@ -31,35 +33,52 @@ class BadFFTStage extends Module { required this.inputSamplesB, required this.twiddleFactorROM, super.name = 'badfftstage'}) - : assert(ready.width == 1) { - addInput('clk', clk); - addInput('reset', reset); - addInput('ready', ready); + : assert(ready.width == 1), + assert( + inputSamplesA.dataWidth == 2 * (1 + exponentWidth + mantissaWidth)), + assert(inputSamplesB.dataWidth == + 2 * (1 + exponentWidth + mantissaWidth)) { + clk = addInput('clk', clk); + reset = addInput('reset', reset); + ready = addInput('ready', ready); + final _valid = Logic(); + valid = addOutput('valid')..gets(_valid); + + inputSamplesA = inputSamplesA.clone()..connectIO(this, inputSamplesA); + inputSamplesB = inputSamplesB.clone()..connectIO(this, inputSamplesB); + twiddleFactorROM = twiddleFactorROM.clone() + ..connectIO(this, twiddleFactorROM); outputSamples = + DataPortInterface(inputSamplesA.dataWidth, inputSamplesA.addrWidth) + .clone(); + outputSamples.connectIO(this, outputSamples); + + final outputSamplesWritePortATemp = DataPortInterface(inputSamplesA.dataWidth, inputSamplesA.addrWidth); - final outputSamplesWritePortA = - DataPortInterface(inputSamplesA.dataWidth, inputSamplesA.addrWidth); - final outputSamplesWritePortB = + final outputSamplesWritePortBTemp = DataPortInterface(inputSamplesA.dataWidth, inputSamplesA.addrWidth); + + final outputSamplesWritePortA = outputSamplesWritePortATemp.clone(); + outputSamplesWritePortA.connectIO(this, outputSamplesWritePortATemp); + final outputSamplesWritePortB = outputSamplesWritePortBTemp.clone(); + outputSamplesWritePortB.connectIO(this, outputSamplesWritePortBTemp); + MemoryModel(clk, reset, [outputSamplesWritePortA, outputSamplesWritePortB], [outputSamples], readLatency: 0); - - // outputSamplesWritePort.connectIO(this, srcInterface) - final n = 1 << inputSamplesA.addrWidth; final log2Length = inputSamplesA.addrWidth; final m = 1 << logStage; final mShift = log2Ceil(m); - final i = Counter.ofLogics([~this.valid], + final i = Counter.ofLogics([~_valid], clk: clk, reset: reset, - restart: this.ready & this.valid, - width: log2Length - 1, - maxValue: n / 2); - valid <= i.equalsMax; + restart: this.ready & _valid, + width: max(log2Length - 1, 1), + maxValue: n ~/ 2 - 1); + _valid <= i.equalsMax; final k = (i.count >> (mShift - 1)) << mShift; final j = (i.count & Const((m >> 1) - 1, width: i.width)); @@ -73,13 +92,13 @@ class BadFFTStage extends Module { // A[k + j + m/2] ← u – t // ω ← ω ωm Logic addressA = k + j; - Logic addressB = addressA + n / 2; + Logic addressB = addressA + n ~/ 2; inputSamplesA.addr <= addressA; - inputSamplesA.en <= ~this.valid; + inputSamplesA.en <= ~_valid; inputSamplesB.addr <= addressB; - inputSamplesB.en <= ~this.valid; + inputSamplesB.en <= ~_valid; twiddleFactorROM.addr <= j; - twiddleFactorROM.en <= ~this.valid; + twiddleFactorROM.en <= ~_valid; final butterfly = Butterfly( inA: ComplexFloatingPoint.of(inputSamplesA.data, @@ -90,9 +109,9 @@ class BadFFTStage extends Module { exponentWidth: exponentWidth, mantissaWidth: mantissaWidth)); outputSamplesWritePortA.addr <= addressA; - outputSamplesWritePortA.en <= ~this.valid; + outputSamplesWritePortA.en <= ~_valid; outputSamplesWritePortB.addr <= addressB; - outputSamplesWritePortB.en <= ~this.valid; + outputSamplesWritePortB.en <= ~_valid; Sequential( clk, diff --git a/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart b/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart index 1a0045ea6..688e9d78c 100644 --- a/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart +++ b/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart @@ -35,10 +35,24 @@ class ComplexFloatingPoint extends LogicStructure { name: name, ); - ComplexFloatingPoint.of(Logic input, - {required int exponentWidth, required int mantissaWidth, super.name}) { - this <= input; - } + ComplexFloatingPoint.of( + Logic input, { + required int exponentWidth, + required int mantissaWidth, + String? name, + }) : this._internal( + realPart: FloatingPoint( + exponentWidth: exponentWidth, + mantissaWidth: mantissaWidth, + name: _nameJoin(name, 're'), + )..gets(input.getRange(0, 1 + exponentWidth + mantissaWidth)), + imaginaryPart: FloatingPoint( + exponentWidth: exponentWidth, + mantissaWidth: mantissaWidth, + name: _nameJoin(name, 'im'), + )..gets( + input.getRange(1 + exponentWidth + mantissaWidth, input.width)), + name: name); ComplexFloatingPoint._internal( {required this.realPart, required this.imaginaryPart, super.name}) diff --git a/test/arithmetic/floating_point/bad_fft_stage_test.dart b/test/arithmetic/floating_point/bad_fft_stage_test.dart new file mode 100644 index 000000000..e1cb1ab59 --- /dev/null +++ b/test/arithmetic/floating_point/bad_fft_stage_test.dart @@ -0,0 +1,89 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: BSD-3-Clause + +import 'dart:async'; + +import 'package:rohd/rohd.dart'; +import 'package:rohd_hcl/rohd_hcl.dart'; +import 'package:rohd_hcl/src/arithmetic/floating_point/fft/butterfly.dart'; +import 'package:rohd_hcl/src/arithmetic/floating_point/fft/fft_stage.dart'; +import 'package:rohd_hcl/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart'; +import 'package:rohd_vf/rohd_vf.dart'; +import 'package:test/test.dart'; + +ComplexFloatingPoint newComplex(double real, double imaginary) { + final realFP = FloatingPoint64(); + final imaginaryFP = FloatingPoint64(); + + final realFPValue = FloatingPoint64Value.populator().ofDouble(real); + final imaginaryFPValue = FloatingPoint64Value.populator().ofDouble(imaginary); + + realFP.put(realFPValue); + imaginaryFP.put(imaginaryFPValue); + + final complex = ComplexFloatingPoint( + exponentWidth: realFP.exponent.width, + mantissaWidth: realFP.mantissa.width); + complex.realPart <= realFP; + complex.imaginaryPart <= imaginaryFP; + + return complex; +} + +void main() { + tearDown(() async { + await Simulator.reset(); + }); + + test('fft stage unit test', () async { + final a = newComplex(1.0, 2.0); + final b = newComplex(-3.0, -4.0); + final twiddle = newComplex(1.0, 0.0); + final clk = SimpleClockGenerator(10).clk; + final reset = Logic()..put(0); + final ready = Logic()..put(0); + + final n = 2; + + final exponentWidth = a.realPart.exponent.width; + final mantissaWidth = a.realPart.mantissa.width; + final dataWidth = a.width; //2 * (1 + exponentWidth + mantissaWidth); + final addrWidth = log2Ceil(n); + + final tempMemoryWritePort = DataPortInterface(dataWidth, addrWidth); + final tempMemoryReadPortA = DataPortInterface(dataWidth, addrWidth); + final tempMemoryReadPortB = DataPortInterface(dataWidth, addrWidth); + final twiddleFactorROMWritePort = DataPortInterface(dataWidth, addrWidth); + final twiddleFactorROMReadPort = DataPortInterface(dataWidth, addrWidth); + + await MemoryModel( + clk, reset, [twiddleFactorROMWritePort], [twiddleFactorROMReadPort], + readLatency: 0) + .build(); + await MemoryModel(clk, reset, [tempMemoryWritePort], + [tempMemoryReadPortA, tempMemoryReadPortB], + readLatency: 0) + .build(); + + final stage = BadFFTStage( + logStage: 1, + exponentWidth: exponentWidth, + mantissaWidth: mantissaWidth, + clk: clk, + reset: reset, + ready: ready, + inputSamplesA: tempMemoryReadPortA, + inputSamplesB: tempMemoryReadPortB, + twiddleFactorROM: twiddleFactorROMReadPort); + + await stage.build(); + + Simulator.setMaxSimTime(10000); + unawaited(Simulator.run()); + + reset.inject(1); + await clk.waitCycles(10); + reset.inject(0); + await clk.waitCycles(10); + }); +} From 468abe44d73c81930364c67b8d5304fec8190b7b Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Fri, 27 Jun 2025 11:31:13 -0700 Subject: [PATCH 06/19] Fix butterfly test --- .../floating_point/fft/butterfly.dart | 34 +++--- .../floating_point/butterfly_test.dart | 104 ++++++++++++++++-- 2 files changed, 113 insertions(+), 25 deletions(-) diff --git a/lib/src/arithmetic/floating_point/fft/butterfly.dart b/lib/src/arithmetic/floating_point/fft/butterfly.dart index a9bb72b90..7a039d558 100644 --- a/lib/src/arithmetic/floating_point/fft/butterfly.dart +++ b/lib/src/arithmetic/floating_point/fft/butterfly.dart @@ -5,27 +5,31 @@ import 'package:rohd/rohd.dart'; import 'package:rohd_hcl/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart'; class Butterfly extends Module { - final ComplexFloatingPoint inA; - final ComplexFloatingPoint inB; - final ComplexFloatingPoint twiddleFactor; + late final ComplexFloatingPoint _inA; + late final ComplexFloatingPoint _inB; + late final ComplexFloatingPoint _twiddleFactor; - final outA; - final outB; + late final ComplexFloatingPoint outA; + late final ComplexFloatingPoint outB; Butterfly( - {required this.inA, - required this.inB, - required this.twiddleFactor, + {required ComplexFloatingPoint inA, + required ComplexFloatingPoint inB, + required ComplexFloatingPoint twiddleFactor, super.name = 'butterfly'}) { - addInput('inA', inA, width: inA.width); - addInput('inB', inB, width: inA.width); + _inA = inA.clone()..gets(addInput('inA', inA, width: inA.width)); + _inB = inA.clone()..gets(addInput('inB', inB, width: inA.width)); + _twiddleFactor = inA.clone()..gets(addInput('twiddleFactor', twiddleFactor, width: twiddleFactor.width)); - final outA = addOutput('outA', width: inA.width); - final outB = addOutput('outB', width: inA.width); + final outALogic = addOutput('outA', width: inA.width); + final outBLogic = addOutput('outB', width: inA.width); - final temp = twiddleFactor.multiplier(inB); + final temp = twiddleFactor.multiplier(_inB); - outB <= inA.adder(temp.negated); - outA <= inA.adder(temp); + outALogic <= _inA.adder(temp.negated); + outBLogic <= _inA.adder(temp); + + outA = inA.clone()..gets(outALogic); + outB = inA.clone()..gets(outBLogic); } } diff --git a/test/arithmetic/floating_point/butterfly_test.dart b/test/arithmetic/floating_point/butterfly_test.dart index d6c980467..56065c467 100644 --- a/test/arithmetic/floating_point/butterfly_test.dart +++ b/test/arithmetic/floating_point/butterfly_test.dart @@ -1,6 +1,8 @@ // Copyright (C) 2025 Intel Corporation // SPDX-License-Identifier: BSD-3-Clause +import 'dart:math'; + import 'package:rohd/rohd.dart'; import 'package:rohd_hcl/rohd_hcl.dart'; import 'package:rohd_hcl/src/arithmetic/floating_point/fft/butterfly.dart'; @@ -18,29 +20,111 @@ ComplexFloatingPoint newComplex(double real, double imaginary) { imaginaryFP.put(imaginaryFPValue); final complex = ComplexFloatingPoint( - exponentWidth: realFP.exponent.width, - mantissaWidth: realFP.mantissa.width); + exponentWidth: realFP.exponent.width, + mantissaWidth: realFP.mantissa.width, + ); complex.realPart <= realFP; complex.imaginaryPart <= imaginaryFP; return complex; } +class Complex { + double real; + double imaginary; + + Complex({required this.real, required this.imaginary}); + + Complex add(Complex other) { + return Complex( + real: this.real + other.real, + imaginary: this.imaginary + other.imaginary, + ); + } + + Complex subtract(Complex other) { + return Complex( + real: this.real - other.real, + imaginary: this.imaginary - other.imaginary, + ); + } + + Complex multiply(Complex other) { + return Complex( + real: (this.real * other.real) - (this.imaginary * other.imaginary), + imaginary: (this.real * other.imaginary) + (this.imaginary * other.real), + ); + } + + @override + String toString() { + return '${real}${imaginary >= 0 ? '+' : ''}${imaginary}i'; + } +} + +List butterfly(Complex inA, Complex inB, Complex twiddleFactor) { + final temp = twiddleFactor.multiply(inB); + return [inA.subtract(temp), inA.add(temp)]; +} + +final epsilon = 1e-15; + +void compareDouble(double actual, double expected) { + assert( + (actual - expected).abs() < epsilon, + "actual ${actual}, expected ${expected}", + ); +} + void main() { tearDown(() async { await Simulator.reset(); }); test('butterfly unit test', () { - final a = newComplex(1.0, 2.0); - final b = newComplex(-3.0, -4.0); - final twiddle = newComplex(1.0, 0.0); + final random = Random(); + for (var i = 0; i < 5; i++) { + final a = Complex( + real: random.nextDouble(), + imaginary: random.nextDouble(), + ); + final b = Complex( + real: random.nextDouble(), + imaginary: random.nextDouble(), + ); + final twiddle = Complex( + real: random.nextDouble(), + imaginary: random.nextDouble(), + ); + + final aLogic = newComplex(a.real, a.imaginary); + final bLogic = newComplex(b.real, b.imaginary); + final twiddleLogic = newComplex(twiddle.real, twiddle.imaginary); + + final expected = butterfly(a, b, twiddle); - final butterfly = Butterfly(inA: a, inB: b, twiddleFactor: twiddle); + final butterflyModule = Butterfly( + inA: aLogic, + inB: bLogic, + twiddleFactor: twiddleLogic, + ); - expect(butterfly.outA.realPart.floatingPointValue.toDouble(), -2.0); - expect(butterfly.outA.imaginaryPart.floatingPointValue.toDouble(), -2.0); - expect(butterfly.outB.realPart.floatingPointValue.toDouble(), 4.0); - expect(butterfly.outB.imaginaryPart.floatingPointValue.toDouble(), 6.0); + compareDouble( + butterflyModule.outA.realPart.floatingPointValue.toDouble(), + expected[0].real, + ); + compareDouble( + butterflyModule.outA.imaginaryPart.floatingPointValue.toDouble(), + expected[0].imaginary, + ); + compareDouble( + butterflyModule.outB.realPart.floatingPointValue.toDouble(), + expected[1].real, + ); + compareDouble( + butterflyModule.outB.imaginaryPart.floatingPointValue.toDouble(), + expected[1].imaginary, + ); + } }); } From 51e4e7ccf081360fdae7a7211e057120bfc37bcd Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Tue, 8 Jul 2025 21:48:19 -0700 Subject: [PATCH 07/19] Fix typo in butterfly and add tags to connectIO --- .../floating_point/fft/butterfly.dart | 26 ++-- .../floating_point/fft/fft_stage.dart | 140 +++++++++++------- test.txt | 49 ++++++ .../floating_point/bad_fft_stage_test.dart | 46 +++--- 4 files changed, 179 insertions(+), 82 deletions(-) create mode 100644 test.txt diff --git a/lib/src/arithmetic/floating_point/fft/butterfly.dart b/lib/src/arithmetic/floating_point/fft/butterfly.dart index 7a039d558..39c5f106c 100644 --- a/lib/src/arithmetic/floating_point/fft/butterfly.dart +++ b/lib/src/arithmetic/floating_point/fft/butterfly.dart @@ -5,26 +5,26 @@ import 'package:rohd/rohd.dart'; import 'package:rohd_hcl/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart'; class Butterfly extends Module { - late final ComplexFloatingPoint _inA; - late final ComplexFloatingPoint _inB; - late final ComplexFloatingPoint _twiddleFactor; - late final ComplexFloatingPoint outA; late final ComplexFloatingPoint outB; - Butterfly( - {required ComplexFloatingPoint inA, - required ComplexFloatingPoint inB, - required ComplexFloatingPoint twiddleFactor, - super.name = 'butterfly'}) { - _inA = inA.clone()..gets(addInput('inA', inA, width: inA.width)); - _inB = inA.clone()..gets(addInput('inB', inB, width: inA.width)); - _twiddleFactor = inA.clone()..gets(addInput('twiddleFactor', twiddleFactor, width: twiddleFactor.width)); + Butterfly({ + required ComplexFloatingPoint inA, + required ComplexFloatingPoint inB, + required ComplexFloatingPoint twiddleFactor, + super.name = 'butterfly', + }) { + final _inA = inA.clone()..gets(addInput('inA', inA, width: inA.width)); + final _inB = inA.clone()..gets(addInput('inB', inB, width: inA.width)); + final _twiddleFactor = inA.clone() + ..gets( + addInput('twiddleFactor', twiddleFactor, width: twiddleFactor.width), + ); final outALogic = addOutput('outA', width: inA.width); final outBLogic = addOutput('outB', width: inA.width); - final temp = twiddleFactor.multiplier(_inB); + final temp = _twiddleFactor.multiplier(_inB); outALogic <= _inA.adder(temp.negated); outBLogic <= _inA.adder(temp); diff --git a/lib/src/arithmetic/floating_point/fft/fft_stage.dart b/lib/src/arithmetic/floating_point/fft/fft_stage.dart index ad7872aa6..5a0dcc3f6 100644 --- a/lib/src/arithmetic/floating_point/fft/fft_stage.dart +++ b/lib/src/arithmetic/floating_point/fft/fft_stage.dart @@ -22,62 +22,93 @@ class BadFFTStage extends Module { late final Logic valid; late final DataPortInterface outputSamples; - BadFFTStage( - {required this.logStage, - required this.exponentWidth, - required this.mantissaWidth, - required this.clk, - required this.reset, - required this.ready, - required this.inputSamplesA, - required this.inputSamplesB, - required this.twiddleFactorROM, - super.name = 'badfftstage'}) - : assert(ready.width == 1), - assert( - inputSamplesA.dataWidth == 2 * (1 + exponentWidth + mantissaWidth)), - assert(inputSamplesB.dataWidth == - 2 * (1 + exponentWidth + mantissaWidth)) { + BadFFTStage({ + required this.logStage, + required this.exponentWidth, + required this.mantissaWidth, + required this.clk, + required this.reset, + required this.ready, + required this.inputSamplesA, + required this.inputSamplesB, + required this.twiddleFactorROM, + super.name = 'badfftstage', + }) : assert(ready.width == 1), + assert( + inputSamplesA.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), + ), + assert( + inputSamplesB.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), + ) { clk = addInput('clk', clk); reset = addInput('reset', reset); ready = addInput('ready', ready); final _valid = Logic(); valid = addOutput('valid')..gets(_valid); - inputSamplesA = inputSamplesA.clone()..connectIO(this, inputSamplesA); - inputSamplesB = inputSamplesB.clone()..connectIO(this, inputSamplesB); + inputSamplesA = inputSamplesA.clone() + ..connectIO( + this, + inputSamplesA, + inputTags: [DataPortGroup.data, DataPortGroup.control], + ); + inputSamplesB = inputSamplesB.clone() + ..connectIO( + this, + inputSamplesB, + inputTags: [DataPortGroup.data, DataPortGroup.control], + ); twiddleFactorROM = twiddleFactorROM.clone() - ..connectIO(this, twiddleFactorROM); - - outputSamples = - DataPortInterface(inputSamplesA.dataWidth, inputSamplesA.addrWidth) - .clone(); - outputSamples.connectIO(this, outputSamples); - - final outputSamplesWritePortATemp = - DataPortInterface(inputSamplesA.dataWidth, inputSamplesA.addrWidth); - final outputSamplesWritePortBTemp = - DataPortInterface(inputSamplesA.dataWidth, inputSamplesA.addrWidth); + ..connectIO( + this, + twiddleFactorROM, + inputTags: [DataPortGroup.data, DataPortGroup.control], + ); + + outputSamples = DataPortInterface( + inputSamplesA.dataWidth, + inputSamplesA.addrWidth, + ).clone(); + outputSamples.connectIO( + this, + outputSamples, + outputTags: [DataPortGroup.data, DataPortGroup.control], + ); + + final outputSamplesWritePortATemp = DataPortInterface( + inputSamplesA.dataWidth, + inputSamplesA.addrWidth, + ); + final outputSamplesWritePortBTemp = DataPortInterface( + inputSamplesA.dataWidth, + inputSamplesA.addrWidth, + ); final outputSamplesWritePortA = outputSamplesWritePortATemp.clone(); outputSamplesWritePortA.connectIO(this, outputSamplesWritePortATemp); final outputSamplesWritePortB = outputSamplesWritePortBTemp.clone(); outputSamplesWritePortB.connectIO(this, outputSamplesWritePortBTemp); - MemoryModel(clk, reset, [outputSamplesWritePortA, outputSamplesWritePortB], - [outputSamples], - readLatency: 0); + MemoryModel( + clk, + reset, + [outputSamplesWritePortA, outputSamplesWritePortB], + [outputSamples], + readLatency: 0, + ); final n = 1 << inputSamplesA.addrWidth; final log2Length = inputSamplesA.addrWidth; final m = 1 << logStage; final mShift = log2Ceil(m); - final i = Counter.ofLogics([~_valid], - clk: clk, - reset: reset, - restart: this.ready & _valid, - width: max(log2Length - 1, 1), - maxValue: n ~/ 2 - 1); + final i = Counter.ofLogics( + [~_valid], + clk: clk, + reset: reset, + restart: this.ready & _valid, + width: max(log2Length - 1, 1), + maxValue: n ~/ 2 - 1, + ); _valid <= i.equalsMax; final k = (i.count >> (mShift - 1)) << mShift; @@ -101,24 +132,31 @@ class BadFFTStage extends Module { twiddleFactorROM.en <= ~_valid; final butterfly = Butterfly( - inA: ComplexFloatingPoint.of(inputSamplesA.data, - exponentWidth: exponentWidth, mantissaWidth: mantissaWidth), - inB: ComplexFloatingPoint.of(inputSamplesB.data, - exponentWidth: exponentWidth, mantissaWidth: mantissaWidth), - twiddleFactor: ComplexFloatingPoint.of(twiddleFactorROM.data, - exponentWidth: exponentWidth, mantissaWidth: mantissaWidth)); + inA2: ComplexFloatingPoint.of( + inputSamplesA.data, + exponentWidth: exponentWidth, + mantissaWidth: mantissaWidth, + ), + inB: ComplexFloatingPoint.of( + inputSamplesB.data, + exponentWidth: exponentWidth, + mantissaWidth: mantissaWidth, + ), + twiddleFactor: ComplexFloatingPoint.of( + twiddleFactorROM.data, + exponentWidth: exponentWidth, + mantissaWidth: mantissaWidth, + ), + ); outputSamplesWritePortA.addr <= addressA; outputSamplesWritePortA.en <= ~_valid; outputSamplesWritePortB.addr <= addressB; outputSamplesWritePortB.en <= ~_valid; - Sequential( - clk, - [ - outputSamplesWritePortA.data < butterfly.outA, - outputSamplesWritePortB.data < butterfly.outB - ], - reset: reset); + Sequential(clk, [ + outputSamplesWritePortA.data < butterfly.outA, + outputSamplesWritePortB.data < butterfly.outB, + ], reset: reset); } } diff --git a/test.txt b/test.txt new file mode 100644 index 000000000..9660ad8b9 --- /dev/null +++ b/test.txt @@ -0,0 +1,49 @@ +CubulonSpec { + ComponentASpec, + ComponentBSpec { + [ComponentCSpec], [ComponentDSpec { + [ComponentESpec] + }] + } +} + +[ + [ALU, f.f..], + [a, b, ], + [f], + [ff, a] +] +[ + [ALU.new, FPU.new] +] + +Executor (InputStuff) + + +CubulonSpec(componentASpec: ComponetASpec(() => MyComponentA()), componentBSpec: ComponentBSpec(componentCs: [ +ComponentCSpec +])) + + +ALU extends Executor + +(inputStuff, outputStuff) { + ALU().connectInputStuff(inputStuff).connectOutputStuff(outputStuff) +} + + +class SchedulerID { + final int _index +} + +let config = + +let schedulerA = config.newSchedulerConfig(MyScheduler.new); +let schedulerB = config.newSchedulerConfig(MyOtherScheduler.new); +let schedulerC = config.newSchedulerConfig(MyThirdScheduler.new); +let schedulerC = config.newSchedulerConfig(); + + +let esources = config.resourcesConfig([ + (foo, schedulerA) +]) diff --git a/test/arithmetic/floating_point/bad_fft_stage_test.dart b/test/arithmetic/floating_point/bad_fft_stage_test.dart index e1cb1ab59..6659c70eb 100644 --- a/test/arithmetic/floating_point/bad_fft_stage_test.dart +++ b/test/arithmetic/floating_point/bad_fft_stage_test.dart @@ -22,8 +22,9 @@ ComplexFloatingPoint newComplex(double real, double imaginary) { imaginaryFP.put(imaginaryFPValue); final complex = ComplexFloatingPoint( - exponentWidth: realFP.exponent.width, - mantissaWidth: realFP.mantissa.width); + exponentWidth: realFP.exponent.width, + mantissaWidth: realFP.mantissa.width, + ); complex.realPart <= realFP; complex.imaginaryPart <= imaginaryFP; @@ -57,24 +58,31 @@ void main() { final twiddleFactorROMReadPort = DataPortInterface(dataWidth, addrWidth); await MemoryModel( - clk, reset, [twiddleFactorROMWritePort], [twiddleFactorROMReadPort], - readLatency: 0) - .build(); - await MemoryModel(clk, reset, [tempMemoryWritePort], - [tempMemoryReadPortA, tempMemoryReadPortB], - readLatency: 0) - .build(); + clk, + reset, + [twiddleFactorROMWritePort], + [twiddleFactorROMReadPort], + readLatency: 0, + ).build(); + await MemoryModel( + clk, + reset, + [tempMemoryWritePort], + [tempMemoryReadPortA, tempMemoryReadPortB], + readLatency: 0, + ).build(); final stage = BadFFTStage( - logStage: 1, - exponentWidth: exponentWidth, - mantissaWidth: mantissaWidth, - clk: clk, - reset: reset, - ready: ready, - inputSamplesA: tempMemoryReadPortA, - inputSamplesB: tempMemoryReadPortB, - twiddleFactorROM: twiddleFactorROMReadPort); + logStage: 1, + exponentWidth: exponentWidth, + mantissaWidth: mantissaWidth, + clk: clk, + reset: reset, + ready: ready, + inputSamplesA: tempMemoryReadPortA, + inputSamplesB: tempMemoryReadPortB, + twiddleFactorROM: twiddleFactorROMReadPort, + ); await stage.build(); @@ -85,5 +93,7 @@ void main() { await clk.waitCycles(10); reset.inject(0); await clk.waitCycles(10); + + await Simulator.endSimulation(); }); } From f2ee651a53239adf660670266626452d79774edb Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Tue, 8 Jul 2025 21:56:12 -0700 Subject: [PATCH 08/19] Confused? --- .../floating_point/fft/fft_stage.dart | 20 ++++++++++++++++--- .../floating_point/bad_fft_stage_test.dart | 10 ++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/lib/src/arithmetic/floating_point/fft/fft_stage.dart b/lib/src/arithmetic/floating_point/fft/fft_stage.dart index 5a0dcc3f6..ee15aa9e5 100644 --- a/lib/src/arithmetic/floating_point/fft/fft_stage.dart +++ b/lib/src/arithmetic/floating_point/fft/fft_stage.dart @@ -51,18 +51,21 @@ class BadFFTStage extends Module { this, inputSamplesA, inputTags: [DataPortGroup.data, DataPortGroup.control], + uniquify: (name) => "inputSamplesA${name}", ); inputSamplesB = inputSamplesB.clone() ..connectIO( this, inputSamplesB, inputTags: [DataPortGroup.data, DataPortGroup.control], + uniquify: (name) => "inputSamplesB${name}", ); twiddleFactorROM = twiddleFactorROM.clone() ..connectIO( this, twiddleFactorROM, inputTags: [DataPortGroup.data, DataPortGroup.control], + uniquify: (name) => "twiddleFactorROM${name}", ); outputSamples = DataPortInterface( @@ -73,6 +76,7 @@ class BadFFTStage extends Module { this, outputSamples, outputTags: [DataPortGroup.data, DataPortGroup.control], + uniquify: (name) => "outputSamples${name}", ); final outputSamplesWritePortATemp = DataPortInterface( @@ -85,9 +89,19 @@ class BadFFTStage extends Module { ); final outputSamplesWritePortA = outputSamplesWritePortATemp.clone(); - outputSamplesWritePortA.connectIO(this, outputSamplesWritePortATemp); + outputSamplesWritePortA.connectIO( + this, + outputSamplesWritePortATemp, + inputTags: [DataPortGroup.data, DataPortGroup.control], + uniquify: (name) => "outputSamplesWritePortA${name}", + ); final outputSamplesWritePortB = outputSamplesWritePortBTemp.clone(); - outputSamplesWritePortB.connectIO(this, outputSamplesWritePortBTemp); + outputSamplesWritePortB.connectIO( + this, + outputSamplesWritePortBTemp, + inputTags: [DataPortGroup.data, DataPortGroup.control], + uniquify: (name) => "outputSamplesWritePortB${name}", + ); MemoryModel( clk, @@ -132,7 +146,7 @@ class BadFFTStage extends Module { twiddleFactorROM.en <= ~_valid; final butterfly = Butterfly( - inA2: ComplexFloatingPoint.of( + inA: ComplexFloatingPoint.of( inputSamplesA.data, exponentWidth: exponentWidth, mantissaWidth: mantissaWidth, diff --git a/test/arithmetic/floating_point/bad_fft_stage_test.dart b/test/arithmetic/floating_point/bad_fft_stage_test.dart index 6659c70eb..e38c64ea2 100644 --- a/test/arithmetic/floating_point/bad_fft_stage_test.dart +++ b/test/arithmetic/floating_point/bad_fft_stage_test.dart @@ -57,20 +57,20 @@ void main() { final twiddleFactorROMWritePort = DataPortInterface(dataWidth, addrWidth); final twiddleFactorROMReadPort = DataPortInterface(dataWidth, addrWidth); - await MemoryModel( + MemoryModel( clk, reset, [twiddleFactorROMWritePort], [twiddleFactorROMReadPort], readLatency: 0, - ).build(); - await MemoryModel( + ); + MemoryModel( clk, reset, [tempMemoryWritePort], [tempMemoryReadPortA, tempMemoryReadPortB], readLatency: 0, - ).build(); + ); final stage = BadFFTStage( logStage: 1, @@ -86,6 +86,8 @@ void main() { await stage.build(); + print(stage.generateSynth()); + Simulator.setMaxSimTime(10000); unawaited(Simulator.run()); From 7712bf85ef3aca51115060901852bc4e873ba08e Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Thu, 17 Jul 2025 13:06:48 -0700 Subject: [PATCH 09/19] Remove extraneous file --- test.txt | 49 ------------------------------------------------- 1 file changed, 49 deletions(-) delete mode 100644 test.txt diff --git a/test.txt b/test.txt deleted file mode 100644 index 9660ad8b9..000000000 --- a/test.txt +++ /dev/null @@ -1,49 +0,0 @@ -CubulonSpec { - ComponentASpec, - ComponentBSpec { - [ComponentCSpec], [ComponentDSpec { - [ComponentESpec] - }] - } -} - -[ - [ALU, f.f..], - [a, b, ], - [f], - [ff, a] -] -[ - [ALU.new, FPU.new] -] - -Executor (InputStuff) - - -CubulonSpec(componentASpec: ComponetASpec(() => MyComponentA()), componentBSpec: ComponentBSpec(componentCs: [ -ComponentCSpec -])) - - -ALU extends Executor - -(inputStuff, outputStuff) { - ALU().connectInputStuff(inputStuff).connectOutputStuff(outputStuff) -} - - -class SchedulerID { - final int _index -} - -let config = - -let schedulerA = config.newSchedulerConfig(MyScheduler.new); -let schedulerB = config.newSchedulerConfig(MyOtherScheduler.new); -let schedulerC = config.newSchedulerConfig(MyThirdScheduler.new); -let schedulerC = config.newSchedulerConfig(); - - -let esources = config.resourcesConfig([ - (foo, schedulerA) -]) From 0b8c3bf91790c19c083520bfcecd4658c16b69d3 Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Thu, 17 Jul 2025 14:02:55 -0700 Subject: [PATCH 10/19] For good measure --- test/arithmetic/floating_point/bad_fft_stage_test.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/arithmetic/floating_point/bad_fft_stage_test.dart b/test/arithmetic/floating_point/bad_fft_stage_test.dart index e38c64ea2..78eb92cd0 100644 --- a/test/arithmetic/floating_point/bad_fft_stage_test.dart +++ b/test/arithmetic/floating_point/bad_fft_stage_test.dart @@ -96,6 +96,8 @@ void main() { reset.inject(0); await clk.waitCycles(10); + assert(false); + await Simulator.endSimulation(); }); } From 7481def0c31f92de4eda48135e5e4d5a728e61f9 Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Tue, 22 Jul 2025 15:28:41 -0700 Subject: [PATCH 11/19] backup --- .../arithmetic/floating_point/fft/fft_stage.dart | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/src/arithmetic/floating_point/fft/fft_stage.dart b/lib/src/arithmetic/floating_point/fft/fft_stage.dart index ee15aa9e5..e219d50cb 100644 --- a/lib/src/arithmetic/floating_point/fft/fft_stage.dart +++ b/lib/src/arithmetic/floating_point/fft/fft_stage.dart @@ -20,7 +20,6 @@ class BadFFTStage extends Module { DataPortInterface twiddleFactorROM; late final Logic valid; - late final DataPortInterface outputSamples; BadFFTStage({ required this.logStage, @@ -32,6 +31,8 @@ class BadFFTStage extends Module { required this.inputSamplesA, required this.inputSamplesB, required this.twiddleFactorROM, + required DataPortInterface outputSamplesA, + required DataPortInterface outputSamplesB, super.name = 'badfftstage', }) : assert(ready.width == 1), assert( @@ -68,13 +69,9 @@ class BadFFTStage extends Module { uniquify: (name) => "twiddleFactorROM${name}", ); - outputSamples = DataPortInterface( - inputSamplesA.dataWidth, - inputSamplesA.addrWidth, - ).clone(); - outputSamples.connectIO( + outputSamples = outputSamplesA.clone()..connectIO( this, - outputSamples, + outputSamplesA, outputTags: [DataPortGroup.data, DataPortGroup.control], uniquify: (name) => "outputSamples${name}", ); @@ -107,7 +104,7 @@ class BadFFTStage extends Module { clk, reset, [outputSamplesWritePortA, outputSamplesWritePortB], - [outputSamples], + [outputSamplesA], readLatency: 0, ); final n = 1 << inputSamplesA.addrWidth; From 823c57b16dcf7946f8733496c5f07681337a42fa Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Wed, 23 Jul 2025 15:17:02 -0700 Subject: [PATCH 12/19] Fix weird error Signed-off-by: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> --- .../floating_point/fft/bad_fft.dart | 71 ----------------- .../floating_point/fft/fft_stage.dart | 79 +++++++++++-------- .../floating_point/bad_fft_stage_test.dart | 4 + 3 files changed, 50 insertions(+), 104 deletions(-) delete mode 100644 lib/src/arithmetic/floating_point/fft/bad_fft.dart diff --git a/lib/src/arithmetic/floating_point/fft/bad_fft.dart b/lib/src/arithmetic/floating_point/fft/bad_fft.dart deleted file mode 100644 index 71b2ba298..000000000 --- a/lib/src/arithmetic/floating_point/fft/bad_fft.dart +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (C) 2025 Intel Corporation -// SPDX-License-Identifier: BSD-3-Clause - -import 'package:rohd/rohd.dart'; - -// class FFT extends Module { -// LogicArray get out => output('out') as LogicArray; -// -// FFT(Logic en, Logic clk, Logic reset, LogicArray input, {super.name = 'fft'}) -// : assert(input.dimensions.length == 1) { -// final int length = input.dimensions[0]; -// if ((length & (~(length - 1))) != length) { -// assert(false); -// } -// final int log2Length = log2Ceil(length); -// -// input = addInputArray( -// 'input_array', -// input, -// dimensions: input.dimensions, // it seems like these are needed -// elementWidth: input.elementWidth, -// numUnpackedDimensions: input.numUnpackedDimensions, -// ); -// -// List stageArrays = List.generate( -// log2Length + 1, -// (stage) => LogicArray( -// input.dimensions, -// input.elementWidth, -// name: 'stage${stage}Array', -// numUnpackedDimensions: input.numUnpackedDimensions, -// ), -// ); -// -// LogicArray out = addOutputArray( -// 'out', -// dimensions: input.dimensions, -// elementWidth: input.elementWidth, -// numUnpackedDimensions: input.numUnpackedDimensions, -// ); -// out <= stageArrays[log2Length]; -// -// List Function(PipelineStageInfo)> fftStages = []; -// -// fftStages.add((p) => [stageArrays[0] < BitReverse(input).out]); -// -// for (var s = 1; s <= log2Length; s++) { -// final m = 1 << s; -// final mShift = log2Ceil(m); -// -// Counter i = Counter(en, reset, clk, width: log2Length - 1); -// -// Logic k = (i.val >> (mShift - 1)) << mShift; -// Logic j = (i.val & Const((m >> 1) - 1, width: i.width)); -// } -// -// // ReadyValidPipeline() -// -// // for s = 1 to log(n) do -// // m ← 2s -// // ωm ← exp(−2πi/m) -// // for k = 0 to n-1 by m do -// // ω ← 1 -// // for j = 0 to m/2 – 1 do -// // t ← ω A[k + j + m/2] -// // u ← A[k + j] -// // A[k + j] ← u + t -// // A[k + j + m/2] ← u – t -// // ω ← ω ωm -// } -// } diff --git a/lib/src/arithmetic/floating_point/fft/fft_stage.dart b/lib/src/arithmetic/floating_point/fft/fft_stage.dart index e219d50cb..8482fcdc5 100644 --- a/lib/src/arithmetic/floating_point/fft/fft_stage.dart +++ b/lib/src/arithmetic/floating_point/fft/fft_stage.dart @@ -44,70 +44,83 @@ class BadFFTStage extends Module { clk = addInput('clk', clk); reset = addInput('reset', reset); ready = addInput('ready', ready); - final _valid = Logic(); + final _valid = Logic(name: "_valid"); valid = addOutput('valid')..gets(_valid); inputSamplesA = inputSamplesA.clone() ..connectIO( this, inputSamplesA, - inputTags: [DataPortGroup.data, DataPortGroup.control], + inputTags: [DataPortGroup.data], + outputTags: [DataPortGroup.control], uniquify: (name) => "inputSamplesA${name}", ); inputSamplesB = inputSamplesB.clone() ..connectIO( this, inputSamplesB, - inputTags: [DataPortGroup.data, DataPortGroup.control], + inputTags: [DataPortGroup.data], + outputTags: [DataPortGroup.control], uniquify: (name) => "inputSamplesB${name}", ); twiddleFactorROM = twiddleFactorROM.clone() ..connectIO( this, twiddleFactorROM, - inputTags: [DataPortGroup.data, DataPortGroup.control], + inputTags: [DataPortGroup.data], + outputTags: [DataPortGroup.control], uniquify: (name) => "twiddleFactorROM${name}", ); - outputSamples = outputSamplesA.clone()..connectIO( - this, - outputSamplesA, - outputTags: [DataPortGroup.data, DataPortGroup.control], - uniquify: (name) => "outputSamples${name}", - ); + outputSamplesA = outputSamplesA.clone() + ..connectIO( + this, + outputSamplesA, + inputTags: [DataPortGroup.control], + outputTags: [DataPortGroup.data], + uniquify: (name) => "outputSamplesA${name}", + ); + outputSamplesB = outputSamplesB.clone() + ..connectIO( + this, + outputSamplesB, + inputTags: [DataPortGroup.control], + outputTags: [DataPortGroup.data], + uniquify: (name) => "outputSamplesB${name}", + ); - final outputSamplesWritePortATemp = DataPortInterface( + final outputSamplesWritePortA = DataPortInterface( inputSamplesA.dataWidth, inputSamplesA.addrWidth, ); - final outputSamplesWritePortBTemp = DataPortInterface( + final outputSamplesWritePortB = DataPortInterface( inputSamplesA.dataWidth, inputSamplesA.addrWidth, ); - - final outputSamplesWritePortA = outputSamplesWritePortATemp.clone(); - outputSamplesWritePortA.connectIO( - this, - outputSamplesWritePortATemp, - inputTags: [DataPortGroup.data, DataPortGroup.control], - uniquify: (name) => "outputSamplesWritePortA${name}", + final outputSamplesReadPortA = DataPortInterface( + inputSamplesA.dataWidth, + inputSamplesA.addrWidth, ); - final outputSamplesWritePortB = outputSamplesWritePortBTemp.clone(); - outputSamplesWritePortB.connectIO( - this, - outputSamplesWritePortBTemp, - inputTags: [DataPortGroup.data, DataPortGroup.control], - uniquify: (name) => "outputSamplesWritePortB${name}", + final outputSamplesReadPortB = DataPortInterface( + inputSamplesA.dataWidth, + inputSamplesA.addrWidth, ); - MemoryModel( + final n = 1 << inputSamplesA.addrWidth; + RegisterFile( clk, reset, [outputSamplesWritePortA, outputSamplesWritePortB], - [outputSamplesA], - readLatency: 0, + [outputSamplesReadPortA, outputSamplesReadPortB], + numEntries: n, ); - final n = 1 << inputSamplesA.addrWidth; + outputSamplesA.data <= outputSamplesReadPortA.data; + outputSamplesReadPortA.en <= outputSamplesA.en; + outputSamplesReadPortA.addr <= outputSamplesA.addr; + outputSamplesB.data <= outputSamplesReadPortB.data; + outputSamplesReadPortB.en <= outputSamplesB.en; + outputSamplesReadPortB.addr <= outputSamplesB.addr; + final log2Length = inputSamplesA.addrWidth; final m = 1 << logStage; final mShift = log2Ceil(m); @@ -133,8 +146,8 @@ class BadFFTStage extends Module { // A[k + j] ← u + t // A[k + j + m/2] ← u – t // ω ← ω ωm - Logic addressA = k + j; - Logic addressB = addressA + n ~/ 2; + Logic addressA = (k + j).named("addressA"); + Logic addressB = (addressA + n ~/ 2).named("addressB"); inputSamplesA.addr <= addressA; inputSamplesA.en <= ~_valid; inputSamplesB.addr <= addressB; @@ -166,8 +179,8 @@ class BadFFTStage extends Module { outputSamplesWritePortB.en <= ~_valid; Sequential(clk, [ - outputSamplesWritePortA.data < butterfly.outA, - outputSamplesWritePortB.data < butterfly.outB, + outputSamplesWritePortA.data < butterfly.outA.named("butterflyOutA"), + outputSamplesWritePortB.data < butterfly.outB.named("butterflyOutB"), ], reset: reset); } } diff --git a/test/arithmetic/floating_point/bad_fft_stage_test.dart b/test/arithmetic/floating_point/bad_fft_stage_test.dart index 78eb92cd0..0c5ea6bcd 100644 --- a/test/arithmetic/floating_point/bad_fft_stage_test.dart +++ b/test/arithmetic/floating_point/bad_fft_stage_test.dart @@ -56,6 +56,8 @@ void main() { final tempMemoryReadPortB = DataPortInterface(dataWidth, addrWidth); final twiddleFactorROMWritePort = DataPortInterface(dataWidth, addrWidth); final twiddleFactorROMReadPort = DataPortInterface(dataWidth, addrWidth); + final outputSamplesA = DataPortInterface(dataWidth, addrWidth); + final outputSamplesB = DataPortInterface(dataWidth, addrWidth); MemoryModel( clk, @@ -82,6 +84,8 @@ void main() { inputSamplesA: tempMemoryReadPortA, inputSamplesB: tempMemoryReadPortB, twiddleFactorROM: twiddleFactorROMReadPort, + outputSamplesA: outputSamplesA, + outputSamplesB: outputSamplesB ); await stage.build(); From f88400b63958438acb5496a83ec91e18b0a46c51 Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Wed, 23 Jul 2025 16:02:07 -0700 Subject: [PATCH 13/19] Fix memory harness Signed-off-by: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> --- .../floating_point/fft/fft_stage.dart | 5 ++- .../floating_point/bad_fft_stage_test.dart | 45 +++++++++++++++---- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/lib/src/arithmetic/floating_point/fft/fft_stage.dart b/lib/src/arithmetic/floating_point/fft/fft_stage.dart index 8482fcdc5..97bac4fa8 100644 --- a/lib/src/arithmetic/floating_point/fft/fft_stage.dart +++ b/lib/src/arithmetic/floating_point/fft/fft_stage.dart @@ -132,11 +132,12 @@ class BadFFTStage extends Module { restart: this.ready & _valid, width: max(log2Length - 1, 1), maxValue: n ~/ 2 - 1, + name: "i", ); _valid <= i.equalsMax; - final k = (i.count >> (mShift - 1)) << mShift; - final j = (i.count & Const((m >> 1) - 1, width: i.width)); + final k = ((i.count >> (mShift - 1)) << mShift).named("k"); + final j = (i.count & Const((m >> 1) - 1, width: i.width)).named("j"); // for k = 0 to n-1 by m do // ω ← 1 diff --git a/test/arithmetic/floating_point/bad_fft_stage_test.dart b/test/arithmetic/floating_point/bad_fft_stage_test.dart index 0c5ea6bcd..c671c501a 100644 --- a/test/arithmetic/floating_point/bad_fft_stage_test.dart +++ b/test/arithmetic/floating_point/bad_fft_stage_test.dart @@ -31,6 +31,35 @@ ComplexFloatingPoint newComplex(double real, double imaginary) { return complex; } +Future write( + Logic clk, + DataPortInterface writePort, + int value, + int addr, +) async { + await clk.nextNegedge; + writePort.addr.inject(LogicValue.ofInt(addr, writePort.addrWidth)); + writePort.data.inject(LogicValue.ofInt(value, writePort.dataWidth)); + writePort.en.inject(1); + + await clk.nextNegedge; + writePort.en.inject(0); + await clk.nextNegedge; +} + +Future read(Logic clk, DataPortInterface readPort, int addr) async { + readPort.addr.inject(LogicValue.ofInt(addr, readPort.addrWidth)); + readPort.en.inject(1); + await clk.nextPosedge; + final value = readPort.data.value; + + await clk.nextNegedge; + readPort.en.inject(0); + await clk.nextNegedge; + + return value; +} + void main() { tearDown(() async { await Simulator.reset(); @@ -59,19 +88,19 @@ void main() { final outputSamplesA = DataPortInterface(dataWidth, addrWidth); final outputSamplesB = DataPortInterface(dataWidth, addrWidth); - MemoryModel( + final twiddleFactorROM = RegisterFile( clk, reset, [twiddleFactorROMWritePort], [twiddleFactorROMReadPort], - readLatency: 0, + numEntries: n, ); - MemoryModel( + final tempMemory = RegisterFile( clk, reset, [tempMemoryWritePort], [tempMemoryReadPortA, tempMemoryReadPortB], - readLatency: 0, + numEntries: n, ); final stage = BadFFTStage( @@ -85,14 +114,11 @@ void main() { inputSamplesB: tempMemoryReadPortB, twiddleFactorROM: twiddleFactorROMReadPort, outputSamplesA: outputSamplesA, - outputSamplesB: outputSamplesB + outputSamplesB: outputSamplesB, ); await stage.build(); - print(stage.generateSynth()); - - Simulator.setMaxSimTime(10000); unawaited(Simulator.run()); reset.inject(1); @@ -100,7 +126,8 @@ void main() { reset.inject(0); await clk.waitCycles(10); - assert(false); + await write(clk, twiddleFactorROMWritePort, 1, 0); + expect((await read(clk, twiddleFactorROMReadPort, 0)).toInt(), 1); await Simulator.endSimulation(); }); From f634b186509a447fc0bcf65407dfa6d6a2f722a6 Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Wed, 23 Jul 2025 16:53:52 -0700 Subject: [PATCH 14/19] Rework interface Signed-off-by: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> --- .../floating_point/fft/fft_stage.dart | 38 ++++++++++--------- .../floating_point/bad_fft_stage_test.dart | 22 ++++++++--- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/lib/src/arithmetic/floating_point/fft/fft_stage.dart b/lib/src/arithmetic/floating_point/fft/fft_stage.dart index 97bac4fa8..0478abfe5 100644 --- a/lib/src/arithmetic/floating_point/fft/fft_stage.dart +++ b/lib/src/arithmetic/floating_point/fft/fft_stage.dart @@ -14,12 +14,12 @@ class BadFFTStage extends Module { final int mantissaWidth; Logic clk; Logic reset; - Logic ready; + Logic go; DataPortInterface inputSamplesA; DataPortInterface inputSamplesB; DataPortInterface twiddleFactorROM; - late final Logic valid; + late final Logic done; BadFFTStage({ required this.logStage, @@ -27,14 +27,14 @@ class BadFFTStage extends Module { required this.mantissaWidth, required this.clk, required this.reset, - required this.ready, + required this.go, required this.inputSamplesA, required this.inputSamplesB, required this.twiddleFactorROM, required DataPortInterface outputSamplesA, required DataPortInterface outputSamplesB, super.name = 'badfftstage', - }) : assert(ready.width == 1), + }) : assert(go.width == 1), assert( inputSamplesA.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), ), @@ -43,9 +43,10 @@ class BadFFTStage extends Module { ) { clk = addInput('clk', clk); reset = addInput('reset', reset); - ready = addInput('ready', ready); - final _valid = Logic(name: "_valid"); - valid = addOutput('valid')..gets(_valid); + go = addInput('go', go); + final _done = Logic(name: "_done"); + done = addOutput('done')..gets(_done); + final en = go & ~_done; inputSamplesA = inputSamplesA.clone() ..connectIO( @@ -124,17 +125,18 @@ class BadFFTStage extends Module { final log2Length = inputSamplesA.addrWidth; final m = 1 << logStage; final mShift = log2Ceil(m); + print("m is ${m}"); final i = Counter.ofLogics( - [~_valid], + [flop(clk, en)], clk: clk, - reset: reset, - restart: this.ready & _valid, + reset: reset | (this.go & _done), + resetValue: 0, width: max(log2Length - 1, 1), - maxValue: n ~/ 2 - 1, + maxValue: n ~/ 2, name: "i", ); - _valid <= i.equalsMax; + _done <= i.equalsMax; final k = ((i.count >> (mShift - 1)) << mShift).named("k"); final j = (i.count & Const((m >> 1) - 1, width: i.width)).named("j"); @@ -148,13 +150,13 @@ class BadFFTStage extends Module { // A[k + j + m/2] ← u – t // ω ← ω ωm Logic addressA = (k + j).named("addressA"); - Logic addressB = (addressA + n ~/ 2).named("addressB"); + Logic addressB = (addressA + m ~/ 2).named("addressB"); inputSamplesA.addr <= addressA; - inputSamplesA.en <= ~_valid; + inputSamplesA.en <= en; inputSamplesB.addr <= addressB; - inputSamplesB.en <= ~_valid; + inputSamplesB.en <= en; twiddleFactorROM.addr <= j; - twiddleFactorROM.en <= ~_valid; + twiddleFactorROM.en <= en; final butterfly = Butterfly( inA: ComplexFloatingPoint.of( @@ -175,9 +177,9 @@ class BadFFTStage extends Module { ); outputSamplesWritePortA.addr <= addressA; - outputSamplesWritePortA.en <= ~_valid; + outputSamplesWritePortA.en <= en; outputSamplesWritePortB.addr <= addressB; - outputSamplesWritePortB.en <= ~_valid; + outputSamplesWritePortB.en <= en; Sequential(clk, [ outputSamplesWritePortA.data < butterfly.outA.named("butterflyOutA"), diff --git a/test/arithmetic/floating_point/bad_fft_stage_test.dart b/test/arithmetic/floating_point/bad_fft_stage_test.dart index c671c501a..bfca40639 100644 --- a/test/arithmetic/floating_point/bad_fft_stage_test.dart +++ b/test/arithmetic/floating_point/bad_fft_stage_test.dart @@ -34,12 +34,12 @@ ComplexFloatingPoint newComplex(double real, double imaginary) { Future write( Logic clk, DataPortInterface writePort, - int value, + LogicValue value, int addr, ) async { await clk.nextNegedge; writePort.addr.inject(LogicValue.ofInt(addr, writePort.addrWidth)); - writePort.data.inject(LogicValue.ofInt(value, writePort.dataWidth)); + writePort.data.inject(value); writePort.en.inject(1); await clk.nextNegedge; @@ -71,7 +71,7 @@ void main() { final twiddle = newComplex(1.0, 0.0); final clk = SimpleClockGenerator(10).clk; final reset = Logic()..put(0); - final ready = Logic()..put(0); + final go = Logic()..put(0); final n = 2; @@ -109,7 +109,7 @@ void main() { mantissaWidth: mantissaWidth, clk: clk, reset: reset, - ready: ready, + go: go, inputSamplesA: tempMemoryReadPortA, inputSamplesB: tempMemoryReadPortB, twiddleFactorROM: twiddleFactorROMReadPort, @@ -119,6 +119,8 @@ void main() { await stage.build(); + WaveDumper(stage); + unawaited(Simulator.run()); reset.inject(1); @@ -126,8 +128,16 @@ void main() { reset.inject(0); await clk.waitCycles(10); - await write(clk, twiddleFactorROMWritePort, 1, 0); - expect((await read(clk, twiddleFactorROMReadPort, 0)).toInt(), 1); + await write(clk, tempMemoryWritePort, a.value, 0); + await write(clk, tempMemoryWritePort, b.value, 1); + await write(clk, twiddleFactorROMWritePort, a.value, 0); + await write(clk, twiddleFactorROMWritePort, b.value, 1); + + go.inject(1); + stage.done.posedge.listen((_) { + go.inject(0); + }); + await clk.waitCycles(5); await Simulator.endSimulation(); }); From 972fcb1e2d705324881a40fd4e64d6e094d27329 Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Mon, 11 Aug 2025 16:03:24 -0700 Subject: [PATCH 15/19] switch to connectIntf Signed-off-by: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> --- .../floating_point/fft/fft_stage.dart | 76 ++++++++----------- pubspec.yaml | 6 +- test.dart | 0 .../floating_point/bad_fft_stage_test.dart | 2 + 4 files changed, 40 insertions(+), 44 deletions(-) create mode 100644 test.dart diff --git a/lib/src/arithmetic/floating_point/fft/fft_stage.dart b/lib/src/arithmetic/floating_point/fft/fft_stage.dart index 0478abfe5..add8836e1 100644 --- a/lib/src/arithmetic/floating_point/fft/fft_stage.dart +++ b/lib/src/arithmetic/floating_point/fft/fft_stage.dart @@ -46,49 +46,39 @@ class BadFFTStage extends Module { go = addInput('go', go); final _done = Logic(name: "_done"); done = addOutput('done')..gets(_done); - final en = go & ~_done; - - inputSamplesA = inputSamplesA.clone() - ..connectIO( - this, - inputSamplesA, - inputTags: [DataPortGroup.data], - outputTags: [DataPortGroup.control], - uniquify: (name) => "inputSamplesA${name}", - ); - inputSamplesB = inputSamplesB.clone() - ..connectIO( - this, - inputSamplesB, - inputTags: [DataPortGroup.data], - outputTags: [DataPortGroup.control], - uniquify: (name) => "inputSamplesB${name}", - ); - twiddleFactorROM = twiddleFactorROM.clone() - ..connectIO( - this, - twiddleFactorROM, - inputTags: [DataPortGroup.data], - outputTags: [DataPortGroup.control], - uniquify: (name) => "twiddleFactorROM${name}", - ); - - outputSamplesA = outputSamplesA.clone() - ..connectIO( - this, - outputSamplesA, - inputTags: [DataPortGroup.control], - outputTags: [DataPortGroup.data], - uniquify: (name) => "outputSamplesA${name}", - ); - outputSamplesB = outputSamplesB.clone() - ..connectIO( - this, - outputSamplesB, - inputTags: [DataPortGroup.control], - outputTags: [DataPortGroup.data], - uniquify: (name) => "outputSamplesB${name}", - ); + final en = (go & ~_done).named("enable"); + + inputSamplesA = connectInterface( + inputSamplesA, + inputTags: [DataPortGroup.data], + outputTags: [DataPortGroup.control], + uniquify: (name) => "inputSamplesA${name}", + ); + inputSamplesB = connectInterface( + inputSamplesB, + inputTags: [DataPortGroup.data], + outputTags: [DataPortGroup.control], + uniquify: (name) => "inputSamplesB${name}", + ); + twiddleFactorROM = connectInterface( + twiddleFactorROM, + inputTags: [DataPortGroup.data], + outputTags: [DataPortGroup.control], + uniquify: (name) => "twiddleFactorROM${name}", + ); + + outputSamplesA = connectInterface( + outputSamplesA, + inputTags: [DataPortGroup.control], + outputTags: [DataPortGroup.data], + uniquify: (name) => "outputSamplesA${name}", + ); + outputSamplesB = connectInterface( + outputSamplesB, + inputTags: [DataPortGroup.control], + outputTags: [DataPortGroup.data], + uniquify: (name) => "outputSamplesB${name}", + ); final outputSamplesWritePortA = DataPortInterface( inputSamplesA.dataWidth, diff --git a/pubspec.yaml b/pubspec.yaml index 4a6f6ca25..02c7bd00e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -19,4 +19,8 @@ dev_dependencies: logging: ^1.0.1 test: ^1.25.0 - +dependency_overrides: + rohd: + git: + url: https://github.com/mkorbel1/rohd + ref: clone_and_match diff --git a/test.dart b/test.dart new file mode 100644 index 000000000..e69de29bb diff --git a/test/arithmetic/floating_point/bad_fft_stage_test.dart b/test/arithmetic/floating_point/bad_fft_stage_test.dart index bfca40639..b4f418c56 100644 --- a/test/arithmetic/floating_point/bad_fft_stage_test.dart +++ b/test/arithmetic/floating_point/bad_fft_stage_test.dart @@ -120,6 +120,8 @@ void main() { await stage.build(); WaveDumper(stage); + + print(stage.generateSynth()); unawaited(Simulator.run()); From 2537fcbdb401a4629054970c10873f40d56446c7 Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Tue, 12 Aug 2025 12:50:40 -0700 Subject: [PATCH 16/19] Finish fft test Signed-off-by: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> --- .../floating_point/fft/fft_stage.dart | 1 + .../floating_point/bad_fft_stage_test.dart | 116 ++++++++++++++++-- 2 files changed, 104 insertions(+), 13 deletions(-) diff --git a/lib/src/arithmetic/floating_point/fft/fft_stage.dart b/lib/src/arithmetic/floating_point/fft/fft_stage.dart index add8836e1..4dfe8a668 100644 --- a/lib/src/arithmetic/floating_point/fft/fft_stage.dart +++ b/lib/src/arithmetic/floating_point/fft/fft_stage.dart @@ -104,6 +104,7 @@ class BadFFTStage extends Module { [outputSamplesWritePortA, outputSamplesWritePortB], [outputSamplesReadPortA, outputSamplesReadPortB], numEntries: n, + name: 'outputSamplesBuffer', ); outputSamplesA.data <= outputSamplesReadPortA.data; outputSamplesReadPortA.en <= outputSamplesA.en; diff --git a/test/arithmetic/floating_point/bad_fft_stage_test.dart b/test/arithmetic/floating_point/bad_fft_stage_test.dart index b4f418c56..57f621f9f 100644 --- a/test/arithmetic/floating_point/bad_fft_stage_test.dart +++ b/test/arithmetic/floating_point/bad_fft_stage_test.dart @@ -31,6 +31,53 @@ ComplexFloatingPoint newComplex(double real, double imaginary) { return complex; } +class Complex { + double real; + double imaginary; + + Complex({required this.real, required this.imaginary}); + + Complex add(Complex other) { + return Complex( + real: this.real + other.real, + imaginary: this.imaginary + other.imaginary, + ); + } + + Complex subtract(Complex other) { + return Complex( + real: this.real - other.real, + imaginary: this.imaginary - other.imaginary, + ); + } + + Complex multiply(Complex other) { + return Complex( + real: (this.real * other.real) - (this.imaginary * other.imaginary), + imaginary: (this.real * other.imaginary) + (this.imaginary * other.real), + ); + } + + @override + String toString() { + return '${real}${imaginary >= 0 ? '+' : ''}${imaginary}i'; + } +} + +List butterfly(Complex inA, Complex inB, Complex twiddleFactor) { + final temp = twiddleFactor.multiply(inB); + return [inA.subtract(temp), inA.add(temp)]; +} + +final epsilon = 1e-15; + +void compareDouble(double actual, double expected) { + assert( + (actual - expected).abs() < epsilon, + "actual ${actual}, expected ${expected}", + ); +} + Future write( Logic clk, DataPortInterface writePort, @@ -66,18 +113,21 @@ void main() { }); test('fft stage unit test', () async { - final a = newComplex(1.0, 2.0); - final b = newComplex(-3.0, -4.0); - final twiddle = newComplex(1.0, 0.0); + final a = Complex(real: 1.0, imaginary: 2.0); + final b = Complex(real: -3.0, imaginary: -4.0); + final twiddle = Complex(real: 1.0, imaginary: 0.0); + final aLogic = newComplex(a.real, a.imaginary); + final bLogic = newComplex(b.real, b.imaginary); + final twiddleLogic = newComplex(twiddle.real, twiddle.imaginary); final clk = SimpleClockGenerator(10).clk; final reset = Logic()..put(0); final go = Logic()..put(0); final n = 2; - final exponentWidth = a.realPart.exponent.width; - final mantissaWidth = a.realPart.mantissa.width; - final dataWidth = a.width; //2 * (1 + exponentWidth + mantissaWidth); + final exponentWidth = aLogic.realPart.exponent.width; + final mantissaWidth = aLogic.realPart.mantissa.width; + final dataWidth = aLogic.width; //2 * (1 + exponentWidth + mantissaWidth); final addrWidth = log2Ceil(n); final tempMemoryWritePort = DataPortInterface(dataWidth, addrWidth); @@ -120,8 +170,8 @@ void main() { await stage.build(); WaveDumper(stage); - - print(stage.generateSynth()); + + // print(stage.generateSynth()); unawaited(Simulator.run()); @@ -130,17 +180,57 @@ void main() { reset.inject(0); await clk.waitCycles(10); - await write(clk, tempMemoryWritePort, a.value, 0); - await write(clk, tempMemoryWritePort, b.value, 1); - await write(clk, twiddleFactorROMWritePort, a.value, 0); - await write(clk, twiddleFactorROMWritePort, b.value, 1); + await write(clk, tempMemoryWritePort, aLogic.value, 0); + await write(clk, tempMemoryWritePort, bLogic.value, 1); + await write(clk, twiddleFactorROMWritePort, twiddleLogic.value, 0); go.inject(1); - stage.done.posedge.listen((_) { + flop(clk, stage.done).posedge.listen((_) { go.inject(0); }); await clk.waitCycles(5); + final output1 = await read(clk, outputSamplesA, 0); + final output2 = await read(clk, outputSamplesA, 1); + final output1float = ComplexFloatingPoint.of( + Const(output1), + exponentWidth: exponentWidth, + mantissaWidth: mantissaWidth, + ); + final output2float = ComplexFloatingPoint.of( + Const(output2), + exponentWidth: exponentWidth, + mantissaWidth: mantissaWidth, + ); + print(output1float.realPart.floatingPointValue.toDouble()); + print(output1float.imaginaryPart.floatingPointValue.toDouble()); + print(output2float.realPart.floatingPointValue.toDouble()); + print(output2float.imaginaryPart.floatingPointValue.toDouble()); + + final expected = butterfly(a, b, twiddle); + + print(expected[0].real); + print(expected[0].imaginary); + print(expected[1].real); + print(expected[1].imaginary); + + compareDouble( + output1float.realPart.floatingPointValue.toDouble(), + expected[0].real, + ); + compareDouble( + output1float.imaginaryPart.floatingPointValue.toDouble(), + expected[0].imaginary, + ); + compareDouble( + output2float.realPart.floatingPointValue.toDouble(), + expected[1].real, + ); + compareDouble( + output2float.imaginaryPart.floatingPointValue.toDouble(), + expected[1].imaginary, + ); + await Simulator.endSimulation(); }); } From 7c1ad045f6bd7d41a8509a5a9e5761fb492f33ff Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Thu, 14 Aug 2025 16:48:55 -0700 Subject: [PATCH 17/19] print stuff Signed-off-by: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> --- .../floating_point/fft/fft_stage.dart | 26 +++--- test.dart | 1 + .../floating_point/bad_fft_stage_test.dart | 79 +------------------ .../floating_point/butterfly_test.dart | 68 +--------------- test/arithmetic/floating_point/fft_utils.dart | 72 +++++++++++++++++ 5 files changed, 89 insertions(+), 157 deletions(-) create mode 100644 test/arithmetic/floating_point/fft_utils.dart diff --git a/lib/src/arithmetic/floating_point/fft/fft_stage.dart b/lib/src/arithmetic/floating_point/fft/fft_stage.dart index 4dfe8a668..925b2c67c 100644 --- a/lib/src/arithmetic/floating_point/fft/fft_stage.dart +++ b/lib/src/arithmetic/floating_point/fft/fft_stage.dart @@ -34,13 +34,13 @@ class BadFFTStage extends Module { required DataPortInterface outputSamplesA, required DataPortInterface outputSamplesB, super.name = 'badfftstage', - }) : assert(go.width == 1), - assert( - inputSamplesA.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), - ), - assert( - inputSamplesB.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), - ) { + }) : assert(go.width == 1), + assert( + inputSamplesA.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), + ), + assert( + inputSamplesB.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), + ) { clk = addInput('clk', clk); reset = addInput('reset', reset); go = addInput('go', go); @@ -116,7 +116,6 @@ class BadFFTStage extends Module { final log2Length = inputSamplesA.addrWidth; final m = 1 << logStage; final mShift = log2Ceil(m); - print("m is ${m}"); final i = Counter.ofLogics( [flop(clk, en)], @@ -172,9 +171,12 @@ class BadFFTStage extends Module { outputSamplesWritePortB.addr <= addressB; outputSamplesWritePortB.en <= en; - Sequential(clk, [ - outputSamplesWritePortA.data < butterfly.outA.named("butterflyOutA"), - outputSamplesWritePortB.data < butterfly.outB.named("butterflyOutB"), - ], reset: reset); + Sequential( + clk, + [ + outputSamplesWritePortA.data < butterfly.outA.named("butterflyOutA"), + outputSamplesWritePortB.data < butterfly.outB.named("butterflyOutB"), + ], + reset: reset); } } diff --git a/test.dart b/test.dart index e69de29bb..8b1378917 100644 --- a/test.dart +++ b/test.dart @@ -0,0 +1 @@ + diff --git a/test/arithmetic/floating_point/bad_fft_stage_test.dart b/test/arithmetic/floating_point/bad_fft_stage_test.dart index 57f621f9f..c27dff365 100644 --- a/test/arithmetic/floating_point/bad_fft_stage_test.dart +++ b/test/arithmetic/floating_point/bad_fft_stage_test.dart @@ -10,73 +10,7 @@ import 'package:rohd_hcl/src/arithmetic/floating_point/fft/fft_stage.dart'; import 'package:rohd_hcl/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart'; import 'package:rohd_vf/rohd_vf.dart'; import 'package:test/test.dart'; - -ComplexFloatingPoint newComplex(double real, double imaginary) { - final realFP = FloatingPoint64(); - final imaginaryFP = FloatingPoint64(); - - final realFPValue = FloatingPoint64Value.populator().ofDouble(real); - final imaginaryFPValue = FloatingPoint64Value.populator().ofDouble(imaginary); - - realFP.put(realFPValue); - imaginaryFP.put(imaginaryFPValue); - - final complex = ComplexFloatingPoint( - exponentWidth: realFP.exponent.width, - mantissaWidth: realFP.mantissa.width, - ); - complex.realPart <= realFP; - complex.imaginaryPart <= imaginaryFP; - - return complex; -} - -class Complex { - double real; - double imaginary; - - Complex({required this.real, required this.imaginary}); - - Complex add(Complex other) { - return Complex( - real: this.real + other.real, - imaginary: this.imaginary + other.imaginary, - ); - } - - Complex subtract(Complex other) { - return Complex( - real: this.real - other.real, - imaginary: this.imaginary - other.imaginary, - ); - } - - Complex multiply(Complex other) { - return Complex( - real: (this.real * other.real) - (this.imaginary * other.imaginary), - imaginary: (this.real * other.imaginary) + (this.imaginary * other.real), - ); - } - - @override - String toString() { - return '${real}${imaginary >= 0 ? '+' : ''}${imaginary}i'; - } -} - -List butterfly(Complex inA, Complex inB, Complex twiddleFactor) { - final temp = twiddleFactor.multiply(inB); - return [inA.subtract(temp), inA.add(temp)]; -} - -final epsilon = 1e-15; - -void compareDouble(double actual, double expected) { - assert( - (actual - expected).abs() < epsilon, - "actual ${actual}, expected ${expected}", - ); -} +import 'fft_utils.dart'; Future write( Logic clk, @@ -171,8 +105,6 @@ void main() { WaveDumper(stage); - // print(stage.generateSynth()); - unawaited(Simulator.run()); reset.inject(1); @@ -202,18 +134,9 @@ void main() { exponentWidth: exponentWidth, mantissaWidth: mantissaWidth, ); - print(output1float.realPart.floatingPointValue.toDouble()); - print(output1float.imaginaryPart.floatingPointValue.toDouble()); - print(output2float.realPart.floatingPointValue.toDouble()); - print(output2float.imaginaryPart.floatingPointValue.toDouble()); final expected = butterfly(a, b, twiddle); - print(expected[0].real); - print(expected[0].imaginary); - print(expected[1].real); - print(expected[1].imaginary); - compareDouble( output1float.realPart.floatingPointValue.toDouble(), expected[0].real, diff --git a/test/arithmetic/floating_point/butterfly_test.dart b/test/arithmetic/floating_point/butterfly_test.dart index 56065c467..47844cd0b 100644 --- a/test/arithmetic/floating_point/butterfly_test.dart +++ b/test/arithmetic/floating_point/butterfly_test.dart @@ -8,73 +8,7 @@ import 'package:rohd_hcl/rohd_hcl.dart'; import 'package:rohd_hcl/src/arithmetic/floating_point/fft/butterfly.dart'; import 'package:rohd_hcl/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart'; import 'package:test/test.dart'; - -ComplexFloatingPoint newComplex(double real, double imaginary) { - final realFP = FloatingPoint64(); - final imaginaryFP = FloatingPoint64(); - - final realFPValue = FloatingPoint64Value.populator().ofDouble(real); - final imaginaryFPValue = FloatingPoint64Value.populator().ofDouble(imaginary); - - realFP.put(realFPValue); - imaginaryFP.put(imaginaryFPValue); - - final complex = ComplexFloatingPoint( - exponentWidth: realFP.exponent.width, - mantissaWidth: realFP.mantissa.width, - ); - complex.realPart <= realFP; - complex.imaginaryPart <= imaginaryFP; - - return complex; -} - -class Complex { - double real; - double imaginary; - - Complex({required this.real, required this.imaginary}); - - Complex add(Complex other) { - return Complex( - real: this.real + other.real, - imaginary: this.imaginary + other.imaginary, - ); - } - - Complex subtract(Complex other) { - return Complex( - real: this.real - other.real, - imaginary: this.imaginary - other.imaginary, - ); - } - - Complex multiply(Complex other) { - return Complex( - real: (this.real * other.real) - (this.imaginary * other.imaginary), - imaginary: (this.real * other.imaginary) + (this.imaginary * other.real), - ); - } - - @override - String toString() { - return '${real}${imaginary >= 0 ? '+' : ''}${imaginary}i'; - } -} - -List butterfly(Complex inA, Complex inB, Complex twiddleFactor) { - final temp = twiddleFactor.multiply(inB); - return [inA.subtract(temp), inA.add(temp)]; -} - -final epsilon = 1e-15; - -void compareDouble(double actual, double expected) { - assert( - (actual - expected).abs() < epsilon, - "actual ${actual}, expected ${expected}", - ); -} +import 'fft_utils.dart'; void main() { tearDown(() async { diff --git a/test/arithmetic/floating_point/fft_utils.dart b/test/arithmetic/floating_point/fft_utils.dart new file mode 100644 index 000000000..20c1c072c --- /dev/null +++ b/test/arithmetic/floating_point/fft_utils.dart @@ -0,0 +1,72 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: BSD-3-Clause + +import 'package:rohd_hcl/rohd_hcl.dart'; +import 'package:rohd_hcl/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart'; + +ComplexFloatingPoint newComplex(double real, double imaginary) { + final realFP = FloatingPoint64(); + final imaginaryFP = FloatingPoint64(); + + final realFPValue = FloatingPoint64Value.populator().ofDouble(real); + final imaginaryFPValue = FloatingPoint64Value.populator().ofDouble(imaginary); + + realFP.put(realFPValue); + imaginaryFP.put(imaginaryFPValue); + + final complex = ComplexFloatingPoint( + exponentWidth: realFP.exponent.width, + mantissaWidth: realFP.mantissa.width, + ); + complex.realPart <= realFP; + complex.imaginaryPart <= imaginaryFP; + + return complex; +} + +class Complex { + double real; + double imaginary; + + Complex({required this.real, required this.imaginary}); + + Complex add(Complex other) { + return Complex( + real: this.real + other.real, + imaginary: this.imaginary + other.imaginary, + ); + } + + Complex subtract(Complex other) { + return Complex( + real: this.real - other.real, + imaginary: this.imaginary - other.imaginary, + ); + } + + Complex multiply(Complex other) { + return Complex( + real: (this.real * other.real) - (this.imaginary * other.imaginary), + imaginary: (this.real * other.imaginary) + (this.imaginary * other.real), + ); + } + + @override + String toString() { + return '${real}${imaginary >= 0 ? '+' : ''}${imaginary}i'; + } +} + +List butterfly(Complex inA, Complex inB, Complex twiddleFactor) { + final temp = twiddleFactor.multiply(inB); + return [inA.subtract(temp), inA.add(temp)]; +} + +final epsilon = 1e-15; + +void compareDouble(double actual, double expected) { + assert( + (actual - expected).abs() < epsilon, + "actual ${actual}, expected ${expected}", + ); +} From dffb1878537dc8b48481935092ed20ab5db62476 Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Thu, 14 Aug 2025 16:58:27 -0700 Subject: [PATCH 18/19] stuff Signed-off-by: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> --- .../floating_point/fft/fft_stage.dart | 56 +++++++++---------- .../complex_floating_point_logic.dart | 6 +- lib/src/memory/csr/csr_backdoor.dart | 1 + lib/src/memory/memory.dart | 1 + .../floating_point/bad_fft_stage_test.dart | 9 ++- .../floating_point/butterfly_test.dart | 2 - .../complex_floating_point_test.dart | 8 +-- test/arithmetic/floating_point/fft_utils.dart | 32 ++++------- 8 files changed, 51 insertions(+), 64 deletions(-) diff --git a/lib/src/arithmetic/floating_point/fft/fft_stage.dart b/lib/src/arithmetic/floating_point/fft/fft_stage.dart index 925b2c67c..8458f5e35 100644 --- a/lib/src/arithmetic/floating_point/fft/fft_stage.dart +++ b/lib/src/arithmetic/floating_point/fft/fft_stage.dart @@ -34,50 +34,50 @@ class BadFFTStage extends Module { required DataPortInterface outputSamplesA, required DataPortInterface outputSamplesB, super.name = 'badfftstage', - }) : assert(go.width == 1), - assert( - inputSamplesA.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), - ), - assert( - inputSamplesB.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), - ) { + }) : assert(go.width == 1), + assert( + inputSamplesA.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), + ), + assert( + inputSamplesB.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), + ) { clk = addInput('clk', clk); reset = addInput('reset', reset); go = addInput('go', go); - final _done = Logic(name: "_done"); - done = addOutput('done')..gets(_done); - final en = (go & ~_done).named("enable"); + final doneInner = Logic(name: '_done'); + done = addOutput('done')..gets(doneInner); + final en = (go & ~done).named('enable'); inputSamplesA = connectInterface( inputSamplesA, inputTags: [DataPortGroup.data], outputTags: [DataPortGroup.control], - uniquify: (name) => "inputSamplesA${name}", + uniquify: (name) => 'inputSamplesA$name', ); inputSamplesB = connectInterface( inputSamplesB, inputTags: [DataPortGroup.data], outputTags: [DataPortGroup.control], - uniquify: (name) => "inputSamplesB${name}", + uniquify: (name) => 'inputSamplesB$name', ); twiddleFactorROM = connectInterface( twiddleFactorROM, inputTags: [DataPortGroup.data], outputTags: [DataPortGroup.control], - uniquify: (name) => "twiddleFactorROM${name}", + uniquify: (name) => 'twiddleFactorROM$name', ); outputSamplesA = connectInterface( outputSamplesA, inputTags: [DataPortGroup.control], outputTags: [DataPortGroup.data], - uniquify: (name) => "outputSamplesA${name}", + uniquify: (name) => 'outputSamplesA$name', ); outputSamplesB = connectInterface( outputSamplesB, inputTags: [DataPortGroup.control], outputTags: [DataPortGroup.data], - uniquify: (name) => "outputSamplesB${name}", + uniquify: (name) => 'outputSamplesB$name', ); final outputSamplesWritePortA = DataPortInterface( @@ -120,16 +120,15 @@ class BadFFTStage extends Module { final i = Counter.ofLogics( [flop(clk, en)], clk: clk, - reset: reset | (this.go & _done), - resetValue: 0, + reset: reset | (go & doneInner), width: max(log2Length - 1, 1), maxValue: n ~/ 2, - name: "i", + name: 'i', ); - _done <= i.equalsMax; + doneInner <= i.equalsMax; - final k = ((i.count >> (mShift - 1)) << mShift).named("k"); - final j = (i.count & Const((m >> 1) - 1, width: i.width)).named("j"); + final k = ((i.count >> (mShift - 1)) << mShift).named('k'); + final j = (i.count & Const((m >> 1) - 1, width: i.width)).named('j'); // for k = 0 to n-1 by m do // ω ← 1 @@ -139,8 +138,8 @@ class BadFFTStage extends Module { // A[k + j] ← u + t // A[k + j + m/2] ← u – t // ω ← ω ωm - Logic addressA = (k + j).named("addressA"); - Logic addressB = (addressA + m ~/ 2).named("addressB"); + final addressA = (k + j).named('addressA'); + final addressB = (addressA + m ~/ 2).named('addressB'); inputSamplesA.addr <= addressA; inputSamplesA.en <= en; inputSamplesB.addr <= addressB; @@ -171,12 +170,9 @@ class BadFFTStage extends Module { outputSamplesWritePortB.addr <= addressB; outputSamplesWritePortB.en <= en; - Sequential( - clk, - [ - outputSamplesWritePortA.data < butterfly.outA.named("butterflyOutA"), - outputSamplesWritePortB.data < butterfly.outB.named("butterflyOutB"), - ], - reset: reset); + Sequential(clk, [ + outputSamplesWritePortA.data < butterfly.outA.named('butterflyOutA'), + outputSamplesWritePortB.data < butterfly.outB.named('butterflyOutB'), + ], reset: reset); } } diff --git a/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart b/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart index 688e9d78c..49d6e3f20 100644 --- a/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart +++ b/lib/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart @@ -74,7 +74,7 @@ class ComplexFloatingPoint extends LogicStructure { imaginaryPart: FloatingPointAdderSinglePath(imaginaryPart, other.imaginaryPart) .sum, - name: _nameJoin(name, "adder")); + name: _nameJoin(name, 'adder')); ComplexFloatingPoint multiplier(ComplexFloatingPoint other) { // use only 3 multipliers: https://mathworld.wolfram.com/ComplexMultiplication.html @@ -92,11 +92,11 @@ class ComplexFloatingPoint extends LogicStructure { imaginaryPart: FloatingPointAdderSinglePath(abcd, FloatingPointAdderSinglePath(ac.negated(), bd.negated()).sum) .sum, - name: _nameJoin(name, "multiplier")); + name: _nameJoin(name, 'multiplier')); } late final ComplexFloatingPoint negated = ComplexFloatingPoint._internal( realPart: realPart.negated(), imaginaryPart: imaginaryPart.negated(), - name: _nameJoin(name, "negated")); + name: _nameJoin(name, 'negated')); } diff --git a/lib/src/memory/csr/csr_backdoor.dart b/lib/src/memory/csr/csr_backdoor.dart index 777eafdb3..a4063e963 100644 --- a/lib/src/memory/csr/csr_backdoor.dart +++ b/lib/src/memory/csr/csr_backdoor.dart @@ -71,5 +71,6 @@ class CsrBackdoorInterface extends Interface { } /// Makes a copy of this [Interface] with matching configuration. + @override CsrBackdoorInterface clone() => CsrBackdoorInterface(config: config); } diff --git a/lib/src/memory/memory.dart b/lib/src/memory/memory.dart index 723e681df..8f0889e7e 100644 --- a/lib/src/memory/memory.dart +++ b/lib/src/memory/memory.dart @@ -80,6 +80,7 @@ class DataPortInterface extends Interface { } /// Makes a copy of this [Interface] with matching configuration. + @override DataPortInterface clone() => DataPortInterface(dataWidth, addrWidth); } diff --git a/test/arithmetic/floating_point/bad_fft_stage_test.dart b/test/arithmetic/floating_point/bad_fft_stage_test.dart index c27dff365..bf613ee75 100644 --- a/test/arithmetic/floating_point/bad_fft_stage_test.dart +++ b/test/arithmetic/floating_point/bad_fft_stage_test.dart @@ -5,7 +5,6 @@ import 'dart:async'; import 'package:rohd/rohd.dart'; import 'package:rohd_hcl/rohd_hcl.dart'; -import 'package:rohd_hcl/src/arithmetic/floating_point/fft/butterfly.dart'; import 'package:rohd_hcl/src/arithmetic/floating_point/fft/fft_stage.dart'; import 'package:rohd_hcl/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart'; import 'package:rohd_vf/rohd_vf.dart'; @@ -47,9 +46,9 @@ void main() { }); test('fft stage unit test', () async { - final a = Complex(real: 1.0, imaginary: 2.0); - final b = Complex(real: -3.0, imaginary: -4.0); - final twiddle = Complex(real: 1.0, imaginary: 0.0); + final a = Complex(real: 1, imaginary: 2); + final b = Complex(real: -3, imaginary: -4); + final twiddle = Complex(real: 1, imaginary: 0); final aLogic = newComplex(a.real, a.imaginary); final bLogic = newComplex(b.real, b.imaginary); final twiddleLogic = newComplex(twiddle.real, twiddle.imaginary); @@ -57,7 +56,7 @@ void main() { final reset = Logic()..put(0); final go = Logic()..put(0); - final n = 2; + const n = 2; final exponentWidth = aLogic.realPart.exponent.width; final mantissaWidth = aLogic.realPart.mantissa.width; diff --git a/test/arithmetic/floating_point/butterfly_test.dart b/test/arithmetic/floating_point/butterfly_test.dart index 47844cd0b..742d4c87f 100644 --- a/test/arithmetic/floating_point/butterfly_test.dart +++ b/test/arithmetic/floating_point/butterfly_test.dart @@ -4,9 +4,7 @@ import 'dart:math'; import 'package:rohd/rohd.dart'; -import 'package:rohd_hcl/rohd_hcl.dart'; import 'package:rohd_hcl/src/arithmetic/floating_point/fft/butterfly.dart'; -import 'package:rohd_hcl/src/arithmetic/signals/floating_point_logics/complex_floating_point_logic.dart'; import 'package:test/test.dart'; import 'fft_utils.dart'; diff --git a/test/arithmetic/floating_point/complex_floating_point_test.dart b/test/arithmetic/floating_point/complex_floating_point_test.dart index d2fd85a80..9ebcba671 100644 --- a/test/arithmetic/floating_point/complex_floating_point_test.dart +++ b/test/arithmetic/floating_point/complex_floating_point_test.dart @@ -38,8 +38,8 @@ void main() { }); test('complex addition', () { - final a = newComplex(1.0, 0.0); - final b = newComplex(0.0, -1.0); + final a = newComplex(1, 0); + final b = newComplex(0, -1); final c = a.adder(b); expect(c.realPart.floatingPointValue.toDouble(), 1.0); @@ -47,8 +47,8 @@ void main() { }); test('complex multiplication', () { - final a = newComplex(1.0, 2.0); - final b = newComplex(-3.0, -4.0); + final a = newComplex(1, 2); + final b = newComplex(-3, -4); final c = a.multiplier(b); expect(c.realPart.floatingPointValue.toDouble(), 5.0); diff --git a/test/arithmetic/floating_point/fft_utils.dart b/test/arithmetic/floating_point/fft_utils.dart index 20c1c072c..cd671cd40 100644 --- a/test/arithmetic/floating_point/fft_utils.dart +++ b/test/arithmetic/floating_point/fft_utils.dart @@ -30,31 +30,23 @@ class Complex { Complex({required this.real, required this.imaginary}); - Complex add(Complex other) { - return Complex( - real: this.real + other.real, - imaginary: this.imaginary + other.imaginary, + Complex add(Complex other) => Complex( + real: real + other.real, + imaginary: imaginary + other.imaginary, ); - } - Complex subtract(Complex other) { - return Complex( - real: this.real - other.real, - imaginary: this.imaginary - other.imaginary, + Complex subtract(Complex other) => Complex( + real: real - other.real, + imaginary: imaginary - other.imaginary, ); - } - Complex multiply(Complex other) { - return Complex( - real: (this.real * other.real) - (this.imaginary * other.imaginary), - imaginary: (this.real * other.imaginary) + (this.imaginary * other.real), + Complex multiply(Complex other) => Complex( + real: (real * other.real) - (imaginary * other.imaginary), + imaginary: (real * other.imaginary) + (imaginary * other.real), ); - } @override - String toString() { - return '${real}${imaginary >= 0 ? '+' : ''}${imaginary}i'; - } + String toString() => '$real${imaginary >= 0 ? '+' : ''}${imaginary}i'; } List butterfly(Complex inA, Complex inB, Complex twiddleFactor) { @@ -62,11 +54,11 @@ List butterfly(Complex inA, Complex inB, Complex twiddleFactor) { return [inA.subtract(temp), inA.add(temp)]; } -final epsilon = 1e-15; +const epsilon = 1e-15; void compareDouble(double actual, double expected) { assert( (actual - expected).abs() < epsilon, - "actual ${actual}, expected ${expected}", + 'actual $actual, expected $expected', ); } From bc4f828f1b0a11972f69157091205c0ada4b125b Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Thu, 14 Aug 2025 17:06:29 -0700 Subject: [PATCH 19/19] ok Signed-off-by: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> --- .../floating_point/fft/fft_stage.dart | 35 ++--- .../floating_point_logic.dart | 130 +++++++++--------- test/arithmetic/floating_point/fft_utils.dart | 18 +-- 3 files changed, 92 insertions(+), 91 deletions(-) diff --git a/lib/src/arithmetic/floating_point/fft/fft_stage.dart b/lib/src/arithmetic/floating_point/fft/fft_stage.dart index 8458f5e35..4a1bf6c5d 100644 --- a/lib/src/arithmetic/floating_point/fft/fft_stage.dart +++ b/lib/src/arithmetic/floating_point/fft/fft_stage.dart @@ -34,13 +34,13 @@ class BadFFTStage extends Module { required DataPortInterface outputSamplesA, required DataPortInterface outputSamplesB, super.name = 'badfftstage', - }) : assert(go.width == 1), - assert( - inputSamplesA.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), - ), - assert( - inputSamplesB.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), - ) { + }) : assert(go.width == 1), + assert( + inputSamplesA.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), + ), + assert( + inputSamplesB.dataWidth == 2 * (1 + exponentWidth + mantissaWidth), + ) { clk = addInput('clk', clk); reset = addInput('reset', reset); go = addInput('go', go); @@ -48,32 +48,32 @@ class BadFFTStage extends Module { done = addOutput('done')..gets(doneInner); final en = (go & ~done).named('enable'); - inputSamplesA = connectInterface( + inputSamplesA = addInterfacePorts( inputSamplesA, inputTags: [DataPortGroup.data], outputTags: [DataPortGroup.control], uniquify: (name) => 'inputSamplesA$name', ); - inputSamplesB = connectInterface( + inputSamplesB = addInterfacePorts( inputSamplesB, inputTags: [DataPortGroup.data], outputTags: [DataPortGroup.control], uniquify: (name) => 'inputSamplesB$name', ); - twiddleFactorROM = connectInterface( + twiddleFactorROM = addInterfacePorts( twiddleFactorROM, inputTags: [DataPortGroup.data], outputTags: [DataPortGroup.control], uniquify: (name) => 'twiddleFactorROM$name', ); - outputSamplesA = connectInterface( + outputSamplesA = addInterfacePorts( outputSamplesA, inputTags: [DataPortGroup.control], outputTags: [DataPortGroup.data], uniquify: (name) => 'outputSamplesA$name', ); - outputSamplesB = connectInterface( + outputSamplesB = addInterfacePorts( outputSamplesB, inputTags: [DataPortGroup.control], outputTags: [DataPortGroup.data], @@ -170,9 +170,12 @@ class BadFFTStage extends Module { outputSamplesWritePortB.addr <= addressB; outputSamplesWritePortB.en <= en; - Sequential(clk, [ - outputSamplesWritePortA.data < butterfly.outA.named('butterflyOutA'), - outputSamplesWritePortB.data < butterfly.outB.named('butterflyOutB'), - ], reset: reset); + Sequential( + clk, + [ + outputSamplesWritePortA.data < butterfly.outA.named('butterflyOutA'), + outputSamplesWritePortB.data < butterfly.outB.named('butterflyOutB'), + ], + reset: reset); } } diff --git a/lib/src/arithmetic/signals/floating_point_logics/floating_point_logic.dart b/lib/src/arithmetic/signals/floating_point_logics/floating_point_logic.dart index f9868511a..71ae6facf 100644 --- a/lib/src/arithmetic/signals/floating_point_logics/floating_point_logic.dart +++ b/lib/src/arithmetic/signals/floating_point_logics/floating_point_logic.dart @@ -42,21 +42,21 @@ class FloatingPoint extends LogicStructure { bool subNormalAsZero = false, String? name, }) : this._( - Logic(name: 'sign', naming: Naming.mergeable), - Logic( - width: exponentWidth, - name: 'exponent', - naming: Naming.mergeable, - ), - Logic( - width: mantissaWidth, - name: 'mantissa', - naming: Naming.mergeable, - ), - explicitJBit, - subNormalAsZero, - name: name, - ); + Logic(name: 'sign', naming: Naming.mergeable), + Logic( + width: exponentWidth, + name: 'exponent', + naming: Naming.mergeable, + ), + Logic( + width: mantissaWidth, + name: 'mantissa', + naming: Naming.mergeable, + ), + explicitJBit, + subNormalAsZero, + name: name, + ); /// [FloatingPoint] internal constructor. FloatingPoint._( @@ -71,22 +71,22 @@ class FloatingPoint extends LogicStructure { @mustBeOverridden @override FloatingPoint clone({String? name}) => FloatingPoint( - exponentWidth: exponent.width, - mantissaWidth: mantissa.width, - explicitJBit: explicitJBit, - subNormalAsZero: subNormalAsZero, - name: name, - ); + exponentWidth: exponent.width, + mantissaWidth: mantissa.width, + explicitJBit: explicitJBit, + subNormalAsZero: subNormalAsZero, + name: name, + ); /// A [FloatingPointValuePopulator] for values associated with this /// [FloatingPoint] type. @mustBeOverridden FloatingPointValuePopulator valuePopulator() => FloatingPointValue.populator( - exponentWidth: exponent.width, - mantissaWidth: mantissa.width, - explicitJBit: explicitJBit, - subNormalAsZero: subNormalAsZero, - ); + exponentWidth: exponent.width, + mantissaWidth: mantissa.width, + explicitJBit: explicitJBit, + subNormalAsZero: subNormalAsZero, + ); /// Return `true` if the J-bit is explicitly represented in the mantissa. final bool explicitJBit; @@ -98,18 +98,19 @@ class FloatingPoint extends LogicStructure { /// mantissa resolved if not [isNormal] and [subNormalAsZero] is `true`. FloatingPoint resolveSubNormalAsZero() { if (subNormalAsZero) { - return clone()..gets( - mux( - isNormal, - this, - FloatingPoint.zero( - exponentWidth: exponent.width, - mantissaWidth: mantissa.width, - explicitJBit: explicitJBit, - subNormalAsZero: subNormalAsZero, + return clone() + ..gets( + mux( + isNormal, + this, + FloatingPoint.zero( + exponentWidth: exponent.width, + mantissaWidth: mantissa.width, + explicitJBit: explicitJBit, + subNormalAsZero: subNormalAsZero, + ), ), - ), - ); + ); } else { return this; } @@ -132,33 +133,30 @@ class FloatingPoint extends LogicStructure { /// Return a [Logic] `1`if this [FloatingPoint] is Not a Number (NaN) /// by having its exponent field set to the NaN value (typically all /// ones) and a non-zero mantissa. - late final isNaN = - exponent.eq(valuePopulator().nan.exponent) & + late final isNaN = exponent.eq(valuePopulator().nan.exponent) & mantissa.or().named(_nameJoin('isNaN', name), naming: Naming.mergeable); /// Return a [Logic] `1` if this [FloatingPoint] is an infinity /// by having its exponent field set to the NaN value (typically all /// ones) and a zero mantissa. - late final isAnInfinity = - (floatingPointValue.supportsInfinities - ? exponent.isIn([ - valuePopulator().positiveInfinity.exponent, - valuePopulator().negativeInfinity.exponent, - ]) & - ~mantissa.or() - : Const(0)) - .named(_nameJoin('isAnInfinity', name), naming: Naming.mergeable); + late final isAnInfinity = (floatingPointValue.supportsInfinities + ? exponent.isIn([ + valuePopulator().positiveInfinity.exponent, + valuePopulator().negativeInfinity.exponent, + ]) & + ~mantissa.or() + : Const(0)) + .named(_nameJoin('isAnInfinity', name), naming: Naming.mergeable); /// Return a [Logic] `1` if this [FloatingPoint] is a zero /// by having its exponent field set to the NaN value (typically all /// ones) and a zero mantissa. - late final isAZero = - (exponent.isIn([ - valuePopulator().positiveZero.exponent, - valuePopulator().negativeZero.exponent, - ]) & - ~mantissa.or()) - .named(_nameJoin('isAZero', name), naming: Naming.mergeable); + late final isAZero = (exponent.isIn([ + valuePopulator().positiveZero.exponent, + valuePopulator().negativeZero.exponent, + ]) & + ~mantissa.or()) + .named(_nameJoin('isAZero', name), naming: Naming.mergeable); /// Return the zero exponent representation for this type of [FloatingPoint]. late final zeroExponent = Const( @@ -182,11 +180,11 @@ class FloatingPoint extends LogicStructure { /// Construct a [FloatingPoint] that represents infinity for this FP type. FloatingPoint inf({Logic? sign, bool negative = false}) => FloatingPoint.inf( - exponentWidth: exponent.width, - mantissaWidth: mantissa.width, - sign: sign, - negative: negative, - ); + exponentWidth: exponent.width, + mantissaWidth: mantissa.width, + sign: sign, + negative: negative, + ); /// Construct a [FloatingPoint] that represents NaN for this FP type. late final nan = FloatingPoint.nan( @@ -216,12 +214,12 @@ class FloatingPoint extends LogicStructure { } FloatingPoint negated() => FloatingPoint._( - ~sign, - exponent.clone()..gets(exponent), - mantissa.clone()..gets(mantissa), - explicitJBit, - subNormalAsZero, - ); + ~sign, + exponent.clone()..gets(exponent), + mantissa.clone()..gets(mantissa), + explicitJBit, + subNormalAsZero, + ); /// Construct a [FloatingPoint] that represents infinity. factory FloatingPoint.inf({ diff --git a/test/arithmetic/floating_point/fft_utils.dart b/test/arithmetic/floating_point/fft_utils.dart index cd671cd40..0ca863198 100644 --- a/test/arithmetic/floating_point/fft_utils.dart +++ b/test/arithmetic/floating_point/fft_utils.dart @@ -31,19 +31,19 @@ class Complex { Complex({required this.real, required this.imaginary}); Complex add(Complex other) => Complex( - real: real + other.real, - imaginary: imaginary + other.imaginary, - ); + real: real + other.real, + imaginary: imaginary + other.imaginary, + ); Complex subtract(Complex other) => Complex( - real: real - other.real, - imaginary: imaginary - other.imaginary, - ); + real: real - other.real, + imaginary: imaginary - other.imaginary, + ); Complex multiply(Complex other) => Complex( - real: (real * other.real) - (imaginary * other.imaginary), - imaginary: (real * other.imaginary) + (imaginary * other.real), - ); + real: (real * other.real) - (imaginary * other.imaginary), + imaginary: (real * other.imaginary) + (imaginary * other.real), + ); @override String toString() => '$real${imaginary >= 0 ? '+' : ''}${imaginary}i';