主要内容

IP核心代工作流MicroBlaze处理器:Xilinx Kintex-7 KC705

这个例子展示了如何使用HDL编码器™IP核心代工作流开发参考设计Xilinx®部分没有嵌入式ARM®处理器,但仍然利用高密度脂蛋白编码器控制DUT™AXI生成界面。具体地说,这个例子将使用Xilinx Kintex-7 KC705董事会和MicroBlaze™软处理器运行LightWeightIP (lwIP)基于TCP / IP参考设计中的固件服务器访问HDL编码器生成™DUT寄存器从连接网络的任何地方。进一步说,这个例子还将突出的区别从一组寄存器访问数据实现为多个标量港口和一组端口寄存器实现为一个向量。

需求

  • Xilinx Vivado设计套件,支持版本中列出金宝appHDL编码文档

  • Xilinx Kintex-7 KC705开发板

  • 高密度脂蛋白编码器™X金宝appilinx FPGA板支持包

  • 以太网连接

Xilinx Kintex-7 KC705开发板

例子参考设计

MicroBlaze是一个简单的,通用的软核处理器只能用于Xilinx FPGA平台,如Kintex-7、执行功能成熟的处理器,或作为一种灵活的、可编程的IP。当程序很小,精灵可以坐在布拉姆和FPGA设计成完全自包含的。有许多应用程序适合MicroBlaze实施。在这里我们列出几个:

  1. 远程网络控制部署IP核心算法

  2. 嵌入式web服务器的控制和数据显示

  3. 纯硬件平台集成现有的软件算法

下面是一个系统级图MicroBlaze系统:

参考设计,“Xilinx MicroBlaze TCP / IP AXI4-Lite大师”,使用Vivado™MicroBlaze IP TCP / IP数据包转化为AXI4-Lite读和写。下面是一个完整的系统的框图,包括所有所需的外围设备运行TCP / IP服务器,并调试通过UART串行控制台。

MicroBlaze设置

为了运行TCP / IP服务器,MicroBlaze IP需要一些基本的外围设备:

  • 本地内存(BRAM)数据/指令

  • 核心以太网传输和接收帧

  • UART发送调试消息的核心

  • 核心产生超时定时器中断

  • 从所有这些外设中断控制器来处理中断。

在下面的地址编辑器中,可以看出这些外围设备连接到MicroBlaze通过AXI4接口。

当地的数量分配的内存使用BRAM是1 mb。这个数量需要运行lwIP堆栈。为本地内存指定布拉姆的好处是可执行的精灵可以包含在比特流,它简化了编程,使现有针对FPGA板可能没有外部DRAM内存。然而,这种便利是有代价的增加利用率:

如果BRAM利用率是一个关心和DRAM资源可用,您可能会选择替换本地BRAM内存与外部DRAM内存。看到Xilinx应用注意“xapp1026备用配置和应用程序信息的更多细节。

例子参考设计plugin_rd.m

plugin_rd。m参考设计如下所示:

函数hRD = plugin_rd ()%参考设计的定义
% 2014 - 2018版权MathWorks公司。
%构造设计对象的引用hRD = hdlcoder.ReferenceDesign (“SynthesisTool”,“Xilinx Vivado”);
hRD。ReferenceDesignName =“Xilinx MicroBlaze TCP / IP AXI4-Lite主”;hRD。BoardName =“Xilinx Kintex-7 KC705开发板的;
%的工具信息hRD。金宝appSupportedToolVersion = {“2017.2”,“2017.4”};
% %添加自定义设计文件%添加自定义Vivado设计hRD.addCustomVivadoDesign (“CustomBlockDesignTcl”,“system_top.tcl”,“VivadoBoardPart”,“xilinx.com: kc705: part0:1.1”);
%添加自定义文件,使用相对路径hRD。CustomFiles = {“mw_lwip_tcpip_axi4.elf”};
% %添加接口%添加时钟接口hRD.addClockInterface (“ClockConnection”,“clk_wiz_0 / clk_out1”,“ResetConnection”,“proc_sys_reset_0 / peripheral_aresetn”,“DefaultFrequencyMHz”,100,“MinFrequencyMHz”,100,“MaxFrequencyMHz”,100,“ClockNumber”, 1“ClockModuleInstance”,“clk_wiz_0”);
%添加AXI4和AXI4-Lite奴隶接口hRD.addAXI4SlaveInterface (“InterfaceConnection”,“microblaze_0_axi_periph / M04_AXI”,“BaseAddress”,“0 x44a00000”,“MasterAddressSpace”,“microblaze_0 /数据”,“InterfaceType”,“AXI4-Lite”,“InterfaceID”,“MicroBlaze AXI4-Lite接口”);
hRD。HasProcessingSystem = false;%没有确凿的处理系统

注意,参考设计包括MicroBlaze可执行mw_lwip_tcpip_axi4.elf在参考设计属性CustomFiles。这将参考设计的可执行文件复制到Vivado项目,这样就可以将相关MicroBlaze IP。

在“system_top额外的代码。tcl的uBlaze把精灵

“system_top。tcl的大部分的参考设计文件包括用于创建顶级Vivado IP积分器框图包含大部分的参考设计IP。我们添加一些额外的Tcl代码后,这个文件已经创建了框图关联的独立MicroBlaze精灵执行MicroBlaze IP。

import_files -norecurse mw_lwip_tcpip_axi4。精灵generate_target所有[get_files system_top。bd) set_property SCOPED_TO_REF system_top [get_files - -of_objects [get_fileset sources_1] {mw_lwip_tcpip_axi4。精灵}]set_property SCOPED_TO_CELLS {microblaze_0} [get_files——-of_objects [get_fileset sources_1] {mw_lwip_tcpip_axi4.elf}]

这样做允许精灵被打包的比特流和编程MicroBlaze BRAM记忆的同时,FPGA。

执行IP核心工作流

使用上面的参考设计你会生成一个高密度脂蛋白IP核心闪烁led KC705董事会。然后,您将使用tcpclient发送/接收的数据包的MicroBlaze发行的读/写/ AXI4-Lite接口生成的HDL IP核。下面的演示中使用的文件位于:

  • matlab /工具箱/ hdlcoder / hdlcoderdemos / customboards / KC705

1。MicroBlaze参考设计文件添加到MATLAB路径使用命令:

> >目录(fullfile (matlabroot,“工具箱”,“hdlcoder”,“hdlcoderdemos”,“customboards”,“KC705”));

2。设置Xilinx Vivado™工具路径通过使用下面的命令:

> > hdlsetuptoolpath (“ToolName”,“Xilinx Vivado”,“路径”,“C: \ Xilinx \ Vivado \ 2017.4 \ bin \ vivado.bat ');

使用自己的Xilinx Vivado™安装路径时执行的命令。

3所示。打开模型模型,实现金宝app了LED闪烁,以及向量输出端口为标量港口相比,使用命令:

open_system (“hdlcoder_led_vector”)

4所示。发射HDL工作流的顾问hdlcoder_led_vector / DUT子系统通过右击DUT子系统,并选择HDL代码>高密度脂蛋白工作流顾问

5。从下拉选择参考设计在步骤1.2

6。寄存器分配端口“MicroBlaze AXI4-Lite接口”。这些将被访问的十六进制偏移表所示。

7所示。在工作流运行剩下的步骤生成一个比特流和项目目标设备。

确定地址的IP核心报告

高密度脂蛋白的基地址编码器™IP核心是设计plugin_rd中定义的引用。使用下面的命令:

%添加AXI4和AXI4-Lite奴隶接口hRD.addAXI4SlaveInterface (“InterfaceConnection”,“microblaze_0_axi_periph / M04_AXI”,“BaseAddress”,“0 x44a00000”,“MasterAddressSpace”,“microblaze_0 /数据”,“InterfaceType”,“AXI4-Lite”,“InterfaceID”,“MicroBlaze AXI4-Lite接口”);

这个设计的基地址0 x44a0_0000。IP核心的补偿可以找到报告寄存器地址映射表:

用闪光灯同步矢量数据读/写

矢量数据支持AXI4 / AX金宝appI4-Lite R2017a接口。与标量端口的集合,矢量数据的所有元素被视为同步的IP核心算法逻辑。附加闪光灯为每个向量寄存器添加输入和输出端口保持这种同步多个顺序AXI4读/写。

输入端口,闪光灯寄存器控制使影子寄存器的设置,允许IP核心逻辑同时看到所有更新的向量元素。输出端口,闪光灯寄存器控制矢量数据的同步捕获是阅读。下面是图与矢量数据生成的同步逻辑:

连接到服务器的TCP / IP

开始与TCP / IP交互服务器上运行MicroBlaze,首先连接UART串行控制台查看调试信息,这将有助于确保一切都按预期工作。首先找到的串行端口连接到UART在黑板上:

然后使用这个端口连接使用一个程序(如腻子™:

一旦连接到UART串行控制台,运行hdlworkflow_ProgramTargetDevice.m脚本重组董事会。

> > hdlworkflow_ProgramTargetDevice # # #工作流程开始。# # #从模型加载设置。# # # + + + + + + + + + + + + + +任务计划目标设备+ + + + + + + + + + + + + + # # #生成日志文件:hdl_prj \ hdlsrc \ hdlcoder_led_vector \ workflow_task_ProgramTargetDevice。任务日志# # #”计划目标设备”成功。# # #工作流程完成。

在控制台窗口中,您应该看到下面的标题,显示IP地址和端口号连接到服务器。

注意:如果董事会是连接到一个网络启用DHCP服务器后,将不同的IP信息如上所示。在这种情况下,您将需要修改行43的read_write_test.m脚本连接到正确的IP地址:

t = tcpclient (“192.168.1.10”7);

发送AX4-Lite MicroBlaze从MATLAB使用事务tcpipclient

为了问题的读和写的IP核心通过TCP / IP和AXI4-Lite,地址、数据和命令必须执行编码的数据包发送到服务器的TCP / IP。对于本例,我们使用以下数据包格式:

(——地址)32位(- - - - - Cmd - - - - -] 32位字的低字节(读= 0,写= 1,调试= 2)[——长度- - -]低字节的32位工作(N < 255)——数据——32位,仅用于写Cmd

例如,一个包发出读取连续3的值从地址0开始x44a0010c:

[44 a0 0 01 c] [00 00 00 00] [00 00 00 03]

这将返回0 x10c数据补偿,而且。0 x110, 0 x114 (ios

例如,一个包发出0 x0抵消0 x04写,是:

[44 a0 00 04] [00 00 00 01] [00 00 00 01] [00 00 00 00]

改变调试水平用于打印到控制台,发送一个调试cmd包:

[xx xx xx xx][00 00 00 03][00 00 00 01] % 0 =没有味精,1 =读|写满2 = pkt

运行read_write_test。m脚本

这个例子包含一个脚本将设置一个TCP / IP连接服务器上运行MicroBlaze,创建命令启用/禁用DUT,读取6标量港口和相同的数据作为一个向量港口和比较结果。

1。要运行此脚本,首先将其复制到您的本地目录

> >复制文件(fullfile (matlabroot,“工具箱”,“hdlcoder”,“hdlcoderdemos”,“ublaze_lwip_read_write_vector_test.m”),“ublaze_test.m”);

在编辑器中打开脚本:

> >编辑(“ublaze_test.m”);

这个脚本有三个部分。第一部分,连接到董事会和将使用设置命令。如果需要,更新的IP地址在41行。

2。执行第一节。您将生成以下命令uint32数组的类型:

read6_cmd = uint32 ([hex2dec (“44 a0010c”)0 6]);%读6 32位海军学校规则read_vec_cmd = uint32 ([hex2dec (“44 a00140”)0 6]);%读6 vec的元素strobe_vec_cmd = uint32 ([hex2dec (“44 a00160”)1 1 1]);%为vec写选通enable_cmd = uint32 ([hex2dec (“44 a00004”)1 1 1]);%启用ip核心disable_cmd = uint32 ([hex2dec (“44 a00004”)1 1 0]);%禁用ip核心debug0_cmd = uint32 ([hex2dec (“00000000”)3 0]);%禁用所有调试printfdebug1_cmd = uint32 ([hex2dec (“00000000”)3 1]);%使读|写printfdebug2_cmd = uint32 ([hex2dec (“00000000”2)3));%启用pkt printf

注意:这些数组存储数据端字节格式所使用的本地机器上,这对许多x86系统是小端字节格式。不过,TCP / IP服务器预计值大端字节格式(网络字节顺序)。因此,如果你是小端字节序的系统,每个元素必须交换使用的字节swapbytes

3所示。执行第二节禁用DUT逻辑和阅读一个计数器值连接到6标量港口以及所有6端口元素向量。请注意,所有的计数器值匹配。这是因为相同的数据,所有的港口和DUT是禁用的,所以整个AXI4异步访问界面不明显。

标量端口(上)和矢量端口(底部)访问DUT禁用:7 e8aec14 7 e8aec14 7 e8aec14 7 e8aec14 7 e8aec14 7 e8aec14
7 e8aec14 7 e8aec14 7 e8aec14 7 e8aec14 7 e8aec14 7 e8aec14

4所示。执行第三节重新启用DUT逻辑和阅读相同的计数器值。注意到6标量港口都显示不同的值,而6元素向量的端口都是一样的。这是由于在AXI4必须发生的顺序存取接口和缺乏同步寄存器在标量港口情况和存在一个显式同步寄存器在向量港口情况。

标量端口(上)和矢量端口(底部)访问启用了DUT: 7 f7796dc 7 fc70e4b 8016860 8104 8065 fdce 80 b5758d ed4d
815964 dd 815964 dd 815964 dd 815964 dd 815964 dd 815964 dd

相应的调试输出串行控制台将:

总结

这个演示了使用MicroBlaze软核处理器在FPGA设计。MicroBlaze非常适合函数作为成熟的处理器或灵活的IP运行遗留C代码作为一个固件程序。这个演示还显示不同标量港口和一个向量的集合港口关于整个AXI4数据同步接口。

附录A:创建和编辑Xilinx SDK应用程序

本节将展示如何创建一个新的Xilinx SDK项目然后将从这个例子的代码修改或扩展。

1。通过单击该链接将打开Xilinx Vivado项目在高密度脂蛋白工作流顾问步骤4.1“创建项目”:

2。导出现有的设计,包括生成的比特流,到本地文件夹中。一旦做出了选择,继续,“发射SDK”。

3所示。在SDK,创建一个新的应用程序项目

4所示。然后,您将可以选择命名项目并创建一个新的bsp

接下来,您可以选择从几个预先配置的例子/模板项目开始。这个例子是建立“lwIP回声服务器”的项目,所以选择现在。

5。使用回显服务器作为一个模板,你可以用下面的代码片段替换以下3方法修改服务器的行为

附录B: C文件内容复制到项目

/ *版权2016 - 2020 MathWorks公司。* / # define IPCOREBASE 0 x44a00000 # define写0 x01 # define读0 x00 #定义调试0 x03 int transfer_data(){返回0;}无效print_app_header () {xil_printf (“\ n \ r \ n \ r——-MathWorks HDL编码器AXI4-Lite IP核心读/写服务器- - - - - - r \ n \”);xil_printf (“TCP数据包发送到端口7将AXI4-Lite读/写\ n \ r”);xil_printf (" \ n \ r ");xil_printf(“[32位地址](基址= 0 x44a0_0000) \ n \ r”);xil_printf(“[32位cmd](读= 0 x00写= 0 x01 debug = 0 x03) \ n \ r”);xil_printf(“[32位len] (N < 255) \ N \ r”);xil_printf(“(32位数据)(N 32位数据值编写cmd) \ N \ r”);xil_printf (“- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ n \ r”);}无效print_packet (struct pbuf * p) {u16 ii; u8 *pktPtr; pktPtr = p->payload; xil_printf("DEBUG | packet payload:\r\n"); for (ii=0;iilen;ii+=4) { xil_printf("%02x %02x %02x %02x\r\n",*(pktPtr+ii),*(pktPtr+ii+1),*(pktPtr+ii+2),*(pktPtr+ii+3)); } } err_t recv_callback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { u8 *pktPtr,*pktEnd; volatile u32 *addr; u32 data[255],cmd; u16 len; int ii; static u8 debug = 3; /* do not read the packet if we are not in ESTABLISHED state */ if (!p) { tcp_close(tpcb); tcp_recv(tpcb, NULL); return ERR_OK; } /* indicate that the packet has been received */ tcp_recved(tpcb, p->len); if (debug > 1) print_packet(p); //[ 32 bits address ] //[ 32 bits read = 0x00, write =0x01] //[ 32 bits length ] //[ 32 bits write data] pktPtr = p->payload; pktEnd = pktPtr+p->len; /* could be multiple commands per packet */ while ( pktPtr < pktEnd) { addr = (u32*) (pktPtr[0]<<24 | pktPtr[1]<<16 | pktPtr[2]<<8 | pktPtr[3]); cmd = (u32) pktPtr[7]; // cmd is 32 bits, but only 1st byte used, ignore rest pktPtr += 8; switch(cmd) { case WRITE : len = (u32) pktPtr[3]; // len is 32 bits, but only 1st byte used, ignore rest pktPtr += 4; for (ii=0;ii 0) xil_printf("WRITE | address: 0x%08x, data[0]: 0x%08x\r\n",addr,data[0]); addr++; pktPtr += 4; } break; case READ : len = (u32) pktPtr[3]; // len is 32 bits, but only 1st byte used, ignore rest pktPtr += 4; for (ii=0;ii 0) xil_printf("READ | address: 0x%08x, data[%d]: 0x%08x\r\n",addr,ii,data[ii]); addr++; } /* send the packet back */ if (tcp_sndbuf(tpcb) > p->len) err = tcp_write(tpcb, data, 4*len, 1); else xil_printf("no space in tcp_sndbuf\n\r"); break; case DEBUG: debug = pktPtr[3]; // only need the low byte pktPtr += 4; xil_printf("Debug level set to : 0x%02x\r\n",debug); break; default : xil_printf("INVALID | cmd: 0x%08x\r\n",cmd); } } /* free the received pbuf */ pbuf_free(p); return ERR_OK; }

6。保存已修改的回声。c文件和应用程序将被重建。

附录C:程序FPGA与精灵和比特流

现在,您可以使用导出的程序FPGA比特流文件和新创建的精灵。