From b2d60da55348166ec855c4258fcd679c2ef859c6 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 18 Sep 2021 17:48:42 -0700 Subject: [PATCH] [ESI] Switch to the new parameter model. --- lib/Dialect/ESI/ESIPasses.cpp | 38 +++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/lib/Dialect/ESI/ESIPasses.cpp b/lib/Dialect/ESI/ESIPasses.cpp index 2648cb422e..a870bb1f0d 100644 --- a/lib/Dialect/ESI/ESIPasses.cpp +++ b/lib/Dialect/ESI/ESIPasses.cpp @@ -56,6 +56,8 @@ class ESIHWBuilder : public circt::ImplicitLocOpBuilder { public: ESIHWBuilder(Operation *top); + ArrayAttr getStageParameterList(Attribute value); + HWModuleExternOp declareStage(Operation *symTable, Type); // Will be unused when CAPNP is undefined HWModuleExternOp declareCosimEndpoint(Operation *symTable, Type sendType, @@ -69,7 +71,7 @@ public: const StringAttr dataOutValid, dataOutReady, dataOut, dataInValid, dataInReady, dataIn; const StringAttr clk, rstn; - const Identifier width; + const StringAttr width; // Various identifier strings. Keep them all here in case we rename them. static constexpr char dataStr[] = "data", validStr[] = "valid", @@ -109,7 +111,7 @@ ESIHWBuilder::ESIHWBuilder(Operation *top) dataIn(StringAttr::get(getContext(), "DataIn")), clk(StringAttr::get(getContext(), "clk")), rstn(StringAttr::get(getContext(), "rstn")), - width(Identifier::get("WIDTH", getContext())) { + width(StringAttr::get(getContext(), "WIDTH")) { auto regions = top->getRegions(); if (regions.size() == 0) { @@ -170,6 +172,14 @@ StringAttr ESIHWBuilder::constructInterfaceName(ChannelPort port) { return constructUniqueSymbol(tableOp, proposedName); } +/// Return a parameter list for the stage module with the specified value. +ArrayAttr ESIHWBuilder::getStageParameterList(Attribute value) { + auto type = IntegerType::get(width.getContext(), 32, IntegerType::Unsigned); + auto widthParam = + ParameterAttr::get(width, TypeAttr::get(type), value, width.getContext()); + return ArrayAttr::get(width.getContext(), widthParam); +} + /// Write an 'ExternModuleOp' to use a hand-coded SystemVerilog module. Said /// module implements pipeline stage, adding 1 cycle latency. This particular /// implementation is double-buffered and fully pipelines the reverse-flow ready @@ -192,9 +202,10 @@ HWModuleExternOp ESIHWBuilder::declareStage(Operation *symTable, {x, PortDirection::OUTPUT, dataType, 1}, {xValid, PortDirection::OUTPUT, getI1Type(), 2}, {xReady, PortDirection::INPUT, getI1Type(), 4}}; + stage = create( constructUniqueSymbol(symTable, "ESI_PipelineStage"), ports, - "ESI_PipelineStage"); + "ESI_PipelineStage", getStageParameterList({})); return stage; } @@ -563,11 +574,8 @@ void ESIPortsPass::updateInstance(HWModuleOp mod, InstanceOp inst) { // ----- // Clone the instance. b.setInsertionPointAfter(inst); - DictionaryAttr parameters; - if (inst.oldParameters().hasValue()) - parameters = inst.oldParameters().getValue(); auto newInst = b.create(mod, inst.instanceNameAttr(), newOperands, - parameters, inst.sym_nameAttr()); + inst.parameters(), inst.sym_nameAttr()); // ----- // Wrap the results back into ESI channels and connect up all the ready @@ -801,13 +809,9 @@ void ESIPortsPass::updateInstance(HWModuleExternOp mod, InstanceOp inst) { } // Create the new instance! - DictionaryAttr parameters; - if (inst.oldParameters().hasValue()) - parameters = inst.oldParameters().getValue(); - InstanceOp newInst = instBuilder.create(mod, inst.instanceNameAttr(), newOperands, - parameters, inst.sym_nameAttr()); + inst.parameters(), inst.sym_nameAttr()); // Go through the old list of non-ESI result values, and replace them with the // new non-ESI results. @@ -852,9 +856,10 @@ LogicalResult PipelineStageLowering::matchAndRewrite( Operation *symTable = stage->getParentWithTrait(); auto stageModule = builder.declareStage(symTable, chPort.getInner()); - NamedAttrList stageParams; size_t width = circt::hw::getBitWidth(chPort.getInner()); - stageParams.set(builder.width, rewriter.getUI32IntegerAttr(width)); + + ArrayAttr stageParams = + builder.getStageParameterList(rewriter.getUI32IntegerAttr(width)); // Unwrap the channel. The ready signal is a Value we haven't created yet, so // create a temp value and replace it later. Give this constant an odd-looking @@ -872,9 +877,8 @@ LogicalResult PipelineStageLowering::matchAndRewrite( circt::Backedge stageReady = back.get(rewriter.getI1Type()); Value operands[] = {stage.clk(), stage.rstn(), unwrap.rawOutput(), unwrap.valid(), stageReady}; - auto stageInst = rewriter.create( - loc, stageModule, pipeStageName, operands, - stageParams.getDictionary(rewriter.getContext()), StringAttr()); + auto stageInst = rewriter.create(loc, stageModule, pipeStageName, + operands, stageParams); auto stageInstResults = stageInst.getResults(); // Set a_ready (from the unwrap) back edge correctly to its output from stage.