VerilogFPGA入门笔记源于学习经验积累.docx

上传人:b****8 文档编号:9798674 上传时间:2023-05-21 格式:DOCX 页数:56 大小:78.35KB
下载 相关 举报
VerilogFPGA入门笔记源于学习经验积累.docx_第1页
第1页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第2页
第2页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第3页
第3页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第4页
第4页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第5页
第5页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第6页
第6页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第7页
第7页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第8页
第8页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第9页
第9页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第10页
第10页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第11页
第11页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第12页
第12页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第13页
第13页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第14页
第14页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第15页
第15页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第16页
第16页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第17页
第17页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第18页
第18页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第19页
第19页 / 共56页
VerilogFPGA入门笔记源于学习经验积累.docx_第20页
第20页 / 共56页
亲,该文档总共56页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

VerilogFPGA入门笔记源于学习经验积累.docx

《VerilogFPGA入门笔记源于学习经验积累.docx》由会员分享,可在线阅读,更多相关《VerilogFPGA入门笔记源于学习经验积累.docx(56页珍藏版)》请在冰点文库上搜索。

VerilogFPGA入门笔记源于学习经验积累.docx

VerilogFPGA入门笔记源于学习经验积累

FPGA入门笔记(源于学习经验积累)

17.verilog特点:

区分大小写,所有关键字都要求小写

不是强类型语言,不同类型数据之间可以赋值和运算

//是单行注释可以跨行注释

描述风格有系统级描述、行为级描述、RTL级描述、门级描述,其中RTL级和门级别与具体电路结构有关,行为级描述要遵守可综合原则

门级描述使用门级模型或者用户自定义模型UDP来代替具体基本元件,在IDE中针对不同FPGA器件已经有对应的基本元件原语

18.verlog语法要点:

moduleendmodule之间由两部分构成:

接口描述和逻辑功能描述

IO端口种类:

inputoutputinout

相同位宽的输入输出信号可以一起声明,input[3:

0]a,b;不同位宽的必须分开写

内部信号为reg类型,内部信号信号的状态:

01xz,3'bx1=3'bxx1x/z会往左扩展3'b1=3'b001数字不往左扩展

逻辑功能描述中常用assign描述组合逻辑电路,always既可以描述组合逻辑电路又可以描述时序逻辑电路,还可以用元件调用方法描述逻辑功能

always之间、assign之间、实例引用之间以及它们之间都是并行执行,always内部是顺序执行

常量格式:

<+/-><二进制位宽><'><进制><该进制的数值>:

默认进制为10进制

默认位宽为32位

位宽是从二进制宽度角度而言的

由位宽决定从低位截取二进制数2'hFF=2'b11,通常由被赋值的reg变量位宽决定

parameter常用于定义延迟和变量位宽,可用常量或常量表达式定义

变量种类:

wireregmemory

IO信号默认为wire类型,除非指定为reg类型

wire可以用作任何输入输出端口

wire包括inputoutputinout

wire不带寄存功能

assign赋值语句中,被赋值的信号都是wire类型

assign之所以称为连续赋值,是因为不断检测表达式的变化

reg类型可以被赋值后再使用,而不是向wire一样只能输出,类似VHDL中的buffer端口

reg类型变量初始值为x(VHDL中初始值为本类型最小值,通常是0)

always模块里被赋值的信号都必须定义为reg类型,因为always可以反复执行,而reg表示信号的寄存,可以保留上次执行的值

reg类型变量与integer变量不同,即使赋负值,实质上也是按二进制无符号数存储的,integer是有符号数

verilog中所有内部信号都是静态变量,因为它们的值都在reg中存储起来了

memory型只有一维数组,由reg型变量组成

memory初始化只能按地址赋值,不能一次性赋值

1*256的memory写法:

regmema[255:

0]mema[3]=0;

不同位宽的变量之间赋值,处理之前都以被赋值的变量位宽为准扩展或截取

A[a:

b]无论ab谁大,a总是实际电路的信号高位,b总是实际电路的信号低位

算术运算中如果有X值则结果为X

for循环中的变量另外定义成integer,因为它不是实际信号,有正负;reg则以无符号数存在

==和!

=只比较0、1,遇到z或x时结果都为x(x在if中算做假条件),结果可能是1、0、x

===和!

==比较更加苛刻,包括x和z的精确比较,结果可能是0、1

&&的结果只有1'b1或1'b0两种,A&A的结果位宽则是与A相同的

{1,0}为64'h100000000,所以拼接运算中各信号一定要指定位宽

移位运算左移将保留4'b1000<<1等于5'b10000,右移则舍弃4'b0011等于4'b0001

数字电路里位运算应用普遍,包括按位逻辑运算、移位运算、拼接运算、缩减运算

非阻塞式赋值<=与阻塞式赋值=

阻塞:

在同一个always过程中,后面的赋值语句要等待前一个赋值语句执行完,后面的语句被该赋值语句阻塞

非阻塞:

在同一个always过程中,非阻塞赋值语句是同时进行的,排在后面的语句不会被该赋值语句阻塞

<=:

块结束后才能完成赋值

块内所有<=语句在always块结束时刻同时赋值

<=右边各变量的值是上一次时钟边沿时,这些变量当时的值

用于描述可综合的时序电路

=:

=语句结束之后过程always才可能结束

在always过程中,beginend块内按先后顺序立即赋值,在forkjoin内同时赋值(可能造成冲突)

与assign连用描述组合电路

beginend中阻塞的含义:

begin...@(A)B=C...;end如果A事件不发生则永远不能执行下去,被阻塞了

由于时钟的延时(往往在ps级),多个always(posedge)之间究竟谁先执行是个未知数

使用原则:

同一个always过程块内建立时序电路用<=

纯组合逻辑电路用=,生成的电路结构最简单,执行速度最快

同一个always块内不要混用<=和=

不要在多个always块内对同一个变量赋值(多源驱动)

ifelse的三种形式,第三种形式适合描述优先编码器

if条件中0/x/z当成假,1当成真,非0的数值也当成真

case语句的三种:

case(四种状态的比较)casez(忽略z)casex(忽略x和z,只看哪些位的信号有用)

case语句中所有表达式值的位宽必须相等,default中不能将n'bx用'bx代替

避免生成锁存器的方法:

电平触发时if后加elsecase中加default?

使用casex会将不必要的状态视为无关项,使得综合出来的电路最简单

两种特殊的括号:

begin顺序语句...endfork并行语句...join,其差别在于块内语句的起止时间、执行顺序、相对延时

块被命名后,其内部变量可以被调用,因为变量都是静态的(调用信号:

对应电路中的一个信号线被引到另一处)

initial块只无条件执行一次always块在满足条件时不断执行

initial常用来写测试文件,always块常用来写电路描述

always既可以描述组合逻辑电路又可以描述时序逻辑电路

always如果后面有敏感信号列表则不能用wait语句

always既可以描述电平触发又可以描述边沿触发,wait只能描述电平触发

assign常用于描述组合逻辑电路

测试文件中一般都是现initial后always

生成语句:

生成快的本质是使用循环内的一条语句代替多条重复的verilog语句,简化了用户的编程

genvar用于声明生成变量,生成变量只能用在生成快之间

仿真时,仿真器会将生成块中的代码展平,在确立后的方针代码中,生成变量是不存在的

最好是先想象出来循环生成语句被展平后的电路样子,再写相关的描述语句

task和function的区别:

task可以定义自己的仿真时间单位,function与主模块共用同一个仿真时间单位

函数不能启动任务,任务能够启动函数

函数至少要有一个输入变量,任务没有输入变量

函数返回一个值,任务不返回值

一个模块的设计包括3个部分:

电路模块的设计测试模块的设计设计文档的编写

设计者通过布局布线工具生成具有布线延迟的电路,再进行后仿真,得到时序分析报告

从时序分析报告中可以知道电路的实际延迟t,同步电路内每个时钟周期要大于t,从而可确定该运算逻辑的最高频率

综合器之所以能够实现加法器、乘法器是因为库中已经存在可配置的参数化器件模型

FPGA内总线宽度容易自定义,以便实现高速数据流,三态数据总线相当于数据流的控制阀门

数字系统内数据流的控制:

开关(或三态数据总线)、数据暂存部件(寄存器)、同步状态机控制(整个系统在一个时钟域内)

流水线操作pipeline:

K级流水线就是从组合逻辑的输入到输出恰好有K个寄存器组,上一级的输出是下一级的输入

流水线操作获得第一个结果的时间要比不用流水线操作的时间长,但以后结果获得时间都只需要一个时钟周期,提高了数据吞吐量

流水线操作的保证:

Tclk>K*(组合逻辑延迟+触发器的建立保持时间/触发时间),即时间片段要长于最大路径延迟

体现了面积换速度的思想,在综合时考虑的是以面积小为主还是以速度为主

本质上是一种同步逻辑

同步时序逻辑和异步时序逻辑:

同步时序逻辑指所有寄存器组由唯一时钟触发always@(posedgeclk)或always@(negedageclk)

异步时序逻辑指触发条件不唯一,任意一个条件都会引起触发always@(posedgeclkorposedagereset)

目前的综合器是以同步时序逻辑综合的,因为同步时序逻辑较异步时序逻辑可靠

严格的同步要求时钟信号传递速度远远大于各部分的延迟,实际中clk要单独用线,而不要经过反相器等部件

always@(posedge..)begin...<=...end表示同步时序逻辑(同时刻赋值)

不同速率数据接口的处理方法(异步数据的处理方法):

帧同步FIFO双端口RAM

同步状态机:

包括moore和mealy型两种,及其反馈模型(是一种反馈控制系统,当前状态就是其内部状态变量)

状态机的开发步骤:

根据实际问题列出输入输出变量和状态数

画出状态图并化简

写出状态转移真值表得到逻辑表达式

用D触发器或JK触发器构建电路(目前用D触发器多)

verilog描述时只需要得到简化的状态图就可以描述

状态编码方式:

独热码格雷码

状态机主体程序有单always描述方式和多always描述方式

采用case/casez/casex建立模型最好,因为x是无关态,生成的电路最简单

default:

state='bx与实际情况更一致,效果等同于default:

state<=idle

只有同步状态机才能被目前的综合

for语句会将所有变量的情况展开,占用巨量逻辑资源,替代办法是用计数器和case语句说明所有情况

有优先级的ifelse结构会消耗更多资源,建议用无优先级的case替代

模块的复用往往比代码上修改节省的资源多

PLL的分频、倍频、移相操作会增加设计精度

同步时序电路的延时:

#x通常用于仿真测试,实际硬件延时是:

长延迟用计数器,小延迟用D触发器,此方法用来取代延迟链

同步电路中,稳定的数据采用必须满足采样寄存器的建立和保持时间

reg类型在always中不一定综合成时序电路,也可能是组合逻辑电路

乒乓操作与作用异步时钟域同步问题

延迟包括门延迟和线延迟

组合逻辑产生的时钟仅能应用在时钟频率较低、精度要求不高的情况下

增减敏感信号得到的结果一样

补充部分:

verilogHDL起初是作为写testbench而产生的

verilog有1995进入IEEE标准,为IEEE-1364,于2001年进行了扩展,为IEEE1364-2001;

verilogAMS可用于模拟电路和数字电路的综合,目前正在不断发展和完善中;

verilog的标识符区分大小写,关键字使用小写;

用\\来进行单行注释,用\**\来进行跨行注释;

标识符由字母、数字、下划线构成,并以字母开头;

关键字又叫保留字,只有小写的关键字才是保留字;

信号的状态有4种:

01xz

x和z在描述电路时不区分大小写,在仿真时大小写有不同意义;

常量表达式中:

xz不区分大小写;

进制符号hodb与HODB不区分大小写;

十六进制中a~f不区分大小写;

下划线_用于提高可读性;

在数中可以代替z;

x和z的左端补位;

字符和字符串都以ASICII码形式存在,也可以当成电路内的信号;

字符串必须包含在同一行,不能分成多行书写;

如果表达式或者赋值语句中将字符串当成操作数,则字符串中的每个字符都被看成8位的ASCII值序列;

可综合的信号类型:

wireregmemory它们用来描述数字电路

不可综合的数据类型:

integerreal它们只用仿真,位于testbench中

wire是连线的抽象模型,不能保存数据,其值由驱动元的值决定;

wire不能用在always或initial块中;

wire的默认值为高阻z;

wire的使用情形:

1.作为模块的输出端口2.用连续赋值语句assign赋值;

reg是1位寄存器(触发器)的抽象模型,可以保存数据;

reg必须用在always或initial块中;

reg的默认值为x;

reg的使用情形:

1.阻塞赋值<=2.非阻塞赋值=

memory只能是一维的;

memory只能对每个单元分别初始化,方法:

1.一个一个赋值2.通过系统任务$readmem赋值

reg[3:

0]fc;//一个4位寄存器regfc[3:

0]//4个一位寄存器

parameter的作用:

仿真开始以前对其进行赋值,整个仿真过程中保持其值不变;

关系运算符将以逻辑1或逻辑0返回比较的结果;

==!

=的返回值有01x三种情况,===!

==的返回值只有01两种情况;

verilog由于是描述电路的,用于位的操作较多,有:

位逻辑操作,移位操作,并置操作,归约操作;

位逻辑运算的结果中,位数与原操作数一样多;

归约符是在原操作数的所有位上进行操作,并产生1位结果;

并置运算可以发生在bit与bit之间bit与矢量之间矢量与矢量之间

用于仿真的系统任务:

所有系统任务都必须在initial或always内;

所有系统任务都必须以$开头;

常见系统任务:

显示任务($diplay系列和$write系列)

监控任务($monitor系列)

探测任务($strobe系列)

文件打开、输入、关闭任务(&fopen&fclose&fdisplay...)

读取文件任务($readmemb$readmemh)

仿真结束控制任务($finish$stop)

随即信号任务($random)

过程块:

initial块和always块

一个module内可以包含多个initial或always模块;

所有initial或always块在0时刻开始并行执行,各initial或always块内部顺序执行;

initial过程块主要是面向testbench的,通常不具有可综合性;

always过程块在描述电路时既可以描述组合逻辑电路(电平敏感)又可以描述时序逻辑电路(边沿敏感);

写testbench时initial通常用于初始化以及顺序波形的描述,always通常用于重复波形的描述;

任务task与函数function:

为了描述模块中被多次执行的部分以及为了增强代码的易读性

verilog中的高级程序语句如for循环语句只用在写testbench中;

beginend和forkjoin是两种特殊的括号

if语句的第三种形式适合描述优先编码器,case语句适合描述数据选择器和状态机;

case的条件表达式如果与分支项表达式长度不同,则在比较前将所有表达式都统一为这些表达式的最长长度;

casez忽略z,casex忽略z和x;

assign语句只在右端表达式发生变化时才重新计算并重新赋值,其余时间都是连续赋值;

assign语句可以指定bit、vector或是任意拼接操作的结果;

assign语句是连续赋值的,用于驱动网线wire,reg类型不需要连续赋值,reg类型一旦被赋值就会一直保存;

过程赋值语句有两种:

阻塞式=和非阻塞式<=,只能在过程块initial和always中使用;

@对事件触发的控制与wait语句不能同时使用;

FPGA学习心得

(二)

Verilog的两个误区:

使用Reg类型还是Net类型:

  Reg类型只在过程块中被赋值;而Net类型则在过程块外面被赋值或者驱动.

阻塞赋值和非阻塞赋值:

  Verilog中竞争发生的条件:

两个或多个语句在执行顺序不同时导致不同的结果,则存在竞争.

  Nonblocking不是一个类型;

  Blocking赋值是一个单步过程,计算RHS,并更形LHS是不可中断的.

  七条准则:

   1.时序逻辑和锁存器,使用非阻塞赋值

   2.always块中的组合逻辑,使用阻塞赋值

   3.同一always块,时序组合混合逻辑使用非阻塞赋值

   4.通常情况下,在同一always块中不要混合使用阻塞与非阻塞赋值

   5.不要在多个always块中对同一变量进行赋值

   6.使用$strobe显示非阻塞赋值得信号

   7.不要用#0的过程赋值

Verilog中的分层事件队列:

  活动事件:

阻塞赋值;计算非阻塞赋值的RHS;连续赋值;$display命令;计算输入并改变原语的输出.这些事件可能按照任意次序调度.

  非活动事件:

#0的阻塞赋值

  非阻塞事件:

更新非阻塞赋值的LHS

  监视事件:

$monitor命令;$strobe命令

经验:

  在always块中使用非阻塞赋值来产生时序逻辑和锁存器

  在always块中使用阻塞赋值来产生组合逻辑

  在always块中使用非阻塞赋值来产生同一块中的时序和组合逻辑

  在纯组合逻辑中使用非阻塞赋值可能会导致功能错误

阻塞赋值和非阻塞赋值混合使用的方式:

  将组合逻辑赋值通过时序表达式表示

  或者将组合逻辑赋值与时序逻辑分开,在独立的语句块中描述

  不推荐在同一always块中混合使用阻塞和非阻塞赋值

几个关于非阻塞赋值的错误理解:

  错误1:

无法使用$display命令显示非阻塞赋值变量

  正解:

非阻塞赋值变量的更新在所有$display命令之后

  错误2:

#0让一个赋值在每个时间步的最后执行

  正解:

#0只会让赋值语句进入非活动事件队列

  错误3:

在同一always块中对同一变量进行多次非阻塞赋值是不允许的

  正解:

在IEEE1364verilog标准中定义了上述赋值,最后一个非阻塞赋值起作用

模拟开始时候的困难:

  不同的模拟器,不同的模拟选项导致开始模拟时现象不同

  建议:

在0时刻通过非阻塞赋值设置reset信号;

   第一个半周期设置clock为0

编写Verilog代码的一些经验:

  Verilog文件名和模块名相同

  不要在可综合代码中使用casex语句

  当在可综合代码中使用casez语句时要小心

  当写case语句时,对存在不关心的cases时使用casez,使用?

代替Z来表示不关心的cases

Verilog编写状态机相关:

  状态机分类:

Moore(输出只与当前状态相关)和Mealy(输出与当前状态和输入相关)

  二进制编码和One-Hot编码

  状态机的基本块:

下一状态度组合逻辑;时钟同步的当前状态逻辑;输出组合逻辑

  两个always块写状态机,使用三个always块,如果输出需要寄存

  使用高效的One-Hot状态编码,组合输出

  经验:

   每个状态机作为一个独立的Verilog模块

   对状态进行预定义,状态赋值使用状态名作参数,不要使用`define,多使用parameter

  两个always语句块的状态机,一个always用来描述状态向量寄存器的时序逻辑.一个用来描述下一状态度组合逻辑.组合输出可以通过连续赋值语句或者在下一状态度组合always块中描述.

verilog语法规则

1.Verilog分以下四个层次:

 

l低阶交换模型:

电路由开关与储存点所组成

l逻辑间层次描述:

用and,or,buf,not等

l资料处理模型或暂存器转移层次:

用于说明资料如何在暂存器中储存与传送。

使用assign(电路所需功能的指定描述)来描述。

l行为模型:

只需要考虑模组的功能,使用always,for,while,case等

2.关键字keywords必须使用小写来表示。

3.不能用于电路合成的verilog语法:

叙述:

Delay,Initial,Repeat,Forever,Wait,Fork,Join,Event,time,Deassign,Force,Release,Primitive,Ceseindentity,notidentityoperations,Rtuan,tranif0,tranif1,rtranif0,rtranif1

运算子:

===,!

==,/,%

逻辑间型态:

tranif1,tranif0,rtran,trtanif1,rtranif0等逻辑间型态

Triand,trior,tri0,tri1,tritrg等接线型

Nmos,pmos,coms,rnmos,rpmos,rcmos等元件

Pullup,pulldown等讯号改变元件

其他不能用于电路合成的构建方式

1)不能在模组内有另一个阶层式的名称:

module

2)ifdef,endif,else等条件编译命令

verilog的时间控制:

主要用途是设定某一个程序在特定的时间被执行。

事件:

当一条接线wire,wor,wand或暂存器register的值被改变时就是一个事件

当模组的输入埠介绍到新的值时也是一个事件

可用于合成的verilog电路描述的事件基础时间控制,有两种:

1)正规事件控制@当信号产生正缘posedge,负negedge,转换或者值被改变时,叙述才会被执行。

Always@(posedgeclock)

2)当有多个讯号或者事件触发一个叙述或一个内含多个叙述的区块

Always@(resetorgateord)

Verilog的资料型态:

wire,wand,wor,reg

Wire的特性:

1)接线时连接硬体元件之连接线

2)接线必须要被驱动才能改变它的内涵值

3)接线描述的关键字为wire

4)除非有被宣告成一个向量,否则接线是内定为一个位元的值,而且内定值是Z

Wand的特性:

1)我们不能将多条讯号输出线同样连接到使用wire的某一条接线

2)可以将多条讯号输出线同样连接到某一条wand,wor

Reg的特性:

1)可以直接给定一个数值,主要功能在于保持住电路中的某个值,不必像wire才能改变它的内涵值

2)除非有被宣告成一个向量,否则接线是内定为一个位元的值,而且内定值是X

选用wire或reg的时机

1)wire必须配合assign来使用,且不能出现在always里

2)reg的使用方法为a=b格式,也就是必须放在always的区块描述里

3)wire,reg皆可定义为向量

4)在verilog中内定的为WIRE,因此若在端与端的宣告中只有告input,output,inout,则为wire,如果需要将讯号的值储存起来就要宣告为reg

5)在verilog中端的内部与外部的连接必须遵守下列规定:

Input能被net,或register推动,而一个输入端能够推动net型态的接线

output能被net,或register推动,而一个输入端能够推动net型态的接线

双向端能被net推动,而一个输入端能够推动net型态的接线

可用于电路合成的net,包括三种:

wire,wor,wand

Verilog常用的叙述:

1.parameter,用于定义

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

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2