16 #include "mlir/IR/SymbolTable.h"
17 #include "mlir/Pass/Pass.h"
18 #include "mlir/Transforms/DialectConversion.h"
20 using namespace circt;
27 if (
auto ch = t.dyn_cast<ChannelType>())
30 llvm::raw_string_ostream(typeID) << t;
35 if (
auto ch = t.dyn_cast<ChannelType>())
51 : ImplicitLocOpBuilder(UnknownLoc::
get(top->getContext()), top),
52 a(StringAttr::
get(getContext(),
"a")),
53 aValid(StringAttr::
get(getContext(),
"a_valid")),
54 aReady(StringAttr::
get(getContext(),
"a_ready")),
55 x(StringAttr::
get(getContext(),
"x")),
56 xValid(StringAttr::
get(getContext(),
"x_valid")),
57 xReady(StringAttr::
get(getContext(),
"x_ready")),
58 dataOutValid(StringAttr::
get(getContext(),
"DataOutValid")),
59 dataOutReady(StringAttr::
get(getContext(),
"DataOutReady")),
60 dataOut(StringAttr::
get(getContext(),
"DataOut")),
61 dataInValid(StringAttr::
get(getContext(),
"DataInValid")),
62 dataInReady(StringAttr::
get(getContext(),
"DataInReady")),
63 dataIn(StringAttr::
get(getContext(),
"DataIn")),
64 clk(StringAttr::
get(getContext(),
"clk")),
65 rst(StringAttr::
get(getContext(),
"rst")),
66 width(StringAttr::
get(getContext(),
"WIDTH")) {
68 auto regions = top->getRegions();
69 if (regions.empty()) {
70 top->emitError(
"ESI HW Builder needs a region to insert HW.");
72 auto ®ion = regions.front();
74 setInsertionPoint(®ion.front(), region.front().begin());
78 StringRef proposedNameRef) {
79 SmallString<64> proposedName = proposedNameRef;
82 for (
char &ch : proposedName) {
90 size_t baseLength = proposedName.size();
92 while (SymbolTable::lookupSymbolIn(tableOp, proposedName)) {
93 proposedName.resize(baseLength);
94 proposedName.append(llvm::utostr(++tries));
102 getInsertionPoint()->getParentWithTrait<mlir::OpTrait::SymbolTable>();
105 std::string portTypeName;
106 llvm::raw_string_ostream nameOS(portTypeName);
107 TypeSwitch<Type>(port.getInner())
108 .Case([&](hw::ArrayType arr) {
109 nameOS <<
"ArrayOf" << arr.getNumElements() <<
'x'
110 << arr.getElementType();
112 .Case([&](hw::StructType t) { nameOS <<
"Struct"; })
113 .Default([&](Type t) { nameOS << port.getInner(); });
116 ssize_t i = portTypeName.size() - 1;
117 while (i >= 0 && portTypeName[i] ==
'_') {
120 portTypeName = portTypeName.substr(0, i + 1);
123 SmallString<64> proposedName(
"IValidReady_");
124 proposedName.append(portTypeName);
140 PipelineStageOp stage) {
141 Type dataType = stage.innerType();
152 llvm::SmallVector<PortInfo> ports = {
168 stageMod = create<HWModuleExternOp>(
182 SmallVector<Attribute, 8> params;
191 getIntegerType(32,
false)));
210 SmallVector<Attribute, 8> params;
219 getIntegerType(32,
false)));
239 return ifaceIter->second;
247 create<InterfaceSignalOp>(
validStr, getI1Type());
248 create<InterfaceSignalOp>(
readyStr, getI1Type());
249 create<InterfaceSignalOp>(
dataStr, chan.getInner());
250 llvm::SmallVector<StringRef> validDataStrs;
252 validDataStrs.push_back(
dataStr);
253 create<InterfaceModportOp>(
sinkStr,
static void registerPasses()
static StringAttr constructUniqueSymbol(Operation *tableOp, StringRef proposedNameRef)
const StringAttr dataOutValid
hw::HWModuleExternOp declareCosimEndpointFromHostModule(Operation *symTable)
static constexpr char validStr[]
const StringAttr dataInValid
const StringAttr dataOutReady
static constexpr char sinkStr[]
std::optional< hw::HWModuleExternOp > declaredCosimEndpointToHostModule
llvm::DenseMap< Type, sv::InterfaceOp > portTypeLookup
static constexpr char readyStr[]
hw::HWModuleExternOp declareCosimEndpointToHostModule(Operation *symTable)
Write an 'ExternModuleOp' to use a hand-coded SystemVerilog module.
static constexpr char dataStr[]
StringAttr constructInterfaceName(ChannelType)
Construct a type-appropriate name for the interface, making sure it's not taken in the symbol table.
sv::InterfaceOp constructInterface(ChannelType)
ESIHWBuilder(Operation *top)
sv::InterfaceOp getOrConstructInterface(ChannelType)
Return the InterfaceType which corresponds to an ESI port type.
std::optional< hw::HWModuleExternOp > declaredCosimEndpointFromHostModule
llvm::DenseMap< Type, hw::HWModuleExternOp > declaredStage
static constexpr char sourceStr[]
hw::HWModuleExternOp declareStage(Operation *symTable, PipelineStageOp)
Write an 'ExternModuleOp' to use a hand-coded SystemVerilog module.
const StringAttr dataInReady
ArrayAttr getStageParameterList(Attribute value)
Return a parameter list for the stage module with the specified value.
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
uint64_t getWidth(Type t)
StringAttr getTypeID(Type t)
int64_t getBitWidth(mlir::Type type)
Return the hardware bit width of a type.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
This holds the name, type, direction of a module's ports.