Skip to content

Commit

Permalink
[FirParser] Add instance choice selection as circt attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
prithayan committed Dec 5, 2024
1 parent e9150ac commit 611da9d
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 12 deletions.
1 change: 1 addition & 0 deletions include/circt/Dialect/FIRRTL/FIRParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct FIRParserOptions {
std::vector<std::string> enableLayers;
std::vector<std::string> disableLayers;
std::optional<LayerSpecialization> defaultLayerSpecialization;
std::vector<std::string> selectInstanceChoice;
};

mlir::OwningOpRef<mlir::ModuleOp> importFIRFile(llvm::SourceMgr &sourceMgr,
Expand Down
3 changes: 2 additions & 1 deletion include/circt/Dialect/FIRRTL/FIRRTLStructure.td
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ def CircuitOp : FIRRTLOp<"circuit",
DefaultValuedAttr<AnnotationArrayAttr, "{}">:$annotations,
OptionalAttr<SymbolRefArrayAttr>:$enable_layers,
OptionalAttr<SymbolRefArrayAttr>:$disable_layers,
OptionalAttr<LayerSpecializationAttr>:$default_layer_specialization
OptionalAttr<LayerSpecializationAttr>:$default_layer_specialization,
OptionalAttr<ArrayAttr>:$select_inst_choice
);
let results = (outs);
let regions = (region SizedRegion<1>:$body);
Expand Down
30 changes: 21 additions & 9 deletions lib/Dialect/FIRRTL/Import/FIRParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5804,7 +5804,7 @@ ParseResult FIRCircuitParser::parseCircuit(

// Helper to transform a layer name specification of the form `A::B::C` into
// a SymbolRefAttr.
auto parseLayerName = [&](StringRef name) {
auto parseLayerName = [&](StringRef name) -> Attribute {
// Parse the layer name into a SymbolRefAttr.
auto [head, rest] = name.split(".");
SmallVector<FlatSymbolRefAttr> nestedRefs;
Expand All @@ -5816,19 +5816,31 @@ ParseResult FIRCircuitParser::parseCircuit(
return SymbolRefAttr::get(getContext(), head, nestedRefs);
};

auto parseLayers = [&](const auto &layers) {
SmallVector<Attribute> layersAttr;
for (const auto &layer : layers)
layersAttr.push_back(parseLayerName(layer));
if (layersAttr.empty())
auto getArrayAttr = [&](ArrayRef<std::string> strArray, auto getAttr) {
SmallVector<Attribute> attrArray;
auto *context = getContext();
for (const auto &str : strArray)
attrArray.push_back(getAttr(str));
if (attrArray.empty())
return ArrayAttr();
return ArrayAttr::get(getContext(), layersAttr);
return ArrayAttr::get(context, attrArray);
};

if (auto enableLayers = parseLayers(getConstants().options.enableLayers))
if (auto enableLayers =
getArrayAttr(getConstants().options.enableLayers, parseLayerName))
circuit.setEnableLayersAttr(enableLayers);
if (auto disableLayers = parseLayers(getConstants().options.disableLayers))
if (auto disableLayers =
getArrayAttr(getConstants().options.disableLayers, parseLayerName))
circuit.setDisableLayersAttr(disableLayers);

auto getStrAttr = [&](StringRef str) -> Attribute {
return StringAttr::get(getContext(), str);
};

if (auto selectInstChoice =
getArrayAttr(getConstants().options.selectInstanceChoice, getStrAttr))
circuit.setSelectInstChoiceAttr(selectInstChoice);

circuit.setDefaultLayerSpecialization(
getConstants().options.defaultLayerSpecialization);

Expand Down
5 changes: 3 additions & 2 deletions test/firtool/instchoice.fir
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
; RUN: firtool %s --parse-only | FileCheck %s
; RUN: firtool %s --parse-only --select-instance-choice=Platform=ASIC | FileCheck %s

FIRRTL version 4.1.0
; CHECK: firrtl.circuit "Foo" attributes {select_inst_choice = ["Platform=ASIC"]} {
circuit Foo:
; CHECK: firrtl.option @Platform
option Platform:
Expand All @@ -21,7 +22,7 @@ circuit Foo:
public module Foo:
input clock: Clock

; CHECK: %inst_clock = firrtl.instance_choice inst interesting_name @DefaultTarget
; CHECK: %inst_clock = firrtl.instance_choice inst interesting_name @DefaultTarget
; CHECK-SAME: alternatives @Platform {
; CHECK-SAME: @FPGA -> @FPGATarget,
; CHECK-SAME: @ASIC -> @ASICTarget
Expand Down
8 changes: 8 additions & 0 deletions tools/firtool/firtool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,13 @@ static llvm::cl::opt<LayerSpecializationOpt> defaultLayerSpecialization{
"Layers are enabled")),
cl::init(LayerSpecializationOpt::None), cl::cat(mainCategory)};

/// Specify the select option for specializing instance choice. Currently
/// firtool does not support partially specified instance choice.
static cl::list<std::string> selectInstanceChoice(
"select-instance-choice",
cl::desc("Options to specialize instance choice, in option=case format"),
cl::MiscFlags::CommaSeparated, cl::cat(mainCategory));

/// Check output stream before writing bytecode to it.
/// Warn and return true if output is known to be displayed.
static bool checkBytecodeOutputToConsole(raw_ostream &os) {
Expand Down Expand Up @@ -370,6 +377,7 @@ static LogicalResult processBuffer(
options.scalarizeExtModules = scalarizeExtModules;
options.enableLayers = enableLayers;
options.disableLayers = disableLayers;
options.selectInstanceChoice = selectInstanceChoice;

switch (defaultLayerSpecialization) {
case LayerSpecializationOpt::None:
Expand Down

0 comments on commit 611da9d

Please sign in to comment.