海内各种IC设计竞赛、EDA设计竞赛也越来越多,但笔者认为,最具有代表性最能反响一所高校在校学生数字IC设计水平的也便是“龙芯杯”CPU设计竞赛。“龙芯杯”MIPS CPU设计已经举行三届了,参赛的军队水平也在不断的提高,一个大三本科生设计一颗带有4发射乱序处理、分支预测等功能且能跑Linux操作系统的CPU核已经不是什么问题,并且FPGA验证的主频已经超过了120MHz,凸显了FPGA时序优化能力的提升。随着RISC-V等开源CPU的不断发展,相信海内涵CPU设计能力上的差距正在加速缩小,被ARM和INTEL卡脖子的时期可能快要结束了。
从参赛的规模上来看,也在不断的扩大。今年又新加入了不少高校,像北京邮电大学、河北大学等。龙芯杯竞赛至少反响了这些高校在CPU设计方向的课程设置已经没有问题,设计CPU须要浩瀚课程的支撑,《打算机组成事理》、《编译事理》、《操作系统》及FPGA设计开拓等干系课程,相对而言,海内绝大多数高校虽然有干系的课程,可想找到有能力设计CPU的学生组队参赛的高校却不多。

以下二维码链接是一位清华大学大三本科生写的项目分享,可以反应呈现代本科生设计CPU能力的水平。
好了,回归正题,以下先容ZYNQ系列FPGA如何利用。以下内容作者是殷建飞。
部分硬件设计中须要CPU完成对电路寄存器的配置,为了完成Zedboard对FPGA上部分寄存器的配置功能,可以在PS单元(处理器系统)上运行裸机程序(无操作系统支持)完成和PL单元(FPGA部分)的数据交互功能,此时PS单元更像单片机开拓;另一种方法是PS单元运行Linux操作系统,通过驱动程序和运用程序完成对硬件寄存器的读写操作,并且Linux有着完全的网络协议栈支持,后续可拓展性更强,可以更好的发挥ZYNQ这种异构架构芯片的性能。紧张分为两部分,分别阐述Zedboard中FPGA和处理器互联总线与硬件设计和Zedboard处理器系统上嵌入式Linux的移植与通过驱动和运用程序大略配置FPGA寄存器的实现。本文紧张先容不带操作系统的情形。
PS与PL接口设计和硬件设计PS与PL交互可以通过ZYNQ系统内的高速总线来完成,ZYNQ内包含AXI4标准总线、AXI-Lite轻型总线和AXI-Stream流式总线。个中AXI4标准总线支持有地址、猝发和连续的传输,可以用于大容量数据的传输;而AXI-Lite总线则是一个轻量级的地址映射单次传输接口,占用更少的逻辑资源;AXI4-Stream是面向数据流的无地址的传输,更适宜承载视频流等流式数据。综上,由于本次实验硬件设计较为大略,数据传输量较小,因此选用AXI轻型总线作为PS单元与PL单元交互接口。
(1)自定义IP封装VIVADO中供应了多种AXI总线接口的IP核,例如DMA IP中利用AXI-lite用来完成CPU配置DMA引擎的寄存器,而AXI标准总线用来完成DMA引擎面向内存地址映射的搬运数据。但是官方的IP核运用不足灵巧,这里我们可以封装自己的IP并在个中加入须要的逻辑处理。
打开任意一个VIVADO工程,选择Tools中的Creatand Package New IP选项,点击next提高。
选择建立一个AXI4的外设选项
进行IP命名和版本的选择,其余须要选定工程路径,这是稍后建 立IP时VIVADO会新建立的工程路径。
在接口选项中,选择一个AXI-lite的Slave接口,数据位宽为 32位,寄存器数量为4,这里我们不须要太多的寄存器。当然在面对更繁芜的运用时,可以添加更多的AXI总线通道。
选择Edit IP,此时VIVADO会打开一个新的工程。当然,也可以选择将IP添加到库,然后在工程中搜索添加该IP核,然后重新选中该IP选择Edit in IP Packager,VIVADO同样会打开一个新工程修正之前的IP。
在上述新工程中,可以看到工程的组织目录led_v1_1_S00_AXI才是我们创建的总线接口模块,而led_v1顶层模块只是添加了对总线接口的例化而已。那么VIVADO建立的IP为什么要新封装一层例化呢?我们用另一个多个AXI通道的工程来看一下,当IP须要多个AXI通道时,我们创造顶层例化了多个AXI总线通道,我们可以方便的设计和添加.v文件来完成多个数据通道之间的数据传输和总线掌握。
(2)AXI-Lite协议剖析下面我们对AXI-Lite总线协议进行大略剖析,AXI总线共5个数据通道,分别是写地址通道、写数据通道、写相应通道和读地址通道、读数据通道。AXI采取握手旗子暗记机制,当发送数据一端发送valid旗子暗记,而接管旗子暗记一端发送ready旗子暗记,当valid和ready同时有效时数据完成一次传输。
首先来看写数据接口,写数据须要写数据地址通道先发送地址,然后写数据通道发送数据,slave端接管完成后通过写相应通道见告master端。
上述代码完成了slave端写地址通道的相应,slave端在上电复位后保持awreday旗子暗记为低电平,当master发出awvalid旗子暗记时,slave端将写地址通道上的地址数据存入寄存器,并将awready旗子暗记拉高一个时钟周期,完成一次写地址通道的传输过程。
对付写数据通道而言,其数据传输过程和写地址通道的传输过程很类似,slave端上电复位后将wready旗子暗记拉低,在master将wvalid旗子暗记拉高后,slave端将数据存入寄存器同时将wready旗子暗记拉高一个周期,完成一次写数据通道传输过程。
写操作由于是从master传输数据到slave,因此须要slave返回一个精确的相应旗子暗记给master来见告master我已经精确收到数据,这便是写相应通道。由于写相应通道数据是从slave端向master端,因此由master端发出ready旗子暗记,slave端上电复位后拉低valid旗子暗记,在检测到master真个ready旗子暗记后将valid旗子暗记和bresp回应旗子暗记一同发送到总线上完成写相应传输过程。一个完全的写交易过程完成。
通过上述代码,读者可能会困惑写地址通道和写数据通道为什么绑定到一起了呢?难道AXI-Lite总线的写地址通道和写数据通道数据传输必须同时发生吗?我们参考了XILINX的xapp1168中关于AXI总线设计的工程,创造在它的master端设计中,写地址通道和写数据通道的传输是由同一个旗子暗记触发的。也便是说master端总是先准备好写地址通道和写数据通道的数据后,然后同时传输要写入的地址和要写入的数据。因此,在slave端,保持相同的设计就可以得到最优的性能。这也是上述代码中为何写地址通道获取数据时也哀求写数据通道(wvalid)旗子暗记也有效。
通过上述设计,通过写数据通道和写地址通道获取到了CPU想要写入的地址和数据,下一步就要将数据写入对应寄存器。由于我们选择了4个寄存器,在代码中已经由VIVADO为我们自动天生了4个slave寄存器。4个寄存器共须要2位地址线来进行寻址,由于slave是挂在ARM 处理器外部的,当处理器调用函数写外设的寄存器,如果不做偏移,那么数据就会写入寄存器0,因此地址axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]决定了将数据写入哪个寄存器。ADDR_LSB是由数据位宽决定的,DDR数据位宽为字节,以是地址线最低位对应8位数据,对付32位位宽的数据,我们必须进行32位对齐,以是地址偏移从32/4+1位开始。OPT_MEM_ADDR_BITS则决定了偏移范围有多大,两位的位宽就足以寻址4个寄存器,一次本工程中OPT_MEM_ADDR_BITS是1,地址位宽是[1:0]共二位,如果8个寄存器就须要三位,那么OPT_MEM_ADDR_BITS就须要定义为2。
下面的代码实现了根据偏移地址将数据写入对应寄存器的操作。
假设slave基地址0x43c00000,当我们调用Xil_Out32(0x43C00000,Value)写的便是slv_reg0的值,此时axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]即axi_awaddr[3:2]为2’b00,如果地址偏移4位,Xil_Out32(0x43C00000+4,Value),此时写入slv_reg1寄存器,同时axi_awaddr[3:2]为2’b01.
上面剖析了写通道的数据传输,接下来剖析读数据通道
读地址通道和读数据通道的传输不可能同时进行,master端通过握手旗子暗记将读地址写入slave端,slave准备数据然后通过握手旗子暗记返回数据给master。
Slave上电复位后将读地址通道arready旗子暗记拉低,master须要读数据时将地址发送到读地址通道的araddr旗子暗记线上,同时拉高arvalid旗子暗记,发起一次读地址发送,slave端检测到arvalid旗子暗记有效,锁存araddr数据,并拉高arready旗子暗记完成读地址接管过程。slave根据ardddr的偏移获取对应寄存器的数据,然后在读数据通道上主动发起一次数据传输,即将数据置入rdata并拉高读地址通道的rvalid旗子暗记,等待master接管数据并返回rready旗子暗记有效后完成读数据传输。
由于Zedboard开拓板有8位led灯,以是我们设计一个8位宽的wire型线连接到寄存器0的低8位即可。
须要把稳在顶层文件中添加该端口。
至此,我们自定义的IP就设计完成了,我们重新封装该IP核。
首先点击各项的蓝色感叹号,vivado会自动变动IP的一些信息。全部消逝后就可以进行IP封装。
选择重新封装选项进行封装,封装完成后VIVADO工程会自动关闭。
将封装好的IP添加到库目录,在任意VIVADO工程中选择IP Catalog选项,选中USER Repository选项,右键选中Add Repositor,选中我们之前建立IP时选择的目录。添加完成。
(3)硬件工程设计本次实验基于VIVADO2017.4版本进行硬件设计,建立VIVADO工程并选用Zedboard开拓板(这样后面的部分接口可以利用VIVADO默认配置)
新建block design,添加zynq processing_system,然后点击Run BlockAutomation进行硬件板卡信息添补。运行完成后可以看到ZYNQ系统以及配置好了DDR内存和串口设置。
如果你利用其他板卡,那么要根据外设的位置和内存型号进行设置,这里进行大略先容。
PS-PL配置选项用于打开PS单元和PL单元之前的互联总线,PS单元中面向PL单元的有4个GP接口。也便是两个AXI-Lite主端口和两个AXI-Lite从端口,以及4个高速的HP接口。由于我们须要CPU配置FPGA,因此启用一个GP主端口。
配置IO选项用于关闭和打开ZYNQ的外设部分的配置,由于ZYNQ可灵巧配置,因此须要选择和板卡相对应的外设位置,选择Zedboard的好处在于可以利用VIVADO中预设的板卡信息进行自动设置。
须要把稳的是,这部分I/O口为ZYNQ的MIO,而PL部分的为EMIO。
其余,想要成功启动linux至少须要一个TTC外设。
时钟配置选项用于管理PS单元和PL单元的时钟,包括内存频率和CPU主频信息,I/O口频率设置。其余PS部分可以向PL部分供应最多4个时钟,这里仅开启一个100M的时钟。
DDR配置选项选择精确的内存型号即可,这里仍旧利用Zedboard的默认配置即可。较为主要的是下面的中断选项,可以选择打开PS和PL之间的中断开关,由于本次工程暂时没有用到,以是不再赘述。
点击OK保存对处理器系统的配置,连续添加IP,搜索我们之前定制的IP,创造led V1版本的自定义IP核,点击添加。
添加完成后将led端口引出,可以利用快捷键Ctrl+T,或者利用右键菜单也可以完成。我们将剩余的AXI标准端口利用VIVADO的自动连线功能完成连接。点击Run Connection Automation,勾选所有IP,完成后创造VIVADO为我们自动添加了一个AXI交流矩阵和复位模块。
顶层模块如图,保存。
我们在工程管理中选中创建的Block Design,选中天生HDL
VIVADO会将处理器系统和IP部件天生Verilog文件。在工程中添加约束文件,加入对LED[7:0]的管教约束。
set_property PACKAGE_PIN T22 [get_ports {LED[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[0]}]
set_property PACKAGE_PIN T21 [get_ports {LED[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[1]}]
set_property PACKAGE_PIN U22 [get_ports {LED[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[2]}]
set_property PACKAGE_PIN U21 [get_ports {LED[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[3]}]
set_property PACKAGE_PIN V22 [get_ports {LED[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[5]}]
set_property PACKAGE_PIN W22 [get_ports {LED[5]}]
set_property PACKAGE_PIN U19 [get_ports {LED[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[7]}]
set_property PACKAGE_PIN U14 [get_ports {LED[7]}]
然后就可以天生比特流了。
硬件设计部分的事情在这里就完成了,我们须要记录外设在ARM处理器系统上挂载的地址,这样才能利用软件写入和读取其数据。在VIVAOD中Address Edit选项卡中可以编辑外设地址,这里我们保持默认,并记录。
在完成硬件设计部分后,我们可以大略的运行一个裸机程序来考验一下我们的映射关系是否精确。首先在VIVADO中将天生的比特流导出到SDK。
选择File,Export->ExportHardware,而后选择File->Lunch SDK,选择本地路径(这样会包含硬件比特流)。
(4)裸机程序验证
在SDK下,已经包含对应工程的硬件平台和板级支持包,点击File -> New -> Application project建立一个新的SDK工程。
建立工程名称,选择裸机,C措辞开拓,班级支持包默认。Next,选择HelloWord模板。我们在main函数中做大略修正:
#include <stdio.h>#include \"大众xparameters.h\"大众#include \"大众sleep.h\"大众#include \"大众xil_io.h\公众int main(){ int i = 1; while(1) { for(i=0;i<8;i++) { Xil_Out32(0x43c00000, 1<<i); sleep(1); } } return 0;}
通过上述程序,我们讲一个8位循环的数据写入寄存器0中,由于寄存0的低8位连接到了LED灯,因此会有流水灯的效果。
函数 Xil_Out32(0x43c00000,1<<i);将数据写入到物理地址为0x43c00000的地方去,而这里刚好便是我们挂载AXI-Lite slave外设的物理地址。
在软件工程上右键选择Run As -> runconfigurations
选择对应的比特流,选中烧写FPGA和复位系统,点击run,可以看到烧写完成后开拓板成功点亮流水灯。
全文完。