mirror of https://github.com/llvm/circt.git
[ImportVerilog] Insert missing conversions around instance ports (#7647)
In certain corner cases, Slang does not insert the necessary conversion AST nodes around instance ports. This can be problematic if an input or output port is connected to a cast-compatible type (e.g. `i32` and `array<1 x i32>`). To fix this, always insert conversions if the types of a port and the connected value differ.
This commit is contained in:
parent
a7f177312b
commit
b86194929e
|
@ -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());
|
||||
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -2034,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
|
||||
|
|
Loading…
Reference in New Issue