[LLHD] Allow instantiation of hw.module (#2743)

This commit is contained in:
Martin Erhart 2022-03-11 08:24:27 +01:00 committed by GitHub
parent 113094582a
commit a2478bfd26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 9 deletions

View File

@ -841,10 +841,6 @@ static LogicalResult verify(llhd::InstOp op) {
auto proc = op->getParentOfType<ModuleOp>().lookupSymbol<llhd::ProcOp>(
calleeAttr.getValue());
auto entity = op->getParentOfType<ModuleOp>().lookupSymbol<llhd::EntityOp>(
calleeAttr.getValue());
// Verify that the input and output types match the callee.
if (proc) {
auto type = proc.getType();
@ -856,12 +852,16 @@ static LogicalResult verify(llhd::InstOp op) {
return op.emitOpError(
"incorrect number of outputs for proc instantiation");
for (size_t i = 0, e = type.getNumInputs(); i != e; ++i)
for (size_t i = 0, e = type.getNumInputs(); i != e; ++i) {
if (op.getOperand(i).getType() != type.getInput(i))
return op.emitOpError("operand type mismatch");
}
return success();
}
auto entity = op->getParentOfType<ModuleOp>().lookupSymbol<llhd::EntityOp>(
calleeAttr.getValue());
if (entity) {
auto type = entity.getType();
@ -873,14 +873,51 @@ static LogicalResult verify(llhd::InstOp op) {
return op.emitOpError(
"incorrect number of outputs for entity instantiation");
for (size_t i = 0, e = type.getNumInputs(); i != e; ++i)
for (size_t i = 0, e = type.getNumInputs(); i != e; ++i) {
if (op.getOperand(i).getType() != type.getInput(i))
return op.emitOpError("operand type mismatch");
}
return success();
}
return op.emitOpError() << "'" << calleeAttr.getValue()
<< "' does not reference a valid proc or entity";
auto module = op->getParentOfType<ModuleOp>().lookupSymbol<hw::HWModuleOp>(
calleeAttr.getValue());
if (module) {
auto type = module.getType();
if (type.getNumInputs() != op.inputs().size())
return op.emitOpError(
"incorrect number of inputs for hw.module instantiation");
if (type.getNumResults() + type.getNumInputs() != op.getNumOperands())
return op.emitOpError(
"incorrect number of outputs for hw.module instantiation");
// Check input types
for (size_t i = 0, e = type.getNumInputs(); i != e; ++i) {
if (op.getOperand(i)
.getType()
.cast<llhd::SigType>()
.getUnderlyingType() != type.getInput(i))
return op.emitOpError("input type mismatch");
}
// Check output types
for (size_t i = 0, e = type.getNumResults(); i != e; ++i) {
if (op.getOperand(type.getNumInputs() + i)
.getType()
.cast<llhd::SigType>()
.getUnderlyingType() != type.getResult(i))
return op.emitOpError("output type mismatch");
}
return success();
}
return op.emitOpError()
<< "'" << calleeAttr.getValue()
<< "' does not reference a valid proc, entity, or hw.module";
}
FunctionType llhd::InstOp::getCalleeType() {

View File

@ -28,7 +28,7 @@ llhd.entity @caller(%arg : !llhd.sig<i32>) -> () {
// -----
llhd.entity @caller() -> () {
// expected-error @+1 {{does not reference a valid proc or entity}}
// expected-error @+1 {{does not reference a valid proc, entity, or hw.module}}
llhd.inst "does_not_exist" @does_not_exist() -> () : () -> ()
}
@ -41,3 +41,24 @@ llhd.entity @test_uniqueness() -> () {
// expected-error @+1 {{Redefinition of instance named 'inst'!}}
llhd.inst "inst" @empty() -> () : () -> ()
}
// -----
hw.module @module(%arg0: i2) -> () {}
llhd.entity @moduleTypeMismatch(%arg0: !llhd.sig<i3>) -> () {
// expected-error @+1 {{input type mismatch}}
llhd.inst "inst" @module(%arg0) -> () : (!llhd.sig<i3>) -> ()
}
// -----
hw.module @module() -> (arg0: i2) {
%0 = hw.constant 0 : i2
hw.output %0 : i2
}
llhd.entity @moduleTypeMismatch() -> (%arg0: !llhd.sig<i3>) {
// expected-error @+1 {{output type mismatch}}
llhd.inst "inst" @module() -> (%arg0) : () -> !llhd.sig<i3>
}

View File

@ -39,6 +39,12 @@ llhd.proc @proc(%arg0 : !llhd.sig<i32>, %arg1 : !llhd.sig<i16>) -> (%out0 : !llh
llhd.halt
}
// CHECK-LABEL: @hwModule
hw.module @hwModule(%arg0 : i32, %arg1 : i16) -> (arg2: i8) {
%0 = hw.constant 2 : i8
hw.output %0 : i8
}
// CHECK: llhd.entity @caller (%[[ARG0:.*]] : !llhd.sig<i32>, %[[ARG1:.*]] : !llhd.sig<i16>) -> (%[[OUT0:.*]] : !llhd.sig<i8>, %[[OUT1:.*]] : !llhd.sig<i4>) {
llhd.entity @caller(%arg0 : !llhd.sig<i32>, %arg1 : !llhd.sig<i16>) -> (%out0 : !llhd.sig<i8>, %out1 : !llhd.sig<i4>) {
// CHECK-NEXT: llhd.inst "empty_entity" @empty_entity() -> () : () -> ()
@ -57,5 +63,7 @@ llhd.entity @caller(%arg0 : !llhd.sig<i32>, %arg1 : !llhd.sig<i16>) -> (%out0 :
"llhd.inst"(%arg0, %arg1, %out0, %out1) {callee=@entity, operand_segment_sizes=dense<[2,2]> : vector<2xi32>, name="entity"} : (!llhd.sig<i32>, !llhd.sig<i16>, !llhd.sig<i8>, !llhd.sig<i4>) -> ()
// CHECK-NEXT: llhd.inst "proc" @proc(%[[ARG0]], %[[ARG1]]) -> (%[[OUT0]], %[[OUT1]]) : (!llhd.sig<i32>, !llhd.sig<i16>) -> (!llhd.sig<i8>, !llhd.sig<i4>)
"llhd.inst"(%arg0, %arg1, %out0, %out1) {callee=@proc, operand_segment_sizes=dense<[2,2]> : vector<2xi32>, name="proc"} : (!llhd.sig<i32>, !llhd.sig<i16>, !llhd.sig<i8>, !llhd.sig<i4>) -> ()
// CHECK-NEXT: llhd.inst "module" @hwModule(%[[ARG0]], %[[ARG1]]) -> (%[[OUT0]]) : (!llhd.sig<i32>, !llhd.sig<i16>) -> !llhd.sig<i8>
llhd.inst "module" @hwModule(%arg0, %arg1) -> (%out0) : (!llhd.sig<i32>, !llhd.sig<i16>) -> !llhd.sig<i8>
// CHECK-NEXT: }
}