mirror of https://github.com/llvm/circt.git
[ESI] Switch to the new parameter model.
This commit is contained in:
parent
49f55d2a6a
commit
b2d60da553
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue