Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ImportVerilog] Insert missing conversions around instance ports #7647

Merged
merged 3 commits into from
Sep 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions include/circt/Dialect/Moore/MooreOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,7 @@ class Builtin<string mnemonic, list<Trait> traits = []> :
MooreOp<"builtin." # mnemonic, traits>;

//===----------------------------------------------------------------------===//
// Simulation Control
// Simulation Control Builtins
//===----------------------------------------------------------------------===//

def StopBIOp : Builtin<"stop"> {
Expand Down Expand Up @@ -1499,7 +1499,7 @@ def FinishMessageBIOp : Builtin<"finish_message"> {
}

//===----------------------------------------------------------------------===//
// Severity and Display
// Severity and Display Builtins
//===----------------------------------------------------------------------===//

def DisplayBIOp : Builtin<"display"> {
Expand Down Expand Up @@ -1544,4 +1544,26 @@ def SeverityBIOp : Builtin<"severity"> {
let assemblyFormat = "$severity $message attr-dict";
}

//===----------------------------------------------------------------------===//
// Math Builtins
//===----------------------------------------------------------------------===//

def Clog2BIOp : Builtin<"clog2", [SameOperandsAndResultType]> {
let summary = "Compute ceil(log2(x)) of x";
let description = [{
Computes the ceiling of the base-2 logarithm of the argument. The argument
is interpreted as unsigned. The result is 0 if the argument is 0. The result
corresponds to the minimum address width necessary to address a given number
of elements, or the number of bits necessary to represent a given number of
states.

If any of the bits in the argument are X or Z, the result is X.

See IEEE 1800-2017 § 20.8.1 "Integer math functions".
}];
let arguments = (ins IntType:$value);
let results = (outs IntType:$result);
let assemblyFormat = "$value attr-dict `:` type($value)";
}

#endif // CIRCT_DIALECT_MOORE_MOOREOPS
18 changes: 17 additions & 1 deletion lib/Conversion/ImportVerilog/Expressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -691,9 +691,18 @@ struct RvalueExprVisitor {
Value visitCall(const slang::ast::CallExpression &expr,
const slang::ast::CallExpression::SystemCallInfo &info) {
const auto &subroutine = *info.subroutine;
auto args = expr.arguments();

if (subroutine.name == "$signed" || subroutine.name == "$unsigned")
return context.convertRvalueExpression(*expr.arguments()[0]);
return context.convertRvalueExpression(*args[0]);

if (subroutine.name == "$clog2") {
auto value = context.convertToSimpleBitVector(
context.convertRvalueExpression(*args[0]));
if (!value)
return {};
return builder.create<moore::Clog2BIOp>(loc, value);
}

mlir::emitError(loc) << "unsupported system call `" << subroutine.name
<< "`";
Expand Down Expand Up @@ -726,6 +735,13 @@ struct RvalueExprVisitor {
for (unsigned elementIdx = 0; elementIdx < elementCount; ++elementIdx)
elements.push_back(elements[elementIdx]);

// Handle integers.
if (auto intType = dyn_cast<moore::IntType>(type)) {
assert(intType.getWidth() == elements.size());
std::reverse(elements.begin(), elements.end());
return builder.create<moore::ConcatOp>(loc, intType, elements);
}

// Handle packed structs.
if (auto structType = dyn_cast<moore::StructType>(type)) {
assert(structType.getMembers().size() == elements.size());
Expand Down
19 changes: 16 additions & 3 deletions lib/Conversion/ImportVerilog/Structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,13 @@ struct ModuleVisitor : public BaseVisitor {
inputValues.push_back(value);
}

// Insert conversions for input ports.
for (auto [value, type] :
llvm::zip(inputValues, moduleType.getInputTypes()))
if (value.getType() != type)
value =
builder.create<moore::ConversionOp>(value.getLoc(), type, value);

// Create the instance op itself.
auto inputNames = builder.getArrayAttr(moduleType.getInputNames());
auto outputNames = builder.getArrayAttr(moduleType.getOutputNames());
Expand All @@ -403,9 +410,15 @@ struct ModuleVisitor : public BaseVisitor {
inputNames, outputNames);

// Assign output values from the instance to the connected expression.
for (auto [lvalue, output] : llvm::zip(outputValues, inst.getOutputs()))
if (lvalue)
builder.create<moore::ContinuousAssignOp>(loc, lvalue, output);
for (auto [lvalue, output] : llvm::zip(outputValues, inst.getOutputs())) {
if (!lvalue)
continue;
Value rvalue = output;
auto dstType = cast<moore::RefType>(lvalue.getType()).getNestedType();
if (dstType != rvalue.getType())
rvalue = builder.create<moore::ConversionOp>(loc, dstType, rvalue);
builder.create<moore::ContinuousAssignOp>(loc, lvalue, rvalue);
}

return success();
}
Expand Down
24 changes: 24 additions & 0 deletions test/Conversion/ImportVerilog/basic.sv
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,8 @@ module Expressions;
bit [1:0][31:0] arrayInt;
// CHECK: %uarrayInt = moore.variable : <uarray<2 x i32>>
bit [31:0] uarrayInt [2];
// CHECK: %m = moore.variable : <l4>
logic [3:0] m;

initial begin
// CHECK: moore.constant 0 : i32
Expand Down Expand Up @@ -1275,6 +1277,13 @@ module Expressions;
// CHECK: [[TMP3:%.+]] = moore.array_create [[TMP0]], [[TMP1]], [[TMP2]], [[TMP0]], [[TMP1]], [[TMP2]] : !moore.i4, !moore.i4, !moore.i4, !moore.i4, !moore.i4, !moore.i4 -> uarray<6 x i4>
// CHECK: moore.array_create [[TMP3]], [[TMP3]], [[TMP3]] : !moore.uarray<6 x i4>, !moore.uarray<6 x i4>, !moore.uarray<6 x i4> -> uarray<3 x uarray<6 x i4>>
arr = '{3{'{2{4'd1, 4'd2, 4'd3}}}};

// CHECK: [[TMP0:%.+]] = moore.constant 0 :
// CHECK: [[TMP1:%.+]] = moore.constant 0 :
// CHECK: [[TMP2:%.+]] = moore.constant 1 :
// CHECK: [[TMP3:%.+]] = moore.constant 0 :
// CHECK: moore.concat [[TMP3]], [[TMP2]], [[TMP1]], [[TMP0]] : (!moore.l1, !moore.l1, !moore.l1, !moore.l1) -> l4
m = '{default: '0, 2: '1};

//===------------------------------------------------------------------===//
// Builtin Functions
Expand Down Expand Up @@ -2025,3 +2034,18 @@ package ParamPackage;
// CHECK: dbg.variable "ParamPackage::param2", [[TMP]] : !moore.i32
localparam int param2 = 9001;
endpackage

// CHECK-LABEL: moore.module @PortCastA()
module PortCastA;
bit [31:0] a, b;
// CHECK: [[TMP1:%.+]] = moore.read %a : <i32>
// CHECK: [[TMP2:%.+]] = moore.conversion [[TMP1]] : !moore.i32 -> !moore.array<1 x i32>
// CHECK: [[TMP3:%.+]] = moore.instance "sub" @PortCastB(a: [[TMP2]]: !moore.array<1 x i32>)
// CHECK: [[TMP4:%.+]] = moore.conversion [[TMP3]] : !moore.array<1 x i32> -> !moore.i32
// CHECK: moore.assign %b, [[TMP4]] : i32
PortCastB sub(a, b);
endmodule

module PortCastB (input bit [0:0][31:0] a, output bit [0:0][31:0] b);
assign b = a;
endmodule
16 changes: 16 additions & 0 deletions test/Conversion/ImportVerilog/builtins.sv
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
// Internal issue in Slang v3 about jump depending on uninitialised value.
// UNSUPPORTED: valgrind

function void dummyA(int x); endfunction

// IEEE 1800-2017 § 20.2 "Simulation control system tasks"
// CHECK-LABEL: func.func private @SimulationControlBuiltins(
function void SimulationControlBuiltins(bit x);
// CHECK: moore.builtin.finish_message false
Expand Down Expand Up @@ -35,6 +38,8 @@ function void SimulationControlBuiltins(bit x);
$exit;
endfunction

// IEEE 1800-2017 § 20.10 "Severity tasks"
// IEEE 1800-2017 § 21.2 "Display system tasks"
// CHECK-LABEL: func.func private @DisplayAndSeverityBuiltins(
// CHECK-SAME: [[X:%.+]]: !moore.i32
function void DisplayAndSeverityBuiltins(int x);
Expand Down Expand Up @@ -181,3 +186,14 @@ function void DisplayAndSeverityBuiltins(int x);
// CHECK: moore.unreachable
if (0) $fatal(1, "%d", x);
endfunction

// IEEE 1800-2017 § 20.8 "Math functions"
// CHECK-LABEL: func.func private @MathBuiltins(
// CHECK-SAME: [[X:%.+]]: !moore.i32
// CHECK-SAME: [[Y:%.+]]: !moore.l42
function void MathBuiltins(int x, logic [41:0] y);
// CHECK: moore.builtin.clog2 [[X]] : i32
dummyA($clog2(x));
// CHECK: moore.builtin.clog2 [[Y]] : l42
dummyA($clog2(y));
endfunction
9 changes: 9 additions & 0 deletions test/Dialect/Moore/basic.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -385,3 +385,12 @@ func.func @SeverityAndDisplayBuiltins(%arg0: !moore.format_string) {
moore.builtin.severity fatal %arg0
return
}

// CHECK-LABEL: func.func @MathBuiltins
func.func @MathBuiltins(%arg0: !moore.i32, %arg1: !moore.l42) {
// CHECK: moore.builtin.clog2 %arg0 : i32
moore.builtin.clog2 %arg0 : i32
// CHECK: moore.builtin.clog2 %arg1 : l42
moore.builtin.clog2 %arg1 : l42
return
}
Loading