FPGA学习笔记.docx

上传人:b****6 文档编号:5809981 上传时间:2023-01-01 格式:DOCX 页数:11 大小:162.17KB
下载 相关 举报
FPGA学习笔记.docx_第1页
第1页 / 共11页
FPGA学习笔记.docx_第2页
第2页 / 共11页
FPGA学习笔记.docx_第3页
第3页 / 共11页
FPGA学习笔记.docx_第4页
第4页 / 共11页
FPGA学习笔记.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

FPGA学习笔记.docx

《FPGA学习笔记.docx》由会员分享,可在线阅读,更多相关《FPGA学习笔记.docx(11页珍藏版)》请在冰豆网上搜索。

FPGA学习笔记.docx

FPGA学习笔记

FPGA学习笔记

1.Verilog语言的学习心得

我花了两个星期学习VerilogHDL语言,从10月14号开始到10月31号,由于期间还需要学习本专业知识,所以进度比较慢,最近才开始仿真,我用的是ISE软件,我列举一些学习中遇到的问题和笔记,有不全面的地方还希望老师指出。

首先先列举一些学习Verilog的过程中遇到的问题和经验(我用的教材是Verilog数字系统设计教程,夏宇闻编著的):

Verilog与C最大的不同时Verilog里面有并行语句块(fork_join块),块和块之间是并行运行的,C里面全部是顺序执行,Verilog提供了非阻塞赋值来防止形成锁存器,而C语言的话并没有这类似的赋值,Verilog语言里面有x和z,其中x代表未知状态,z代表高阻态,而C语言里面并没有。

Verilog语言编写数字逻辑电路的方法我明白的有两种,一种是通过编写数字电路的逻辑功能来实现,另一种是通过设计数字电路,通过电路的描述来编写module,如果是通过逻辑功能写代码的话,就必须整理好全部的逻辑性,并随时注意Verilog的并行块执行的原理(begin_end块是顺序执行的)。

如果是通过电路结构来写代码的话,就需要先通过设计出相应的电路结构,然后定义相应的端口(其中输出必须定义寄存器类型,输入不能),然后可以通过系统自带的模块(andxor等),注意好每个小模块的输入输出的线即可,但是每个小模块都必须描述,如果不描述,就会造成代码的错误,或者实现功能错误,这是我对Verilog两种编写代码的理解。

Verilog编写程序时,initial块的执行是不需要时间的,在0ms之内执行完毕,并作为电路的初始状态;设计的电路结构最好是同步实行的电路结构,不要是异步时序的,只是因为许多综合器不支持异步时序的逻辑综合,而且也因为异步时序逻辑确实很难来控制由组合逻辑和延迟所产生的冒险和竞争。

 

2.ISE软件的学习心得

ISE仿真:

首先建立文件(我们以加法器为例进行仿真实验,加法器是4位加法器,带进位输出):

命名为addtion_device,点击next>:

 

选择型号为Spantan3E,点击next后面直接点击next知道Finish。

然后在source界面里面点击元器件的名称,然后右键点击NewSource。

 

点击之后,命名为addtion_device即可。

接下来的界面是设置输入输出口的界面,不必管它,到程序里面进行设计也是一样的。

我们直接下一步,出现了要编程的相关属性,见下图:

编写的Verilog语言代码如下:

`timescale1ns/1ps

//////////////////////////////////////////////////////////////////////////////////

//Company:

//Engineer:

//

//CreateDate:

20:

43:

0711/02/2010

//DesignName:

//ModuleName:

addtion_device

//ProjectName:

//TargetDevices:

//Toolversions:

//Description:

//

//Dependencies:

//

//Revision:

//Revision0.01-FileCreated

//AdditionalComments:

//

//////////////////////////////////////////////////////////////////////////////////

moduleaddtion_device(a,b,sum,C);

input[3:

0]a,b;

output[3:

0]sum;

outputC;

reg[3:

0]sum;

regC;

always@(aorb)

begin

{C,sum}=a+b;

end

endmodule

但是此时编写的代码不能仿真,需要新建一个Testbenchwaveform文件,右键点击Testbenchwaveform

自己定义输入即可:

如下图,我定义的是:

设置好之后记得点击保存图标,然后即可生成相应的文件,然后在process里面点击simulatebehaviormodule:

双击即可进行仿真,看仿真波形。

 

看下面的仿真波形可以看见,输出sum和进位C都符合二进制的规则。

见下图:

 

下面仿真三态门,当控制信号en为高电平时,三态门输出等于输入,当控制信号为低电平时,三态门的输出为高阻态:

按照之前的方法建立文件triple_gate,下面是实现的功能代码:

`timescale1ns/1ps

//////////////////////////////////////////////////////////////////////////////////

//Company:

//Engineer:

//

//CreateDate:

19:

38:

5511/03/2010

//DesignName:

//ModuleName:

triple_gate

//ProjectName:

//TargetDevices:

//Toolversions:

//Description:

//

//Dependencies:

//

//Revision:

//Revision0.01-FileCreated

//AdditionalComments:

//

//////////////////////////////////////////////////////////////////////////////////

moduletriple_gate(en,a,b);

inputen,a;

outputb;

regb;

always@(enora)

begin

if(en)

b<=a;

else

b<=1'bz;

end

endmodule

其中,我发现一个问题,那就是如果always语句里面的if-else语句中,当b<=1’bz写成b<=z的时候,会发生错误,因为系统认为此时的z为一个字符,而并不表示高阻态,因此最好写成1’bz的表示形式,这样才能表示高阻态。

仿真代码为下面的形式:

由于我设置的时候,有输出延迟,因此此时的a和b的值不是很理想,但是计算上输出延迟之后很清楚的显示,当en等于0的时候,b表示高阻态,当en=1的时候,b=a。

下面仿真3-8译码器,前面已经介绍了建立文件的方式,此时便不再写了。

`timescale1ns/1ps

//////////////////////////////////////////////////////////////////////////////////

//Company:

//Engineer:

//

//CreateDate:

19:

54:

2011/03/2010

//DesignName:

//ModuleName:

decode

//ProjectName:

//TargetDevices:

//Toolversions:

//Description:

//

//Dependencies:

//

//Revision:

//Revision0.01-FileCreated

//AdditionalComments:

//

//////////////////////////////////////////////////////////////////////////////////

moduledecode(en,in,out);

inputen;

input[2:

0]in;

output[7:

0]out;

reg[7:

0]out;

always@(inoren)

begin

if(en)

case(in)

3'b000:

out=8'b0000_0001;

3'b001:

out=8'b0000_0010;

3'b010:

out=8'b0000_0100;

3'b011:

out=8'b0000_1000;

3'b100:

out=8'b0001_0000;

3'b101:

out=8'b0010_0000;

3'b110:

out=8'b0100_0000;

3'b111:

out=8'b1000_0000;

default:

out=8'b0000_0000;

endcase

else

out=8'bzzzz_zzzz;

end

endmodule

此时可以看见,当en=0时,out=8’hzz,当en=1时,in=3’h5=3’b101,可以看见out=8h’20=8’b0010_0000,因此仿真和预想的一样。

(主要用了case语句,期间写的时候忘记了写endcase,后来提示错误才发现,因此要好好锻炼,多写写简单的代码才能写更好的代码)

以上组合逻辑电路的仿真不是根据仿真代码实现的,而是在testbench里面画的波形进行的,下面的时序逻辑电路我就根据仿真代码来实现仿真功能。

上面写的都是组合逻辑电路,下面写写时序逻辑电路。

设计移位寄存器(8位)的代码在下面(有输入是一位的,在clk上升沿进行移位,带有同步清零功能,输入信号从低位向高位移动):

下面是功能代码部分:

`timescale1ns/1ps

modulemove_device(in,clk,clr,out);

inputin,clr,clk;

output[7:

0]out;

reg[7:

0]out;

always@(posedgeclk)

begin

if(clr)

out<=8'b0000_0000;

else

begin

out<=out<<1;

out[0]<=in;

end

end

endmodule

仿真功能的代码如下:

modulemove;

//Inputs

regin;

regclk;

regclr;

//Outputs

wire[7:

0]out;

//InstantiatetheUnitUnderTest(UUT)

move_deviceuut(

.in(in),

.clk(clk),

.clr(clr),

.out(out)

);

always#50clk=~clk;//设置时钟信号,周期为100ns

initialbegin

//InitializeInputs初始化信号的值

in=0;

clk=0;

clr=0;

#50in=1;

#100in=0;

#150in=1;

#250in=0;

#500;

end

endmodule

进行仿真之后,实现的功能如下图:

上面图中显示了,在clk的上跳沿out信号将进行移位,然后out的最低位的值为in的值,因此仿真和实际波形一样(设置的延迟时间为零)。

 

学习小结:

ISE软件仿真(10.1)先要写功能代码,仅仅只有功能代码是不能进行仿真的,仿真有两种方法,一种是新建一个

,这时必须写仿真代码,即自己写initial里面的值和自己设置仿真时钟的周期,还有一种是建立一个

文件,在波形界面中自己来描述波形的变化,这种方式比较简单,但是不方便编写时钟信号,因为时钟信号在这个文件中是不能改变的,因此需要改变时钟信号的周期就必须选择前一种方法进行仿真。

由于学习的时间比较短,因为在平时的时候还要注意课本的专业课的学习,如果学习进度相比别的同学来说比较慢的话,希望老师指出,我会在以后的时间内抓紧时间学习FPGA,同时也不忘记专业课的学习。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1