Skip to content

Commit

Permalink
[SV] Add optional init operand to sv.reg (#6002)
Browse files Browse the repository at this point in the history
  • Loading branch information
mortbopet authored Sep 13, 2023
1 parent bec964d commit 8f4abac
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 5 deletions.
11 changes: 8 additions & 3 deletions include/circt/Dialect/SV/SVInOutOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,25 @@ def RegOp : SVOp<"reg", [
Declare a SystemVerilog Variable Declaration of 'reg' type.
See SV Spec 6.8, pp100.
}];
let arguments = (ins StrAttr:$name, OptionalAttr<InnerSymAttr>:$inner_sym);
let arguments = (ins
StrAttr:$name,
Optional<AnyType>:$init,
OptionalAttr<InnerSymAttr>:$inner_sym);
let results = (outs InOutType:$result);

let skipDefaultBuilders = 1;
let builders = [
OpBuilder<(ins "::mlir::Type":$elementType,
CArg<"StringAttr", "StringAttr()">:$name,
CArg<"hw::InnerSymAttr", "hw::InnerSymAttr()">:$innerSym)>
CArg<"hw::InnerSymAttr", "hw::InnerSymAttr()">:$innerSym,
CArg<"mlir::Value", "{}">:$init)>
];

// We handle the name in a custom way, so we use a customer parser/printer.
let assemblyFormat = [{
(`sym` $inner_sym^)? `` custom<ImplicitSSAName>($name) attr-dict
(`init` $init^)? (`sym` $inner_sym^)? `` custom<ImplicitSSAName>($name) attr-dict
`:` qualified(type($result))
custom<ImplicitInitType>(ref(type($result)),ref($init), type($init))
}];
let hasCanonicalizeMethod = true;

Expand Down
8 changes: 8 additions & 0 deletions lib/Conversion/ExportVerilog/ExportVerilog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5019,6 +5019,14 @@ LogicalResult StmtEmitter::emitDeclaration(Operation *op) {
});
}

if (auto regOp = dyn_cast<RegOp>(op)) {
if (auto initValue = regOp.getInit()) {
ps << PP::space << "=" << PP::space;
ps.scopedBox(PP::ibox0,
[&]() { emitExpression(initValue, opsForLocation); });
}
}

// Try inlining an assignment into declarations.
if (isa<sv::WireOp, LogicOp>(op) &&
!op->getParentOp()->hasTrait<ProceduralRegion>()) {
Expand Down
25 changes: 23 additions & 2 deletions lib/Dialect/SV/SVOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,16 +244,37 @@ LogicalResult LocalParamOp::verify() {
// RegOp
//===----------------------------------------------------------------------===//

static ParseResult
parseImplicitInitType(OpAsmParser &p, mlir::Type regType,
std::optional<OpAsmParser::UnresolvedOperand> &initValue,
mlir::Type &initType) {
if (!initValue.has_value())
return success();

hw::InOutType ioType = regType.dyn_cast<hw::InOutType>();
if (!ioType)
return p.emitError(p.getCurrentLocation(), "expected inout type for reg");

initType = ioType.getElementType();
return success();
}

static void printImplicitInitType(OpAsmPrinter &p, Operation *op,
mlir::Type regType, mlir::Value initValue,
mlir::Type initType) {}

void RegOp::build(OpBuilder &builder, OperationState &odsState,
Type elementType, StringAttr name,
hw::InnerSymAttr innerSym) {
Type elementType, StringAttr name, hw::InnerSymAttr innerSym,
mlir::Value initValue) {
if (!name)
name = builder.getStringAttr("");
odsState.addAttribute("name", name);
if (innerSym)
odsState.addAttribute(hw::InnerSymbolTable::getInnerSymbolAttrName(),
innerSym);
odsState.addTypes(hw::InOutType::get(elementType));
if (initValue)
odsState.addOperands(initValue);
}

/// Suggest a name for each result value based on the saved result names
Expand Down
11 changes: 11 additions & 0 deletions test/Conversion/ExportVerilog/sv-dialect.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,17 @@ hw.module @reg_1(%in4: i4, %in8: i8) -> (a : i3, b : i5) {
hw.output %c, %d : i3,i5
}

// CHECK-LABEL: module regWithInit(
// CHECK: reg reg1 = 1'h0;
// CHECK: reg [31:0] reg2 = 32'(arg + arg);
hw.module @regWithInit(%arg : i32) {
%c0_i1 = hw.constant 0 : i1
%reg1 = sv.reg init %c0_i1 : !hw.inout<i1>

%init = comb.add %arg, %arg : i32
%reg2 = sv.reg init %init : !hw.inout<i32>
}

// CHECK-LABEL: module struct_field_inout1(
// CHECK-NEXT: inout struct packed {logic b; } a
// CHECK-NEXT: );
Expand Down

0 comments on commit 8f4abac

Please sign in to comment.