首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将PCIe设备连接到芯片厂的设计中

如何将PCIe设备连接到芯片厂的设计中
EN

Stack Overflow用户
提问于 2022-06-12 09:36:29
回答 1查看 102关注 0票数 0

我试图将PCIe设备连接到芯片厂的设计中,使用现有的edge覆盖VCU118 (稍微修改一下,因为我使用的是不同的板,但这不重要)。

@michael-etzkorn已经在Github上发布了一篇关于这个问题的问题文章,其中他们解释了为什么他们只能使用两个不同的时钟来实现这个功能。

如果我能得到一些关于如何做到这一点的提示(这个问题遗漏了信任的一些实现细节),如果不添加额外的时钟(@michael 指出这可能会引起一些问题),我会很感激。

EN

回答 1

Stack Overflow用户

发布于 2022-06-13 14:05:54

根据你要点中的工作,看起来你已经回答了大部分原来的问题,但既然我已经把这个问题打出来了,我会把它作为一个答案。

要连接任何端口,基本上需要做三件事。

  1. 创建一个IOBinder
  2. 创建一个HarnessBinder
  3. 连接TestHarness中的外交节点

IOBinder将系统中的包从系统中取出,并将其穿孔到芯片组。HarnessBinder将ChipTop中的IO连接到线束上。外交谈判外交节点的参数。这个步骤可能是可选的,但是许多模块,比如PCIe覆盖层中的XDMA包装器,都是外交步骤,所以这通常是必需的步骤。

IOBinder

IOBinder可以拿出你的CanHAveMasterTLMMIOPort并为它打孔。

代码语言:javascript
复制
class WithXDMASlaveIOPassthrough extends OverrideIOBinder({
    (system: CanHaveMasterTLMMIOPort) => {
        val io_xdma_slave_pins_temp = IO(DataMirror.internal.chiselTypeClone[HeterogeneousBag[TLBundle]](system.mmio_tl)).suggestName("tl_slave_mmio")
        io_xdma_slave_pins_temp <> system.mmio_tl 
        (Seq(io_xdma_slave_pins_temp), Nil)

    }
})

对于每个端口来说,这看起来可能是相对相同的。然而,我在实验上发现,我不得不为CanHaveSlaveTLPort翻转临时引脚连接CanHaveSlaveTLPort

HarnessBinder

线束绑定器检索该端口并将其连接到外部捆绑包。从线束中检索pcieClient包并连接到从IOBinders返回的ports.head。这本质上是克隆IO并将其连接到ChipTop中的包的一种奇特的函数式编程方法。

代码语言:javascript
复制
class WithPCIeClient extends OverrideHarnessBinder({
    (system: CanHaveMasterTLMMIOPort, th: BaseModule with HasHarnessSignalReferences, ports: Seq[HeterogeneousBag[TLBundle]]) => {
        require(ports.size == 1)
        th match { case vcu118th: XDMAVCU118FPGATestHarnessImp => {
            val bundles = vcu118th.xdmavcu118Outer.pcieClient.out.map(_._1)
            val pcieClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
            // pcieClientBundle <> DontCare 
            bundles.zip(pcieClientBundle).foreach{case (bundle, io) => bundle <> io}
            pcieClientBundle <> ports.head 
        } }
    }
})

另外,我应该注意:这并不是连接到线束的理想方式,因为它可能的BundleMap用户字段是生成的,除非您在那里有pcieClientBundle <> DontCare,否则不会驱动它们。我发现我不得不公开AXI端口,并修改覆盖以输出axi节点,以便在testharness和ChipTop区域之间进行外交操作。

有关该问题的说明以及一些更多的信息,请访问:

信号以及为什么它们只在我的HarnessBinder中有条件地未初始化?

所有这些代码都是关于这个问题的。

TestHarness外交关系

代码语言:javascript
复制
val overlayOutput = dp(PCIeOverlayKey).last.place(PCIeDesignInput(wrangler=pcieWrangler.node, corePLL=harnessSysPLL)).overlayOutput
val (pcieNode: TLNode, pcieIntNode: IntOutwardNode) = (overlayOutput.pcieNode, overlayOutput.intNode)
val (pcieSlaveTLNode: TLIdentityNode, pcieMasterTLNode: TLAsyncSinkNode) = (pcieNode.inward, pcieNode.outward)

val inParamsMMIOPeriph = topDesign match { case td: ChipTop => 
        td.lazySystem match { case lsys: CanHaveMasterTLMMIOPort => 
              lsys.mmioTLNode.edges.in(0)
        }
    }
 val inParamsControl = topDesign match {case td: ChipTop => 
        td.lazySystem match { case lsys: CanHaveMasterTLCtrlPort => 
            lsys.ctrlTLNode.edges.in(0)
        }
    }

 val pcieClient = TLClientNode(Seq(inParamsMMIOPeriph.master))
 val pcieCtrlClient = TLClientNode(Seq(inParamsControl.master))
 val connectorNode = TLIdentityNode()


 // pcieSlaveTLNode should be driven for both the control slave and the axi bridge slave
 connectorNode := pcieClient 
 connectorNode := pcieCtrlClient 
 pcieSlaveTLNode :=* connectorNode

时钟组..。(未解决)

pcieWrangler是我连接axi_aclk的尝试。这不对。这只是创建一个与axi_aclk相同的250 axi_aclk频率的第二个时钟,所以它主要工作,但使用第二个时钟是不正确的。

代码语言:javascript
复制
    val sysClk2Node = dp(ClockInputOverlayKey).last.place(ClockInputDesignInput()).overlayOutput.node 
    val pciePLL = dp(PLLFactoryKey)()
    pciePLL := sysClk2Node 

    val pcieClock = ClockSinkNode(freqMHz = 250) // Is this the reference clock? 
    val pcieWrangler = LazyModule(new ResetWrangler)
    val pcieGroup = ClockGroup()

    pcieClock := pcieWrangler.node := pcieGroup := pciePLL 

也许您可以进行实验,并了解如何将axi_aclk连接为axi异步逻辑的驱动程序:)

我很乐意就此提出一个问题,因为我自己还不知道答案。

回答一些后续问题

我如何知道我应该为PCIe (主控)预留多大的地址范围?

对于控件,可以匹配覆盖0x4000000中的大小。对于主端口,理想情况下,只需将DMA引擎连接到能够访问主机上的完整地址范围的引擎。否则,您必须执行AXI2PCIE条转换逻辑来访问主机内存的不同区域,这并不有趣。

  1. 如何将中断节点连接到系统?

我相信,只有当您连接一个PCIe根复合体时,才会出现这种情况。如果您正在连接设备,则不需要担心中断节点。如果您确实希望添加它,则必须将NExtInterrupts(3)++添加到您的配置中。在我意识到我不需要它之前,我只了解到了这一点和TestHarness中未注释的代码。如果你觉得你做了,我们可以打开一个新的问题,并尝试更充分地回答这个问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72590994

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档