verilog大牛经验总结

合集下载

Verilog 的学习心得.

Verilog 的学习心得.

1.数字电路基础知识:布尔代数、门级电路的内部晶体管结构、组合逻辑电路分析与设计、触发器、时序逻辑电路分析与设计2.数字系统的构成:传感器AD 数字处理器DA 执行部件3.程序通在硬件上的执行过程:C语言(经过编译-->该处理器的机器语言(放入存储器-->按时钟的节拍,逐条取出指令、分析指令、执行指令4.DSP处理是个广泛概念,统指在数字系统中做的变换(DFT、滤波、编码解码、加密解密、压缩解压等处理5.数字处理器包括两部分:高速数据通道接口逻辑、高速算法电路逻辑6.当前,IC产业包括IC制造和IC设计两部分,IC设计技术发展速度高于IC 设计7.FPGA设计的前续课程:数值分析、DSP、C语言、算法与数据结构、数字电路、HDL语言计算机微体系结构8.数字处理器处理性能的提高:软件算法的优化、微体系结构的优化9.数字系统的实现方式:编写C程序,然后用编译工具得到通用微处理器的机器指令代码,在通用微处理器上运行(如8051/ARM/PENTUIM专用DSP硬件处理器用FPGA硬件逻辑实现算法,但性能不如ASIC用ASIC实现,经费充足、大批量的情况下使用,因为投片成本高、周期长10.FPGA设计方法:IP核重用、并行设计、层次化模块化设计、top-down 思想FPGA设计分工:前端逻辑设计、后端电路实现、仿真验证11.matlab的应用:matlab中有许多现成的数学函数可以利用,节省了复杂函数的编写时间matlab 可以与C程序接口做算法仿真和验证时能很快生成有用的数据文件和表格DSP builder可以直接将simulink模型转换成HDL代码,跳过了中间的C 语言改写步骤12.常规从算法到硬件电路的开发过程:算法的开发C语言的功能描述并行结构的C语言改写verilog的改写仿真、验证、修正综合、布局布线、投入实用13.C语言改写成verilog代码的困难点:并行C语言的改写,因为C本身是顺序执行,而不是并行执行不使用C语言中的复杂数据结构,如指针目前有将C语言转换成verilog的工具?14.HDLHDL描述方法是从电路图描述方法演化来的,相比来说更容易修改符合IEEE标准的有verilog HDL和VHDLVHDL由美国国防部开发,有1987和1993两个版本verilog由cadence持有,有1995、2001、2005三个版本verilog较VHDL更有前景:具有模拟电路描述能力、不仅可以开发电路还可以验证电路、门级以下描述比VHDL强RTL级和门级的综合已经成熟,主要是注意行为级的综合结果,使用可综合的编程风格SYSTEM VERILOG是VERILOG的一种延伸15.IP核的应用:软核soft core:功能经过验证的、可综合的、实现后门数在5K以上的HDL代码固核firm core:功能经过验证的、可综合的、实现后门数在5K以上的电路结构编码文件,如edif,不可更改硬核hard core: 功能经过验证的、可综合的、实现后门数在5K以上的电路结构版图,已带工艺参数,不可更改16.HDL语言综合后得到EDIF,这是一种标准电路网表EDIF经过具体工艺库匹配、布局布线、延时计算后得到网表EDIF不可更改,作为固核存在17.verilog特点:区分大小写,所有关键字都要求小写不是强类型语言,不同类型数据之间可以赋值和运算//是单行注释可以跨行注释描述风格有系统级描述、行为级描述、RTL级描述、门级描述,其中RTL级和门级别与具体电路结构有关,行为级描述要遵守可综合原则门级描述使用门级模型或者用户自定义模型UDP来代替具体基本元件,在IDE 中针对不同FPGA器件已经有对应的基本元件原语18.verlog语法要点:module endmodule之间由两部分构成:接口描述和逻辑功能描述IO端口种类:input output inout相同位宽的输入输出信号可以一起声明,input[3:0] a,b; 不同位宽的必须分开写内部信号为reg类型,内部信号信号的状态:0 1 x z,3'bx1=3'bxx1 x/z会往左扩展3'b1=3'b001 数字不往左扩展逻辑功能描述中常用assign描述组合逻辑电路,always既可以描述组合逻辑电路又可以描述时序逻辑电路,还可以用元件调用方法描述逻辑功能always之间、assign之间、实例引用之间以及它们之间都是并行执行, always内部是顺序执行常量格式:<+/-><二进制位宽><'><进制><该进制的数值>:默认进制为10进制默认位宽为32位位宽是从二进制宽度角度而言的由位宽决定从低位截取二进制数2'hFF=2'b11,通常由被赋值的reg变量位宽决定parameter常用于定义延迟和变量位宽,可用常量或常量表达式定义变量种类:wire reg memoryIO信号默认为wire类型,除非指定为reg类型wire可以用作任何输入输出端口wire包括input output inoutwire不带寄存功能assign赋值语句中,被赋值的信号都是wire类型assign之所以称为连续赋值,是因为不断检测表达式的变化reg类型可以被赋值后再使用,而不是向wire一样只能输出,类似VHDL 中的buffer端口reg类型变量初始值为x (VHDL中初始值为本类型最小值,通常是0always模块里被赋值的信号都必须定义为reg类型,因为always可以反复执行,而reg表示信号的寄存,可以保留上次执行的值reg类型变量与integer变量不同,即使赋负值,实质上也是按二进制无符号数存储的,integer是有符号数verilog中所有内部信号都是静态变量,因为它们的值都在reg中存储起来了memory型只有一维数组,由reg型变量组成memory初始化只能按地址赋值,不能一次性赋值1*256的memory写法:reg mema[255:0] mema[3]=0;不同位宽的变量之间赋值,处理之前都以被赋值的变量位宽为准扩展或截取A[a:b] 无论a b谁大,a总是实际电路的信号高位,b总是实际电路的信号低位算术运算中如果有X值则结果为Xfor循环中的变量另外定义成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<<1等于4'b0001数字电路里位运算应用普遍,包括按位逻辑运算、移位运算、拼接运算、缩减运算非阻塞式赋值<=与阻塞式赋值=阻塞:在同一个always过程中,后面的赋值语句要等待前一个赋值语句执行完,后面的语句被该赋值语句阻塞非阻塞:在同一个always过程中,非阻塞赋值语句是同时进行的,排在后面的语句不会被该赋值语句阻塞<=:块结束后才能完成赋值块内所有<=语句在always块结束时刻同时赋值<=右边各变量的值是上一次时钟边沿时,这些变量当时的值用于描述可综合的时序电路=:=语句结束之后过程always才可能结束在always过程中,begin end块内按先后顺序立即赋值,在fork join 内同时赋值(可能造成冲突与assign连用描述组合电路begin end中阻塞的含义:begin ...@(A B=C...; end 如果A 事件不发生则永远不能执行下去,被阻塞了由于时钟的延时(往往在ps级,多个always(posedge之间究竟谁先执行是个未知数使用原则:同一个always过程块内建立时序电路用<=纯组合逻辑电路用=,生成的电路结构最简单,执行速度最快同一个always块内不要混用<=和=不要在多个always块内对同一个变量赋值(多源驱动 if else的三种形式,第三种形式适合描述优先编码器if条件中0/x/z当成假,1当成真,非0的数值也当成真case语句的三种:case(四种状态的比较 casez(忽略z casex(忽略x 和z,只看哪些位的信号有用case语句中所有表达式值的位宽必须相等,default中不能将n'bx用'bx代替避免生成锁存器的方法:电平触发时if后加else case中加default ?使用casex会将不必要的状态视为无关项,使得综合出来的电路最简单两种特殊的括号:begin 顺序语句... end fork 并行语句... join,其差别在于块内语句的起止时间、执行顺序、相对延时块被命名后,其内部变量可以被调用,因为变量都是静态的(调用信号:对应电路中的一个信号线被引到另一处initial块只无条件执行一次always块在满足条件时不断执行initial常用来写测试文件,always块常用来写电路描述always既可以描述组合逻辑电路又可以描述时序逻辑电路always如果后面有敏感信号列表则不能用wait语句always既可以描述电平触发又可以描述边沿触发,wait只能描述电平触发assign 常用于描述组合逻辑电路测试文件中一般都是现initial 后always生成语句:生成快的本质是使用循环内的一条语句代替多条重复的verilog语句,简化了用户的编程genvar用于声明生成变量,生成变量只能用在生成快之间仿真时,仿真器会将生成块中的代码展平,在确立后的方针代码中,生成变量是不存在的最好是先想象出来循环生成语句被展平后的电路样子,再写相关的描述语句task和function的区别:task可以定义自己的仿真时间单位,function与主模块共用同一个仿真时间单位函数不能启动任务,任务能够启动函数函数至少要有一个输入变量,任务没有输入变量函数返回一个值,任务不返回值一个模块的设计包括3个部分:电路模块的设计测试模块的设计设计文档的编写设计者通过布局布线工具生成具有布线延迟的电路,再进行后仿真,得到时序分析报告从时序分析报告中可以知道电路的实际延迟t,同步电路内每个时钟周期要大于t,从而可确定该运算逻辑的最高频率综合器之所以能够实现加法器、乘法器是因为库中已经存在可配置的参数化器件模型FPGA内总线宽度容易自定义,以便实现高速数据流,三态数据总线相当于数据流的控制阀门数字系统内数据流的控制:开关(或三态数据总线、数据暂存部件(寄存器、同步状态机控制(整个系统在一个时钟域内流水线操作pipe line:K级流水线就是从组合逻辑的输入到输出恰好有K个寄存器组,上一级的输出是下一级的输入流水线操作获得第一个结果的时间要比不用流水线操作的时间长,但以后结果获得时间都只需要一个时钟周期,提高了数据吞吐量流水线操作的保证:Tclk>K*(组合逻辑延迟+触发器的建立保持时间/触发时间,即时间片段要长于最大路径延迟体现了面积换速度的思想,在综合时考虑的是以面积小为主还是以速度为主本质上是一种同步逻辑同步时序逻辑和异步时序逻辑:同步时序逻辑指所有寄存器组由唯一时钟触发 always@(posedge clk 或always@(negedage clk 异步时序逻辑指触发条件不唯一,任意一个条件都会引起触发 always@(posedge clk or posedage reset 目前的综合器是以同步时序逻辑综合的,因为同步时序逻辑较异步时序逻辑可靠严格的同步要求时钟信号传递速度远远大于各部分的延迟,实际中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 语句说明所有情况有优先级的 if else 结构会消耗更多资源,建议用无优先级的 case 替代模块的复用往往比代码上修改节省的资源多 PLL 的分频、倍频、移相操作会增加设计精度同步时序电路的延时:#x 通常用于仿真测试,实际硬件延时是:长延迟用计数器,小延迟用 D 触发器,此方法用来取代延迟链同步电路中,稳定的数据采用必须满足采样寄存器的建立和保持时间 reg 类型在 always 中不一定综合成时序电路,也可能是组合逻辑电路乒乓操作与作用异步时钟域同步问题延迟包括门延迟和线延迟组合逻辑产生的时钟仅能应用在时钟频率较低、精度要求不高的情况下增减敏感信号得到的结果一样补充部分: verilog HDL 起初是作为写 testbench 而产生的 verilog 有 1995 进入 IEEE 标准,为 IEEE-1364, 于 2001 年进行了扩展,为 IEEE 1364-2001; verilog AMS 可用于模拟电路和数字电路的综合,目前正在不断发展和完善中; verilog 的标识符区分大小写,关键字使用小写;用\\来进行单行注释,用\* *\来进行跨行注释;标识符由字母、数字、下划线构成,并以字母开头;关键字又叫保留字,只有小写的关键字才是保留字;信号的状态有 4 种: 0 1 x z x 和 z 在描述电路时不区分大小写,在仿真时大小写有不同意义;常量表达式中: x z 不区分大小写;进制符号 h o d b 与 H O D B 不区分大小写;十六进制中 a~f 不区分大小写;下划线_用于提高可读性;?在数中可以代替 z; x 和 z 的左端补位;字符和字符串都以 ASICII 码形式存在,也可以当成电路内的信号;字符串必须包含在同一行,不能分成多行书写;如果表达式或者赋值语句中将字符串当成操作数,则字符串中的每个字符都被看成 8 位的 ASCII 值序列;可综合的信号类型:wire reg memory 它们用来描述数字电路不可综合的数据类型:integer real 它们只用仿真,位于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 位寄存器 reg fc[3:0] //4 个一位寄存器 parameter的作用:仿真开始以前对其进行赋值,整个仿真过程中保持其值不变;关系运算符将以逻辑 1 或逻辑 0 返回比较的结果; == !=的返回值有 0 1 x 三种情况,=== !==的返回值只有 0 1 两种情况; 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 中; begin end 和 fork join 是两种特殊的括号 if 语句的第三种形式适合描述优先编码器,case 语句适合描述数据选择器和状态机;case 的条件表达式如果与分支项表达式长度不同,则在比较前将所有表达式都统一为这些表达式的最长长度; casez 忽略 z,casex 忽略 z 和 x; assign 语句只在右端表达式发生变化时才重新计算并重新赋值,其余时间都是连续赋值; assign 语句可以指定 bit、vector 或是任意拼接操作的结果; assign 语句是连续赋值的,用于驱动网线 wire, reg 类型不需要连续赋值, reg 类型一旦被赋值就会一直保存;过程赋值语句有两种:阻塞式=和非阻塞式<=,只能在过程块 initial 和always 中使用; @对事件触发的控制与 wait 语句不能同时使用;。

Verilog学习总结

Verilog学习总结

顺序块和并行块
语句是顺序执行的 parameter d=50; reg[7:0] r; begin #d r='h35; #d r='hE2; #d r='h00; #d r='hF7; #d ->end_wave; end 用顺序块和延时控制组合来产生一个时序波形 并行块是语句同时执行的
起始时间和结束时间
在并行块和顺序块中都有一个起始时间和结 束时间的概念。对于顺序块,起始时间就是 第一条语句开始被执行的时间,结束时间就 是最后一条语句执行结束的时间。而对于并 行块来说,起始时间对于块内所有的语句是 相同的,即程序植程控制进入该块的时间, 其结束时间是按时间排序在最后的语句执行 结束的时间。
条件语句
数字
整数 有二、八、十、十六进制 <位宽>’<进制><数字>,这是一种全面的描述方式 缺省的位宽由具体的机器系统决定,至少是32位 缺省的进制为十进制 x表示不定值,z代表高阻值,z还可以用?代替 4'b10x0 //位宽为4的二进制数从低位数起第二位为不定值 4'b101z //位宽为4的二进制数从低位数起第一位为高阻值 12'dz //位宽为12的十进制数,其值为高阻值 12'd? //同上 8'h4x //位宽为8的十六进制数,其低4位值为不定值 要表示负数的话只需在位宽表达式前加一个减号 两个不同数据宽度的变量操作时,自动右对齐操作。特别是赋 值操作。
数据类型
Verilog HDL中总共有19种数据类型 4 个最基本的数据类型:integer型、parameter 型、reg型和wire型。其他的类型有large型、 medium型、scalared型、 time型、small型、 tri型、trio型、tril型、triand型、trior型、 trireg型、vectored型、wand型和wor 型。

每天多学一点:Verilog编写技巧(一)

每天多学一点:Verilog编写技巧(一)

每天多学一点:Verilog编写技巧(一)来源:网路素材好的设计者一般都要对电路要实现的功能有清晰的认识,对数据流很清楚,知道数据如何从一个点移动到另一个点,这就是所谓的“勾划”(walk-through)。

一旦设计蓝图在脑海中变得清晰,此后釆用Verilog编写数据路径和控制逻辑就会变得思路清晰。

脑海中的模拟正如大多数人玩过的象棋游戏,我们都知道提前谋划是何等重要,要在下一次移动棋子之前考虑好此后的几步棋应该怎么走,以确保不会出错,不被对手捕捉到机会。

电路设计过程与下棋非常相似。

当设计状态机、数据路径或者控制逻辑时,我们知道它们的功能。

在进行设计仿真之前,我们需要思考代码在不同输入和边界条件下如何工作。

如果用心去做好这一步工作,并且分析可能出现的问题,验证工作将会变得非常高效。

另外,这一步也给我们建立了自信,使我们确信整个设计非常扎实,可以很好地工作。

否则很可能出现的情况是在验证阶段反复发现问题并进行电路修改,不断进行补救T.作,并且最终也不能确定设计足否还隐含着没有被发现的问题。

哪种风格—数据流或算法描述组合逻辑有两种方式—使用wire(对应数据流描述方式)或者使用reg(对应算法描述方式)。

这两种方式都能实现相同的逻辑功能,综合后得到相同的门电路,具体使用哪一种方式可以根据个人喜好。

数据流—短表达式举例wire [7:0] regl0_nxt;assign regl0_nxt = wren ? data_in : regl0;算法—短表达式举例reg [7:0] regl0_nxt;always @(*) beginreglO_nxt = reglO;if (wren)regl0_nxt = data_in;end当表达式非常简单时,一般更倾向于使用数据流风格来实现,此时代码行数很少。

然而,当表达式很长并且与很多条件有关时,数据流风格阅读起来较为费力。

此时可以使用算法风格,可以采用if-else 语句进行描述,以易于阅读和减少错误发生。

verilog课程期末总结

verilog课程期末总结

verilog课程期末总结一、引言Verilog(硬件描述语言)是一种用于描述电子系统的硬件结构和行为的语言,它广泛用于设计和验证数字电路,尤其是在集成电路和FPGA设计中。

在本学期的Verilog课程中,我们学习并实践了Verilog语言的基本概念和设计技巧,通过实验和项目开发,我们对Verilog语言的使用和应用有了更深入的了解。

本文将对这门课程进行总结,包括所学内容、实践经验以及未来的发展方向。

二、课程内容回顾本学期的Verilog课程共包含以下几个部分的内容:1. Verilog的基本语法和数据类型:在这个部分,我们学习了Verilog的基本语法,如模块定义、端口声明、数据类型定义等。

我们了解了如何使用Verilog语言进行模块化设计,利用不同的数据类型来描述数字电路中的信号和寄存器。

2. Verilog建模:这个部分教授了如何使用Verilog语言来建模和设计数字电路。

我们学习了组合逻辑和时序逻辑的建模方法,掌握了常用的门级建模和行为级建模技巧。

3. Verilog仿真:通过仿真可以验证我们设计的电路是否符合功能和时序的要求。

在这个部分,我们学习了如何使用Verilog语言进行仿真,以及如何编写仿真测试平台、编写仿真测试用例等。

通过仿真,我们可以对设计进行调试和验证,同时也方便了我们对电路性能和时序约束的分析。

4. Verilog项目开发:最后一个部分是课程的项目开发,通过一个实际项目的设计和实现,我们将所学的Verilog知识应用到实践中。

这个项目的设计还涉及模块间的通信和数据处理等方面,对我们综合运用所学知识的能力提出了更高的要求。

三、实践经验总结在学习和实践Verilog语言的过程中,我积累了一些宝贵的经验。

以下是我总结的几点实践经验:1. 充分理解和熟练掌握语法规则:Verilog语言的语法规则对于我们正确理解和使用这门语言非常重要。

通过不断的练习和实践,我渐渐熟练掌握了Verilog的语法规则,如模块的定义、端口的声明、数据类型的使用等。

Verilog 学习经验

Verilog  学习经验

在逻辑方面,我觉得比较重要的规范有这些:1.设计必须文档化。

要将设计思路,详细实现等写入文档,然后经过严格评审通过后才能进行下一步的工作。

这样做乍看起来很花时间,但是从整个项目过程来看,绝对要比一上来就写代码要节约时间,且这种做法可以使项目处于可控、可实现的状态。

2.代码规范。

a.设计要参数化。

比如一开始的设计时钟周期是30ns,复位周期是5个时钟周期,我们可以这么写:parameter CLK_PERIOD = 30;parameter RST_MUL_TIME = 5;parameter RST_TIME = RST_MUL_TIME * CLK_PERIOD;...rst_n = 1'b0;# RST_TIME rst_n = 1'b1;...# CLK_PERIOD/2 clk <= ~clk;如果在另一个设计中的时钟是40ns,复位周期不变,我们只需对CLK_PERIOD进行重新例化就行了,从而使得代码更加易于重用。

b.信号命名要规范化。

1) 信号名一律小写,参数用大写。

2) 对于低电平有效的信号结尾要用_n标记,如rst_n。

3) 端口信号排列要统一,一个信号只占一行,最好按输入输出及从哪个模块来到哪个模块去的关系排列,这样在后期仿真验证找错时后方便很多。

如:module a(//inputclk,rst_n, //globle signalwren,rden,avalon_din, //related to avalon bussdi, //related to serial port input//outputdata_ready,avalon_dout, //related to avalon bus...);4) 一个模块尽量只用一个时钟,这里的一个模块是指一个module或者是一个entity。

在多时钟域的设计中涉及到跨时钟域的设计中最好有专门一个模块做时钟域的隔离。

Systemverilog的一个牛人总结

Systemverilog的一个牛人总结

Systemverilog的一个牛人总结SystemVerilog是一种硬件描述语言,用于设计和验证硬件系统。

它是Verilog的扩展版本,提供了更丰富的特性和功能,使得硬件设计变得更加灵活和高效。

在SystemVerilog的大家庭中,有许多牛人通过深入研究和实践,掌握了该语言的精髓,并在硬件设计和验证领域取得了杰出的成绩。

下面是对SystemVerilog牛人的一些总结:1. 对SystemVerilog语言精通:牛人对SystemVerilog语言的语法和语义有着深入的理解,并能充分利用其强大的特性来设计和验证复杂的硬件系统。

他们熟悉SystemVerilog中各种数据类型、控制结构、模块化设计、接口和并发编程等方面的内容,并能灵活运用这些知识来解决实际问题。

2. 良好的编码风格和规范:牛人在编写SystemVerilog代码时,注重良好的编码风格和规范,使得代码易读、易于维护。

他们遵循一致的命名规则,使用有意义的变量名和模块名,编写清晰的注释,避免使用过于复杂的语法和结构,以及注意代码的可重用性和可扩展性。

3. 高效的调试和验证技巧:SystemVerilog牛人具备高效的调试和验证技巧,能够快速定位和解决设计和验证中的问题。

他们熟悉仿真工具的使用方法,能够利用断点、波形查看器、覆盖率分析等功能来分析和调试代码。

此外,他们还熟悉常见的验证方法和技术,如约束随机测试、功能覆盖率分析和形式化验证等,以确保设计的正确性和完整性。

4. 广泛的项目经验:SystemVerilog牛人在硬件设计和验证领域有着广泛的项目经验,涉及多个行业和应用领域。

他们参与过各种规模和复杂度的项目,从小规模的IP设计到大型的SoC设计和验证。

通过这些项目的实践,他们积累了丰富的经验和技巧,能够在不同的项目中灵活应对各种挑战。

5. 持续学习和研究的态度:SystemVerilog牛人具备持续学习和研究的态度,不断追求自我提升和突破。

个人总结FPGA设计中Verilog编程的27条经验

个人总结FPGA设计中Verilog编程的27条经验

个人总结Verilog编程27条经验1.强烈建议用同步设计;2.在设计时总是记住时序问题;3.在一个设计开始就要考虑到地电平或高电平复位、同步或异步复位、上升沿或下降沿触发等问题,在所有模块中都要遵守它;4.在不同的情况下用if和case,最好少用if的多层嵌套(1层或2层比较合适,当在3层以上时,最好修改写法,因为这样不仅可以reduce area,而且可以获得好的timing);5.在锁存一个信号或总线时要小心,对于整个design,尽量避免使用latch,因为在DFT时很难test;6.确信所有的信号被复位,在DFT时,所有的FlipFlop都是controllable;7.永远不要再写入之前读取任何内部存储器(如SRAM);8.从一个时钟到另一个不同的时钟传输数据时用数据缓冲,他工作像一个双时钟FIFO(是异步的),可以用Async SRAM搭建Async FIFO;9.在VHDL中二维数组可以使用,它是非常有用的。

在VERILOG中他仅仅可以使用在测试模块中,不能被综合;10.遵守register-in register-out规则;11.像synopsys的DC的综合工具是非常稳定的,任何bugs都不会从综合工具中产生12.确保FPGA版本与ASIC的版本尽可能的相似,特别是SRAM类型,若版本一致是最理想的,但是在工作中FPGA版本一般用FPGA自带的SRAM,ASIC版本一般用厂商提供的SRAM;13.在嵌入式存储器中使用BIST;14.虚单元和一些修正电路是必需的;15.一些简单的测试电路也是需要的,经常在一个芯片中有许多测试模块;16.除非低功耗不要用门控时钟,强烈建议不要在design中使用gate clock;17.不要依靠脚本来保证设计。

但是在脚本中的一些好的约束能够起到更好的性能(例如前向加法器);18.如果时间充裕,通过时钟做一个多锁存器来取代用MUX;19.不要用内部tri-state, ASIC需要总线保持器来处理内部tri-state,如IOcell;20.在top level中作pad insertion;21.选择pad时要小心(如上拉能力,施密特触发器,5伏耐压等),选择合适的IO cell;22.小心由时钟偏差引起的问题;23.不要试着产生半周期信号;24.如果有很多函数要修正,请一个一个地作,修正一个函数检查一个函数;25.在一个计算等式中排列每个信号的位数是一个好习惯,即使综合工具能做;26.不要使用HDL提供的除法器;27.削减不必要的时钟。

学习FPGAverilog的心得

学习FPGAverilog的心得

学习FPGAverilog的心得一....尽量不要使用"大于""小于"这样的判断语句,这样会明显增加使用的逻辑单元数量 .看一下报告,资源使用差别很大.例程:always@(posedge clk)begincount1=count1+1;if(count1==10000000)feng=1; //no_ringelse if(count1==90000000)beginfeng=0; //ringcount1=0;endend //这么写会用107个逻辑单元// 如果把这句话if(count1==10000000)改成大于小于,报告中用了135个逻辑单元二.....一定要想尽办法减少reg寄存器的长度上次把[30:0]改到[50:0],报告里逻辑单元从100多直升到2000多太吓人了,至于为什么我就不知道了哈!三....case语句里一定要加default if一定要加else如果是组合逻辑的设计,不加default或else的话,不能保证所有的情况都有赋值,就会在内部形成一个锁存器,不再是一个纯粹的组合逻辑了,电路性能就会下降.例如:case({a,b})2'b11 e=b;2'b10 e=a;endcase//不加default,虽然只关心a=1时的结果,但是a=0的时候,e就会保存原来的值,直到a变为1//那么e要保存原来的值,就要在内部生成锁存器了.四....尽量使用Case语句而不是if--else语句复杂的if--else语句通常会生成优先级译码逻辑,这将会增加这些路径上的组合时延用来产生复杂逻辑的Case语句通常会生成不会有太多时延的并行逻辑五...组合逻辑的always块中,要注意所有的输入全部放入敏感变量表里比如:always@(a or b)beginout=(a&b&c);end此时生成的不是纯的组合逻辑,因为当C变化时, out不会立刻发生变化(需要等到a或b变化,c的变化才会显现), 所以需要生成一个寄存器来保存C的值.连续赋值语句的综合:从赋值语句右边提取出逻辑,用于驱动赋值语句左边的net过程赋值语句的综合:从赋值语句右边提取出的逻辑,用于驱动赋值语句左边的reg型变量。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
由于做到这一点,在编码的时候自然就很快了,最重要的是这样做后可以让设计会一直 处于可控的状态,不会因为某一处的错误引起整个设计从头进行。 如何提高电路工作频率
对于设计者来说,我们当然希望我们设计的电路的工作频率(在这里如无特别说明,工 作频率指 FPGA 片内的工作频率)尽量高。我们也经常听说用资源换速度,用流水的方式可以 提高工作频率,这确实是一个很重要的方法,今天我想进一步去分析该如何提高电路的工作 频率。
其它方面的规范一时没有想到,想到了再写,也欢迎大家补充。 ============================================================================== ==============================================================================
1.设计必须文档化。要将设计思路,详细实现等写入文档,然后经过严格评审通过后才能 进行下一步的工作。这样做乍看起来很花时间,但是从整个项目过程来看,绝对要比一上来 就写代码要节约时间,且这种做法可以使项目处于可控、可实现的状态。
2.代码规范。 a.设计要参数化。比如一开始的设计时钟周期是 30ns,复位周期是 5 个时钟周期,我们 可以这么写:
据说是大牛一总结
规范很重要
工作过的朋友肯定知道,公司里是很强调规范的,特别是对于大的设计(无论软件还是 硬件),不按照规范走几乎是不可实现的。逻辑设计也是这样:如果不按规范做的话,过一 个月后调试时发现有错,回头再看自己写的代码,估计很多信号功能都忘了,更不要说检错 了;如果一个项目做了一半一个人走了,接班的估计得从头开始设计;如果需要在原来的版 本基础上增加新功能,很可能也得从头来过,很难做到设计的可重用性。在逻辑方面,我觉 得比较重要的规范有这些:
wren,
rden,
avalon_din, //related to avalon bus
sdi,
//related to serial port input
//output
data_ready,
avalon_dΒιβλιοθήκη ut, //related to avalon bus
...
); 4) 一个模块尽量只用一个时钟,这里的一个模块是指一个 module 或者是一个 entity。 在多时钟域的设计中涉及到跨时钟域的设计中最好有专门一个模块做时钟域的隔离。这样做 可以让综合器综合出更优的结果。 5) 尽量在底层模块上做逻辑,在高层尽量做例化,顶层模块只能做例化,禁止出现任 何胶连逻辑(glue logic),哪怕仅仅是对某个信号取反。理由同上。 6) 在 FPGA 的设计上禁止用纯组合逻辑产生 latch,带 D 触发器的 latch 的是允许的, 比如配置寄存器就是这种类型。 7) 一般来说,进入 FPGA 的信号必须先同步,以提高系统工作频率(板级)。
我们先来分析下是什么影响了电路的工作频率。
我们电路的工作频率主要与寄存器到寄存器之间的信号传播时延及 clock skew 有关。 在 FPGA 内部如果时钟走长线的话,clock skew 很小,基本上可以忽略, 在这里为了简单起 见,我们只考虑信号的传播时延的因素。 信号的传播时延包括寄存器的开关时延、走线时延、 经过组合逻辑的时延(这样划分或许不是很准确,不过对分析问题来说应该是没有可以的), 要提高电路的工作频率,我们就要在这三个时延中做文章,使其尽可能的小。
我们通过给综合器加适当的约束(不可贪心,一般以加 5%裕量较为合适,比如电路工 作在 100Mhz,则加约束加到 105Mhz 就可以了,贪心效果反而不好,且极大增加综合时间) 可以将相关的逻辑在布线时尽量布的靠近一点,从而减少走线的时延。(注:约束的实现不 完全是通过改进布局布线方式去提高工作频率,还有其它的改进措施)
8)所有模块的输出都要寄存器化,以提高工作频率,这对设计做到时序收敛也是极有
好处的。
9) 除非是低功耗设计,不然不要用门控时钟--这会增加设计的不稳定性,在要用到门
控时钟的地方,也要将门控信号用时钟的下降沿打一拍再输出与时钟相与。
clk_gate_en
--------
----
-----------------|D Q |------------------| \ gate_clk_out
我们先来看开关时延,这个时延是由器件物理特性决定的,我们没有办法去改变,所以我 们只能通过改变走线方式和减少组合逻辑的方法来提高工作频率。
1.通过改变走线的方式减少时延。 以 Altera 的器件为例,我们在 quartus 里面的 timing closure floorplan 可以看到有很 多条条块块,我们可以将条条块块按行和按列分,每一个条块代表 1 个 LAB,每个 LAB 里有 8 个或者是 10 个 LE。它们的走线时延的关系如下:同一个 LAB 中(最快) < 同列或者同行 < 不同行且不同列。
parameter CLK_PERIOD = 30; parameter RST_MUL_TIME = 5; parameter RST_TIME = RST_MUL_TIME * CLK_PERIOD; ... rst_n = 1'b0; # RST_TIME rst_n = 1'b1; ... # CLK_PERIOD/2 clk <= ~clk; 如果在另一个设计中的时钟是 40ns,复位周期不变,我们只需对 CLK_PERIOD 进行重新 例化就行了,从而使得代码更加易于重用。
2.通过减少组合逻辑的减少时延。 上面我们讲了可以通过加约束来提高工作频率,但是我们在做设计之初可万万不可将提高 工作频率的美好愿望寄托在加约束上,我们要通过合理的设计去避免出现大的组合逻辑,从 而提高电路的工作频率,这才能增强设计的可移植性,才可以使得我们的设计在移植到另一 同等速度级别的芯片时还能使用。
|
|
---------|
)---------
------o|>
|
|
|/
clk |
--------
|
----
------------------------------------
10)禁止用计数器分频后的信号做其它模块的时钟,而要用改成时钟使能的方式,否则
这种时钟满天飞的方式对设计的可靠性极为不利,也大大增加了静态时序分析的复杂性。如
s1:
a <= 1'b0; //由于上面赋了默认值,这里就不用再对 b、c 赋 值了(b、c 在该状态为 0,不会产生锁存器,下同)
s2: b <= 1'b1;
s3: c <= 1'b1;
default: ... ...
3.ALTERA 参考设计准则 1) Ensure Clock, Preset, and Clear configurations are free of glitch es. 2) Never use Clocks consisting of more than one level of combinatori al logic. 3) Carefully calculate setup times and hold times for multi-Clock sy stems. 4) Synchronize signals between flipflops in multi-Clock systems when the setup and hold time requirements cannot be met. 5) Ensure that Preset and Clear signals do not contain race conditio ns. 6) Ensure that no other internal race conditions exist. 7) Register all glitch-sensitive outputs. Synchronize all asynchronous inputs. 9) Never rely on delay chains for pin-to-pin or internal delays. 10)Do not rely on Power-On Reset. Use a master Reset pin to clear al l flipflops. 11)Remove any stuck states from state machines or synchronous logic.
...
case(current_state)
...
s1:if ...
next_state = s2;
...
...
always @(posedge clk or negedge rst_n)
...
else
a <= 1'b0;
c <= 1'b0;
c <= 1'b0;
//赋默认值
case(current_state)
begin
...
else if ( rs232_1xclk == 1'b1 )
...
end
11)状态机要写成 3 段式的(这是最标准的写法),即
...
always @(posedge clk or negedge rst_n)
...
current_state <= next_state;
...
always @ (current_state ...)
时序是设计出来的
我的 boss 有在华为及峻龙工作的背景,自然就给我们讲了一些华为及 altera 做逻辑的一 些东西,而我们的项目规范,也基本上是按华为的那一套去做。在工作这几个月中,给我感 触最深的是华为的那句话:时序是设计出来的,不是仿出来的,更不是湊出来的。 在我们 公司,每一个项目都有很严格的评审,只有评审通过了,才能做下一步的工作。以做逻辑为 例,并不是一上来就开始写代码,而是要先写总体设计方案和逻辑详细设计方案,要等这些 方案评审通过,认为可行了,才能进行编码,一般来说这部分工作所占的时间要远大于编码 的时间。 总体方案主要是涉及模块划分,一级模块和二级模块的接口信号和时序(我们要 求把接口信号的时序波形描述出来)以及将来如何测试设计。在这一级方案中,要保证在今 后的设计中时序要收敛到一级模块(最后是在二级模块中)。什么意思呢?我们在做详细设 计的时候,对于一些信号的时序肯定会做一些调整的,但是这种时序的调整最多只能波及到 本一级模块,而不能影响到整个设计。记得以前在学校做设计的时候,由于不懂得设计时序, 经常因为有一处信号的时序不满足,结果不得不将其它模块信号的时序也改一下,搞得人很 郁闷。 在逻辑详细设计方案这一级的时候,我们已经将各级模块的接口时序都设计出来了, 各级模块内部是怎么实现的也基本上确定下来了。
相关文档
最新文档