zedboard--用户自定义IP核(pwm发生器)设计(二十)

1:实验说明:

对于Zedboard的用户自定义的IP核有两种可行的方案:

一:通过EMIO交换数据(GPIO,SPI),这个其实就是将PL的IP核看作系统的外设,在数据交互性能和效率上都有很大的缺陷。(不常用)

二:利用向导来制作满足AXI协议的IP核,向导自动生成总线相关的代码,做好地址译码逻辑,读写控制逻辑,并在用户工作区生成一些寄存器。我们写的PL逻辑通过读写这些寄存器和PS交互。这也是常用的方法。

Zedboard也有一些自己做好了的IP core,实验八就是用的自带的IP core。

本实验就是采用第二种方法,制作一个简单的PWM发生器。在PL端开发了这个IP核以后,先在裸跑的程序里面调用这个IP core,测试我们的逻辑有没有实现,这个和之前做的实验没有什么区别(zedboard--zynq使用自带外设IP让ARM PS访问FPGA(八),只不过这里是我们自己写的IP core)

PWM发生器内部只有两个寄存器,一个是调节周期的周期寄存器,另一个是调节占空比的占空比寄存器,其中周期寄存器的最高位是状态位,控制PWM波最后是否产生。


2:具体步骤

启动PlanAhead,创建工程,Next,图1

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第1张图片

输入工程名project_10,Next,图2

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第2张图片

Next,RTL工程  图3

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第3张图片

一路Next,不添加任何文件 图4

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第4张图片

选择board  图5

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第5张图片

完成工程  图6

 

PlanAhead进入工作视图,在Project Manager中单击那个有+的图标(addsources),出现下图,选择Embedded Sources  图7,图8

 

zedboard--用户自定义IP核(pwm发生器)设计(二十)_第6张图片

Next 选着Create Sub-Design。  图9

 

输入名称,这里为system 图10

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第7张图片

点击finish  图11

 

进入了XPS,提示所建立的一个zynq工程,提示是否建立bsb Wizard,选择yes  图12

 

 

出现下图   图13

 

点击ok  出现   图14

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第8张图片

选择next 这里不要大意,一定要把右侧的两个东西来remove掉,我当时就是卡在这里。,remove后出现这样的图   图15

 

Finish,点击finish就可以了,然后进入zynq的配置界面,Diligent公司做好了一个配置方案,可以到网上下载到配置文件。

 如图16 17 18

 


zedboard--用户自定义IP核(pwm发生器)设计(二十)_第9张图片

Hardware- Createor Import  Periphera  来到欢迎界面   图19

 

Next,创建新的模板(默认选择)  图20

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第10张图片

Next  默认   图21

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第11张图片

Next命名工程  图22

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第12张图片

采用AXI4-Lite 图23

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第13张图片

Next,这里只要 User logic master support   图24

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第14张图片

Next,我们要两个寄存器,分别是占空比寄存器和周期寄存器,图25

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第15张图片

Next,不做任何修改  图26

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第16张图片

Next,不需要仿真平台  图27

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第17张图片

Next,  全选图28

第一个选项表示生成的User Logic使用VerilogHDL

第二个选项表示同时生成一个ISE的工程,便于调试和测试Ipcore

第三个选项表示生成软件驱动库文件,方便在SDK里使用Ipcore

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第18张图片

Next,点击finish就可以了 图29

  

我们自己配置的IP核就建立好了,接下来添加刚完成的IP核,在IP Catalog里面的USER选项中找到它  图30

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第19张图片

双击PWM_IP,出现  图31

 

选择YES,  图32

 

点击两次ok,出现 图33

 

注意一下不要粘贴外面的(如word文档里面的),容易出错,输入法选择在英文输入法下。

右击pwm_ip_0,View MPD,添加PORT pwm_out=””,DIR=O,如图34(添加在60行),保存并关闭

 

右击pwm_ip_0,Brouse HDLsources,打开pwm_ip.vhd.添加代码

1添加(138行) 将pwm_out接口设置为模块的输出接口

pwm_out                        :out std_logic;    图35

zedboard--用户自定义IP核(pwm发生器)设计(二十)_第20张图片

2添加(253行)将pwm_out接口到user_logic设备

pwm_out                                          :out std_logic;      图36

zedboard--用户自定义IP核(pwm发生器)设计(二十)_第21张图片

3添加(342)将设备的pwm_out接口和IP核的pwm_out接口连接

       pwm_out                        =>pwm_out,    图37

 

 

保存,退出,右击pwm_ip_0,Brouse HDLsources,打开user_logic.v.添加代码

1添加(58行),声明pwm_out接口,添加pwm_out,   图38

zedboard--用户自定义IP核(pwm发生器)设计(二十)_第22张图片

2添加(88行)定义pwm_out为输出,而且位宽为1,添加

output              pwm_out;  图39


3接下来就是用户实现段了,令slv_reg0为周期寄存器,slv_reg1为占空比寄存器。此外我们还需要一个计数器(pwm_counter),下一个周期的开始信号(Over Period)和预输出信号(pre_pwm_out)。

在110添加逻辑

wire  ovprd;

reg   [C_SLV_DWIDTH-1 :0] pwm_counter;

wire                                           pre_pwm_out;

图40


pwm产生器的逻辑

在124行添加逻辑  图41

  // USER logic implementation added here

always @(posedgeBus2IP_Clk)

begin

       if(!Bus2IP_Resetn || ovprd ||~slv_reg1[31])

              pwm_counter=32'h8000_0000;

       else if(slv_reg1[31])

                            pwm_counter=pwm_counter+1'b1;

                     else pwm_counter=pwm_counter;

end

 

assignovprd=(pwm_counter[30:0]==slv_reg0[30:0])?1'b1:1'b0;

assignpre_pwm_out=(slv_reg1<pwm_counter)?1'b0:1'b1;

assignpwm_out=pre_pwm_out & slv_reg1[31];

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第23张图片

保存,退出,在project菜单中选择RescanUser Repositories,从port中可以看到我们新添加的引脚pwm_out.选择External Ports把引脚引出去,如图42

 

打开Address标签页,单击右上角的GeneratedAddresses按钮,如图43

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第24张图片

单击project –>Design Rule Check,没有报错,关闭xps,回到PlanAhead图44

zedboard--用户自定义IP核(pwm发生器)设计(二十)_第25张图片

在system.xmp文件上右击,选择CreateTop HDL   图45,46

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第26张图片

zedboard--用户自定义IP核(pwm发生器)设计(二十)_第27张图片

单击Add source按钮,选择Add orCreate Constrains 单击Next 图47

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第28张图片

单击 Create File…选项  图48

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第29张图片

改文件名 图49,finish就可以了

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第30张图片

单击左边的Run Synthesis ,这里就出错了,如图50,

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第31张图片

在tcl console 按下ctrl +f 输入error,如图51一看是user_logic.v出错了,<slv_reg> is not d eclared这个时候启动xps,改正错误,可以看到图41,确实是错的,应该在128和134行为slv_reg1,而我漏掉了1,改正,保存,退出xps,重新Run Synthesis,这里也是寻找解决错误的方法。


过程结束后会弹出对话框,图52

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第32张图片

选择Open Synthesized Design,会有一些警告,忽略,打开I/O Port标签,由于以前一直用Altera,这个标签找了一会儿(window->I/O Port),设置pwm_out的引脚,保存。图53

选择Select an existing file

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第33张图片

看不到system.ucf,重启PlanAhead,这时候就可以看到system.ucf文件的内容如下 图54

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第34张图片

单击左边的Generate Bitstream.单击yes,完成implementation,至此硬件工程就做完了。(这个过程又点长)

在PlanAhead中,单击File->Export->ExportHardware  图55

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第35张图片

建立c工程 图56

 

选择Xilinx Tools->Repositories,单击new,找到工程路径,图57

zedboard--用户自定义IP核(pwm发生器)设计(二十)_第36张图片

在hello_bsp_0上右击,选择BoardSupport Package Setting ,找到drivers中得pwm_ip_0,修改Driver,图58,如果你没有出现估计就悲剧了。

 zedboard--用户自定义IP核(pwm发生器)设计(二十)_第37张图片

然后我们将自设的IP核的Driver添加进来后就可以添加c代码了。图59

 

修改bug在hello_bsp_0上面有一个红色的叉,是有一个宏没有设置,需要手动设置这个宏,找到pwm_ip_selftest,c这个文件,C:\zedboard\project_11\project_11.srcs\sources_1\edk\system/drivers/pwm_ip_v1_00_a/src/pwm_ip_selftest.c(我的目录在这里)

注释 #include "xio.h"

添加#define PWM_IP_USER_NUM_REG 2   图60

zedboard--用户自定义IP核(pwm发生器)设计(二十)_第38张图片

保存,等待工程编译结束。

出现图61的错误,解决办法。重新建立一个c工程。然后和上面的是一样的,至于原因就不知道了。

zedboard--用户自定义IP核(pwm发生器)设计(二十)_第39张图片

测试

选择Xilinx Tools->Program FPGA

在hello_world_0工程上右击,选择RunAs->Launch on Hardware,用示波器看波形结果是正确的,修改helloworld.c 中的占空比可以看到不同的波形。


易出错的地方:

第一个:在添加vhdl和verilog代码的时候以及找错误的方法。

        第二个是出现类似于以下的错误: "Building target: hello_world_0.elf Invoking: ARM gcc linker arm-xilinx-eabi-gcc -Wl,-T -Wl,../src/lscript.ld -L../../standalone_bsp_0/ps7_cortexa9_0/lib -o"hello_world_0.elf" ./src/helloworld.o ./src/platform.o -l-Wl,--start-group,-lxil,-lgcc,-lc,--end-group ../lib/gcc/arm-xilinx-eabi/4.6.1/../../../../arm-xilinx-eabi/bin/ld.exe: cannot find -l-Wl,--start-group,-lxil,-lgcc,-lc,--end-group collect2: ld returned 1 exit status make: *** [hello_world_0.elf] Error 1"解决方法就是重新新建一个c工程,(冲PlanAhead重新导入一次),原因不祥。

       以上都在上面有提到过。这次是用裸跑的程序来调用IPcore,下次实验是要为这个IPcore开发Linux系统上的设备驱动,使得运行在Linux上的应用程序可以使用这个驱动程序与PL端进行通信,从而控制PWM的输出。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Xilinx,zynq,zedboard用户ip设计,axi总线,zedboard的pwm发生器)