16 #include "mlir/IR/SymbolTable.h"
17 #include "mlir/Pass/Pass.h"
18 #include "mlir/Transforms/DialectConversion.h"
20 using namespace circt;
28 llvm::raw_string_ostream(typeID) << t;
33 if (
auto ch = dyn_cast<ChannelType>(t))
49 : ImplicitLocOpBuilder(UnknownLoc::
get(top->getContext()), top),
50 a(StringAttr::
get(getContext(),
"a")),
51 aValid(StringAttr::
get(getContext(),
"a_valid")),
52 aReady(StringAttr::
get(getContext(),
"a_ready")),
53 x(StringAttr::
get(getContext(),
"x")),
54 xValid(StringAttr::
get(getContext(),
"x_valid")),
55 xReady(StringAttr::
get(getContext(),
"x_ready")),
56 dataOutValid(StringAttr::
get(getContext(),
"DataOutValid")),
57 dataOutReady(StringAttr::
get(getContext(),
"DataOutReady")),
58 dataOut(StringAttr::
get(getContext(),
"DataOut")),
59 dataInValid(StringAttr::
get(getContext(),
"DataInValid")),
60 dataInReady(StringAttr::
get(getContext(),
"DataInReady")),
61 dataIn(StringAttr::
get(getContext(),
"DataIn")),
62 clk(StringAttr::
get(getContext(),
"clk")),
63 rst(StringAttr::
get(getContext(),
"rst")),
64 width(StringAttr::
get(getContext(),
"WIDTH")) {
66 auto regions = top->getRegions();
67 if (regions.empty()) {
68 top->emitError(
"ESI HW Builder needs a region to insert HW.");
70 auto ®ion = regions.front();
72 setInsertionPoint(®ion.front(), region.front().begin());
76 StringRef proposedNameRef) {
77 SmallString<64> proposedName = proposedNameRef;
80 for (
char &ch : proposedName) {
88 size_t baseLength = proposedName.size();
90 while (SymbolTable::lookupSymbolIn(tableOp, proposedName)) {
91 proposedName.resize(baseLength);
92 proposedName.append(llvm::utostr(++tries));
100 getInsertionPoint()->getParentWithTrait<mlir::OpTrait::SymbolTable>();
103 std::string portTypeName;
104 llvm::raw_string_ostream nameOS(portTypeName);
105 TypeSwitch<Type>(port.getInner())
106 .Case([&](hw::ArrayType arr) {
107 nameOS <<
"ArrayOf" << arr.getNumElements() <<
'x'
108 << arr.getElementType();
110 .Case([&](hw::StructType t) { nameOS <<
"Struct"; })
111 .Default([&](Type t) { nameOS << port.getInner(); });
114 ssize_t i = portTypeName.size() - 1;
115 while (i >= 0 && portTypeName[i] ==
'_') {
118 portTypeName = portTypeName.substr(0, i + 1);
121 SmallString<64> proposedName(
"IValidReady_");
122 proposedName.append(portTypeName);
138 PipelineStageOp stage) {
139 Type dataType = stage.innerType();
150 llvm::SmallVector<PortInfo> ports = {
166 stageMod = create<HWModuleExternOp>(
180 SmallVector<Attribute, 8> params;
189 getIntegerType(32,
false)));
208 SmallVector<Attribute, 8> params;
217 getIntegerType(32,
false)));
237 return ifaceIter->second;
245 create<InterfaceSignalOp>(
validStr, getI1Type());
246 create<InterfaceSignalOp>(
readyStr, getI1Type());
247 create<InterfaceSignalOp>(
dataStr, chan.getInner());
248 llvm::SmallVector<StringRef> validDataStrs;
250 validDataStrs.push_back(
dataStr);
251 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.