mirror of https://github.com/llvm/circt.git
[FIRRTL] Handle memTap on Memories excluded from MemToReg (#3102)
Handle MemTap annotation on Memories that are excluded from `MemToRegOfVec` transformation. This fixes an issue with the commit #26276bf which updated this pass to only work on registers that were generated by `MemToRegOfVec` transformation. The assumption here was that every MemOp, should either be lowered to registers by `MemToRegOfVec` or to `FMemModuleOp` by `LowerMemory`. So, the GCT pass shouldn't expect to see a `MemOp`. But yesterday's commit #b923963, updated the `MemToRegOfVec` to exclude testbench memories but made the incorrect assumption that testbench memories wouldn't have memtap annotations. Finally this commit fixes that assumption and handles the Memtap annotation on `MemOp`s.
This commit is contained in:
parent
0a542f9694
commit
ddb1f6e8bd
|
@ -904,6 +904,35 @@ void GrandCentralTapsPass::processAnnotation(AnnotatedPort &portAnno,
|
|||
portWiring.push_back(std::move(wiring));
|
||||
return;
|
||||
}
|
||||
// This handles the case when the memtap is on a MemOp, which shouldn't have
|
||||
// the PortID attribute. Lookup the op without the portID key.
|
||||
if (auto *op = tappedOps.lookup({key.first, {}})) {
|
||||
|
||||
// Extract the memory location we're supposed to access.
|
||||
auto word = portAnno.anno.getMember<IntegerAttr>("portID");
|
||||
if (!word) {
|
||||
blackBox.extModule.emitError("MemTapAnnotation annotation on port ")
|
||||
<< portName << " missing \"word\" attribute";
|
||||
signalPassFailure();
|
||||
return;
|
||||
}
|
||||
// Formulate a hierarchical reference into the memory.
|
||||
// CAVEAT: This just assumes that the memory will map to something that
|
||||
// can be indexed in the final Verilog. If the memory gets turned into
|
||||
// an instance of some sort, we lack the information necessary to go in
|
||||
// and access individual elements of it. This will break horribly since
|
||||
// we generate memory impls out-of-line already, and memories coming
|
||||
// from an external generator are even worse. This needs a special node
|
||||
// in the IR that can properly inject the memory array on emission.
|
||||
if (!nla)
|
||||
wiring.prefices =
|
||||
instancePaths.getAbsolutePaths(op->getParentOfType<FModuleOp>());
|
||||
wiring.target = PortWiring::Target(op);
|
||||
("Memory[" + Twine(word.getValue().getLimitedValue()) + "]")
|
||||
.toVector(wiring.suffix);
|
||||
portWiring.push_back(std::move(wiring));
|
||||
return;
|
||||
}
|
||||
blackBox.extModule.emitOpError(
|
||||
"MemTapAnnotation annotation was not scattered to "
|
||||
"an operation: ")
|
||||
|
|
|
@ -3,10 +3,7 @@
|
|||
; - github.com/sifive/$internal:
|
||||
; - src/test/scala/grandcentral/DataTapsTest.scala
|
||||
|
||||
circuit Top : %[[{
|
||||
"class": "sifive.enterprise.firrtl.MarkDUTAnnotation",
|
||||
"target": "~Top|Child"
|
||||
}]]
|
||||
circuit Top :
|
||||
extmodule BlackBox :
|
||||
input in : UInt<1>
|
||||
output out : UInt<1>
|
||||
|
@ -88,6 +85,6 @@ circuit Top : %[[{
|
|||
; CHECK: module MemTap_2_impl_0(
|
||||
; CHECK: output _1,
|
||||
; CHECK: _0);
|
||||
; CHECK: assign _1 = Top.unsigned_0.signed_0.always_1;
|
||||
; CHECK: assign _0 = Top.unsigned_0.signed_0.always_0;
|
||||
; CHECK: assign _1 = Top.unsigned_0.signed_0.always_ext.Memory[1];
|
||||
; CHECK: assign _0 = Top.unsigned_0.signed_0.always_ext.Memory[0];
|
||||
; CHECK: endmodule
|
||||
|
|
Loading…
Reference in New Issue