VERILOG综合心得
- 格式:pdf
- 大小:140.65 KB
- 文档页数:3
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中初始值为本类型最小值,通常是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] 无论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等于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 zx和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(硬件描述语言)是一种用于描述电子系统的硬件结构和行为的语言,它广泛用于设计和验证数字电路,尤其是在集成电路和FPGA设计中。
在本学期的Verilog课程中,我们学习并实践了Verilog语言的基本概念和设计技巧,通过实验和项目开发,我们对Verilog语言的使用和应用有了更深入的了解。
本文将对这门课程进行总结,包括所学内容、实践经验以及未来的发展方向。
二、课程内容回顾本学期的Verilog课程共包含以下几个部分的内容:1. Verilog的基本语法和数据类型:在这个部分,我们学习了Verilog的基本语法,如模块定义、端口声明、数据类型定义等。
我们了解了如何使用Verilog语言进行模块化设计,利用不同的数据类型来描述数字电路中的信号和寄存器。
2. Verilog建模:这个部分教授了如何使用Verilog语言来建模和设计数字电路。
我们学习了组合逻辑和时序逻辑的建模方法,掌握了常用的门级建模和行为级建模技巧。
3. Verilog仿真:通过仿真可以验证我们设计的电路是否符合功能和时序的要求。
在这个部分,我们学习了如何使用Verilog语言进行仿真,以及如何编写仿真测试平台、编写仿真测试用例等。
通过仿真,我们可以对设计进行调试和验证,同时也方便了我们对电路性能和时序约束的分析。
4. Verilog项目开发:最后一个部分是课程的项目开发,通过一个实际项目的设计和实现,我们将所学的Verilog知识应用到实践中。
这个项目的设计还涉及模块间的通信和数据处理等方面,对我们综合运用所学知识的能力提出了更高的要求。
三、实践经验总结在学习和实践Verilog语言的过程中,我积累了一些宝贵的经验。
以下是我总结的几点实践经验:1. 充分理解和熟练掌握语法规则:Verilog语言的语法规则对于我们正确理解和使用这门语言非常重要。
通过不断的练习和实践,我渐渐熟练掌握了Verilog的语法规则,如模块的定义、端口的声明、数据类型的使用等。
个人总结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.削减不必要的时钟。
一个新手的verilog学习经验分享来源:网络素材我学verilog语言进行FPGA设计也就半年时间,很多的东西就是在网上学到的,现在想说说自己对使用verilog进行FPGA设计的一些体会,我水平不高,主要是为新手朋友们介绍自己的一点经验少走点弯路。
1、verilog语言学习verilog最重要的不是语法,“因为10%的语法就能完成90%的工作”,verilog语言常用语言就是always@(),if~else,case,assign这几个了,不用去专研繁杂的语法,有些问题等你碰到了查查书就好了。
这里推荐夏雨闻老师的《verilog数字系统设计教程》,一本很适合新手的好书。
2、硬件原则虽然verilog语言很象c语言,但它和c语言还是有本质的区别的,因为verilog进行的是硬件设计,你写出来的东西是实实在在电路,所以要有数字电路的知识是肯定的。
数字电路就是由时序电路(触发器)和组合逻辑电路(各种逻辑门)构成的,用verilog写的程序在FPGA实现就是触发器和逻辑门,所以最重要的就是“你对你写的语言生成的电路心中有数”,做到这一点你就不会有写出来的程序不能综合的麻烦,电路的冗余逻辑肯定也是最少的。
还要注意一点就是verilog程序是并行的,不是象c那样是顺序执行的,这是因为fpga硬件可配置,可形成不同的任务单元同时工作;而单片机这种基于通用目的,硬件结构也固定了,它处理任务只能一件一件顺序的进行。
3、同步原则在进行FPGA设计的时候,同步原则应该是最重要的原则之一了,因为异步电路的不可控性,很可能有毛刺产生,而在芯片内部的任何一点毛刺都会一级一级的传递下去,最终影响系统的稳定性。
同步原则用一句话来总结就是“不要试图产生自己的时钟”,最好一个设计或者一个模块只使用同一个时钟,这样所有的触发器都在同一个时钟沿跳变,当然最稳定了,系统也能跑到很高的速度。
一个小技巧就是多使用触发器的使能端和取沿电路。
学习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型变量。
关于这个学期学习verilog hdl语言后的小结在完成本次verilog大作业的过程中,我不仅学到了很多只靠看书本学不到的知识,而且体会到了团队协作的力量,在团队成员的合作下,经历了不少困难,终于完成了verilog的大作业,虽然过程并不是和想象中的一样,而且作业也与老师要求的有点差距,但是从中学习到了许多关于verilog的使用与仿真的基础知识,也对课上学到的语句有了更深的理解,并将其应用到了实际工程中,使自己的运用能力得到了很好的锻炼,对基本操作已经较熟练的掌握,对其中一些细节问题,如仿真时间的选取等也有了自己的理解。
实践出真知,通过在软件上反复改程序、跑程序我也学会了很多只看书本发现不了的问题,锻炼了自己的解决问题能力。
这对于今后的学习是有很大的帮助的。
以下做一下简要总结:这次的大作业是通过我们小组四个同学共同努力下完成的,其中有很多收获也有很多感受。
这次的大作业给了我们一次很好的锻炼机会,通过这次大作业,我开始熟悉用verilog设计的最基本的方法和流程,课堂上学到的东西只有自己通过应用才能加深自己的理解,课堂上学到的并不是全部,要想真正的学好这门课,只有在实践中运用才能真正的体会到这门课的精髓,这次的大作业很好的验证了。
有一个外因也是给了我们的帮助,那就是网络的强大,在这个信息的时代,互联网的作用显而易见,如果能够充分得利用网络上海量的信息,掌握一定的检索技巧,就可以获得很多有价值的东西,比如参考别人的算法和程序段,观看关于Quartus II软件的使用教程视频。
这比起关起门来自己钻研要强上不少。
对于如何使用verilog hdl写出可综合的代码真的是一件不容易的事情,而真正的可以写出可综合的代码确实还需要经过很长时间的锻炼。
而对Quartus II的使用,感觉也只会得不多,还有很多功能诸如时序分析,逻辑分析,引脚分配等都不会使用。
在完成这次大作业的过程中充分感受到自己知识的不足以及学以致用的重要性,有很多不懂的地方,要通过不断的学习来提高自己,这正验证了学海无涯这句古话。
数字电路与逻辑设计实训课程学习总结基于Verilog的多功能计数器设计与实现数字电路与逻辑设计是计算机科学与技术专业的一门重要课程,通过学习这门课程,我深入了解了数字电路与逻辑设计的基本原理和Verilog语言的应用。
在实践中,我通过设计与实现基于Verilog的多功能计数器,不仅巩固了理论知识,而且提高了自己的实践能力和问题解决能力。
首先,在学习数字电路与逻辑设计的过程中,我了解到数字电路是基于二进制运算的电子电路系统,其中包括了门电路、触发器、寄存器等基本组件。
通过对这些组件的学习和理解,我能够准确地分析和设计各种数字电路电子产品。
其次,我学习了Verilog语言的基本语法和使用方法。
Verilog是一种硬件描述语言,可以用来描述数字电路的结构和功能。
通过学习Verilog语言,我可以使用模块化和层次化的设计思路来实现复杂的数字电路功能。
在实践中,我选择了设计和实现一个多功能计数器作为我的项目。
该多功能计数器能够实现多种计数模式,并且能够通过外部输入信号进行控制。
在设计的过程中,我首先进行了功能需求的分析和设计,然后结合Verilog语言的特点,采用模块化设计的思路,将计数器分为了多个子模块,分别实现不同的功能。
最后,我进行了仿真和综合验证,确保设计的正确性和稳定性。
在实现的过程中,我遇到了一些困难和问题,但通过查阅资料和与同学的讨论,我逐渐解决了这些问题。
例如,在设计过程中,我遇到了一些时序逻辑的问题,通过调整时钟信号和状态转移的顺序,最终解决了这些问题。
另外,在测试和验证的过程中,我遇到了一些功能异常的情况,通过对代码的仔细分析和调试,最终找到了问题的源头并进行了修复。
通过这个实训项目,我不仅深入理解了数字电路与逻辑设计的原理,还提高了我的实践能力和问题解决能力。
我学会了如何使用Verilog语言来描述和实现数字电路,如何进行功能需求的分析和设计,如何进行仿真和综合验证。
这对于我今后的学习和工作都具有重要的意义。
实验心得体会
本次实验,我们一行七人分别尝试使用 Verilog 来编写数字门电路的代码,我们通
过改变门的类型,并结合它们的波形图来理解 Verilog 的运行方式。
首先,我们学习了 Verilog 编程语言的基础知识,对于我们来说,这是个新的体验,学习的过程也有一定的困难度,但是一旦开始动手实践,我们就会非常快乐。
之后,我们开始用 Verilog 编写代码,在随後的实验中,我们实现了一个更为复杂
的电路,并且通过改变门的类型分别了解了各个门的特征,比如说 nand 和 nor 的功能,以及 not 的倒置功能。
接下来,我们又使用 Altera DE1 板,和 Quartus II 软件来模拟实验结果,再一次
接触了到了这个新的工具,最后在嵌入式实验室在 DE1 板上搭建了实验的电路,并长到
了实验的最终成功结果。
总的来说,这次实验对我们有着很大的收获,首先,我们对 Verilog 编程有了初步
的认识,同时也有很大的兴趣;而在软件和硬件上,我们也了解到了 FPGA 的模拟示波器
使用,以及 Quartus II 软件的基本操作,感受到了编程的乐趣,并能够在实践中体会到
其的用处,提高了自己的能力。
希望在今后的学习中,能够更加深入地掌握编程以及硬件知识,用到多样的工具去构
建自己的作品,拓展自己的视野,实践自己的想法,也希望有更多的机会,可以在实验室
里踩着电路,跟上技术的发展,掌握未来发展的领域,朝着不断提高自己的目标前进。
综合:不可综合的运算符:= = = ,!= =,/(除法),%(取余数)。
1、不使用初始化语句。
2、不使用带有延时的描述。
3、不使用循环次数不确定的循环语句,如:forever、while等。
4、尽量采用同步方式设计电路。
5、除非是关键路径的设计,一般不调用门级元件来描述设计的方法,建议采用行为语句来完成设计。
6、用always过程块描述组合逻辑,应在信号敏感列表中列出所有的输入信号。
7、所有的内部寄存器都应该能够被复位,在使用FPGA实现设计时,应尽量使用器件的全局复位端作为系统总的复位。
8、在verilog模块中,任务(task)通常被综合成组合逻辑的形式,每个函数(function)在调用时通常也被综合为一个独立的组合电路模块。
9、用户自定义原语(UDP)是不可综合的,它只能用来建立门级元件的仿真模型。
移位运算符:Verilog HDL提供向右(>>)及向左(<<)两种运算符,运算符高位或地位一旦移出即予丢弃,其空缺的位则予以补零。
连续赋值语句(assign)、case语句、if…else语句都是可以综合的initial 语句内若包含有多个语句时,必须以begin end 作聚合;单一的初值赋值,因此并不需以begin end做聚合。
循环(Loops)并不能单独地在程序中存在,而必须在initial和always块中才能使用。
initial过程块中的语句仅执行一次,而always块中的语句是不断重复执行的。
编写顶层模块的注意事项每个端口除了要声明是输入、输出还是双向外,还要声明其数据类型,是连线型(wire)还是寄存器型(reg),如果没有声明则综合器默认为wire型。
1、输入和双向端口不能声明为寄存器型。
2、在测试模块中不需要定义端口。
编写testbentch所归纳的心得module 模块名称;将input 定义为reg;将output定义为wire;引用欲测试的module 别名initial begin设定reg 初始值endalways处理变化值endmodule在always 、initial 过程块内,被赋值的每一个信号都必须定义成寄存器型。
Verilog 开发经验总结●以硬件为基础的原则Verilog是硬件描述语言,所谓描述就是是在在描绘已经设计好的电路。
尤其是在刚开始学习HDL时,还没有能直接把语言对应到具体电路的能力,更不能上手直接写Verilog代码。
所以最优方案是先设计好硬件电路,再按照电路编写Verilog。
●模块化思想这个思想不仅仅是Verilog的开发了,就算是C语言甚至现在的超高级语言,也一直在强调封装的概念。
Verilog开发遵循的是自顶向下的模块化设计,思路基本是从最终功能不断细分,直到Verilog可以很直接地描述最基础的硬件单元,例如加法器,移位寄存器等等。
模块划分一定要尽量细,功能单一,且一定要留出使能、复位等接口以便于系统搭建。
说明以下,所谓Verilog可直接描述指的是按照规范描述出来的电路,开发工具能够很清晰地理解所要描述的功能,而不会发生误解等现象。
一个只使用编译器能理解的代码开发的电路,错误率会大大降低。
相反,如果功能划分不够清晰,使得一个模块的功能过于庞杂,不仅描述困难,编译器也可能产生很大的误解。
把握编译器的理解方式是有助于做Verilog的开发的,但这就需要一个长远的积累了,我在最后会给出一些例子。
●时序电路与逻辑电路完全分开Verilog中除了数据流模型和门级模型以外,最常用的是always即行为级模型描述电路。
一个always块可以理解为一个电路,或者实物上的一个芯片。
所以不要在一个always里杂糅时序电路和逻辑电路,那样很可能导致编译器综合出一些奇葩的结果。
时序always模块的敏感变量有且最多两个,一个是时钟边沿,一个是复位边沿,没有再多的敏感变量了。
组合逻辑always中敏感变量列表必须包含该模块所有涉及到的变量,或者直接用(*)代替,个人推荐后者。
●时序always块编写规范在时序always中,统一使用非阻塞赋值<=,因为时序always中在赋值号左侧的变量是真实的触发器,非阻塞赋值在触发时是同时赋值的,这很符合触发器在上升沿到来后同时将D输出到Q的实际情况。
Verilog HDL之我见Verilog HDL顾名思义就是一种叫"Verilog"的硬件描述语言,可能同很多有C语言的基础的人一样,对于她相较ABEL和VHDL更有亲切感。
百科一下才知道它就是在C语言基础上发展起来的,有了这点不但减少了对陌生事物的生涩感,甚至还突生了不少兴趣,因为直接在电脑上用C语言设计大规模逻辑电路还是很有吸引力的。
以下就简述本人近几天来对Verilog HDL的一点见解,如有不妥敬请谅解。
首先她和C一样首先要建立项目,当然也可直接编辑源文件,但必须在项目下才能编译。
她的源文件也有很多种类,在还没接触MFC之前可能理解的她与C很大的一个不同就是她可以利用原理图输入直接编译仿真。
这个也是源于她的设计初衷是对现实逻辑电路的仿真和故障排除。
所以她用到的元件必定是现实可见的,这个就简单了,直接把这些器件的原理图和功能像头文件一样放进库里面编码时调用即可。
而且在制作原理图过程中也不像编码那样枯燥,虽然也很严谨,但毕竟更多样化,实现起来方便快捷非常直观。
当然原理图设计也是在你对电路了然于胸才可行的,当遇到大规模电路只知道逻辑和时序关系时则还是编码由软件自动生成原理技术图比较简单高效。
而且他的移植性也比编码实现差了很多,对她的交流学习及企业级间运用有很大障碍。
在编译时和C也有惊人的相似,虽然Warning仍然可以建立工程或者进行仿真,但还是需要注意改进代码。
仿真时需要新建仿真文件,这点就和软件编程语言不一样了,C的输入和输出是什么都是在编码时固定好的,且输入不需要存储。
而HDL需要你手动确定输入输出节点和输入和输出波形,这也是和她的实用性有关,因为一个逻辑电路的输入和输出都是严格固定好的,存储输入较方便。
从代码的角度看,V erilog HDL有个和C的main函数差不多的Module,但是也有很大区别。
在Verilog中可以有多个Module模块,并且执行时是几个Module并发执行,不想C 等其他高级软件语言是顺序执行的,所以C可以步步根据输出检错,而Verilog检测代码部分输出则较麻烦。
个人总结Verilog代码编写的25条经验1、对所有的信号名、变量名和端口名都用小写,这样做是为了和业界的习惯保持一致;对常量名和用户定义的类型用大写;2、使用有意义的信号名、端口名、函数名和参数名;3、信号名长度不要太长;4、对于时钟信号使用clk 作为信号名,如果设计中存在多个时钟,使用clk 作为时钟信号的前缀;5、对来自同一驱动源的信号在不同的子模块中采用相同的名字,这要求在芯片总体设计时就定义好顶层子模块间连线的名字,端口和连接端口的信号尽可能采用相同的名字;6、对于低电平有效的信号,应该以一个下划线跟一个小写字母b 或n 表示。
注意在同一个设计中要使用同一个小写字母表示低电平有效;7、对于复位信号使用rst 作为信号名,如果复位信号是低电平有效,建议使用rst_n;8、当描述多比特总线时,使用一致的定义顺序,对于verilog 建议采用bus_signal[x:0]的表示;9、尽量遵循业界已经习惯的一些约定。
如*_r 表示寄存器输出,*_a 表示异步信号,*_pn 表示多周期路径第n 个周期使用的信号,*_nxt 表示锁存前的信号,*_z 表示三态信号等;10、在源文件、批处理文件的开始应该包含一个文件头、文件头一般包含的内容如下例所示:文件名,作者,模块的实现功能概述和关键特性描述,文件创建和修改的记录,包括修改时间,修改的内容等;11、使用适当的注释来解释所有的always 进程、函数、端口定义、信号含义、变量含义或信号组、变量组的意义等。
注释应该放在它所注释的代码附近,要求简明扼要,只要足够说明设计意图即可,避免过于复杂;12、每一行语句独立成行。
尽管VHDL 和Verilog 都允许一行可以写多个语句,当时每个语句独立成行可以增加可读性和可维护性。
同时保持每行小于或等于72 个字符,这样做都是为了提高代码得可读性;13、建议采用缩进提高续行和嵌套语句得可读性。
缩进一般采用两个空格,如西安交通大学SOC 设计中心2 如果空格太多则在深层嵌套时限制行长。
个人总结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.削减不必要的时钟。
竭诚为您提供优质文档/双击可除veriloghdl学习心得篇一:Verilog学习心得Verilog学习心得因为Verilog是一种硬件描述语言,所以在写Verilog语言时,首先要有所要写的module在硬件上如何实现的概念,而不是去想编译器如何去解释这个module.比如在决定是否使用reg定义时,要问问自己物理上是不是真正存在这个register,如果是,它的clock是什么?D端是什么?Q端是什么?有没有清零和置位?同步还是异步?再比如上面讨论的三态输出问题,首先想到的应该是在register的输出后面加一个三态门,而不是如何才能让编译器知道要“赋值”给一个信号为三态。
同样,Verilog 中没有“编译”的概念,而只有综合的概念。
写硬件描述语言的目的是为了综合,所以说要想写的好就要对综合器有很深的了解,这样写出来的代码才有效率。
曾经接触过motorola苏州设计中心的一位资深工程师,他忠告了一句:就是用verilog描述电路的时候,一定要清楚它实现的电路,很多人只顾学习verilog语言,而不熟悉它实现的电路,这是设计不出好的电路来的.一般写verilogcode时,对整个硬件的结构应该是很清楚了,最好有详细的电路图画出,时序问题等都应该考虑清楚了。
可以看着图直接写code。
要知道,最初Verilog是为了实现仿真而发明的.不可综合的Verilog语句也是很重要的.因为在实际设计电路时,除了要实现一个可综合的module外,你还要知道它的外围电路是怎样的,以及我的这个电路与这些外围电路能否协调工作.这些外围电路就可以用不可综合的语句来实现而不必管它是如何实现的.因为它们可能已经实际存在了,我仅是用它来模拟的.所以,在写verilog的时候应该要先明确我是用它来仿真的还是综合的.要是用来综合的话,就必须要严格地使用可综合的语句,而且不同的写法可能产生的电路会有很大差别,这时就要懂一些verilog综合方法的知识.就像前面说的,脑子里要有一个硬件的概念.特别是当综合报错时,就要想一想我这种写法能不能用硬件来实现,verilog毕竟还不是c,很多写法是不可实现的.要是这个module仅是用来仿真的,就要灵活得多了,这时你大可不必太在意硬件实现.只要满足它的语法,实现你要的功能就行了.有网友说关于#10clk=~clk的问题,虽然这种语句是不可综合的,但是在做simulation和verification是常常用它在testbench中来产生一个clock信号。
学verilog小结第一篇:学verilog小结学习verilog一段时间小结学习verilog, verilog, verilog小结一:基本Verilog中的变量有线网类型和寄存器类型。
线网型变量综合成wire,而寄存器可能综合成WIRE,锁存器和触发器。
二:verilog语句结构到门级的映射1、连续性赋值:assign 连续性赋值语句逻辑结构上就是将等式右边的驱动左边的结点。
因些连续性赋值的目标结点总是综合成由组合逻辑驱动的结点。
Assign语句中的延时综合时都将忽视。
2、过程性赋值:过程性赋值只出现在always语句中。
阻塞赋值和非阻塞赋值就该赋值本身是没有区别的,只是对后面的语句有不同的影响。
建议设计组合逻辑电路时用阻塞赋值,设计时序电路时用非阻塞赋值。
过程性赋值的赋值对象有可能综合成wire,latch,和flip-flop,取决于具体状况。
如,时钟控制下的非阻塞赋值综合成flip-flop。
过程性赋值语句中的任何延时在综合时都将忽略。
建议同一个变量单一地使用阻塞或者非阻塞赋值。
3、逻辑操作符:逻辑操作符对应于硬件中已有的逻辑门4、算术操作符:Verilog中将reg视为无符号数,而integer视为有符号数。
因此,进行有符号操作时使用integer,使用无符号操作时使用reg。
5、进位:通常会将进行运算操作的结果比原操作数扩展一位,用来存放进位或者借位。
如:Wire [3:0] A,B;Wire [4:0] C;Assign C=A+B;C的最高位用来存放进位。
6、关系运算符:关系运算符:,<=,>= 和算术操作符一样,可以进行有符号和无符号运算,取决于数据类型是reg,net还是integer。
7、相等运算符:==,!= 注意:===和!==是不可综合的。
可以进行有符号或无符号操作,取决于数据类型8、移位运算符:左移,右移,右边操作数可以是常数或者是变量,二者综合出来的结果不同。