ZedBoard学习手记(二) 开发自定义AXI总线外设IP核

想要发挥zynq芯片的特长,让整个系统协同工作起来,就需要将ps与pl两部分结合在一起,在cortex-a9核和fpga逻辑资源之间建立通信的通道,这条通道就是axi总线。zedboard推出的官方例子中已经介绍了如何将xilinx做好的axi总线ip(如axi_timer、axi_gpio等)添加到工程中,而下面就让我们一起来自己编写一个简单的axi总线设备——读取板上的8个swtich状态,并控制8个led的开关。有人会问我不了解axi总线啊怎么办,无须担心,xilinx已经为我们设计了建立向导,可以自动生成一个设备模板,即使不了解axi协议,也可以轻松完成设计工作。首先通过planahead建立一个系统工程,导入zedboard的xml文件:zedboard_revc_v2.xml。这步操作还不清楚的童鞋请在zedboard官网上下载zedboard_ctt_v14.1资料并跟随该文档进行扫盲。这个资料很详细,也是step by step的,可以帮助完成基本的操作学习。工程建好后,进入xps界面,选择hardware→create or import peripheral,开始创建外设。(看不清图的话可以点击小图放大,下同)
在弹出的窗口中选择新建模板,建立一个外设。
next后选择集成到xps系统中,这样新建的外设就会保存在edk目录下的pcores文件夹中。
接着next,为自己的ip起个名字,这里叫my_gpio,全称就是my_gpio_v1_00_a了,注意这里的名字不能用大写字母。
之后选择总线的类型,可以看出这里提供了几个axi总线设备的变种形势,可以使设备具备猝发操作及大量数据传输的能力,这里我们选axi4-lite形式,也就是最简单的类型。
下一步进行几个可选项配置,包括软件复位、主从模式等,勾选中间两项即可,虽然现在用不到软件复位。
设置寄存器数量,这里我们设置两个32位寄存器(实际使用低8位,其它部分not care),一个用来控制led,另一个用来读取sw状态。
选择需要的ip连接信号,这些是与用户逻辑对接的信号,保持默认即可。
这一步可以建立一个总线上的仿真设备,不需要,直接next。
来到另一个配置画面,第一个选项是使用verilog来设计用户逻辑;第二个选项建立一个ise的工程文件,方面写代码;第三个选项让xps自动生成底层的控制代码。
设置结束以后,在xps的工程目录下就能找到ip的文件夹了,兔子这里的路径是” .\hello_zed.srcs\sources_1\edk\module_1\pcores\my_gpio_v1_00_a”。里面有三个文件夹,hdl文件夹包含了user_logic.v和my_gpio.vhd。前者就是我们要修改的用户逻辑文件,后者则是用来连接axi与用户逻辑,并封装ip核的vhdl文件。这个文件只能是vhdl的,所以像兔子这样只会verilog的就很苦闷了,还好里面的内容很简单,看一下就能明白。在devl\projnav文件夹下可以找到刚生成的ise工程,用project navigator打开my_gpio.xise,这样就可以开始编辑user_logic了。
user_logic中除了一些定义和信号连接以外,就是两个always块,第一个实现axi总线向用户寄存器写入数据,第二个则是总线从寄存器中读取数据。需要注意的是,这里的axi总线已经通过xilinx的axi lite ip interface进行了中转,到用户这里就变成了非常简单的读写逻辑。为了控制板上的硬件,我们定义两组信号和相应的寄存器:sw_in信号连接8个switch,led_out连接8个led。input[7:0] sw_in;output[7:0] led_out;在这里,规定寄存器0为swtich状态寄存器,寄存器1为led控制寄存器。添加一个always块,使写入寄存器1的数据在led_out上更新。always@(posedgebus2ip_clk )beginif( bus2ip_resetn == 1'b0 )begin led_out <= 0;endelsebegin led_out[7:0] <= slv_reg1[7:0];endend// led_output_proc同时添加逻辑让switch的状态通过简单的同步(不是去抖啊)写入寄存器0。 // implement slave model register read muxalways@( slv_reg_read_sel or slv_reg0 or slv_reg1 )begincase( slv_reg_read_sel ) 2'b10 : slv_ip2bus_data <= slv_reg0; 2'b01 : slv_ip2bus_data <= slv_reg1; default : slv_ip2bus_data <= 0;endcaseend// slave_reg_read_procalways@(posedgebus2ip_clk )beginif( bus2ip_resetn == 1'b0 )begin sw_reg0 <= 0; sw_reg1 <= 0; slv_reg0 <= 0;endelsebegin sw_reg0 <= sw_in; sw_reg1 <= sw_reg0; slv_reg0[7:0] <= sw_reg1[7:0];endend// swtich_input_proc之后还要修改读写逻辑,将case ( slv_reg_write_sel )下的2'b10项注释掉,令寄存器0只读(对写入的数据not care),寄存器1则可以读写。如此,我们的用户逻辑就完成了,简单吧。别忘了还要在my_gpio.vhd中为用户逻辑添加端口,两组信号在整个ip的对外接口中分别命名为gpio_led_out和gpio_sw_in。
具体的代码内容在此:my_gpio_hdl.rar双击synthesize,检查一下有没有问题,没问题的话就可以关掉project navigatorl。
回到xps界面,我们的自定义ip已经在列表中了,但是这个时候将ip添加到工程中,刚才进行的编辑并不生效,gpio端口并没有显示在ip核的框图中,这点兔子没有搞明白是为什么,可能要手动修改mpd文件吧。于是我选择将这个ip再添加一次(不得已而为之,有什么好办法望不吝赐教),还是刚才的方法,只不过这回选择导入已有的外设,这种方法也可以用于导入其他已有的ip核。
依旧起名为my_gpio,在弹出的提示中选yes覆盖,之后一路next到hdl source files窗口,选择ip核的\data\_my_gpio_xst.prj文件。
继续next,直到这里选择总线类型为axi4-lite slave类型。
接着在参数窗口中指定high address的参数为c_highaddr。
好了,next到结束,这时刚才进行的修改已经生效并被成功导入了,现在双击my_gpio,保持默认选项不管,将其添加到系统中。
在graphic视图中,可以看到my_gpio的框图,包括一组已经连接的axi总线,和两组我们刚才定义的端口。
进入port界面,将led和sw端口设置为对外,确保最后看起来是这个样子。
好了,关闭xps,回到planahead,生成top hdl(如果之前做了可忽略)。
新建一个约束文件,并设置sw和led的端口约束。
约束内容如下(建议手动输入,如果copy了什么非法字符是很麻烦的,害我查了好久):
选择generate bitstream,系统会自动完成编译综合工作,最后生成包含pl配置信息的system.bit文件。
至此,my_gpio自定义外设就完成了,这个pl现在可以通过axi总线与ps通信——让然还需要软件支持了,呵呵。下篇将会介绍如何裸机软件调试外设,其步骤与zedboard_ctt文档中大同小异。以上。

浅谈:高温电缆的四大特点
承德科胜真空灌装机|眼药水灌装机|河北灌装机
雷器在选择上要具备哪些技巧,有什么事项需要注意
如何通过布线改善手机的音频性能
初识内存取证-volatility与Easy_dump
ZedBoard学习手记(二) 开发自定义AXI总线外设IP核
AI安防芯片,华为、富瀚微与国外巨头同台博弈
从众盟科技云滇之播探寻互联网上美食直播的商业与公益价值
耗时十年研发而成的真正的柔性传感器
德国RWE计划到2022年投资50亿欧元增加4GW太阳能和风电装机量
pcb宣布涨价,led显示屏材料成本不断上涨
SART和UART是什么及USART与UART有什么不同之处
用于状态监测和热点探测的自动多光谱温度传感器现在RS Components有售
声卡的发展史
基于ADRF6655的100-2500MHz有源混频设计及应
浅谈AMD锐龙Z1和锐龙Z1 Extreme处理器
pcb板上的红胶是什么_pcb上红胶有什么作用
从0-1带你入门物联网操作系统(2)——潘多拉 STM32L475 上手指南
自制6N9P+6P3P单端胆机电路图
浦桑尼克790t扫地机器人值不值得买