Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[issue#137]: Add mechanism for reset all flop of Sequential #302

Merged
merged 21 commits into from
May 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d71b57f
[issue#137]: Add mechanism for reset all flop of Sequential
RPG-coder-intc Mar 7, 2023
326f5ac
[issue#137] resetting flipflops for sequential via _Always constructor
RPG-coder-intc Mar 16, 2023
ca846e0
[issue#137] fixing reset arg for sequential and passing args to _always
RPG-coder-intc Mar 16, 2023
f086a4e
[issue#137] reordering args in _always
RPG-coder-intc Mar 16, 2023
a080a95
[issue#137] resolving override errors
RPG-coder-intc Mar 16, 2023
bf24cba
fix: resolving code conflict
RPG-coder-intc Mar 21, 2023
12fea90
Merge branch 'intel:main' into fix-issue-137
RPG-coder-intc Mar 21, 2023
c86e902
Merge branch 'intel:main' into fix-issue-137
RPG-coder-intc Apr 4, 2023
a229135
counter test for reset flipflops
RPG-coder-intc Apr 6, 2023
20127c2
resolving code_review
RPG-coder-intc Apr 6, 2023
94a99ea
transfering reset flipflop test cases to wintf
RPG-coder-intc Apr 13, 2023
d7f8ca6
[issue#137] resolving code reviews
RPG-coder-intc Apr 20, 2023
e4c4651
updating wintf tests for resetFlipflop
RPG-coder-intc Apr 20, 2023
48b9314
maintaining code quality
RPG-coder-intc Apr 20, 2023
fe7dc43
[issue-137] refining counter test
RPG-coder-intc Apr 20, 2023
ce86966
Merge branch 'intel:main' into fix-issue-137
RPG-coder-intc May 18, 2023
8e75df8
Resolving code reviews
RPG-coder-intc May 18, 2023
65bc5e3
Merge branch 'fix-issue-137' of https://github.com/RPG-coder-intc/roh…
RPG-coder-intc May 18, 2023
97c76d1
replace getReceiver() to receiver for perf boost
RPG-coder-intc May 18, 2023
f38e4d2
removing unused import
RPG-coder-intc May 18, 2023
9064935
removing unused class var
RPG-coder-intc May 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 45 additions & 7 deletions lib/src/modules/conditional.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import 'package:rohd/src/utilities/uniquifier.dart';
/// Represents a block of logic, similar to `always` blocks in SystemVerilog.
abstract class _Always extends Module with CustomSystemVerilog {
/// A [List] of the [Conditional]s to execute.
final List<Conditional> conditionals;
List<Conditional> get conditionals =>
UnmodifiableListView<Conditional>(_conditionals);
late List<Conditional> _conditionals;

/// A mapping from internal receiver signals to designated [Module] outputs.
final Map<Logic, Logic> _assignedReceiverToOutputMap =
Expand All @@ -34,9 +36,43 @@ abstract class _Always extends Module with CustomSystemVerilog {

final Uniquifier _portUniquifier = Uniquifier();

_Always(this.conditionals, {super.name = 'always'}) {
/// Executes provided [conditionals] at the appropriate time (specified by
/// child class).
///
/// If [reset] is provided, then all signals driven by this block will be
/// conditionally reset when the signal is high.
/// The default reset value is to `0`, but if [resetValues] is provided then
/// the corresponding value
/// associated with the driven signal will be set to that value instead upon
/// reset.
_Always(this._conditionals,
{Logic? reset, Map<Logic, dynamic>? resetValues, super.name = 'always'}) {
// create a registration of all inputs and outputs of this module
var idx = 0;

// Get all Receivers
final allReceivers =
RPG-coder-intc marked this conversation as resolved.
Show resolved Hide resolved
conditionals.map((e) => e.receivers).expand((e) => e).toList();

// This will reset the conditionals on setting the `reset` flag
if (reset != null) {
_conditionals = [
// If resetValue for a receiver is defined,
If(
reset,
// then use it for assigning receiver
then: [
...allReceivers.map((rec) {
final driver = resetValues?[rec] ?? 0;
return rec < driver;
})
],
// else assign zero as resetValue
orElse: conditionals,
),
];
}

for (final conditional in conditionals) {
for (final driver in conditional.drivers) {
if (!_assignedDriverToInputMap.containsKey(driver)) {
Expand Down Expand Up @@ -309,13 +345,15 @@ class Sequential extends _Always {

/// Constructs a [Sequential] single-triggered by [clk].
Sequential(Logic clk, List<Conditional> conditionals,
{String name = 'sequential'})
: this.multi([clk], conditionals, name: name);
{Logic? reset,
mkorbel1 marked this conversation as resolved.
Show resolved Hide resolved
Map<Logic, dynamic>? resetValues,
String name = 'sequential'})
: this.multi([clk], conditionals,
name: name, reset: reset, resetValues: resetValues);

/// Constructs a [Sequential] multi-triggered by any of [clks].
Sequential.multi(List<Logic> clks, List<Conditional> conditionals,
{String name = 'sequential'})
: super(conditionals, name: name) {
Sequential.multi(List<Logic> clks, super.conditionals,
{super.reset, super.resetValues, super.name = 'sequential'}) {
for (var i = 0; i < clks.length; i++) {
final clk = clks[i];
if (clk.width > 1) {
Expand Down
94 changes: 71 additions & 23 deletions test/counter_wintf_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
/// 2021 May 25
/// Author: Max Korbel <max.korbel@intel.com>
///

import 'package:rohd/rohd.dart';
import 'package:rohd/src/utilities/simcompare.dart';
import 'package:test/test.dart';
Expand All @@ -17,6 +18,7 @@ class CounterInterface extends Interface<CounterDirection> {
Logic get en => port('en');
Logic get reset => port('reset');
Logic get val => port('val');
Logic get resetVal => port('resetVal');

final int width;
CounterInterface(this.width) {
Expand All @@ -32,7 +34,8 @@ class CounterInterface extends Interface<CounterDirection> {

class Counter extends Module {
late final CounterInterface intf;
Counter(CounterInterface intf) {
Counter(CounterInterface intf,
{bool useBuiltInSequentialReset = false, int resetValue = 0}) {
this.intf = CounterInterface(intf.width)
..connectIO(this, intf,
inputTags: {CounterDirection.inward},
Expand All @@ -41,14 +44,27 @@ class Counter extends Module {
// this should do nothing
this.intf.connectIO(this, intf);

_buildLogic();
}

void _buildLogic() {
final nextVal = Logic(name: 'nextVal', width: intf.width);

nextVal <= intf.val + 1;

if (useBuiltInSequentialReset) {
_buildResetValLogic(nextVal, resetValue: resetValue);
} else {
_buildLogic(nextVal);
}
}
void _buildResetValLogic(Logic nextVal, {int resetValue = 0}) {
final resetValues = <Logic, Logic>{intf.val: Const(resetValue, width: 8)};
Sequential(
SimpleClockGenerator(10).clk,
[
If(intf.en, then: [intf.val < nextVal])
],
reset: intf.reset,
resetValues: resetValues);
}

void _buildLogic(Logic nextVal) {
Sequential(SimpleClockGenerator(10).clk, [
If(intf.reset, then: [
intf.val < 0
Expand All @@ -59,6 +75,27 @@ class Counter extends Module {
}
}

Future<void> moduleTest(Counter mod) async {
await mod.build();
final vectors = [
Vector({'en': 0, 'reset': 1}, {}),
Vector({'en': 0, 'reset': 1}, {'val': 0}),
Vector({'en': 1, 'reset': 1}, {'val': 0}),
Vector({'en': 1, 'reset': 0}, {'val': 0}),
Vector({'en': 1, 'reset': 0}, {'val': 1}),
Vector({'en': 1, 'reset': 0}, {'val': 2}),
Vector({'en': 1, 'reset': 0}, {'val': 3}),
Vector({'en': 0, 'reset': 0}, {'val': 4}),
Vector({'en': 0, 'reset': 0}, {'val': 4}),
Vector({'en': 1, 'reset': 0}, {'val': 4}),
Vector({'en': 0, 'reset': 0}, {'val': 5}),
Vector({'en': 0, 'reset': 0}, {'val': 5}),
];
await SimCompare.checkFunctionalVector(mod, vectors);
final simResult = SimCompare.iverilogVector(mod, vectors);
expect(simResult, equals(true));
}

void main() {
tearDown(() async {
await Simulator.reset();
Expand All @@ -67,23 +104,34 @@ void main() {
group('simcompare', () {
test('counter', () async {
final mod = Counter(CounterInterface(8));
await mod.build();
final vectors = [
Vector({'en': 0, 'reset': 1}, {}),
Vector({'en': 0, 'reset': 1}, {'val': 0}),
Vector({'en': 1, 'reset': 1}, {'val': 0}),
Vector({'en': 1, 'reset': 0}, {'val': 0}),
Vector({'en': 1, 'reset': 0}, {'val': 1}),
Vector({'en': 1, 'reset': 0}, {'val': 2}),
Vector({'en': 1, 'reset': 0}, {'val': 3}),
Vector({'en': 0, 'reset': 0}, {'val': 4}),
Vector({'en': 0, 'reset': 0}, {'val': 4}),
Vector({'en': 1, 'reset': 0}, {'val': 4}),
Vector({'en': 0, 'reset': 0}, {'val': 5}),
];
await SimCompare.checkFunctionalVector(mod, vectors);
final simResult = SimCompare.iverilogVector(mod, vectors);
expect(simResult, equals(true));
await moduleTest(mod);
});
});
test('resetFlipflop from root w/o resetVal', () async {
final mod = Counter(CounterInterface(8), useBuiltInSequentialReset: true);
await moduleTest(mod);
});

test('resetFlipflop from root w/ resetVal', () async {
final mod = Counter(CounterInterface(8),
useBuiltInSequentialReset: true, resetValue: 3);
await mod.build();
final vectors = [
Vector({'en': 0, 'reset': 1}, {}),
Vector({'en': 0, 'reset': 1}, {'val': 3}),
Vector({'en': 1, 'reset': 1}, {'val': 3}),
Vector({'en': 1, 'reset': 0}, {'val': 3}),
Vector({'en': 1, 'reset': 0}, {'val': 4}),
Vector({'en': 1, 'reset': 0}, {'val': 5}),
Vector({'en': 1, 'reset': 0}, {'val': 6}),
Vector({'en': 0, 'reset': 0}, {'val': 7}),
Vector({'en': 0, 'reset': 0}, {'val': 7}),
Vector({'en': 1, 'reset': 0}, {'val': 7}),
Vector({'en': 0, 'reset': 0}, {'val': 8}),
Vector({'en': 0, 'reset': 0}, {'val': 8}),
];
await SimCompare.checkFunctionalVector(mod, vectors);
final simResult = SimCompare.iverilogVector(mod, vectors);
expect(simResult, equals(true));
});
}