最近矿难,某宝某鱼上都出现了大量矿机控制板。。。ASIC负责挖矿,控制板负责联网、监视、控制之类。控制板不乏有各种水果派,像香橙派、树莓派、狗骨头之类的所谓“极客玩具”在其之列,想必国内水果派厂家活的是相当滋润。。。光靠极客教育哪有什么赚头,极客大都很穷的,像我这样看到这么便宜的“zynq开发板”,便忍不住要跟风收一波垃圾了。。。

某鱼上EBAZ4205控制板泛滥,它出自翼比特E9+矿机。它的老版控制卡EBAZ4203配置与其基本一样。

ebaz4205
ebaz4205

下面一大坨都是计算卡,上面一小块才是控制板

板子概况

ebaz4205
ebaz4205
主控 XC7Z010CLG400-1
内存 256MB DDR3,EM6GD16EWKG或者MT41K128M16
nand 128MB SLC
以太网 百兆网卡,IP101GA
供电 5V也行
其他 TF卡,UART1,2个风扇口,14针jtag,3个20pin IO口

开发工程

SOC启动配置

ZYNQ系列的SOC集成了双核ARM Cortex-A9和FPGA。整个SOC分为PS(processing system)和PL(programmable logic)两部分。PS包括处理器、片上AMBA总线、存储控制器、部分外设以及固定的IO口;PL就是FPGA。ZYNQ 7010处理器主频可以到约600MHz,FPGA有约28K个LE。

zynq
zynq

ZYNQ的PS部分可以抛开PL部分而独立运行,因为PS的外设都默认绑定了一些IO口(MIO),内存控制器之类的IO口还是不可更改的,这时候就可以像开发其他ARM SOC那样去玩ZYNQ。MIO是有限的,一些外设端口冲突的话可以通过EMIO绕道PL将其引出,这时候就需要管PL部分了。

ZYNQ的启动分为三步:

  • BOOT ROM,根据引脚配置选择从哪里启动,如QSPI、nand/nor flash、SD卡等。将FSBL(first stage bootloader)加载到片上内存里。7010的片上内存有256k。
  • FSBL,初始化更多的MIO口,初始化DDR,还可以初始化PL部分,然后将应用程序搬到DDR中。初始化部分由vivado直接生成,即那个上万行的ps7_init.c。FSBL可以直接用Xilinx SDK的例子工程,相当于这些工作都可以点点鼠标就完成了。
  • 应用程序。可以直接是用户的应用程序,也可以是又一个loader,比如uboot之类的,剩下的事情就由程序员自己做决定了。

应当指出,FSBL相当于是uboot SPL的地位。在Xilinx uboot工程中,那个上万行的初始化c程序就编译进SPL中去了,所以如果用SDK的FSBL就不需要uboot的SPL了。

这块板子的R2577R2584电阻用于配置启动设备。把R2584焊到R2577上,将原来nand启动改为SD卡启动。

vivado
vivado

Vivado操作流程

利用Xilinx那套笨重的开发环境,helloworld工程完全可以用鼠标操作出来,一行代码都不用写。。

首先新建个工程

一直next到选择芯片。选xc7z010clg400-1

vivado
vivado

接下来就顺着左边栏Flow Navigator进行操作。

vivado
vivado
Create Board Design

点加号添加ZYNQ7 Processing System:

vivado
vivado

双击出来的zynq7 processing system蓝框框,配置PS系统:

  • 添加nand控制器,默认就行了:

    vivado
    vivado
  • 添加MIO设置。勾上ENET0、SD0、UART1。注意引脚配置:

    vivado
    vivado
  • 设置外设时钟。把网口改成百兆的:

    vivado
    vivado
  • 设置DDR。幸好我们的MT41K128M16有默认参数配置:

    vivado
    vivado

因为板子的网口通过EMIO引出,所以我们需要一个个手动分配引脚。但是这个IP是GMII千兆网口,TX RX有8位,而百兆网卡用的MII接口TX RX只有4位,必须显式地加两个concat模块来将8位转为4位,否则多余的引脚引出了但是不分配IO口,最后生成bitstream时候会报错。

vivado
vivado

将GMII的TX、RX引到各自的concat模块处,将GMII其他引脚以及MDIO引出:右键点击Make External

vivado
vivado

FCLK_CLK0M_AXI_GP0_ACLK连起来,最后点击上方栏的Run Block Automation完成剩下的工作。

vivado
vivado

完成后的效果:

vivado
vivado
左边栏Generate Block Design

Generate Block Design,然后右键Source框下面的bd文件,Create HDL Wrapper

vivado
vivado
左边栏Run Synthesis

先综合一次,然后打开Open Synthesized Design->Constraint Wizard,分配引脚。这时需要新建一个constraint文件。

将网口的引脚都设置为LVCMOS33电平,然后逐个分配引脚。。。

vivado
vivado

设置完成后Ctrl-S保存,约束文件生成如下:

set_property IOSTANDARD LVCMOS33 [get_ports ENET0_GMII_RX_CLK_0]
...
set_property PACKAGE_PIN U14 [get_ports ENET0_GMII_RX_CLK_0]
set_property PACKAGE_PIN U15 [get_ports ENET0_GMII_TX_CLK_0]
set_property PACKAGE_PIN W19 [get_ports {ENET0_GMII_TX_EN_0[0]}]
set_property PACKAGE_PIN W18 [get_ports {enet0_gmii_txd[0]}]
set_property PACKAGE_PIN Y18 [get_ports {enet0_gmii_txd[1]}]
set_property PACKAGE_PIN V18 [get_ports {enet0_gmii_txd[2]}]
set_property PACKAGE_PIN Y19 [get_ports {enet0_gmii_txd[3]}]
set_property PACKAGE_PIN W16 [get_ports ENET0_GMII_RX_DV_0]
set_property PACKAGE_PIN W15 [get_ports MDIO_ETHERNET_0_0_mdc]
set_property PACKAGE_PIN Y14 [get_ports MDIO_ETHERNET_0_0_mdio_io]
set_property PACKAGE_PIN Y16 [get_ports {enet0_gmii_rxd[0]}]
set_property PACKAGE_PIN V16 [get_ports {enet0_gmii_rxd[1]}]
set_property PACKAGE_PIN V17 [get_ports {enet0_gmii_rxd[2]}]
set_property PACKAGE_PIN Y17 [get_ports {enet0_gmii_rxd[3]}]

然后再综合一次。。。

左边栏Run Implementation 和 Generate Bitstream

要跑一段时间。。。

输出设计

File->Export->Export Hardware

记得勾上Include Bitstream

进入SDK

File->Launch SDK

SDK操作流程

首先需要新建FSBL。

File->New->Application Project,Next到Templates,选Zynq FSBL

sdk
sdk

然后它会自动开始编译。。。

然后才新建helloworld。。

File->New->Application Project,Next到Templates,选Hello World。它也会自动开始编译,不出意外的话就完事了。

最后生成启动文件BOOT.bin

左边栏右键helloworld工程,Create Boot Image。可以看到这个启动文件包括了三部分:

  • fsbl
  • bitstream
  • 应用程序
sdk
sdk
点亮板子

将一张SD卡格式化为fat文件系统,将bootimage/BOOT.bin丢进去,插上电就能启动了。

sdk
sdk
测试网口

SDK里面新建lwIP Echo Server工程,等它编译完,生成BOOT.bin,拷到SD卡里。插好网线,在终端中telnet它的7号端口,输入一行,回车,然后它就将你输入的东西返回来了。。。

sdk
sdk
debugging
debugging
debugging
debugging