16 #include "mlir/IR/SymbolTable.h"
17 #include "mlir/Pass/Pass.h"
18 #include "mlir/Transforms/DialectConversion.h"
20 using namespace circt;
37 : ImplicitLocOpBuilder(UnknownLoc::
get(top->getContext()), top),
38 a(StringAttr::
get(getContext(),
"a")),
39 aValid(StringAttr::
get(getContext(),
"a_valid")),
40 aReady(StringAttr::
get(getContext(),
"a_ready")),
41 x(StringAttr::
get(getContext(),
"x")),
42 xValid(StringAttr::
get(getContext(),
"x_valid")),
43 xReady(StringAttr::
get(getContext(),
"x_ready")),
44 dataOutValid(StringAttr::
get(getContext(),
"DataOutValid")),
45 dataOutReady(StringAttr::
get(getContext(),
"DataOutReady")),
46 dataOut(StringAttr::
get(getContext(),
"DataOut")),
47 dataInValid(StringAttr::
get(getContext(),
"DataInValid")),
48 dataInReady(StringAttr::
get(getContext(),
"DataInReady")),
49 dataIn(StringAttr::
get(getContext(),
"DataIn")),
50 clk(StringAttr::
get(getContext(),
"clk")),
51 rst(StringAttr::
get(getContext(),
"rst")),
52 width(StringAttr::
get(getContext(),
"WIDTH")) {
54 auto regions = top->getRegions();
55 if (regions.empty()) {
56 top->emitError(
"ESI HW Builder needs a region to insert HW.");
58 auto ®ion = regions.front();
60 setInsertionPoint(®ion.front(), region.front().begin());
64 StringRef proposedNameRef) {
65 SmallString<64> proposedName = proposedNameRef;
68 for (
char &ch : proposedName) {
76 size_t baseLength = proposedName.size();
78 while (SymbolTable::lookupSymbolIn(tableOp, proposedName)) {
79 proposedName.resize(baseLength);
80 proposedName.append(llvm::utostr(++tries));
88 getInsertionPoint()->getParentWithTrait<mlir::OpTrait::SymbolTable>();
91 std::string portTypeName;
92 llvm::raw_string_ostream nameOS(portTypeName);
93 TypeSwitch<Type>(port.getInner())
94 .Case([&](hw::ArrayType arr) {
95 nameOS <<
"ArrayOf" << arr.getNumElements() <<
'x'
96 << arr.getElementType();
98 .Case([&](hw::StructType t) { nameOS <<
"Struct"; })
99 .Default([&](Type t) { nameOS << port.getInner(); });
102 ssize_t i = portTypeName.size() - 1;
103 while (i >= 0 && portTypeName[i] ==
'_') {
106 portTypeName = portTypeName.substr(0, i + 1);
109 SmallString<64> proposedName(
"IValidReady_");
110 proposedName.append(portTypeName);
126 PipelineStageOp stage) {
127 Type dataType = stage.innerType();
138 llvm::SmallVector<PortInfo> ports = {
154 stageMod = create<HWModuleExternOp>(
166 HWModuleExternOp &endpoint =
183 SmallVector<Attribute, 8> params;
191 endpoint = create<HWModuleExternOp>(
203 return ifaceIter->second;
211 create<InterfaceSignalOp>(
validStr, getI1Type());
212 create<InterfaceSignalOp>(
readyStr, getI1Type());
213 create<InterfaceSignalOp>(
dataStr, chan.getInner());
214 llvm::SmallVector<StringRef> validDataStrs;
216 validDataStrs.push_back(
dataStr);
217 create<InterfaceModportOp>(
sinkStr,
static void registerPasses()
static StringAttr constructUniqueSymbol(Operation *tableOp, StringRef proposedNameRef)
const StringAttr dataOutValid
hw::HWModuleExternOp declareCosimEndpointOp(Operation *symTable, Type sendType, Type recvType) LLVM_ATTRIBUTE_UNUSED
Write an 'ExternModuleOp' to use a hand-coded SystemVerilog module.
static constexpr char validStr[]
const StringAttr dataInValid
const StringAttr dataOutReady
static constexpr char sinkStr[]
llvm::DenseMap< Type, sv::InterfaceOp > portTypeLookup
static constexpr char readyStr[]
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.
llvm::DenseMap< std::pair< Type, Type >, hw::HWModuleExternOp > declaredCosimEndpointOp
sv::InterfaceOp constructInterface(ChannelType)
ESIHWBuilder(Operation *top)
sv::InterfaceOp getOrConstructInterface(ChannelType)
Return the InterfaceType which corresponds to an ESI port type.
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.
This file defines an intermediate representation for circuits acting as an abstraction for constraint...
This holds the name, type, direction of a module's ports.