Skip to content

Commit

Permalink
[SeqToSV] Put fragments on hw.module.generated
Browse files Browse the repository at this point in the history
When generating modules as part of the SeqToSV conversion, put appropriate
memory generation fragments onto the created `hw.module.generated`.  No
longer put memory randomization fragments onto the original module.

Fixes #8164.

Signed-off-by: Schuyler Eldridge <[email protected]>
  • Loading branch information
seldridge committed Feb 1, 2025
1 parent 805f542 commit 9cb6175
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 11 deletions.
33 changes: 23 additions & 10 deletions lib/Conversion/SeqToSV/SeqToSV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ struct ModuleLoweringState {

struct FragmentInfo {
bool needsRegFragment = false;
bool needsMemFragment = false;
} fragment;

HWModuleOp module;
Expand Down Expand Up @@ -591,9 +590,11 @@ void SeqToSVPass::runOnOperation() {
// Identify memories and group them by module.
auto uniqueMems = memLowering.collectMemories(modules);
MapVector<HWModuleOp, SmallVector<FirMemLowering::MemoryConfig>> memsByModule;
SmallVector<HWModuleGeneratedOp> generatedModules;
for (auto &[config, memOps] : uniqueMems) {
// Create the `HWModuleGeneratedOp`s for each unique configuration.
auto genOp = memLowering.createMemoryModule(config, memOps);
generatedModules.push_back(genOp);

// Group memories by their parent module for parallelism.
for (auto memOp : memOps) {
Expand Down Expand Up @@ -630,10 +631,10 @@ void SeqToSVPass::runOnOperation() {

if (auto *it = memsByModule.find(module); it != memsByModule.end()) {
memLowering.lowerMemoriesInModule(module, it->second);
if (!disableMemRandomization) {
state.fragment.needsMemFragment = true;
}
// Generated memories need register randomization since `HWMemSimImpl`
// may add registers.
needsMemRandomization = true;
needsRegRandomization = true;
}
return state.immutableValueLowering.lower();
});
Expand All @@ -650,8 +651,8 @@ void SeqToSVPass::runOnOperation() {

for (auto &[_, state] : moduleLoweringStates) {
const auto &info = state.fragment;
if (!info.needsRegFragment && !info.needsMemFragment) {
// If neither is emitted, just skip it.
// Do not add fragments if not needed.
if (!info.needsRegFragment) {
continue;
}

Expand All @@ -661,16 +662,28 @@ void SeqToSVPass::runOnOperation() {
module->getAttrOfType<ArrayAttr>(emit::getFragmentsAttrName()))
fragmentAttrs = llvm::to_vector(others);

if (info.needsRegFragment)
if (info.needsRegFragment) {
fragmentAttrs.push_back(randomInitRegFragmentName);
if (info.needsMemFragment)
fragmentAttrs.push_back(randomInitMemFragmentName);
fragmentAttrs.push_back(randomInitFragmentName);
fragmentAttrs.push_back(randomInitFragmentName);
}

module->setAttr(emit::getFragmentsAttrName(),
ArrayAttr::get(context, fragmentAttrs));
}

// Set fragments for generated modules.
SmallVector<Attribute> genModFragments;
if (!disableRegRandomization)
genModFragments.push_back(randomInitRegFragmentName);
if (!disableMemRandomization)
genModFragments.push_back(randomInitMemFragmentName);
if (!genModFragments.empty()) {
genModFragments.push_back(randomInitFragmentName);
auto fragmentAttr = ArrayAttr::get(context, genModFragments);
for (auto genOp : generatedModules)
genOp->setAttr(emit::getFragmentsAttrName(), fragmentAttr);
}

// Mark all ops which can have clock types as illegal.
SeqToSVTypeConverter typeConverter;
ConversionTarget target(*context);
Expand Down
5 changes: 4 additions & 1 deletion test/Conversion/SeqToSV/header.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,11 @@

emit.fragment @SomeFragment {}

// CHECK-LABEL: hw.module.generated
// CHECK-SAME: emit.fragments = [@RANDOM_INIT_REG_FRAGMENT, @RANDOM_INIT_MEM_FRAGMENT, @RANDOM_INIT_FRAGMENT]

// CHECK-LABEL: hw.module @fragment_ref(in %clk : i1)
// CHECK-SAME: emit.fragments = [@SomeFragment, @RANDOM_INIT_REG_FRAGMENT, @RANDOM_INIT_MEM_FRAGMENT, @RANDOM_INIT_FRAGMENT]
// CHECK-SAME: emit.fragments = [@SomeFragment, @RANDOM_INIT_REG_FRAGMENT, @RANDOM_INIT_FRAGMENT]
hw.module @fragment_ref(in %clk : !seq.clock) attributes {emit.fragments = [@SomeFragment]} {
%cst0_i32 = hw.constant 0 : i32
%rA = seq.firreg %cst0_i32 clock %clk sym @regA : i32
Expand Down

0 comments on commit 9cb6175

Please sign in to comment.