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,开始创建外设。(看不清图的话可以点击小图放大,下同)
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 @( posedge Bus2IP_Clk ) begin if ( Bus2IP_Resetn == 1'b0 ) begin LED_Out <= 0; end else begin LED_Out[7:0] <= slv_reg1[7:0]; end end // LED_OUTPUT_PROC 同时添加逻辑让Switch的状态通过简单的同步(不是去抖啊)写入寄存器0。 // implement slave model register read mux always @( slv_reg_read_sel or slv_reg0 or slv_reg1 ) begin case ( slv_reg_read_sel ) 2'b10 : slv_ip2bus_data <= slv_reg0; 2'b01 : slv_ip2bus_data <= slv_reg1; default : slv_ip2bus_data <= 0; endcase end // SLAVE_REG_READ_PROC always @( posedge Bus2IP_Clk ) begin if ( Bus2IP_Resetn == 1'b0 )