FPGA开发学习 Verilog基础语法整理

 

我主要做传统图像处理模块,再次总结自己研究生生涯所学的针对FPGA的系统知识。

预计时间:十天。

内容包括:

Verilog基础语法整理。主要针对经常遇到的问题以及一些优化技巧。

系统设计思路和方法。主要包括系统设计、系统瓶颈评估,怎么设计符合要求的时序。

图像算法实现。 主要包括基于FPGA的算法实现思路,以及优化。

图像系统调试。 主要包括各类接口问题及解决方式。

 

编者注:

所有工作都是为了解决需求问题,为了工作所学的一切东西都应该有针对性。所有经验都会随着时间过时,真正重要的是这个过程中,自己掌握了什么,能够解决什么问题,依靠什么解决思路。

目的:系统整理Verilog知识,深化自己的Verilog水平。可以根据文档设计,精准翻译Verilog代码,遇到相关问题都可以参考资料的方式查询。

在此,分享一个自己学习任何语言的方式。个人觉得,语言是为了描述功能,类似于英语描述一个事件需要主谓宾,编程语言如果想实现一个功能必须具备什么东西?回答这个问题的核心需要知道编程的核心目的——用数学计算的方式解决问题,其核心是计算。

  1. 结构:即该语言的特点,类似于Verolog的module,C的指针,C++的class等。
  2. 常量和变量:用来运算和判断的基础元素。
  3. 计算:对应的各种运算符。
  4. 判断:对应的条件和循环。
  5. 该语言的特点及系统函数。

所以整个流程可以理解成,用常量或者变量通过对比判断后的结果产生对应运算,然后用符合该平台的编程语言执行并生成结果。

毕竟不是写一本书,可能系统性较差,且需要读者自行判断正误

第一部分:Verilog基础语法整理

第一部分:结构

首先知道,为什么使用Verilog,才能更好的理解Verilog结构。 这个问题我不回答。需要理解Verilog解决了什么问题,Verilog有什么优势。

硬件描述语言其实描述的就是一个特定功能的芯片。其Module就是一个特定芯片,其内部就是一系列运算单元,则其与外界交互的方式就是IO;

硬件IO可以理解成一系列管教,则在模块内部就需要定义某些功能管教的个数{a{‘b0}},实现位宽自定义,a是个数,这个功能很重要。然后顺序或者逆序排列,其输入一般经过缓存处理后,直接进入到运算单元。如果不考虑底层门级电路,主要描述数据流 和行为及建模。其输出则有两种赋值方式,其always就是一个触发器,且顺序执行,其assign就是一个单路或者多路选择器。(再次强调,个人理解)。

附:为了美观,以及调用方便。缓存寄存器或者线网声明一般放到端口下方。 各个功能的always或者 assign语句放到一起。

第二部分:常量和变量

反正C语言的数据类型,动不动溢出这就很烦。

而Verilog也需要考虑数据的类型。常用的主要就是reg、wire、parameter和integer,针对数据的进制运算这里不做描述。

Parameter主要是状态机以及参数定义,这样在实例化Ip时,只需要更改参数即可。但这种设计一般在设计时也要考虑到数据的变化。

Integer是有符号类型,反正在图像处理领域,除了for循环作为参数,我是没咋用过,但是做加速的时候,这就用的多了。

这里强调一下reg和wire的区别。

Wire可以理解成导线,用来连接各个端口。Reg理解成触发器,主要是缓存延迟作用。一点区别就是,如果组合逻辑关键路径过长,可以用reg分割关键路径从而满足时序要求。其中reg可以是正值,也可以是负值,但在表达式中的操作数时,只能时无符号数。

另外,在写fifo时,也就是块区域数据缓存时,需要用到Memery类型。Reg [n:0] a[m:0];其中,n是存储器位宽,m是是存储器大小。一旦理解这个是存储器的时候就应该明白,对存储器赋值只能是对地址进行赋值,例如:a[1]={n+1{‘b0}};

第三部分:计算

算数运算符:+ 、-、*、/、%;

赋值运算符: =、<=。

关系运算符:>、<、>=、<= ;更多用在判断语句中。

。。。各类语句其实主要就是搞懂要干嘛,以及注意优先级即可。

这里说一下条件判断符  a=b?1:0;在组合逻辑的赋值语句中比较常用。

拼接运算符 {a,b}=2’b0;在打节拍,以及整合数据的时候比较常用。

接着就是我之前还犯错误的阻塞和非阻塞赋值。

阻塞赋值,是给左值执行完后的值,而非阻塞赋值是给左值当前值。  尤其是右值在此时刻(即使是不同的always块)发生变化也就是,always总是在下个时钟周期发生变化,在同一个always块,或者同一时刻的always语句中,非阻塞赋值总是把当前时刻的值同时赋值给左值,这就导致如果此时刻数据发生变化,也无法同时将数据赋值给右值。

 

第四部分 判断

    判断之前,首先要有条件,就两种,顺序判断或者并行判断。在资源使用上,并行判断case要更占面积,但是功耗会更低。

If else:先判断if,再执行else,一致到状态结束。

case endcase; 谁满足执行谁。该方式也会被用作状态机,通过条件跳转到该状态。

循环

    For、repeat、while、forever;

首先,for语句可以用在电路中,但是判断条件不能是变量,会根据for语句综合处对应的电路。

Forever:必须写在initial里面,常用来产生波形。

Repeat和while我几乎没用过。

For语句,经典格式for(;;)begin end;但是其变量增值可以是其他方式,比如左右移位,log等。

最牛逼的就是结合判断语句使用各类系统函数,比如disable等。

第五部分:功能函数

生成语句:生成语句可以理解成多个赋值,或者条件赋值。在循环生成语句中,genvar是一个虚拟变量,在综合时作为平铺条件,但不实际生成电路。类似于一个虚拟常量。

结构块:always、initial、task、function。其中initial 常被用在生成测试语句。

Always (*),是将该模块的所有输入信号作为敏感信号。

Task和Function

简单理解就是Funtion只能理解成该模块的操作符,操作符不能干的事他也不能干,而Task可以作为系统函数,甚至一个module。也就是在满足某个条件时可以选择执行某项任务,这个任务和当前工作甚至无关。而Function只能是满足条件,且只取得一个结果,这个结果在这个module中还有用。

Function<返回类型和位宽> 函数名;

输入;

执行语句;

Endfuntion

如果多次调用函数,必须声明成automatic;从而动态分配新的地址。

第六部分:仿真调试

说实话,写完这一章才更理解,开发人员是设计,语言只是一个描述工具。对FPGA而言,更重要就是要想清楚时序关系,然后用Verilog满足该时序要求。

而且最重要的是,任何语言最重要的是要了解他的特点。发现写完Verilog复习这一章后,似乎对电路设计没什么帮助,但其实也另一方面展示了电路对应关系等。当然,最重要的就是系统设计,该怎么设计出符合时序要求的电路设计,用什么设计更方便。

 

今天看到一句话:就是知道自己在学什么,各个技能都属于什么程度,结合目标要学到什么样子。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值