[ESI] Switch to the new parameter model.

This commit is contained in:
Chris Lattner 2021-09-18 17:48:42 -07:00
parent 49f55d2a6a
commit b2d60da553
1 changed files with 21 additions and 17 deletions

View File

@ -56,6 +56,8 @@ class ESIHWBuilder : public circt::ImplicitLocOpBuilder {
public: public:
ESIHWBuilder(Operation *top); ESIHWBuilder(Operation *top);
ArrayAttr getStageParameterList(Attribute value);
HWModuleExternOp declareStage(Operation *symTable, Type); HWModuleExternOp declareStage(Operation *symTable, Type);
// Will be unused when CAPNP is undefined // Will be unused when CAPNP is undefined
HWModuleExternOp declareCosimEndpoint(Operation *symTable, Type sendType, HWModuleExternOp declareCosimEndpoint(Operation *symTable, Type sendType,
@ -69,7 +71,7 @@ public:
const StringAttr dataOutValid, dataOutReady, dataOut, dataInValid, const StringAttr dataOutValid, dataOutReady, dataOut, dataInValid,
dataInReady, dataIn; dataInReady, dataIn;
const StringAttr clk, rstn; const StringAttr clk, rstn;
const Identifier width; const StringAttr width;
// Various identifier strings. Keep them all here in case we rename them. // Various identifier strings. Keep them all here in case we rename them.
static constexpr char dataStr[] = "data", validStr[] = "valid", static constexpr char dataStr[] = "data", validStr[] = "valid",
@ -109,7 +111,7 @@ ESIHWBuilder::ESIHWBuilder(Operation *top)
dataIn(StringAttr::get(getContext(), "DataIn")), dataIn(StringAttr::get(getContext(), "DataIn")),
clk(StringAttr::get(getContext(), "clk")), clk(StringAttr::get(getContext(), "clk")),
rstn(StringAttr::get(getContext(), "rstn")), rstn(StringAttr::get(getContext(), "rstn")),
width(Identifier::get("WIDTH", getContext())) { width(StringAttr::get(getContext(), "WIDTH")) {
auto regions = top->getRegions(); auto regions = top->getRegions();
if (regions.size() == 0) { if (regions.size() == 0) {
@ -170,6 +172,14 @@ StringAttr ESIHWBuilder::constructInterfaceName(ChannelPort port) {
return constructUniqueSymbol(tableOp, proposedName); 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 /// Write an 'ExternModuleOp' to use a hand-coded SystemVerilog module. Said
/// module implements pipeline stage, adding 1 cycle latency. This particular /// module implements pipeline stage, adding 1 cycle latency. This particular
/// implementation is double-buffered and fully pipelines the reverse-flow ready /// 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}, {x, PortDirection::OUTPUT, dataType, 1},
{xValid, PortDirection::OUTPUT, getI1Type(), 2}, {xValid, PortDirection::OUTPUT, getI1Type(), 2},
{xReady, PortDirection::INPUT, getI1Type(), 4}}; {xReady, PortDirection::INPUT, getI1Type(), 4}};
stage = create<HWModuleExternOp>( stage = create<HWModuleExternOp>(
constructUniqueSymbol(symTable, "ESI_PipelineStage"), ports, constructUniqueSymbol(symTable, "ESI_PipelineStage"), ports,
"ESI_PipelineStage"); "ESI_PipelineStage", getStageParameterList({}));
return stage; return stage;
} }
@ -563,11 +574,8 @@ void ESIPortsPass::updateInstance(HWModuleOp mod, InstanceOp inst) {
// ----- // -----
// Clone the instance. // Clone the instance.
b.setInsertionPointAfter(inst); b.setInsertionPointAfter(inst);
DictionaryAttr parameters;
if (inst.oldParameters().hasValue())
parameters = inst.oldParameters().getValue();
auto newInst = b.create<InstanceOp>(mod, inst.instanceNameAttr(), newOperands, auto newInst = b.create<InstanceOp>(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 // 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! // Create the new instance!
DictionaryAttr parameters;
if (inst.oldParameters().hasValue())
parameters = inst.oldParameters().getValue();
InstanceOp newInst = InstanceOp newInst =
instBuilder.create<InstanceOp>(mod, inst.instanceNameAttr(), newOperands, instBuilder.create<InstanceOp>(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 // Go through the old list of non-ESI result values, and replace them with the
// new non-ESI results. // new non-ESI results.
@ -852,9 +856,10 @@ LogicalResult PipelineStageLowering::matchAndRewrite(
Operation *symTable = stage->getParentWithTrait<OpTrait::SymbolTable>(); Operation *symTable = stage->getParentWithTrait<OpTrait::SymbolTable>();
auto stageModule = builder.declareStage(symTable, chPort.getInner()); auto stageModule = builder.declareStage(symTable, chPort.getInner());
NamedAttrList stageParams;
size_t width = circt::hw::getBitWidth(chPort.getInner()); 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 // 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 // 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()); circt::Backedge stageReady = back.get(rewriter.getI1Type());
Value operands[] = {stage.clk(), stage.rstn(), unwrap.rawOutput(), Value operands[] = {stage.clk(), stage.rstn(), unwrap.rawOutput(),
unwrap.valid(), stageReady}; unwrap.valid(), stageReady};
auto stageInst = rewriter.create<InstanceOp>( auto stageInst = rewriter.create<InstanceOp>(loc, stageModule, pipeStageName,
loc, stageModule, pipeStageName, operands, operands, stageParams);
stageParams.getDictionary(rewriter.getContext()), StringAttr());
auto stageInstResults = stageInst.getResults(); auto stageInstResults = stageInst.getResults();
// Set a_ready (from the unwrap) back edge correctly to its output from stage. // Set a_ready (from the unwrap) back edge correctly to its output from stage.