引言
FPGA,全程现场可编程门阵列,是指一切通过软件手段更改、配置器件内部连接结构和逻辑单元,完成既定设计功能的数字集成电路。换个简单通俗的介绍方式,就好比一个全能的运动员,FPGA就是这么神奇的可以通过设定而实现各种复杂的功能电路。FPGA的核心优点:可编程灵活性高、开发周期短、并行计算可编程灵活性高。同时FPGA也有自身的很多需要解决的问题,FPGA限制因素:成本、功耗和编程设计。现在已经在三个重要领域发挥着重量级作用:(1)通信设备的高速接口电路设计一般如果AD采样率高,数据速率高,这时就需要FPGA对数据进行处理,比如对数据进行抽取滤波,降低数据速率,使信号容易处理,传输,存储;(2)数字信号处理方向/数学计算方向,包括图像处理,雷达信号处理,医学信号处理等,优势是实时性好,用面积换速度,比CPU快的多;(3)SOPC,即利用FPGA这个平台搭建的一个嵌入式系统的底层硬件环境,然后设计者在上面进行嵌入式软件开发。
自1984年Xilinx刚刚创造出FPGA时,它还是简单的胶合逻辑芯片,而如今在信号处理和控制应用中,它已经取代了自定制专用集成电路(ASIC)和处理器。短短不到40年的历史长河中,超过上百家行业巨头杀入这个市场,不过最后大部分都铩羽而归。这些公司包括了Intel、Philips、Agere Systems、AMD以及摩托罗拉等国际知名的芯片设计厂商。这是因为,Xilinx和Altera在这个领域深耕几十年,两家持续不断地军备竞赛,占据了90%市场
已经更新了很久的zynq系列就是xilinx的产品,但是对于时代和特殊应用场景的选择下,我们需要介绍仍在进步中的国产芯片:如对标zynq,复旦微电子的FMQL可编程融合芯片(全可编程PSOC芯片)系列。在实际的调试中,不难发现,除去明面上容易查到的比如PS端双核的A9替换为了四核A7等硬件参数,一些不容易查到的比如xilinx成熟的底层硬件加速等,还是有不少差异的。
调试了有段时间,这里记录一些FMQL的调试笔记,可以与zynq相互对比,本篇首先更新 Ps 的千兆网口gmac 有哪些需要注意的地方
单phy 节点明确指定phy 地址的 设备树写法
&gmac0 {
status = "okay";
snps,reset-gpio = <&portb 17 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 10000 100000>;
phy-handle = <&phy0>;
mdio@0 {
compatible= "snps,dwmac-mdio";
#address-cells = <1>;
#size-cells = <0>;
phy0: eth-phy@7 {
reg = <7>;
};
};
};
单phy 节点不明确指定 phy 地址写法
&gmac0 {
status = "okay";
snps,reset-gpio = <&portb 17 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 10000 100000>;
};
phy 核心层代码会扫描所有的 phy 地址(0-31),特别要注意的是 20210816bsp 里 uboot 需要则一定需要加上 mdio 节点了,主要是修改了共享 mdio 的支持(进口没有做相应的支持)。
一路mdio 控制两个phy,设备树写法
&gmac0 {
status = "okay";
snps,reset-gpio = <&portb 17 0>;
snps,reset-active-low;
snps,reset-delays-us =<0 10000 100000>;
phy-handle = <&phy0>;
mdio@0 {
compatible= "snps,dwmac-mdio";
#address-cells = <1>;
#size-cells = <0>;
phy0: eth-phy@7 {
reg = <7>;//按实际修改
};
phy1: eth-phy@4 {
reg = <4>; //按实际修改
};
};
};
&gmac1 {
phy-mode="rgmii-id"; //gmac1 默认的 phy-mode 是 rgmii,和 gmac0 不一样
status="okay";
phy-handle=<&phy1>;
};
mac1 的默认 phy-mode 和 gmac0 不一样, 不管怎么样,能 link 不能通信时,每个gmac 都是要调整一下 tx 和 rx delay 的。
PS:一路mdio 控制两个phy,phy 地址不能有0,因为0 地址是广播地址,对 0 地址处理不同 phy 表现不一样,,这样会引起混乱。 下面是简单讨论一下:
https://www.xilinx.com/support/answers/59554.html
有的 phy 厂家可以关掉 phy 对0地址的响应,另外 demo 的 88E1116R 应该就不响应0地址,这个还要看 phy 厂家的,不管怎么样,对于共享 mdio 总线的两个 phy,不要用0地址了,否则大概率会碰到问题,单 phy 则没有这个限制,因为没有潜在的冲突。特备要注意的是, mdio 勾在哪个 mac 下面,则要写到对应的 gmac 设备节点下面。
phy-mode 属性说明
rgmii-txid rgmii -rxid rgmii-id rgmii 可 以 参 考 内 核 文 档
Documentations/devicetree/bindings/net/ethernet.txt。
“rgmii” (RX and TX delays are added by the MAC when required) 。
“rgmii-id” (RGMII with internal RX and TX delays provided by the PHY, the MAC should not add the RX or TX delays in this case)。
指PHY 的内部有延时寄存器设置,mac 就不用设置了。
两个变体:
“rgmii-rxid” (RGMII with internal RX delay provided by the PHY, the MAC should not add an RX delay in this case)。
“rgmii-txid” (RGMII with internal TX delay provided by the PHY, the MAC should not add an TX delay in this case) 。
千兆有问题的时候,特别是怀疑 tx 和 rx delay 有问题时,可以尝试用百兆或十兆模式尝试一下。
另外和 u-boot 一样,可以在设备树 gmac 里限定 max-speed 为 100M:
max-speed=<100>;
方便某些调试场合可能会用到。
Linux 和 uboot 测试设备树相同,如下图
可以用 ethtool eth0 查看网口速度,另外插拔网线或者 down 和 up 一下 eth0。
国产之路:复旦微zynq调试笔记2--PL网口---------------------------------
引言
PL侧的网口需求相较于PS部分还是有一定区别的,主要需要添加axi ethernet 的移植
PL 的 PCS/PMA IP 使用说明
关于xilinx 的Xilinx PCS/PMA PHY 的IP,这个是SGMII 接口,这里PCS/PMA IP 核相当 于PHY,外部通过PCB 连接到光模块,是电口转光口,对应的linux 驱动是xilinx_phy.c ,20200304 版本的内核默认没有移植过来,需要自己从 xilinx 的 release 内核比如 2018.3里移植过来, 20101022 和 20210816 版本的 linux bsp 都已经移植了这个驱动
ps 网口GMII 从emio 出引脚需要注意的地方:
1)phy 节点里compatible 属性去掉才行,没有用到。
2) EMIO GMII RXC 需要增加时钟约束。
create_clock -period 8.000 -name rx_clk waveform {0.000 4.000} [get_ports RGMII_rxc]
调试通过的设备树节点写法:
&gmac1 {
status = "okay";
phy-mode = "gmii"; //看硬件,实际是什么接法,确定是GMII 还是SGMII
phy-handle = <&phy0>;
mdio@0 {
compatible= "snps,dwmac-mdio";
#address-cells = <1>;
#size-cells = <0>;
phy0: eth-phy@6 {
/*compatible = "Xilinx PCS/PMA PHY";*/
xlnx,phy -type = <0x5>; //1000BASEx; sgmii 是4
reg = <6>; //phy 地址,根据实际硬件调整
};
};
};
AXI_Ethernet
2018.3
Psoc 的 linux 是从 kernel.org 上游 4.14.55-release 版本一致的, xilinx 的驱动是比较老的,这取决 xilinx 在什么时机点往 kernel upstream 推送他们的更新补丁, 基本很少更新, 因为他们自己维护一个 github 仓库,所以 PL 驱动建议从 2018.3 版本(内核版本是 4.14.0)移植驱动, xlnx 的 2018.3-relase 内核链接如下:
https://github.com/Xilinx/linux-xlnx/releases/tag/xilinx-v2018.3
驱动路路径是 drivers/net/ethernet/Xilinx, 备份或改名 psoc 内核目录, 把 2018.3 内核里的 drivers/net/ethernet/xilinx 目录替换,另外把 include/linux/xilinx_phy.h 拷贝复旦微目录下。Kconfig 修改:
Psoc 默认内核配置只有 microblaze 架构下才能看到 axi ethernet 驱动:
对比 xlnx-2018.3 内核:
三种架构都支持,另外注意 axi ethernet 依赖 NET_VENDOR_XILINX,在上面也需要加上ARCH_FMSH 架构支持。然后就可以用 make menuconfig 里看到驱动选项并可以操作使能 axi ethernet 内核选项了。
驱动小修改:
内核编译就基本没有问题了。
另外 psoc 的 linux bsp 的 sdk 处理中断号脚本有点小 bug,两个中断号写到一对<>里时,第 2 个中断号处理不了, 可以在 procise 生成的 system-top.dts 里手动覆盖一下 pl.dtsi里的 interrupts 属性。
&axi_ethernet_0_dma {
Interrupts = <0 25 4 >, <0 26 4>; //中断号从 29,30 修正到 25,26
};
或者:在 device-tree/get_pldts.sh 增加一个中断修复函数(只能处理两个,但是能处理两种格式)
fix_interrupt_again() {
sed -i "s/\( *interrupts.*\)\(<0.*\)\(0 29\)\(.*\)/\1\2 0 25\4/g" ${DTS_FILES_PATH}/pl.dtsi
sed -i "s/\( *interrupts.*\)\(<0.*\)\(0 30\)\(.*\)/\1\2 0 26\4/g" ${DTS_FILES_PATH}/pl.dtsi
sed -i "s/\( *interrupts.*\)\(<0.*\)\(0 31\)\(.*\)/\1\2 0 27\4/g" ${DTS_FILES_PATH}/pl.dtsi
sed -i "s/\( *interrupts.*\)\(<0.*\)\(0 32\)\(.*\)/\1\2 0 28\4/g" ${DTS_FILES_PATH}/pl.dtsi
sed -i "s/\( *interrupts.*\)\(<0.*\)\(0 33\)\(.*\)/\1\2 0 29\4/g" ${DTS_FILES_PATH}/pl.dtsi
sed -i "s/\( *interrupts.*\)\(<0.*\)\(0 34\)\(.*\)/\1\2 0 30\4/g" ${DTS_FILES_PATH}/pl.dtsi
sed -i "s/\( *interrupts.*\)\(<0.*\)\(0 35\)\(.*\)/\1\2 0 31\4/g" ${DTS_FILES_PATH}/pl.dtsi
sed -i "s/\( *interrupts.*\)\(<0.*\)\(0 36\)\(.*\)/\1\2 0 32\4/g" ${DTS_FILES_PATH}/pl.dtsi
}
2018.2
如果是2018.2版本,找到xilinx_axienet_main是在XILINX_AXI_EMAC的配置项决定,
那为什么直接在menuconfig中找不到呢,如图位置打开defined 所在的kconfig配置文件,将无关的依赖项depends on去掉就可以显示编译了
phy-handle = <&phy0>;
axi_ethernet_0_mdio: mdio {
#address-cells = <1>;
#size-cells = <0>;
phy0: pl_phy@0 {
reg = <5>;
};
测试结果
实际上在复旦微的设计并不是那么完善的,按照xilinx的经验,在没有其他硬件选型等问题的前提下,截止到目前应该软件部分应该已经设置修改完毕了,可测量结果有显示,即便只是单纯的ping包,也时断时续,打开iperf,也能明显看到只有单向的速率还算稳定,另一个方向惨不忍睹
现象分析
经过和复旦微测试人员的不断沟通,终于在修改了ddr的频率后有了明显改善。探究原因,本质上是由于时钟的不稳定导致的,造成原因是逻辑的配置是由vivado生成后导入procise的,在导入过程中,原本时钟使用IO的时钟,但是导入后由于procise设置(直接在prosice上配置也不行,因为procise只支持用ddr时钟,应该是设计缺陷),会自动转为ddr时钟,而ddr高速又不稳定,在降速至300m后才可正常使用,暂未对其他功能有影响。