Skip to content

SystemC#662

Open
desmonddak wants to merge 7 commits into
intel:mainfrom
desmonddak:systemc
Open

SystemC#662
desmonddak wants to merge 7 commits into
intel:mainfrom
desmonddak:systemc

Conversation

@desmonddak

Copy link
Copy Markdown
Contributor

Description & Motivation

We should have a SystemC translation of our ROHD modules to simulate in a SystemC environment.

Related Issue(s)

None.

Testing

Leverage iverilog tests to drive SystemC testing, except for somethings like lack of 'X' propagation.

Backwards-compatibility

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

No.

Documentation

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

Very basic documentation added to parallel SystemVerilog.

@desmonddak desmonddak changed the title Systemc SystemC May 9, 2026
}

/// Generates the inline SystemC expression for the gate module.
String _inlineSystemCExpression(Map<String, String> inputs) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why do this here instead of how SV does it as a part of the module definition? surely we can reuse the operator string

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure: this is an architectural question -- as you add languages, do you expand Module for inlining and could different Modules be 'leaf' for different languages. In the case of netlist, the leaf modules are just empty boxes.

SystemC does some type conversions as it assigns

_aExtended_add_bExtended_carry = static_cast<bool>(sc_uint<6>(sc_uint<6>(aExtended.read()) + sc_uint<6>(bExtended.read()))[5]);

   bExtended = (sc_uint<1>(bool(0)), b.read());

But SystemVerilog can be different:

assign {_aExtended_add_bExtended_carry, sum} = ({

On the top-side we agreed that we don't want Module.generateSynth even as a simplification to .generateSystemVerilog and .generateSystemC, but on the leaf side, we need some kind of LeafService which provides these things rather than fattening Module for each language.

Really, the 'inline' concept is fairly tied to SV output, and while we could transmogrify the string, it is probably cleaner to have an API that says 'am I leaf in this context, if so, let me pass you to the LeafService with this context and module.

For example, the MLIR compiled version may need something else at leaf level.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i agree I think, should we consider what the API might look like for SV first and then map systemc onto it? or do it together? there's a lot of context within the modules that is relevant for generating outputs of them, some of it private, but maybe it need not be private and can be defined and registered separately? then there's backwards compatibility to consider.


// ===== Modules from flop_test.dart =====

class FlopTestModule extends Module {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why do modules need to be copied in here? why can't it leverage them either via relative import or just add to the existing tests to run the same existing vectors on systemc versions as well?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I should fix.

We DO run the same vectors on SystemC as SystemVerilog (see simcompare.dart).

final n = _scName(sig.name);
lines.add(' ${systemCOutType(sig.width)} $n{"$n"};');
}
return lines.join('\n');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

are inouts not supported?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

They are -- this is my mistake. sc_inout.

final dst = _scName(resultSynthLogic.name);
destinations.add(dst);
bodyLines.add(' $dst = $expr;');
} else if (m is Add) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

here also, can't this special case be implemented in Add itself?

/// In CI, the PCH is pre-built by `tool/gh_actions/setup_systemc_pch.sh`
/// before tests run, so this just finds it on disk. Locally it builds
/// on first use (safe because local runs are typically sequential).
static String? _ensurePch(String scHome, String cxxStd) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

should we split out system-c specific (and sv specific?) things from simcompare into separate classes/utilities?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes. I'll look into a cleaner partitioning.

}

// ══════════════════════════════════════════════════════════════════════
// Trace-based SystemC co-simulation

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is cool, but why only systemc? can we make it more generic up through sv also?

..writeln(' return _buf;')
..writeln('}')
..writeln()
// ──── sc_cosim_advance ────

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

multi-line strings instead?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

should this live in rohd-cosim instead and also support arbitrary systemc modules instead of only ROHD-generated ones?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Here is the dilemma: for SystemVerilog we have the iVerilog simulator for doing regressions. For SystemC we can use the SystemC compiler (really just g++) But in order to drive it, I used this ffi technique.

But we cannot depend on rohd-cosim inside rohd to validate SystemC gate representations which is what we want to do: for every iVerilog simulation of a ROHD primitive, we would want to add a quick sim for SystemC to do a miter test with the same vectors (simcompare).

So should we add this to rohd-cosim -- sure, but rohd-cosim already points to rohd, so perhaps it can import them, or we can build a more general form.

If we move it entirely there, then we cannot validate the SystemC synthesizer; as we add more capabilities to ROHD (perhaps another leaf gate), it would be good to validate in parallel with Verilog.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah ok, gotcha. Options are to use the FFI like you have i guess, or to do something like we do in the iverilog case where we generate the vectored testbench natively in the target language instead of expecting cross-language communication. either way seems ok to me, but now i understand the motivation for this in here, thanks!

Comment thread lib/src/module.dart
///
/// Generates SystemC code that is equivalent to the hardware described by
/// this module, using the same naming strategy as [generateSynth].
String generateSystemC() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

similar comment as before -- shall we avoid adding functions like this in favor of heading towards deprecation of generateSynth or making it more generic to accept different Synthesizers?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'll remove.

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.

2 participants