Skip to content

SchematicSynthesizer#639

Open
desmonddak wants to merge 9 commits intointel:mainfrom
desmonddak:schematic
Open

SchematicSynthesizer#639
desmonddak wants to merge 9 commits intointel:mainfrom
desmonddak:schematic

Conversation

@desmonddak
Copy link
Contributor

Description & Motivation

This PR adds a Synthesizer for D3 schematics that can be loaded using an ELK-JSON loader.
This produces the Yosys JSON format.

Related Issue(s)

This fixes intel/rohd-hcl#162, but moves it into the rohd repository as a general purpose capability for ROHD.

Testing

We added a basic yosys JSON loader borrowed and documented from d3-hwschematics (https://github.com/Nic30/d3-hwschematic. We ran a few complex examples with multiple instantiation.

Backwards-compatibility

Is this a breaking change that will not be backwards-compatible? If yes, how so?

No. We added a prepare() routine for SynthBuilder which is optional and helpful for this and future Synthesizers.

Documentation

Does the change require any updates to documentation? If so, where? Are they included?

Just a simple one-liner to parallel the SystemVerilogSynthesizer. We probably need to make a concerted effort to document more of the utilities in ROHD.

} else {
raw = fs.readFileSync(jsonPath, 'utf8');
}
const yosysJson = JSON.parse(raw);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really the only key test we need -- we don't need the yosys.js or icons files. I need to look at the Utils files to see if anything is needed. What we want here is just to make sure the schematic JSON is healthy. We don't need a full d3 evaluation of it.

Copy link
Contributor

@mkorbel1 mkorbel1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still WIP reviewing this, but posting current checkpoint

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these files from d3 copied exactly or modified?

return;
}

final topModule = tops.first;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the first?

final topModule = tops.first;
for (final name in globalPortNames) {
// Check inputs, outputs, and inOuts
final port = topModule.inputs[name] ??
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer tryInput, etc.

}
}

// ModuleMap-based helpers removed — Schematic synthesis prefers
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this comment?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not follow the same pattern as we did with SystemVerilog mixins where property information about how it synthesizes is stored within the class instead of registered separately? This makes it easier to (a) introspect on the object (rather than regex), (b) for users to expand capabilities without modifying ROHD, (c) override things

SynthesisResult synthesize(
Module module, String Function(Module module) getInstanceTypeOfModule);
Module module, String Function(Module module) getInstanceTypeOfModule,
{SynthesisResult? Function(Module module)? lookupExistingResult,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused why you need this lookupExistingResult argument in various places, why you need it in addition to existingResults, and how it relates to something called "ModuleMap" that I see referenced in various places but don't see any class or variable with that name. Is this legacy stuff from a prior iteration?

});

@override
void prepare(List<Module> tops) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this have to happen in a separate prepare step instead of just upon synthesizing?

});

@override
void prepare(List<Module> tops) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does it need to know all the tops? Can't it just match any port with those names on any module or just look for specific Logic instances?

}

/// Deep list equality (compare contents, not identity).
static bool listEquals<T>(List<T> a, List<T> b) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use the available ListEquality utilities for collections instead of building your own?

continue;
}
reachableFromGlobals.add(cur);
for (final dst in cur.dstConnections) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if a global signal is an output? or is that not supported?

what if a global signal is an inOut? then we need to search in both directions, or is that not supported?

import 'package:rohd/src/synthesizers/schematic/schematic_mixins.dart';
import 'package:rohd/src/synthesizers/schematic/schematic_synthesis_result.dart';

bool _listEquals<T>(List<T> a, List<T> b) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another list equality check custom implementation?

final List<int> _ids;

/// The constant value being driven.
final BigInt _value;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this BigInt instead of LogicValue?

extension ModuleUtils on Module {
/// Returns a map of all declared ports (inputs, outputs, inOuts)
/// keyed by port name.
Map<String, Logic> get ports => {...inputs, ...outputs, ...inOuts};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: should this just be added to Module instead of an extension? any reason not to?

import 'package:rohd/rohd.dart';
import 'package:rohd/src/synthesizers/schematic/schematic_synthesis_result.dart';

/// Result of pass-through collection.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a "pass-through"?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Offline schematic generation

2 participants