传输。
l
片内RAM模块,用于存储从PCIe链路接收来的数据和需要通过该链路发送的数据。和DMA一样,片内RAM模块也被映射到了PCIe的存储空间,所以可以被PCIe系统访问。
l
Qsys互连,Qsys工具用于将FPGA内元件连接在一起的逻辑,这样有利于数据和命令它们之间传输。

图2:Qsys PCIe端口框图
PCIe端点可以按照以下方式来使用:
l
从高速链路接收到PCIe写请求,然后将数据写入并保存到片内RAM中。
l
从高速链路接收到PCIe读请求,然后从片内RAM读出数据,并经PCIe链向请求方返回读出的数据。
l
从PCIe接收到DMA写或者读请求,然后DMA自动传输数据,数据传输结束后,DMA会向PCIe硬核触发一个中断请求。
注意上述DMA操作,只要启动,DMA可以从片内RAM读出数据并将其写入到PCIe硬核,PCIe将此操作转化为对系统其它地址空间的写请求。或者,DMA可以从PCIe硬核读数据,这个操作会被转化为向PCIe发送一个读请求,PCIe会返回数据和对应的完成包,这些数据被自动写入到片内RAM。
一步一步地完成设计
我们可以按照以下流程一步步地完成这个PCIe端点设计,首先第一步是创建Quartus
II工程。
步骤一:创建Quartus
II工程
1.
从电脑的开始菜单里启动Quartus II软件。
2.
从Quartus II软件的File菜单里选择“New Project Wizard”。
3.
当“Introduction”页面出现时,点击下一步。
4.
在新建工程的第一页,指定新建工程的路径、名称和顶层设计入口。
5.
在“What is the name of this
project”下输入“civgx_gen1x4_qsys_top”来指定设计的顶层设计入口,如图3所示。

图3:指定工程路径、名字以及设计顶层入口
6.
点击“Next”进入第一页。
7.
在第二页,即“Add Files”,可以点击
按钮找到存放源文件的目录,然后添加相应的源文件(由于一开始没有设计文件,也可以略过此步)。
a)
这里我们选择三个设计文件
i.
civgx_gen1x4_qsys_top.v
ii.
altgxb_rconfig.v
iii.
gpll.v
b)
点击“Open”加入这些设计文件到工程
8.
同上一步,可以通过改变文件类型,我们可以给工程添加SDC文件。
9.
点击“Next”进入第三页。
10.
在第三页(
Family & Device
Settings),选择
Cyclone IV GX
11.
指定器件具体型号,按一下方式滤出需要的器件型号
a)
选择FBGA封装
b)
选择672引脚数
c)
速度等级选择6
12.
最终选择EP4CGX50DF27C6,如图4所示。

图4:为工程指定具体FPGA型号
13.
剩下使用默认设置,所以直接点击“Finish”完成工程创建
步骤二:启动Qsys工具
1.
从Quartus II工具菜单下选择“Qsys”打开Qsys工具,或者直接在Quartus II工具栏里点击
按钮打开。
这是Qsys工具开始打开并启动其初始化流程。
2.
移除系统默认添加的clk_0元件,在System Contents下高亮选中“clk_0”然后点击
按钮。
此时,我们有了一个空的Qsys系统,本例,时钟将由PCIe硬核产生,所以时钟源元件在这里是不需要的。
3.
从Qsys工具的File菜单下选择save
as,在保存文件名设置为civgx_gen1x4_qsys,然后选择save。
步骤三:使用PCI Express IP Compiler加入PCIe硬核到系统
1.
在Qsys工具里找到Component Library,展开里面的Interface
Protocol,然后找到PCI并展开,最后高亮选择“IP Compiler for PCI
Express”,如图5所示。

图5:添加PCIe硬核到系统
2.
如图5所示,点击Add开始添加PCIe硬核到系统,并启动PCIe参数编辑界面。
此时我们会看到一个名为“pcie_hard_ip_0”的模块被添加到了系统,同时IP_Compiler for PCI
Express的参数编辑也被立即打开。PCIe硬核的所有参数设置都在这页界面可以找到,如果就算你对于PCIe协议不是很熟悉也没有关系,以下我们会详细介绍如何配置PCIe硬核。这时候忽略系统给出的任何错误,因为当我们连接PCIe硬核IP到系统时,这些错误都将会解决。
3.
PCIe硬核通用配置,在PCIe参数编辑器里选择“System
Settings”来进行与系统相关的设置,如图6所示。
a)
为“Lane”选择x4。
b)
为“Reference clock frequency”选择100MHz。
c)
为“Testout width”选择64bits。
d)
不勾选“Gen2 Lane Rate Mode”和“Enable 62.5MHz
application clock”。

图6:PCIe相关系统设置
4.
到“PCI Base Address Register(Type 0 Configuration
Space)”区域安照图7所示,设置PCIe的基地址寄存器(BARs)。
a)
确认BAR0(第一行)设置为64 bit Prefetchable。
这时候BAR1显示为“1-Occupied”
b)
点击BAR2(第三行)的BAR Type区域,从下拉菜单里选择“32-bit
Non-Prefechable”。
c)
保持BAR Size和Avalon Base Address区域为其默认值不变。

图7:设置PCIe端点的BAR
如图7所示,这些设置用于控制链路如何产生针对内部Avalon-MM地址空间的PCIe事务,当使用Qsys工具时,图中这些BARSize和Avalon基地址列在设备连接的时候添加。
5.
为PCIe端点配置只读寄存器,在“Device Identification
Register”框下按照图8所示,进行设置。
a)
为Vendor ID设置0x1172。
b)
为Device ID设置0xE001.
c)
为Revision ID设置0x01.
d)
为Class code设置0xFF0000.
e)
为Subsystem vendor ID设置0x1172.
f)
为Subsystem ID设置0x0004.

图8:设置设备ID寄存器
6.
“Link Capabilities”和“Error Reporting”保持默认设置。
7.
“Buffer Configuration”按照图9所示进行设置。
a)
最大载荷尺寸(Maximum Payload Size),从下拉框里选择256字节。
b)
“Desired performance for received
requests”选择设置为“High”。

图9:缓冲器配置
8.
到Avalon-MM
Settings框下配置Avalon-MM接口,按照以下要求设置,设置的界面如图10所示。
a)
在“Peripheral
Mode”下拉框下选择“Requester/Completer”。
b)
使能“Control Register Access(CRA) Avalon
slave”端口选项。
c)
其它勾选项保持不使能状态。

图10:设置Avalon-MM接口
9.
到“Address
Translation”框下按照以下要求设置Avalon地址转换,设置好的界面如图11所示。
a)
为地址转换表配置选择动态转换表。
b)
地址页选择2.
c)
每页地址范围选择1MByte-20 bits。

图11:Avalon地址转换配置
这些设置控制Avalon-MM到PCI Express的地址转换,意味着Qsys系统内部的数据传输是如何转换为PCI
Express的请求的。由于地址转换设置为动态转换,所以IP_Compiler for PCI
Express编辑器的最后一项设置,即“Address Translation Table
Contents”不需要编辑设置。
10.
点击“Finish”关闭PCIe参数设置页面,返回到Qsys系统。
这样一个名为“pcie_hard_ip_0”的PCIe硬核已经加入到了Qsys系统,它共有20种不同的接口(其中许多为管道接口,conduits),我们需要根据如何使用该硬核来连接这些接口,后面我们会对这些接口进行连接,图12显示了这时候Qsys系统界面,我们看到在消息窗口显示了以下错误,这时候我们不用理会这些错误,后面我们会处理这些错误的。

图12:只加入PCIe硬核后Qsys系统界面
步骤4:添加剩下的设备到Qsys系统
接着我们把剩下的DMA和片内RAM添加到Qsys系统,来完成这个PCI
Express端点设计。
1.
在Qsys工具的设备库下找到Bridges,展开在其下面找到DMA并展开找到DMA控制器,如图13所示。

图13:在Qsys工具元件库里找到DMA控制器
2.
点击Add按钮开始添加DMA控制器,并打开DMA控制器的参数设置界面。
和之前添加PCIe硬核类似,这时候我们可以看到一个名字叫“dma_0”的设备已经被自动添加到了Qsys系统,同时一个参数编辑界面展现在我们面前,并允许我们对此DMA控制进行参数配置。
3.
按照如下要求对DMA控制进行配置,配置好的界面如图14所示(Advanced保持默认设置即可)。
a)
为DMA的长度寄存器选择位宽为13
bits,该参数定义了我们启动DMA传输的最大数据尺寸,也即8191 (2
13
– 1)。
b)
在突发事务下选择使能突发传输,该参数允许DMA使用Avalon-MM的突发处理机制来提供系统性能。
c)
设置突发尺寸为128个字。

图14:配置DMA控制
4.
点击完成按钮关闭DMA控制器参数设置编辑界面。
这样添加到Qsys的名为dma_0的DMA控制器已经配置完成,它有两个Avalon
master接口来分别启动系统内的读和写传输,还有一个名为control_port_slave的Avalon
salve接口,该接口用户对DMA的编程配置,一个名为clk的时钟输入接口和一个名为reset的复位输入接口。
5.
在Qsys工具的设备库下找到存储器和存储控制器,展开其下面的On-Chip,然后找到并高亮选择On-Chip
Memory(RAM or ROM),如图15所示。

图15:添加On-Chip Memory到Qsys系统
6.
点击Add按钮,开始添加On-Chip Memory到Qsys并打开其参数编辑界面。
7.
按照如下要求配置片内存储器:(配置好的界面如图16所示)
a)
在存储器类型选项下选择RAM(Writable)。
b)
在Block类型下选择Auto。这样设置让编译器自己为这个片内存储器自动选择片内RAM类型,因为大部分器件内部都有多种片内RAM块类型。
c)
数据宽度选择64,这是因为PCIe硬核使用了64-bit数据总线。
d)
为其配置总的存储尺寸为4096字节,这样就在系统内部创建一个512x64的RAM来用于存储传输的数据。
e)
去使能掉初始化存储器内容选项。存储器的内容在系统操作期间将总是处于可写状态。

图16:配置On-Chip 存储器
8.
点击完成按钮关闭并完成片内RAM配置界面。
9.
按照以上规律,为该片内RAM重命名为onchip_memory_0。
RAM块只有一个Avalon
salve接口用于访问其内部地址空间,同时只有一个时钟和复位输入接口。这时候我们可以看到Qsys系统如图17所示。

图17:所有设备添加完毕后的Qsys
步骤5:将设备连接起来
下面我们开始在图17所示System
Contents下的“connections”列内完成各个设备之间的连接。
1.将PCIe的输出时钟pcie_core_clk连接到片内RAM的clk1端口,如图18所示。

图18:连接PCIe的输出时钟到RAM时钟输入端口
2.
按照下表所示完成剩下的设备连接。
表1:
从
|
到
|
元件(设备)
|
接口名称
|
元件(设备)
|
接口名称
|
pcie_hard_ip_0
|
pcie_core_clk
|
dma_0
|
clk
|
pcie_hard_ip_0
|
pcie_core_reset
|
on-chip_memory_0
|
reset1
|
pcie_hard_ip_0
|
pcie_core_reset
|
dma_0
|
reset
|
pcie_hard_ip_0
|
bar1_0
|
on-chip_memory_0
|
s1
|
pcie_hard_ip_0
|
bar2
|
dma_0
|
control_port_slave
|
pcie_hard_ip_0
|
bar2
|
pcie_hard_ip_0
|
cra
|
dma_0
|
read_master
|
on-chip_memory_0
|
s1
|
dma_0
|
read_master
|
pcie_hard_ip_0
|
txs
|
dma_0
|
write_master
|
on-chip_memory_0
|
s1
|
dma_0
|
write_master
|
pcie_hard_ip_0
|
txs
|
当按照表1所示完成连接后,Qsys系统如图19所示。这将显示系统的时钟和复位信号都是来源于PCIe硬核模块。针对BAR1:0的PCIe事务将直接转换为对片内RAM元件的操作,而针对BAR2的PCIe事务将直接转换为针对DMA控制器或者片内RAM的操作,这取决于该事务的地址偏移。DMA控制的两个master接口能在片内RAM和PCIe链路之间传输数据,可以通过PCIe硬核的发送(TXs)接口访问PCIe链路。

图19:连接完成的Qsys
3.
在IRQ列连接DMA的中断到PCIe硬核,连接DMA的control_port_slave到PCIe的中断,如图20所示。

图20:DMA中断连接到PCIe硬核
4.
将PCIe硬核的校准模块的接口输出到Qsys系统外面,可以看到在“export”列,每个接口都有灰色的提示“双击导出”,如图21所示,双击cal_blk_clk接口将其导出Qsys系统
5.
确认导出接口名称为pcie_hard_ip_0_cal_blk_clk,如果需要可以修改到上述名称。

图21:导出PCIe硬核校准模块时钟
如图21所示,cal_blk_clk在connection列应该有一个导出的引脚符号,但是12.1和13.0目前还没有解决这个问题问题,所以这里我们看不到导出的引脚符号。
6.
按照表2所示,为PCIe硬核导出剩下的接口。
表2:需要导出的PCIe硬核接口
接口名称
|
被导出的端口名称
|
refclk
|
pcie_hard_ip_0_refclk
|
test_in
|
pcie_hard_ip_0_test_in
|
pcie_rstn
|
pcie_hard_ip_0_pcie_rstn
|
clocks_sim
|
pcie_hard_ip_0_clocks_sim
|
reconfig_busy
|
pcie_hard_ip_0_reconfig_busy
|
pipe_ext
|
pcie_hard_ip_0_pipe_ext
|
test_out
|
pcie_hard_ip_0_test_out
|
rx_in
|
pcie_hard_ip_0_rx_in
|
tx_out
|
pcie_hard_ip_0_tx_out
|
reconfig_togxb
|
pcie_hard_ip_0_reconfig_togxb
|
reconfig_gxbclk
|
pcie_hard_ip_0_reconfig_gxbclk
|
reconfig_fromgxb_0
|
pcie_hard_ip_0_reconfig_fromgxb_0
|
fixedclk
|
pcie_hard_ip_0_fixedclk
|
完成上述操作后,PCIe硬核在Qsys中就如图22所示那样。

图22:在Qsys中完成整个配置和连接的PCIe硬核
步骤6:调整系统地址空间
- 在System Contents里的Base列,我们为PCIe硬核的cra分配的地址为0x0000_0000.
- 按照表3所示分配剩下设备的地址空间。
表3:地址空间分配表
Component
|
Interface
|
Base Address
|
pcie_hard_ip_0
|
txs
|
0x0000_0000
|
dma_0
|
control_port_slave
|
0x0000_4000
|
onchip_mem_0
|
s1
|
0x0020_0000
|
地址空间分配好以后,Qsys系统如图23所示。

图23:分配好地址空间后的Qsys系统
步骤7:选择最终设置并生成Qsys系统
这一步,我们选择好最终的系统设置以后,生成Qsys文件,然后准备继续开始剩下的硬件设计。
- 在Qsys工具里,选择地址映射标号,确认所有的地址映射和之前的步骤5所做的连接相匹配,如图24所示。

图24:系统地址映射
2.
在时钟设置标号下,确认PCIe硬核为系统产生的是125MHz时钟。
3.
在工程设置标号下,查看系统导出的接口都是可见的,并在参数框里选择合适选项,如图25所示。

图25:查看工程设置及系统导出接口
- 生成系统。
- 在Generation标号下,让所有仿真选项设置为None。
- 系统测试激励也设置为none。
- 在综合块,使能创建符号文件(.bsf)选项。
- 点击Generate。
- 点击Save保存系统并开始生出系统。
系统生成的时候,我们可以看到若干警告,但是没有了错误。
5. 关闭生成完成窗口和关闭Qsys工具
步骤8:在Quartus软件里完成顶层文件设计,并对工程进行编译。
这里我们预先设计好了一个基于Verilog名为civgx_gen1x4_qsys_top.v的顶层文件,其原理框图如图26所示。

图26:顶层设计框图
可以看到在Qsys系统外,我们还需要其他一些逻辑设计,比如PLL、GXB重配置以及PCIe硬核重配置等。PLL为PCIe硬核产生一个125MHz的参考时钟,同时产生一个50MHz的校准时钟和GXB重配置时钟。
- 添加Qsys系统生成的QIP文件和SDC文件到工程,打开文件添加对话框:
- 浏览到目录\civgx_gen1x4_qsys\synthesis文件夹下。
- 改变文件类型,选择IP Variation Files(*.qip)选择刚刚生成系统的.qip文件。
- 点击打开并添加到工程。
- 点击OK关闭添加文件对话框和Settings窗口。
通过上述简单的添加QIP文件,将Qsys工具产生的综合文件都添加到了工程,SDC文件在顶层约束了一个50MHz的时钟。
- 打开顶层设计文件,即civgx_gen1x4_qsys_top.v。
- 查看该文件,并注意以下:
- 顶层端口(FPGA的IO),包括两个独立的时钟源,一个复位和4-bit的高速收发通道(RX和TX)。
- Qsys系统的实例化,可以直接从Qsys工具里的HDL
example下复制过来。许多被定为管道的接口都是用于仿真或者调试,所以它们并不一定要在顶层连接到具体的逻辑。
- 编译设计。点击
按钮对工程进行全编译。
参考:
1] Avalon接口协议
[2] PCI-E hard IP User guide