From ace51549cb7697049f3ce14b62e101421e317dc9 Mon Sep 17 00:00:00 2001 From: Max Korbel Date: Thu, 16 Nov 2023 10:07:28 -0800 Subject: [PATCH 1/3] Fix bug with fifo depth 1 --- lib/src/fifo.dart | 7 +++++- test/fifo_test.dart | 56 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/lib/src/fifo.dart b/lib/src/fifo.dart index b0ea7f1f..ed25c1b7 100644 --- a/lib/src/fifo.dart +++ b/lib/src/fifo.dart @@ -7,6 +7,8 @@ // 2023 March 13 // Author: Max Korbel +import 'dart:math'; + import 'package:rohd/rohd.dart'; import 'package:rohd_hcl/rohd_hcl.dart'; import 'package:rohd_vf/rohd_vf.dart'; @@ -84,8 +86,11 @@ class Fifo extends Module { this.generateBypass = false, super.name = 'fifo'}) : dataWidth = writeData.width, - _addrWidth = log2Ceil(depth), + _addrWidth = max(1, log2Ceil(depth)), assert(depth > 0, 'Depth must be at least 1.') { + assert(_addrWidth > 0, + 'Assumptions that address is non-zero in implementation'); + addInput('clk', clk); addInput('reset', reset); diff --git a/test/fifo_test.dart b/test/fifo_test.dart index 901eda7f..ce86dd8f 100644 --- a/test/fifo_test.dart +++ b/test/fifo_test.dart @@ -127,6 +127,62 @@ void main() { await Simulator.simulationEnded; }); + test('fifo with depth 1', () async { + final clk = SimpleClockGenerator(10).clk; + final reset = Logic()..put(0); + + final wrEn = Logic()..put(0); + final rdEn = Logic()..put(0); + final wrData = Logic(width: 32); + + final fifo = Fifo( + clk, + reset, + writeEnable: wrEn, + readEnable: rdEn, + writeData: wrData, + generateError: true, + depth: 1, + ); + + await fifo.build(); + + unawaited(Simulator.run()); + + // a little reset flow + await clk.nextNegedge; + reset.put(1); + await clk.nextNegedge; + await clk.nextNegedge; + reset.put(0); + await clk.nextNegedge; + await clk.nextNegedge; + + wrEn.put(1); + wrData.put(0xdeadbeef); + + await clk.nextNegedge; + + wrEn.put(0); + wrData.put(0); + expect(fifo.full.value.toBool(), true); + expect(fifo.error!.value.toBool(), false); + + await clk.nextNegedge; + + rdEn.put(1); + expect(fifo.readData.value.toInt(), 0xdeadbeef); + + await clk.nextNegedge; + rdEn.put(0); + + expect(fifo.empty.value.toBool(), true); + expect(fifo.error!.value.toBool(), false); + + Simulator.endSimulation(); + await Simulator.simulationEnded; + }); + test('fifo underflow error without bypass', () async { final clk = SimpleClockGenerator(10).clk; final reset = Logic()..put(0); From b0100efa8486b21cb64c622cf059ea7497c3d754 Mon Sep 17 00:00:00 2001 From: Max Korbel Date: Thu, 16 Nov 2023 10:51:29 -0800 Subject: [PATCH 2/3] fix typo --- lib/src/fifo.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/fifo.dart b/lib/src/fifo.dart index ed25c1b7..d101f8e3 100644 --- a/lib/src/fifo.dart +++ b/lib/src/fifo.dart @@ -89,7 +89,7 @@ class Fifo extends Module { _addrWidth = max(1, log2Ceil(depth)), assert(depth > 0, 'Depth must be at least 1.') { assert(_addrWidth > 0, - 'Assumptions that address is non-zero in implementation'); + 'Assumption that address width is non-zero in implementation'); addInput('clk', clk); addInput('reset', reset); From 23a1a4081161f7de18754d674abb21b742d71308 Mon Sep 17 00:00:00 2001 From: Max Korbel Date: Thu, 16 Nov 2023 11:00:17 -0800 Subject: [PATCH 3/3] Make exception for non-positive depth rather than assertion --- lib/src/fifo.dart | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/src/fifo.dart b/lib/src/fifo.dart index d101f8e3..b075a219 100644 --- a/lib/src/fifo.dart +++ b/lib/src/fifo.dart @@ -42,6 +42,8 @@ class Fifo extends Module { Logic? get occupancy => generateOccupancy ? output('occupancy') : null; /// The depth of this FIFO. + /// + /// Must be greater than 0. final int depth; /// If `true`, then the [occupancy] output will be generated. @@ -86,8 +88,11 @@ class Fifo extends Module { this.generateBypass = false, super.name = 'fifo'}) : dataWidth = writeData.width, - _addrWidth = max(1, log2Ceil(depth)), - assert(depth > 0, 'Depth must be at least 1.') { + _addrWidth = max(1, log2Ceil(depth)) { + if (depth <= 0) { + throw RohdHclException('Depth must be at least 1.'); + } + assert(_addrWidth > 0, 'Assumption that address width is non-zero in implementation');