mirror of https://github.com/llvm/circt.git
[MSFT] [Py] Add physical location and switch instance attributes to python module (#1606)
This commit is contained in:
parent
21485874c8
commit
43ccc6584e
|
@ -51,6 +51,30 @@ MLIR_CAPI_EXPORTED void mlirMSFTAddPhysLocationAttr(MlirOperation op,
|
|||
DeviceType type, long x,
|
||||
long y, long num);
|
||||
|
||||
// Values represented in `MSFT.td`.
|
||||
typedef uint32_t CirctMSFTDevType;
|
||||
|
||||
bool circtMSFTAttributeIsAPhysLocationAttribute(MlirAttribute);
|
||||
MlirAttribute circtMSFTPhysLocationAttrGet(MlirContext, CirctMSFTDevType,
|
||||
uint64_t x, uint64_t y,
|
||||
uint64_t num);
|
||||
CirctMSFTDevType circtMSFTPhysLocationAttrGetDeviceType(MlirAttribute);
|
||||
uint64_t circtMSFTPhysLocationAttrGetX(MlirAttribute);
|
||||
uint64_t circtMSFTPhysLocationAttrGetY(MlirAttribute);
|
||||
uint64_t circtMSFTPhysLocationAttrGetNum(MlirAttribute);
|
||||
|
||||
typedef struct {
|
||||
MlirAttribute instance;
|
||||
MlirAttribute attr;
|
||||
} CirctMSFTSwitchInstanceCase;
|
||||
|
||||
bool circtMSFTAttributeIsASwitchInstanceAttribute(MlirAttribute);
|
||||
MlirAttribute circtMSFTSwitchInstanceAttrGet(
|
||||
MlirContext, CirctMSFTSwitchInstanceCase *listOfCases, size_t numCases);
|
||||
size_t circtMSFTSwitchInstanceAttrGetNumCases(MlirAttribute);
|
||||
void circtMSFTSwitchInstanceAttrGetCases(MlirAttribute,
|
||||
CirctMSFTSwitchInstanceCase *dstArray,
|
||||
size_t space);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -61,7 +61,7 @@ def SwitchInstance : MSFT_Attr<"SwitchInstance"> {
|
|||
let summary = "Select an attribute to be use based on the instance";
|
||||
let mnemonic = "switch.inst";
|
||||
let parameters = (ins
|
||||
ArrayRefParameter<"InstIDAttrPair">:$instPairs);
|
||||
ArrayRefParameter<"SwitchInstanceCase">:$cases);
|
||||
|
||||
let extraClassDeclaration = [{
|
||||
Attribute lookup(InstanceIDAttr);
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
namespace circt {
|
||||
namespace msft {
|
||||
using InstanceIDAttr = mlir::SymbolRefAttr;
|
||||
using InstIDAttrPair = std::pair<InstanceIDAttr, Attribute>;
|
||||
using SwitchInstanceCase = std::pair<InstanceIDAttr, Attribute>;
|
||||
} // namespace msft
|
||||
} // namespace circt
|
||||
|
||||
|
|
|
@ -5,16 +5,16 @@ import circt
|
|||
from circt import msft
|
||||
from circt.dialects import hw, seq
|
||||
|
||||
from mlir.ir import *
|
||||
import mlir.ir as ir
|
||||
import sys
|
||||
|
||||
with Context() as ctx, Location.unknown():
|
||||
with ir.Context() as ctx, ir.Location.unknown():
|
||||
circt.register_dialects(ctx)
|
||||
i32 = IntegerType.get_signless(32)
|
||||
i1 = IntegerType.get_signless(1)
|
||||
i32 = ir.IntegerType.get_signless(32)
|
||||
i1 = ir.IntegerType.get_signless(1)
|
||||
|
||||
m = Module.create()
|
||||
with InsertionPoint(m.body):
|
||||
m = ir.Module.create()
|
||||
with ir.InsertionPoint(m.body):
|
||||
# CHECK: hw.module @MyWidget()
|
||||
# CHECK: hw.output
|
||||
op = hw.HWModuleOp(name='MyWidget',
|
||||
|
@ -26,7 +26,7 @@ with Context() as ctx, Location.unknown():
|
|||
output_ports=[],
|
||||
body_builder=lambda module: hw.OutputOp([]))
|
||||
|
||||
with InsertionPoint.at_block_terminator(top.body.blocks[0]):
|
||||
with ir.InsertionPoint.at_block_terminator(top.body.blocks[0]):
|
||||
inst = op.create("inst1")
|
||||
msft.locate(inst.operation, "mem", devtype=msft.M20K, x=50, y=100, num=1)
|
||||
# CHECK: hw.instance "inst1" @MyWidget() {"loc:mem" = #msft.physloc<M20K, 50, 100, 1>, parameters = {}} : () -> ()
|
||||
|
@ -39,6 +39,16 @@ with Context() as ctx, Location.unknown():
|
|||
|
||||
m.operation.print()
|
||||
|
||||
physAttr = msft.PhysLocationAttr.get(msft.M20K, x=2, y=6, num=1)
|
||||
|
||||
# CHECK: #msft.physloc<M20K, 2, 6, 1>
|
||||
print(physAttr)
|
||||
|
||||
inst = ir.Attribute.parse("@foo::@bar")
|
||||
# CHECK-NEXT: #msft.switch.inst<@foo::@bar=#msft.physloc<M20K, 2, 6, 1>>
|
||||
instSwitch = msft.SwitchInstance.get([(inst, physAttr)])
|
||||
print(instSwitch)
|
||||
|
||||
# CHECK-LABEL: === tcl ===
|
||||
print("=== tcl ===")
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@ static void registerGenerator(MlirContext ctxt, std::string opName,
|
|||
parameters);
|
||||
}
|
||||
|
||||
using namespace mlir::python::adaptors;
|
||||
|
||||
/// Populate the msft python module.
|
||||
void circt::python::populateDialectMSFTSubmodule(py::module &m) {
|
||||
mlirMSFTRegisterPasses();
|
||||
|
@ -65,4 +67,63 @@ void circt::python::populateDialectMSFTSubmodule(py::module &m) {
|
|||
|
||||
m.def("register_generator", &::registerGenerator,
|
||||
"Register a generator for a design module");
|
||||
|
||||
mlir_attribute_subclass(m, "PhysLocationAttr",
|
||||
circtMSFTAttributeIsAPhysLocationAttribute)
|
||||
.def_classmethod(
|
||||
"get",
|
||||
[](py::object cls, DeviceType devType, uint64_t x, uint64_t y,
|
||||
uint64_t num, MlirContext ctxt) {
|
||||
return cls(circtMSFTPhysLocationAttrGet(ctxt, (uint64_t)devType, x,
|
||||
y, num));
|
||||
},
|
||||
"Create a physical location attribute", py::arg(),
|
||||
py::arg("dev_type"), py::arg("x"), py::arg("y"), py::arg("num"),
|
||||
py::arg("ctxt") = py::none())
|
||||
.def_property_readonly(
|
||||
"devtype",
|
||||
[](MlirAttribute self) {
|
||||
return (DeviceType)circtMSFTPhysLocationAttrGetDeviceType(self);
|
||||
})
|
||||
.def_property_readonly("x",
|
||||
[](MlirAttribute self) {
|
||||
return (DeviceType)circtMSFTPhysLocationAttrGetX(
|
||||
self);
|
||||
})
|
||||
.def_property_readonly("y",
|
||||
[](MlirAttribute self) {
|
||||
return (DeviceType)circtMSFTPhysLocationAttrGetY(
|
||||
self);
|
||||
})
|
||||
.def_property_readonly("num", [](MlirAttribute self) {
|
||||
return (DeviceType)circtMSFTPhysLocationAttrGetNum(self);
|
||||
});
|
||||
|
||||
mlir_attribute_subclass(m, "SwitchInstance",
|
||||
circtMSFTAttributeIsASwitchInstanceAttribute)
|
||||
.def_classmethod(
|
||||
"get",
|
||||
[](py::object cls,
|
||||
std::vector<std::tuple<MlirAttribute, MlirAttribute>> listOfCases,
|
||||
MlirContext ctxt) {
|
||||
std::vector<CirctMSFTSwitchInstanceCase> cases;
|
||||
for (auto p : listOfCases)
|
||||
cases.push_back({std::get<0>(p), std::get<1>(p)});
|
||||
return cls(circtMSFTSwitchInstanceAttrGet(ctxt, cases.data(),
|
||||
cases.size()));
|
||||
},
|
||||
"Create an instance switch attribute", py::arg(),
|
||||
py::arg("list_of_cases"), py::arg("ctxt") = py::none())
|
||||
.def_property_readonly(
|
||||
"cases",
|
||||
[](MlirAttribute self) {
|
||||
size_t numCases = circtMSFTSwitchInstanceAttrGetNumCases(self);
|
||||
std::vector<CirctMSFTSwitchInstanceCase> cases(numCases);
|
||||
circtMSFTSwitchInstanceAttrGetCases(self, cases.data(),
|
||||
cases.max_size());
|
||||
return cases;
|
||||
})
|
||||
.def_property_readonly("num_cases", [](MlirAttribute self) {
|
||||
return circtMSFTSwitchInstanceAttrGetNumCases(self);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
#include "mlir/CAPI/Registration.h"
|
||||
#include "mlir/CAPI/Support.h"
|
||||
#include "mlir/CAPI/Utils.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(MSFT, msft, circt::msft::MSFTDialect)
|
||||
|
||||
using namespace circt;
|
||||
using namespace circt::msft;
|
||||
|
||||
void mlirMSFTRegisterPasses() { circt::msft::registerMSFTPasses(); }
|
||||
|
@ -50,3 +52,61 @@ void mlirMSFTAddPhysLocationAttr(MlirOperation cOp, const char *entityName,
|
|||
entity.append(entityName);
|
||||
op->setAttr(entity, loc);
|
||||
}
|
||||
|
||||
bool circtMSFTAttributeIsAPhysLocationAttribute(MlirAttribute attr) {
|
||||
return unwrap(attr).isa<PhysLocationAttr>();
|
||||
}
|
||||
MlirAttribute circtMSFTPhysLocationAttrGet(MlirContext cCtxt,
|
||||
CirctMSFTDevType devType, uint64_t x,
|
||||
uint64_t y, uint64_t num) {
|
||||
auto ctxt = unwrap(cCtxt);
|
||||
return wrap(PhysLocationAttr::get(
|
||||
ctxt, DeviceTypeAttr::get(ctxt, (DeviceType)devType), x, y, num));
|
||||
}
|
||||
|
||||
CirctMSFTDevType circtMSFTPhysLocationAttrGetDeviceType(MlirAttribute attr) {
|
||||
return (CirctMSFTDevType)unwrap(attr)
|
||||
.cast<PhysLocationAttr>()
|
||||
.getDevType()
|
||||
.getValue();
|
||||
}
|
||||
uint64_t circtMSFTPhysLocationAttrGetX(MlirAttribute attr) {
|
||||
return (CirctMSFTDevType)unwrap(attr).cast<PhysLocationAttr>().getX();
|
||||
}
|
||||
uint64_t circtMSFTPhysLocationAttrGetY(MlirAttribute attr) {
|
||||
return (CirctMSFTDevType)unwrap(attr).cast<PhysLocationAttr>().getY();
|
||||
}
|
||||
uint64_t circtMSFTPhysLocationAttrGetNum(MlirAttribute attr) {
|
||||
return (CirctMSFTDevType)unwrap(attr).cast<PhysLocationAttr>().getNum();
|
||||
}
|
||||
|
||||
bool circtMSFTAttributeIsASwitchInstanceAttribute(MlirAttribute attr) {
|
||||
return unwrap(attr).isa<SwitchInstanceAttr>();
|
||||
}
|
||||
MlirAttribute
|
||||
circtMSFTSwitchInstanceAttrGet(MlirContext cCtxt,
|
||||
CirctMSFTSwitchInstanceCase *listOfCases,
|
||||
size_t numCases) {
|
||||
SmallVector<SwitchInstanceCase, 64> cases;
|
||||
for (size_t i = 0; i < numCases; ++i) {
|
||||
CirctMSFTSwitchInstanceCase pair = listOfCases[i];
|
||||
auto instance = unwrap(pair.instance).cast<SymbolRefAttr>();
|
||||
auto attr = unwrap(pair.attr);
|
||||
cases.push_back(std::make_pair(instance, attr));
|
||||
}
|
||||
return wrap(SwitchInstanceAttr::get(unwrap(cCtxt), cases));
|
||||
}
|
||||
size_t circtMSFTSwitchInstanceAttrGetNumCases(MlirAttribute attr) {
|
||||
return unwrap(attr).cast<SwitchInstanceAttr>().getCases().size();
|
||||
}
|
||||
void circtMSFTSwitchInstanceAttrGetCases(MlirAttribute attr,
|
||||
CirctMSFTSwitchInstanceCase *dstArray,
|
||||
size_t space) {
|
||||
auto sw = unwrap(attr).cast<SwitchInstanceAttr>();
|
||||
ArrayRef<SwitchInstanceCase> cases = sw.getCases();
|
||||
assert(space >= cases.size());
|
||||
for (size_t i = 0, e = cases.size(); i < e; ++i) {
|
||||
auto c = cases[i];
|
||||
dstArray[i] = {wrap(c.first), wrap(c.second)};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ Attribute SwitchInstanceAttr::parse(MLIRContext *ctxt, DialectAsmParser &p,
|
|||
if (!p.parseOptionalGreater())
|
||||
return SwitchInstanceAttr::get(ctxt, {});
|
||||
|
||||
SmallVector<InstIDAttrPair> instPairs;
|
||||
SmallVector<SwitchInstanceCase> instPairs;
|
||||
do {
|
||||
SymbolRefAttr instId;
|
||||
Attribute attr;
|
||||
|
@ -45,7 +45,7 @@ Attribute SwitchInstanceAttr::parse(MLIRContext *ctxt, DialectAsmParser &p,
|
|||
|
||||
void SwitchInstanceAttr::print(DialectAsmPrinter &p) const {
|
||||
p << "switch.inst<";
|
||||
llvm::interleaveComma(getInstPairs(), p, [&](auto instPair) {
|
||||
llvm::interleaveComma(getCases(), p, [&](auto instPair) {
|
||||
p << instPair.first << '=';
|
||||
p.printAttribute(instPair.second);
|
||||
});
|
||||
|
@ -54,7 +54,7 @@ void SwitchInstanceAttr::print(DialectAsmPrinter &p) const {
|
|||
|
||||
Attribute SwitchInstanceAttr::lookup(InstanceIDAttr id) {
|
||||
// TODO: This is obviously very slow. Speed this up by using a sorted list.
|
||||
for (auto pair : getInstPairs())
|
||||
for (auto pair : getCases())
|
||||
if (pair.first == id)
|
||||
return pair.second;
|
||||
return Attribute();
|
||||
|
|
Loading…
Reference in New Issue