cuter

Vivado实现纯逻辑开发——从最简单的开始

0
阅读(26632) 评论(25)

 Vivado实现纯逻辑开发

——从最简单的开始

硬件平台:ZedBoard

开发工具:Vivado 2014.2


1.       前言:

1.1.       关于软件的安装

本来不想提这一环节的,因为去官网下载安装包,安装,到网上找个license就搞定了,结果在这一环还走了弯路,不得不记录下来,作为教训和供他人借鉴的经验。

Xilinx官网有ISE+Vivado合体的安装包,也有网友推荐这个安装包,一次装俩,何乐而不为呢?本着这种贪小便宜的想法,我下载了这个安装包,下载的时候发现这个安装包和ISE的安装包差不多大,当时也没太在意。

我的破电脑哼哧哼哧下了N小时,完了安装,发现是Vivado版本是2012.4,当时觉得版本太低了,不太爽,想想再下载又要N久,先凑合用吧。破解,打开Vivado发现这个界面太熟悉了,和PlanAheadXPS的欢迎界面很像,有点不好的预感啊。

新建工程,发现不支持zynq系列芯片,只支持v7k7两个系列,太坑了!既不支持以前的低端系列,也不支持后来的高端系列。

无奈啊,回过头来去看启动Vivado时弹出的命令行窗口,根据一些提示信息可以推测,这个版本的Vivado只是做了一个界面,真正工作时是跑去调用ISE的组件,这也是为什么这个安装包的大小和ISE安装包大小差不多的原因。

在这里告诉后来人,不要贪小便宜,果断不要安装这个合体包,老老实实下载比较新的版本,最好不是最新的,有可能没破解。

1.1.       本来应该是前言的前言

在接触新东西的时候,我总会带有一丝敬畏,好像未知的东西总是不如熟悉的东西让人感觉踏实。所以我喜欢用自己掌握的很熟练的或者是很简单的东西去验证未知的东西,加快自己学习的进度。现在我选择上手Vivado,也打算从最简单的纯逻辑设计开始。

2.       规划:

在设计之初就能够进行良好地规划,可以节省后续的设计时间,当项目复杂度增加时,项目的规划和方案设计更加重要。

1)        项目功能:流水灯

2)        编程语言:Verilog

3)        设计流程:建立工程à代码编辑à功能仿真à综合、实现à板级测试(本文是现象的观察,后续会给出ChipScope的使用方法)

项目的功能十分简单,主要目的是为了Vivado开发流程,也就是上述第3个步骤。

3.       设计

功能简单,上个示意框图,简单描述一下吧。

1 总体框图

timer500ms模块:

功能是产生2hz的时钟,为led_ctrl模块提供时钟。

led_ctrl模块:

功能是实现循环移位,在硬件上的体现就是流水灯。输入时钟为2hz,时钟上升沿进行一次移位操作,每个led点亮0.5s

4.       实现:

4.1.       建立工程

下载了最新版的Vivado2014.2,找了个license,工具可以用了,IP可不可以还没有验证。欢迎界面看起来和之前的PlanAheadXPS的欢迎界面差别比较大了,可以说是焕然一新吧。


2 欢迎界面

点击Create New Project,进入新建工程的向导,逐步next即可。

3 新建工程向导step1

4 新建工程向导step2 指定工程名和存储路径

勾选图5椭圆内的选项,表明不在此时指定源文件。

5 新建工程向导step3

6 选择器件/开发板

最后一步:所建立工程的概要信息。

7 新建工程信息总览

点击Finish之后,就进入Vivado主界面了,如图8所示。

8 Vivado主界面

主界面主要包括:

Flow Navigator       在此可以找到整个设计过程中涉及到的所有流程

Sources                   工程包含的设计源文件,源码、约束等

Properties                所选中对象的属性信息

Project Summary     在此可以查看工程信息

Design Runs            在此可以查看提示信息、警告、错误、也可以输入tcl命令

4.2.       流程控制子窗口

9 流程子窗口

后续的“Add Sources”、“Simulation”、“Synthesis”、“Implementation”以及“Generate Bitstream”,都可以在该窗口找到执行菜单。

4.3.       代码编辑

顶层:


module runled_top(
    input iClk,
    input iRst_n,
    output [7:0] oLed
    );

wire    clk2hz_sig;
    
timer500ms timer500ms_inst(
    .iClk100mhz(iClk),
    .iRst_n(~iRst_n),
    .oClk2hz(clk2hz_sig)
);    

led_ctrl led_ctrl_inst(
    .iClk(clk2hz_sig),
    .iRst_n(~iRst_n),
    .oLed(oLed)
);
        
endmodule


时钟发生:


/*
oFreq = iFreq/(2N)
 => 
N=iFreq/(2oFreq)=100,000,000/(2*2)=25,000,000=0x17d7840
*/
module timer500ms(iClk100mhz,iRst_n,oClk2hz)
input	iClk100mhz;
input	iRst_n;
output	oClk2hz;			// period = 1/2s

reg	[31:0]	cnt2hz;
always @(posedge iClk100mhz) begin
if(iRst_n=1’b0) begin
		oClk2hz <= 1’b0;
		cnt2hz <= 32’b0;
	end
	else begin
		if(cnt2hz=32’d25000000) begin
			cnt2hz <= 32’b0;
			oClk2hz <= ~ oClk2hz;
		end	
else begin
	cnt2hz <= cnt2hz + 1’b1;
	oClk2hz <= oClk2hz;
end
	end
end
endmodule


led控制模块:


module led_ctrl(
    input iClk,
    input iRst_n,
    output [7:0] oLed
    );
reg [7:0]   led;    

/*
\ 每个时钟上升沿,左移1bit,写法是为了实现循环左移
*/    
always @(posedge iClk) begin

    if(iRst_n==1'b0)
        led <= 8'b1;
    else
        led <= {led[6:0],led[7]};        

end    

assign  oLed = led;
    
endmodule


添加代码源文件方法:点击Add Sources按钮,有两处有该按钮,如图10所示。

10 add source(1)

另外,还可以在Design Sources文件夹上单击鼠标右键,弹出的菜单中有“Add Sources”选项,如图11所示。

11 add source (2)

弹出图12所示的向导。

12 选择资源类型

此处添加的是HDL设计文件,所以选择椭圆内的“Add or Create Design Sources”,NEXT,弹出图13所示的界面,选择创建或者添加源文件。

13 创建/添加源文件

单击Create File按钮,进入图14所示的界面。

14 新建源文件

指定文件名和存储位置后点击OK,返回上一界面,界面发生变化,如图15所示。

15

点击Finish,弹出新建文件的助手,如图16所示。

16 源文件编辑助手

这里应该和ISE添加源文件的向导一样,我直接点击OK略过,然后自己编辑的代码。

4.4.       功能仿真

添加testbench,方法和4.3所述的类似,只是文件类型为“Add or Create Simulation Sources”(图12)。

Run Simulation,会弹出仿真结果。此处以timer500ms模块的仿真为例,给出仿真结果:

17 timer500ms模块仿真结果

体会:在ISE中新建Testbench文件时,可以选择被仿真模块,然后自动实例化待仿真的模块;Vivado中需要自己手动编写所有代码。

4.5.       综合、实现、烧写

4.5.1.      约束文件的编写

ISE约束文件格式为ucfVivado约束文件为xdc,这是Vivado又一改进。xdc文件是

我的约束文件为:

#In the following the XDC constraint is matched to the origanal UCF constraint, XDC above, UCF below # Commented

set_property PACKAGE_PIN Y9 [get_ports {iClk}]

set_property IOSTANDARD LVCMOS33 [get_ports {iClk}]

#NET GCLK          LOC = Y9   | IOSTANDARD=LVCMOS33;  # "GCLK"

# Bank 33, Vcco = 3.3V

#set_property IOSTANDARD LVCMOS33 [get_ports -filter { IOBANK == 33 } ]

set_property PACKAGE_PIN T22 [get_ports {oLed[0]}]

set_property IOSTANDARD LVCMOS33 [get_ports {oLed[0]}]

#NET LD0           LOC = T22  | IOSTANDARD=LVCMOS33;  # "LD0"

set_property PACKAGE_PIN T21 [get_ports {oLed[1]}]

set_property IOSTANDARD LVCMOS33 [get_ports {oLed[1]}]

#NET LD1           LOC = T21  | IOSTANDARD=LVCMOS33;  # "LD1"

set_property PACKAGE_PIN U22 [get_ports {oLed[2]}]

set_property IOSTANDARD LVCMOS33 [get_ports {oLed[2]}]

#NET LD2           LOC = U22  | IOSTANDARD=LVCMOS33;  # "LD2"

set_property PACKAGE_PIN U21 [get_ports {oLed[3]}]

set_property IOSTANDARD LVCMOS33 [get_ports {oLed[3]}]

#NET LD3           LOC = U21  | IOSTANDARD=LVCMOS33;  # "LD3"

set_property PACKAGE_PIN V22 [get_ports {oLed[4]}]

set_property IOSTANDARD LVCMOS33 [get_ports {oLed[4]}]

#NET LD4           LOC = V22  | IOSTANDARD=LVCMOS33;  # "LD4"

set_property IOSTANDARD LVCMOS33 [get_ports {oLed[5]}]

set_property PACKAGE_PIN W22 [get_ports {oLed[5]}]

#NET LD5           LOC = W22  | IOSTANDARD=LVCMOS33;  # "LD5"

set_property PACKAGE_PIN U19 [get_ports {oLed[6]}]

set_property IOSTANDARD LVCMOS33 [get_ports {oLed[6]}]

#NET LD6           LOC = U19  | IOSTANDARD=LVCMOS33;  # "LD6"

set_property IOSTANDARD LVCMOS33 [get_ports {oLed[7]}]

set_property PACKAGE_PIN U14 [get_ports {oLed[7]}]

#NET LD7           LOC = U14  | IOSTANDARD=LVCMOS33;  # "LD7"

# Bank 34, Vcco = Vadj

#set_property IOSTANDARD LVCMOS18 [get_ports -filter { IOBANK == 34 } ]

set_property IOSTANDARD LVCMOS18 [get_ports {iRst_n}]

set_property PACKAGE_PIN P16 [get_ports {iRst_n}]

#NET BTNC          LOC = P16  | IOSTANDARD=LVCMOS18;  # "BTNC"

注释写的很清楚了,和ZedBoarducf文件是一一对应的,很容易理解。

不过关于约束的编写也不是这么简单能说的清的,后续还需要进一步学习。如果快速入门的话,可以参考模版文件,模板文件如图18所示:

18 模板文件的使用

注意要选中Templates子选项卡(位于Sources旁边),然后点开红色方框内的xdc文件夹,找到自己想要进行的约束,然后可以看到参考语句,预览结果在上图绿色直线上方。

同样的,还有verilogvhdlTestbench等文件的参考语句,需要时可以参考,从而提高代码编辑效率。

4.5.2.      综合、实现、烧写

综合、实现的菜单在Flow Navigator中,如果想分开执行,分别点击即可。为了方便,可以直接选择“Generate Bitstream”。除错,直到成功为止。

烧写有两种方式,一种是通过impact,一种是通过SDK Tools菜单下的Progress FPGA指令实现

4.5.3.      本节体验:

从主观感觉上来说,对于简单的设计,ISE在综合、实现的时间上要比Vivado短。

4.6.       实验现象

传个视频玩一玩。


5.       小结

通过本次学习,基本掌握了Vivado做纯逻辑开发的流程,Vivado做逻辑开发较ISE而言稍微,在操作上稍微有点繁琐,但也有方便之处,可谓各有千秋吧。

6.       隐藏的小问题

设计存在两处小问题,我没有改,有兴趣的童鞋可以看看在哪里。


版权声明:

本文由博主“cuter”发布。欢迎转载,但不得擅自更改博文内容,也不得用于任何盈利目的。转载时不得删除作者简介和版权声明。如有盗用而不说明出处引起的版权纠纷,由盗用者自负。

博客官方地址:

ChinaAET:http://blog.chinaaet.com/cuter521

EDN China: http://bbs.ednchina.com/BLOG_cuter521_356737.HTM

  1. 厉害了我的哥

  2. 编程为什不使用C语言啊,verilog语言不太懂

  3. 代码有问题,不能直接移植,包括:等于判断写成了赋值,同步复位仿真现象错误,改成异步复位后,仿真结果正确。


  4.  跟着学习了一下,对于熟悉vivado真不错,支持一下

  5. 博主,您好!

    4.4的仿真那块弄不出来,能否将的再详细一些。谢谢

  6. ***此内容已被管理员屏蔽***

  7. 试试
  8. 匿名用户匿名用户
  9. 博主

          我在PS中编写c代码来控制LD9(MIO7),请问在PL中需要做什么设置吗?与PL有没有关系哪?谢谢!

  10. 匿名用户匿名用户

    博主,您好!

    仿真那块弄不出来,你能否再来个详细一点的,谢谢啦!!!    

  11. 好例程哈  ,感谢楼主的分享,刚好需要哈
  12. 匿名用户匿名用户

    Vivado的威力是在大型電路, 在大型電路的合成上, 會比ISE快很多


  13. 匿名用户匿名用户
    约束文件这块能讲的细一点吗
  14. 一步步学习!

  15. @lynn

    1、复位问题

    始终发生模块设计采用同步复位,所以按下复位按键后并不能达到逻辑上想要的 led全灭效果,复位按键按下后,时钟消失,所以无任何操作,会保持在当前状态。

    2、仿真时间问题

    这个问题比较隐蔽,其实也无伤大雅,仿真结果:周期不是500ms,而是1s,这是Testbench输入写错了,没有改~