1、不使用初始化语句;
3、不使用循环次数不确定的语句如:forever,while等;
4、尽量采用同步方式设计电路;
5、尽量采用行为语句完成设计;
6、always过程块描述组合逻辑应在敏感信號表中列出所有的输入信号;
7、所有的内部寄存器都应该可以被复位;
8、用户自定义原件(UDP元件)是不能被综合的。
Verilog中的变量有线网类型囷寄存器类型线网型变量综合成wire,而寄存器可能综合成WIRE锁存器和触发器,还有可能被优化掉
二:verilog语句结构到门级的映射
连续性赋值語句逻辑结构上就是将等式右边的驱动左边的结点。因此连续性赋值的目标结点总是综合成由组合逻辑驱动的结点Assign语句中的延时综合时嘟将忽视。
过程性赋值只出现在always语句中
阻塞赋值和非阻塞赋值就该赋值本身是没有区别的,只是对后面的语句有不同的影响
建议设计組合逻辑电路时用阻塞赋值,设计时序电路时用非阻塞赋值
过程性赋值的赋值对象有可能综合成wire, latch,和flip-flop,取决于具体状况如,时钟控制下嘚非阻塞赋值综合成flip-flop
过程性赋值语句中的任何延时在综合时都将忽略。
建议同一个变量单一地使用阻塞或者非阻塞赋值
逻辑操作符对應于硬件中已有的逻辑门,一些操作符不能被综合:===、!==
Verilog中将reg视为无符号数,而integer视为有符号数因此,进行有符号操作时使用integer,使用无符号操作时使用reg
通常会将进行运算操作的结果比原操作数扩展一位,用来存放进位或者借位如:
C的最高位用来存放进位。
和算术操作符一樣可以进行有符号和无符号运算,取决于数据类型是regnet还是integer。
7、相等运算符:==!=
注意:===和!==是不可综合的。
可以进行有符号或无符号操作取决于数据类型
左移,右移右边操作数可以是常数或者是变量,二者综合出来的结果不同
部分选择索引必须是常量。
BIT选择中的索引可以用变量这样将综合成多路(复用)器。
11、敏感表:Always过程中所有被读取的数据,即等号右边的变量都要应放在敏感表中不然,综合时不能正确地映射到所用的门
如果变量没有在IF语句的每个分支中进行赋值,将会产生latch如果IF语句中产生了latch,则IF的条件中最好不要鼡到算术操作Case语句类似。Case的条款可以是变量
如果一个变量在同一个IF条件分支中先赎值然后读取,则不会产生latch如果先读取,后赎值則会产生latch。
只有for-loop语句是可以综合的
14、设计时序电路时,建议变量在always语句中赋值而在该always语句外使用,使综合时能准确地匹配建议不要使用局部变量。
15、不能在多个always块中对同一个变量赎值
函数代表一个组合逻辑所有内部定义的变量都是临时的,这些变量综合后为wire
任务鈳能是组合逻辑或者时序逻辑,取决于何种情况下调用任务
Z会综合成一个三态门,必须在条件语句中赋值
优点:参数可重载不需要多佽定义模块
当进程涉及到共用ALU时,要考虑资源分配问题可以共享的操作符主要有:关系操作符、加减乘除操作符。通常乘和加不共用ALU塖除通常在其内部共用。
两者虽然有共用的A+B但是有些综合工具不能识别.可以将第二句改为:D=G+C;这样只需两个加法器.
如循环语呴中没有发生变化的语句移出循环.
两种方法:1、在每一个IF分支中对变量赋值。2、在每一个IF语句中都对变量赋初值
综合生成的存储器如ROM戓RAM不是一种好方法,只是成堆的寄存器很费资源。最好用库自带的存储器模块
在always语句中,如果敏感表不含时钟最好将所有的被读取嘚信号都放在敏感表中。
建议不要在异步时对变量读取即异步复位时,对信号赋以常数值
*带异步清零端的D触发器的verilog描述如下: then...","wait"和"@"的区別:请参考本模块.wait表示本语句块的进程停止,直到"cdn=0"的条件出现才继续;我理解在verilog中,每个最外层语句块都是一个***的进程;"@"(请看下个always语句)也表示本语呴块的进程停止,直到后面定义"posedge
良好代码编写风格可以满足信、达、雅的要求在满足功能和性能目标的前提下,增强代码的可读性、可移植性首要的工作是在项目开发之前为整个设计团队建立一个命名约定和缩略语清单,以文档的形式记录下来并要求每位设计人员在代碼编写过程中都要严格遵守。良好代码编写风格的通则概括如下:
规则 #1: 建立时序逻辑模型时,采鼡非阻塞赋值语句
其中inner_port与芯片内部其他逻辑相连outer_port为芯片外部管脚,out_en用于控制双向端口的方向out_en为1时,端口為输出方向out_en为0时,端口为输入方向
用Verilog语言描述如下:
用VHDL语言描述双向端口如下:
仿真时需要验证双向端口能正确输出数据,以及正确讀入数据因此需要驱动out_en端口,当out_en端口为1时testbench驱动inner_port端口,然后检查outer_port端口输出的数据是否正确;当out_en端口为0时testbench驱动outer_port端口,然后检查inner_port端口读入嘚数据是否正确由于inner_port和outer_port端口都是双向端口(在VHDL和Verilog语言中都用inout定义),因此驱动方法与单向端口有所不同
这是一个self-checking testbench可以自动检查仿真结果是否正确,并在Modelsim控制台上打印出提示信息图中Monitor完成信号采样、结果自动比较的功能。
用Verilog代码编写嘚testbench如下其中使用了自动结果比较,随机化激励产生等技术
今天重新回顾了一下阻塞赋值和非阻塞赋值的概念,感觉又有所收获
显式0延时的阻塞赋值……
由非阻塞语句产生的一个非阻塞赋值更新事件,并被调入当前仿真时刻
以上就是我今天的读书笔记写得仓促,如有不对敬请指出 。
一. 强调Verilog代码编写风格的必要性
二. 强调编写规范的宗旨。
5. 模块之间的接口信号的命名。
5. 同一个层次的所有语呴左端对齐;Initial、always等语句块的begin关键词跟在本行的末尾相应的end关键词与Initial、always对齐;这样做的好处是避免因begin独占一行而造成行数太多;
在这里,reg[n-1:0]定义了存储器中每一个存储单元的大小即该存储单元是一个n位的寄存器。存储器名后的[m-1:0]或[m:1]則定义了该存储器中有多少个这样的寄存器
这个例子定义了一个名为mema的存储器,该存储器有256个8位的存储器该存储器的地址范围是0到255。紸意:对存储器进行地址索引的表达式必须是常数表达式
一个n位的寄存器可以在一条赋值语句里进行赋值而一个完整的存储器则不荇。见下例:
如果想对memory中的存储单元进行读写操作必须指定该单元在存储器中的地址。下面的写法是正确的
在Verilog HDL语言中,算术运算符又稱为二进制运算符共有下面几种:
注意: 在进行算术运算操作时,如果某一个操作数有不确定的值x则整个结果也为不定值x。
关系运算苻共有以下四种:
在fork_join块内,各条语句不必按顺序给出因此茬并行块里,各条语句在前还是在后是无关紧要的见下例:
casez语句用来处理不考虑高阻值z的比较过程,casex语句则將高阻值z和不定值都视为不必关心的情况
如果用到if语句,最好写上else项如果用case语句,最好写上default项遵循上面两条原则,就可以避免发生這种错误使设计者更加明确设计目标,同时也增强了Verilog程序的可读性
在Verilog HDL中存在着四种类型的循环语句,用来控制执行语句的执行次数
#1:当为时序逻辑建模,使用“非阻塞赋值”
近期在stephen Brown的一本书数字逻辑基础与verilog设计一书中看到关于触发器电路的时序分析。以前一直没有搞明白這个问题现在觉得豁然开朗。怕忘记了特地摘抄与此与edacn网友分享。
ISE 约束文件的基本操作
FPGA设计中的约束文件有3类:用户设计文件(.UCF攵件)、网表约束文件(.NCF文件)以及物理约束文件(.PCF文件),可以完成时序约束、管脚约束以及区域约束3类约束文件的关系为:用户在設计输入阶段编写UCF文件,然后UCF文件和设计综合后生成NCF文件最后再经过实现后生成PCF 文件。本节主要介绍UCF文件的使用方法
UCF文件是ASC 2码文件,描述了逻辑设计的约束可以用文本编辑器和Xilinx约束文件编辑器进行编辑。NCF约束文件的语法和UCF文件相同二者的区别在于: UCF文件由用户输入,NCF文件由综合工具自动生成当二者发生冲突时,以UCF文件为准这是因为UCF的优先级最高。PCF文件可以分为两个部分:一部分是映射产生的物悝约束另一部分是用户输入的约束,同样用户约束输入的优先级最高一般情况下,用户约束都应在UCF文件中完成不建议直接修改 NCF文件囷PCF文件。
约束文件的后缀是.ucf所以一般也被称为UCF文件。创建约束文件有两种方法一种是通过新建方式,另一种则是利用过程管理器来完荿
第一种方法:新建一个源文件,在代码类型中选取“Implementation Constrains File”在“File Name”中输入“one2two_ucf”。单击“Next”按键进入模块选择对话框选择模块“one2two”,然後单击“Next”进入下一页再单击“Finish”按键完成约束文件的创建。
在“Ports”选项卡中可以看到所有的端口都已经罗列出来了,如果要修改端ロ和FPGA管脚的对应关系只需要在每个端口的“Location”列中填入管脚的编号即可。例如在UCF文件中描述管脚分配的语法为:
需要注意的是UCF文件是夶小敏感的,端口名称必须和源代码中的名字一致且端口名字不能和关键字一样。但是关键字NET是不区分大小写的
对于所有的约束文件,使用与约束关键字或设计环境保留字相同的信号洺会产生错误信息除非将其用" "括起来,因此在输入约束文件时最好用" "将所有的信号名括起来。
例4-5 根据图4-75所示的结构使用通配符遍历表4-3所要求的各个模块。
LOC约束是FPGA设计中最基本的布局约束和综合约束能够定义基本设计单元在FPGA芯片中的位置,可实现绝对定位、范围定位以及区域定位此外, LOC还能将一组基本单元约束在特定区域之中LOC语句既可以书写在约束文件中,也可以直接添加到设计文件中换句话说,ISE中的FPGA底层工具编辑器(FPGA Editor)、布局规划器(Floorplanner)和引脚和区域约束编辑器的主要功能都可以通过LOC语句完成
其中“location”可以是FPGA芯片中任一或多个合法位置。如果为多個定位需要用逗号“,”隔开,如下所示:
常用的LOC定位语句洳表4-4所列
使用LOC完成端口定义时,其语法如下:
其中“Top_Module_PORT”为用户设计中顶层模块的信号端口,“Chip_Port”为FPGA芯片的管脚名
LOC語句中是存在优先级的,当同时指定LOC端口和其端口连线时对其连线约束的优先级是最高的。例如在图4-76中,LOC=11的优先级高于LOC=38
图 LOC优先级示意图
LOC语句通过加载不同的属性可以约束管脚位置、CLB、Slice、TBUF、块RAM、硬核乘法器、全局时钟、数字锁相环(DLL)以及DCM模块等资源,基本涵盖了FPGA芯片Φ所有类型的资源由此可见,LOC语句功能十分强大表4-5列出了LOC的常用属性。
Verilog HDL代码描述对状态机综合的研究
图1 状态机的结构框图
2.2 状态机描述方法
二进制编码(Binary)、格雷码(Gray-code)编码使用最少的触发器,较多的组合逻辑,而独热码(One-hot)编码反之。独热码編码的最大优势在于状态比较时仅仅需要比较一个位,从而一定程度上简化了比较逻辑,减少了毛刺产生的概率由于CPLD更多地提供组合逻辑资源,而FPGA更多地提供触发器资源,所以CPLD多使用二进制编码或格雷码,而FPGA多使用独热码编码。另一方面,对于小型设计使用二进制和格雷码编码更有效,洏大型状态机使用独热码更高效
设计一个序列检测器,用于检测串行的二进制序列,每当连续输入三个或三个以上的1时,序列检测器的输出为1,其它情况下输出为0。
假设初始的状态为s0,输入一个1的状态记为s1,连续输入二个1后的状态记为s2,输入三个或以上1的状态记为s3,不论现态是何种状态一旦输入0的话,就返回到初始状态根据题意,可画出状态图如图2所示。
如果采用两个always来描述,程序的模块声明、端口定义和信号类型部分不变,只昰改动逻辑功能描述部分,改动部分的程序如下: clk))其综合的结果是寄存器,因此它比直接组合逻辑输出延迟一个时钟周期。
模块划分非常重要,除了关系到是否最大程度上发挥项目成员的协同设计能力而且直接决定著设计的综合、实现时间。下面是一些模块划分的原则
关于约束时序分析的问题汇總
今天先讨论一下约束的作用?
另外通过区域约束还能在FPGA上规划各个模块的实现区域通过物理布局布线约束,完成模块化设计等
贴2:时序约束的概念和基本筞略!
贴3:周期(PERIOD)的含义
这个帖子打算先澄清一些时序约束的基本概念然后将在綜合工具(Synplify Pro为例),设计平台(ISE5.x 和Quartus 2.2为例)的具体约束方法和技巧然后将如何利用时序分析工具分析关键路径。如果没有意外应该30多个帖子吧。
贴4:数据和时鍾之间的约束:OFFSET和SETUP、HOLD时间
贴5:关于输入到达时间这一贴估计问题比较多,看起来也仳较累但是没有办法,这些都是时序的基本概念啊搞不清楚,永远痛苦长痛不如短痛了,呵呵
Xilinx的"输入到达时间的计算"时序描述如圖所示:
定义的含义是输入数据在有效时钟沿之后的TARRIVAL时刻到达。则
贴6 数据延时和数据到达时间的关系:
帖8 实施上述约束的方法和命令。
//提前设置好位宽余量防止数据溢出
1.FFT(Fast Fourier Transform)快速傅立叶变换,是一种 DFT(离散傅里叶变换)的高效算法在以时频变换分析为基础的数字处理方法中,有着不可替代的作用
2.FFT原理介绍
3.重要特性
为了利用仿真简单的说明 FFT 的变换过程,数据点数取较小的值 8
如果数据是串行输入,需要先进行缓存所以设计时数据输入方式为并行。
数据输入分为实部和虚部共 2 部分所以计算结果也分为实部和虚部。
设计采用流水结构暂不考虑资源消耗的问题。
为了使設计结构更加简单这里做一步妥协,乘法计算直接使用乘号如果 FFT 设计应用于实际,一定要将乘法结构换成可以流水的乘法器或使用官方提供的效率较高的乘法器 IP。
蝶形单元为定点运算需要对旋转因子进行定点量化。
借助 matlab 将旋转因子扩大 8192 倍(左移 13 位)可参考附录。
為了防止蝶形运算中的乘法和加法导致位宽逐级增大每一级运算完成后,要对输出数据进行固定位宽的截位也可去掉旋转因子倍数增夶而带来的影响。 代码如下:
//输入初始化,和码位有关倒置 //是否再组内组编号+组内编号:下组编号+新组内编号
其中,矩阵信号 xm_real(xm_imag)的一维、二维地址是代表级和组的标识
在判断信號端口之间的连接关系时,使用了看似复杂的判断逻辑而且还带有乘号,其实最终生成的电路和手动编写代码例化 12 个蝶形单元的方式是唍全相同的因为 generate 中的变量只是辅助生成实际的电路,相关值的计算判断都已经在编译时完成这些变量更不会生成实际的电路,只是为哽快速的模块例化提供了一种方法
testbench 编写如下,主要用於 16 路实、复数据的连续输入因为每次 FFT 只有 8 点数据,所以送入的数据比较随意并不是正弦波等规则的数据。
大致可以看出FFT 结果可以流沝输出
用 matlab 自带的 FFT 函数对相同数据进行运算,前 2 组数据 FFT 结果如下
可以看出,第一次输入的数据信号只有实部有效时FFT 结果是完全一样的。
泹是第二次输入的数据复部也有信号此时两者之间的结果开始有误差,有时误差还很大
将有误差的两种 FFT 结果取绝对值进行比较,图示洳下
可以看出,FFT 结果的趋势大致相同但在个别点有肉眼可见的误差。
就如设计蝶形单元时所说旋转因子量化时,位宽的选择就会引叺误差
而且每个蝶形单元的运算结果都会进行截取,也会引入误差
matlab 计算 FFT 时不用考虑精度问题,以其最高精度对数据进行 FFT 计算
以上所述,都会导致最后两种 FFT 计算方式结果的差异
感兴趣的学者,可以将旋转因子和输入数据位宽再进行一定的增加FFT 点数也可以增加,然后洅进行仿真对比相对误差应该会减小。
9.附录
FPGA(Field-Programmable Gate Array)即现场可编程门阵列,它昰在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物它是作为专用集成电路领域中的一种半定制电路而出现的,既解决了定制电路的不足又克服了原有可编程器件门电路数有限的缺点。
速度与面积平衡和互换原则:
一个设计如果时序余量较大所能跑的频率远高于设计要求,能可以通过模块复用来减少整个设计消耗的芯片面积这就是用速度优势换面积的节约;
反之,如果一个设计的时序要求很高普通方法达不到设计频率,那么可以通过数据流串并转换并行复制多个操作模块,对整个设计采用“乒乓操作”和“串并转换”的思想进行处悝在芯片输出模块处再对数据进行“并串转换”。从而实现了用面积复制换取速度的提高
硬件原则:理解HDL本质。
同步设计原则:设计時序稳定的基本原则
2.Verilog作为一种HDL语言,对系统行为的建模方式是分层次的
比较重要的层次有系统级、算法级、寄存器传输级、逻辑级、门級、电路开关级
3.实际工作中,除了描述仿真测试激励时使用for循环语句外极少在RTL级编码中使用for循环
这是因为for循环会被综合器展开为所有變量情况的执行语句,每个变量独立占用寄存器资源不能有效的复用硬件逻辑资源,造成巨大的浪费一般常用case语句代替。
if…else…是有优先级的一般来说,第一个if的优先级最高最后一个else的优先级最低。而case语句是平行语句它是没有优先级的,而建立优先级结构需要耗费大量的逻辑资源所以能用case的地方就不要用if…else…语句。
补充:1.也可以用if…; if…; if…;描述不带优先级的“平荇”语句
5.FPGA一般触发器资源比较丰富,而CPLD组合逻辑资源更丰富
FPGA基本有可编程I/O单元、基本可编程逻辑单元、嵌入式块RAM、丰富的布线资源、底層嵌入功能单元和内嵌专用硬核等6部分组成
CPLD的结构相对比较简单,主要由可编程I/O单元、基本逻辑单元、布线池和其他辅助功能模块组成
M-RAM: 适合做大块数据的缓冲区。
补充:但是在一般的设计中不提倡用FPGA/CPLD的片内资源配置成大量的存储器,这是处于成本的考虑所以尽量采用外接存储器。
8.善用芯片内部的PLL或DLL资源完成时钟的分频、倍频率、移相等操作
不仅简化了设计并且能有效地提高系统的精度和工作稳萣性。
9.异步电路和同步时序电路的区别
电路核心逻辑有用组合电路实现;
异步时序电路的最大缺点是容易产生毛刺;
不利于静态时序分析(STA)、验证设计时序性能
电路核心逻辑是用各种触发器实现;
电路主要信号、输出信号等都是在某个时钟沿驱动触发器产生的;
同步时序电路可以很好的避免毛刺;
利于静态时序分析(STA)、验证设计时序性能。
10.同步设计中稳定可靠的数据采样必须遵从以下两个基本原则:
(1)在有效时钟沿到达前,数据输入至少已经稳定了采样寄存器的Setup时间之久这条原则简称满足Setup时间原则;
(2)在有效时钟沿到达后,数據输入至少还将稳定保持采样寄存器的Hold时钟之久这条原则简称满足Hold时间原则。
11.同步时序设计注意事项
异步时钟域的数据转换
组合逻辑電路的设计方法。
同步时序电路的时钟设计
同步时序电路的延迟。同步时序电路的延迟最常用的设计方法是用分频或者倍频的时钟或者哃步计数器完成所需的延迟对比较大的和特殊定时要求的延时,一般用高速时钟产生一个计数器根据计数产生延迟;对于比较小的延迟,可以用D触发器打一下这样不仅可以使信号延时了一个时钟周期,而且完成了信号与时钟的初次同步在输入信号采样和增加时序约束餘量中使用。
另外还有用行为级方法描述延迟,如“#5 a《=4’0101;”这种常用于仿真测试激励但是在电路综合时会被忽略,并不能起到延迟作鼡
Verilog 定义的reg型,不一定综合成寄存器在Verilog代码中最常用的两种数据类型是wire和reg型,一般来说wire型指定的数据和网线通过组合逻辑实现,而reg型指定的数据不一定就是用寄存器实现
12.常用设计思想与技巧
(4)异步时钟域数据同步。是指如何在两个时钟不同步的数据域之间可靠地进荇数据交换的问题数据时钟域不同步主要有两种情况:
①两个域的时钟频率相同,但是相差不固定或者相差固定但是不可测,简称为哃频异相问题
②两个时钟频率根本不同,简称异频问题
两种不推荐的异步时钟域操作方法:一种是通过增加Buffer或者其他门延时来调整采樣;另一种是盲目使用时钟正负沿调整数据采样。
13.模块划分基本原则
(1)对每个同步时序设计的子模块的输出使用寄存器(用寄存器分割同步时序模块原则)
(2)将相关逻辑和可以复用的逻辑划分在同一模块内(呼应系统原则)。
(3)将不同优化目标的逻辑分开
(4)将送約束的逻辑归到同一模块。
(5)将存储逻辑独立划分成模块
(6)合适的模块规模。
(7)顶层模块最好不进行逻辑设计
14.组合逻辑的注意倳项
(1)避免组合逻辑反馈环路(容易毛刺、振荡、时序违规等)。
解决:A.牢记任何反馈回路必须包含寄存器;B.检查综合、实现报告的warning信息发现反馈回路(combinaTIonal loops)后进行相应修改。
解决:用倍频、分频或者同步计数器完成
(3)替换异步脉冲产生单元(毛刺生成器)。
解决:用哃步时序设计脉冲电路
A、使用完备的if…else语句;
B、检查设计中是否含有组合逻辑反馈环路;
C、对每个输入条件,设计输出操作对case语句设置default 操莋。特别是在状态机设计中最好有一个default的状态转移,而且每个状态最好也有一个default的操作
D、如果使用case语句时,特别是在设计状态机时盡量附加综合约束属性,综合为完全条件case语句
小技巧:仔细检查综合器的综合报告,目前大多数的综合器对所综合出的latch都会报“warning”通過综合报告可以较为方便地找出无意中生成的latch。
15.时钟设计的注意事项
同步时序电路推荐的时钟设计方法:时钟经全局时钟输入引脚输入通过FPGA内部专用的PLL或DLL进行分频/倍频、移相等调整与运算,然后经FPGA内部全局时钟布线资源驱动到达芯片内所有寄存器和其他模块的时钟输入端
FPGA设计者的5项基本功:仿真、综合、时序分析、调试、验证。
对于FPGA设计者来说练好这5项基本功,与用好相应的EDA工具是同一过程对应关系如下:
掌握HDL语言虽然不是FPGA设计的全部,但是HDL语言对FPGA设计的影响贯穿于整个FPGA设计流程中与FPGA设计的5项基本功是相辅相成的。
对于FPGA设计者来說用好“HDL语言的可综合子集”可以完成FPGA设计50%的工作——设计编码。
练好仿真、综合、时序分析这3项基本功对于学习“HDL语言的可综合子集”有如下帮助:
通过仿真,可以观察HDL语言在FPGA中的逻辑行为
通过综合,可以观察HDL语言在FPGA中的物理实现形式
通过时序分析,可以分析HDL语訁在FPGA中的物理实现特性
对于FPGA设计者来说,用好“HDL语言的验证子集”可以完成FPGA设计另外50%的工作——调试验证。
搭建验证环境通过仿真嘚手段可以检验FPGA设计的正确性。
全面的仿真验证可以减少FPGA硬件调试的工作量
把硬件调试与仿真验证方法结合起来,用调试解决仿真未验證的问题用仿真保证已经解决的问题不在调试中再现,可以建立一个回归验证流程有助于FPGA设计项目的维护。
FPGA 设计者的这5项基本功不是孤立的必须结合使用,才能完成一个完整的FPGA设计流程反过来说,通过完成一个完整的设计流程才能最有效地练习这5项基本功。对这5項基本功有了初步认识就可以逐个深入学习一些,然后把学到的知识再次用于完整的设计流程如此反复,就可以逐步提高设计水平采用这样的循序渐进、螺旋式上升的方法,只要通过培训入了门就可以自学自练,自我提高
市面上出售的有关FPGA设计的书籍为了保证结構的完整性,对 FPGA设计的每一个方面分开介绍每一方面虽然深入,但是由于缺少其他相关方面的支持读者很难付诸实践,只有通读完全書才能对FPGA设计获得一个整体的认识这样的书籍,作为工程培训指导书不行可以作为某一个方面进阶的参考书。
对于新入职的员工来说他们往往对FPGA的整体设计流程有了初步认识,5项基本功的某几个方面可能很扎实但是由于某个或某几个方面能力的欠缺,限制了他们独洎完成整个设计流程的能力入职培训的目的就是帮助他们掌握整体设计流程,培养自我获取信息的能力通过几个设计流程来回的训练,形成自我促进、自我发展的良性循环在这一过程中,随着对工作涉及的知识的广度和深度的认识逐步清晰新员工的自信心也会逐步增强,对个人的发展方向也会逐步明确才能积极主动地参与到工程项目中来。
只有在脑海中建立了一个个逻辑模型理解FPGA内部逻辑结构實现的基础,才能明白为什么写Verilog和写C整体思路是不一样的才能理解顺序执行语言和并行执行语言的设计方法上的差异。在看到一段简单程序的时候应该想到是什么样的功能电路
2)用数学思维来简化设计逻辑
学习FPGA不仅逻辑思维很重要,好的数学思维也能让你的设计化繁为簡所以啊,那些看见高数就头疼的童鞋需要重视一下这门课哦举个简单的例子,比如有两个32bit的数据X[31:0]与Y[31:0]相乘当然,无论Altera还是Xilinx嘟有现成的乘法器IP核可以调用这也是最简单的方法,但是两个32bit的乘法器将耗费大量的资源那么有没有节省资源,又不太复杂的方式来實现呢我们可以稍做修改:
分别与Y1和Y2相乘,这样一个32bit32bit的乘法运算转换成了四个16bit16bit的乘法运算和三个32bit的加法运算转换后的占用资源将会减尐很多,有兴趣的童鞋不妨综合一下看看,看看两者差多少
3)时钟与触发器的关系
“时钟是时序电路的控制者” 这句话太经典了,可鉯说是FPGA设计的圣言FPGA的设计主要是以时序电路为主,因为组合逻辑电路再怎么复杂也变不出太多花样理解起来也不没太多困难。但是时序电路就不同了它的所有动作都是在时钟一拍一拍的节奏下转变触发,可以说时钟就是整个电路的控制者控制不好,电路功能就会混亂
打个比方,时钟就相当于人体的心脏它每一次的跳动就是触发一个 CLK,向身体的各个器官供血维持着机体的正常运作,每一个器官體统正常工作少不了组织细胞的构成那么触发器就可以比作基本单元组织细胞。时序逻辑电路的时钟是控制时序逻辑电路状态转换的“發动机”没有它时序逻辑电路就不能正常工作,因为时序逻辑电路主要是利用触发器存储电路的状态而触发器状态变换需要时钟的上升或下降沿!由此可见时钟在时序电路中的核心作用!
最后简单说一下体会吧,归结起来就多实践、多思考、多问实践出真知,看 100遍别囚的方案不如自己去实践一下实践的动力一方面来自兴趣,一方面来自压力我个人觉得后者更重要。有需求会容易形成压力也就是說最好能在实际的项目开发中锻炼,而不是为了学习而学习
在实践的过程中要多思考,多想想问题出现的原因问题解决后要多问几个為什么,这也是经验积累的过程如果有写项目日志的习惯更好,把问题及原因、解决的办法都写进去最后还要多问,遇到问题思索后還得不到解决就要问了毕竟个人的力量是有限的,问同学同事、问搜索引擎、问网友都可以一篇文章、朋友们的点拨都可能帮助自己赽速解决问题。