VERILOG综合心得
编写 testbentch 所归纳的心得
2
module 模块名称; 将 input 定义为 reg; 将 output 定义为 wire; 引用欲测试的 module 别名 initial begin 设定 reg 初始值 end always 处理变化值 endmodule
在 always 、initial 过程块内,被赋值的每一个信号都必须定义成寄存器型。
阻塞赋值(=)和非阻塞赋值(<=)的应用注意事项: 1、 非阻塞赋值不能用于“assign”持续赋值中,一般只出现在“initial”和“always”等过
程块中,对 reg 型变量进行赋值。象 assign out<=a+b;这样的语句是错误的。 2、 当用“always”块来描述组合逻辑时,既可以用阻塞赋值,也可以采用非阻塞赋值。但
可综合性说明
module mocromodule
是
wire reg integer 数据类型
是
parameter
是
端口类型
input output inout 运算符
+、-、*、% & 、~& 、| 、~| 、^ 、^~
= = != && || | ~ & | ^ ^~ >> << ?: { }
是
大部分可以综合 全等运算符(= = = != =)不支持 多数工具对除法(/)和求模(%)有限制 如对除法操作,只有除数是常数,且是 2 的
综合:不可综合的运算符:= = = ,!= =,/(除法),%(取余数)。
Verilog HDL 语句及可综合性:
类别
语句
可综合性
initial
否
过程语句
begin
是
串行块 begin - end
是
块语句
并行块 fork-join
否
持续赋值 assign
是
赋值语句
过程赋值 =、<=
是
if – else
一般支持,有的综合器不支持 casex casez 是
是
是 一般支持,少数综合器不支持
是
一般综合工具忽略的 Verilog HDL 结构
Veriolg HDL 结构
可综合性说明
延时控制
scalared
vectored
specify
这些结构和语句在综合时全被忽略
small large medium
weak1 weak0 highz0 highz1 pull0 pull1
是
条件语句
case , casez , casex
是
for
是
repeat
否
循环语句
while
否
forever
否
`define
是
编译向导语句
`include
是
`ifdef, `else , `endif
是
可综合设计的特点:
1、不使用初始化语句。
2、不使用带有延时的描述。
3、不使用循环次数不确定的循环语句,如:forever、while 等。
if- else case casez casex endcase for 循环语句
always 过程语句 begin-end 块语句 function endfunction
task endtask 编译向导:`include `define `ifdef `else `endif
支持,但对同一 reg 型变量只能采用阻塞和非 阻塞赋值中的一种进行赋值
deassign defparam event
force
release
fork join
rpmos
多数综合器对这些结构和语句不支持, 用这些语句描述的程序代码不能转化 为具体的电路网表结构,但这些结构能
forever repeat while
够被仿真工具所支持。
initial
rtran tran tranif0 tranif1 rtranif0 rtranif1
在同一个过程块中,最好不要同时用阻塞赋值和非阻塞赋值,虽然同时 这两种赋值方
式在综合时并不一定会出错。
3、 在向函数的返回值赋值时,应该使用阻塞赋值“=”。 4、 不能在一个以上的“always”过程块中对同一个变量赋值,这样会引起冲突,在综合时
会报错。
5、 在一个模块中,严禁对同一变量既进行阻塞赋值,又进行非阻塞赋值,这样在综合时会 报错。
指数时才支持
基本元件
and nand nor or xor xnor buf not bufif1 bufif0 notif1 notif0 pullup pulldown
全部可综合: 但某些工具对取值为 x 和 z 有所限制
持续赋值 assign
是
1
过程赋值:阻塞赋值(=) 非阻塞赋值(<=) 条件语句
net 型和 reg 型的变量可以声明为(signed)变量;操作数可以从无符号数转换为有符号数。
例如: wire signed[3:0] a; reg signed[7:0] out;
系统函数$signed 和$usigned,以实现无符号数转化为有符号数,或者有符号数转化为无符
号数。
例如:c=$signed(s);
time
有些综合工具将其视为整数(integer)
wait
有些综合工具有限制地支持
一般综合工具不支持的 Verilog HDL 结构VerilFra bibliotekg HDL 结构
可综合性说明
在 assign 持续赋值中,等式左边含有变量的位选择
全等运算符(= = =、!= =)
cmos
nmos rcmos rnmos pmos
8、在 verilog 模块中,任务(task)通常被综合成组合逻辑的形式,每个函数(function)在 调用时通常也被综合为一个独立的组合电路模块。
9、用户自定义原语(UDP)是不可综合的,它只能用来建立门级元件的仿真模型。
一般综合工具支持的 Verilog HDL 结构
Verilog HDL 结构
3
6、 对时序逻辑描述和建模,应尽量使用非阻塞赋值方式,此外,若在同一个“always”过 程块中描述时序和组合逻辑混合电路时,也最好使用非阻塞赋值方式。
7、 对于阻塞赋值来说,赋值语句的顺序对最后的综合结果有着直接的影响。 而对于非阻塞赋值,不用考虑赋值语句的排列顺序。
布局与布线(Auto Placement & Route, AP&R) 布局的目的在于产生制作掩膜所需的 GDSII 文件。 CTS(时钟树综合)必须尽可能地使同一个 Tree 内 Clock 到达的时间一致,即使 Clock Skrew 越小越好。
table endtable primitive endprimitive
移位运算符:Verilog HDL 提供向右(>>)及向左(<<)两种运算符,运算符高位或地位一旦 移出即予丢弃,其空缺的位则予以补零。
连续赋值语句(assign)、case 语句、if…else 语句都是可以综合的 initial 语句内若包含有多个语句时,必须以 begin end 作聚合;单一的初值赋值,因此并不 需以 begin end 做聚合。 循环(Loops) 并不能单独地在程序中存在,而必须在 initial 和 always 块中才能使用。
算术移位操作符:‘>>>’, ‘<<<’,对于有符号数,执行算术移位操作的时,将符号填补移出
的位。例如:定义有符号数:8’b10100011,则执行逻辑移位操作和算术移位操作后的值分
别如下:
A>>3;
//逻辑右移后其值为:8’b00010100
A>>>3;
//算术右移后其值为 8’b11110100
4、尽量采用同步方式设计电路。
5、除非是关键路径的设计,一般不调用门级元件来描述设计的方法,建议采用行为语句来
完成设计。
6、用 always 过程块描述组合逻辑,应在信号敏感列表中列出所有的输入信号。
7、所有的内部寄存器都应该能够被复位,在使用 FPGA 实现设计时,应尽量使用器件的全
局复位端作为系统总的复位。
initial 过程块中的语句仅执行一次,而 always 块中的语句是不断重复执行的。 编写顶层模块的注意事项
每个端口除了要声明是输入 、输出还是双向外,还要声明其数据类型,是连线型(wire) 还是寄存器型(reg),如果没有声明则综合器默认为 wire 型。 1、 输入和双向端口不能声明为寄存器型。 2、 在测试模块中不需要定义端口。
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语法学习心得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课程期末总结一、引言Verilog(硬件描述语言)是一种用于描述电子系统的硬件结构和行为的语言,它广泛用于设计和验证数字电路,尤其是在集成电路和FPGA设计中。
在本学期的Verilog课程中,我们学习并实践了Verilog语言的基本概念和设计技巧,通过实验和项目开发,我们对Verilog语言的使用和应用有了更深入的了解。
本文将对这门课程进行总结,包括所学内容、实践经验以及未来的发展方向。
二、课程内容回顾本学期的Verilog课程共包含以下几个部分的内容:1. Verilog的基本语法和数据类型:在这个部分,我们学习了Verilog的基本语法,如模块定义、端口声明、数据类型定义等。
我们了解了如何使用Verilog语言进行模块化设计,利用不同的数据类型来描述数字电路中的信号和寄存器。
2. Verilog建模:这个部分教授了如何使用Verilog语言来建模和设计数字电路。
我们学习了组合逻辑和时序逻辑的建模方法,掌握了常用的门级建模和行为级建模技巧。
3. Verilog仿真:通过仿真可以验证我们设计的电路是否符合功能和时序的要求。
在这个部分,我们学习了如何使用Verilog语言进行仿真,以及如何编写仿真测试平台、编写仿真测试用例等。
通过仿真,我们可以对设计进行调试和验证,同时也方便了我们对电路性能和时序约束的分析。
4. Verilog项目开发:最后一个部分是课程的项目开发,通过一个实际项目的设计和实现,我们将所学的Verilog知识应用到实践中。
这个项目的设计还涉及模块间的通信和数据处理等方面,对我们综合运用所学知识的能力提出了更高的要求。
三、实践经验总结在学习和实践Verilog语言的过程中,我积累了一些宝贵的经验。
以下是我总结的几点实践经验:1. 充分理解和熟练掌握语法规则:Verilog语言的语法规则对于我们正确理解和使用这门语言非常重要。
通过不断的练习和实践,我渐渐熟练掌握了Verilog的语法规则,如模块的定义、端口的声明、数据类型的使用等。
个人总结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.削减不必要的时钟。
一个新手的verilog学习经验分享
一个新手的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的心得
学习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后的总结
关于这个学期学习verilog hdl语言后的小结在完成本次verilog大作业的过程中,我不仅学到了很多只靠看书本学不到的知识,而且体会到了团队协作的力量,在团队成员的合作下,经历了不少困难,终于完成了verilog的大作业,虽然过程并不是和想象中的一样,而且作业也与老师要求的有点差距,但是从中学习到了许多关于verilog的使用与仿真的基础知识,也对课上学到的语句有了更深的理解,并将其应用到了实际工程中,使自己的运用能力得到了很好的锻炼,对基本操作已经较熟练的掌握,对其中一些细节问题,如仿真时间的选取等也有了自己的理解。
实践出真知,通过在软件上反复改程序、跑程序我也学会了很多只看书本发现不了的问题,锻炼了自己的解决问题能力。
这对于今后的学习是有很大的帮助的。
以下做一下简要总结:这次的大作业是通过我们小组四个同学共同努力下完成的,其中有很多收获也有很多感受。
这次的大作业给了我们一次很好的锻炼机会,通过这次大作业,我开始熟悉用verilog设计的最基本的方法和流程,课堂上学到的东西只有自己通过应用才能加深自己的理解,课堂上学到的并不是全部,要想真正的学好这门课,只有在实践中运用才能真正的体会到这门课的精髓,这次的大作业很好的验证了。
有一个外因也是给了我们的帮助,那就是网络的强大,在这个信息的时代,互联网的作用显而易见,如果能够充分得利用网络上海量的信息,掌握一定的检索技巧,就可以获得很多有价值的东西,比如参考别人的算法和程序段,观看关于Quartus II软件的使用教程视频。
这比起关起门来自己钻研要强上不少。
对于如何使用verilog hdl写出可综合的代码真的是一件不容易的事情,而真正的可以写出可综合的代码确实还需要经过很长时间的锻炼。
而对Quartus II的使用,感觉也只会得不多,还有很多功能诸如时序分析,逻辑分析,引脚分配等都不会使用。
在完成这次大作业的过程中充分感受到自己知识的不足以及学以致用的重要性,有很多不懂的地方,要通过不断的学习来提高自己,这正验证了学海无涯这句古话。
数字电路与逻辑设计实训课程学习总结基于Verilog的多功能计数器设计与实现
数字电路与逻辑设计实训课程学习总结基于Verilog的多功能计数器设计与实现数字电路与逻辑设计是计算机科学与技术专业的一门重要课程,通过学习这门课程,我深入了解了数字电路与逻辑设计的基本原理和Verilog语言的应用。
在实践中,我通过设计与实现基于Verilog的多功能计数器,不仅巩固了理论知识,而且提高了自己的实践能力和问题解决能力。
首先,在学习数字电路与逻辑设计的过程中,我了解到数字电路是基于二进制运算的电子电路系统,其中包括了门电路、触发器、寄存器等基本组件。
通过对这些组件的学习和理解,我能够准确地分析和设计各种数字电路电子产品。
其次,我学习了Verilog语言的基本语法和使用方法。
Verilog是一种硬件描述语言,可以用来描述数字电路的结构和功能。
通过学习Verilog语言,我可以使用模块化和层次化的设计思路来实现复杂的数字电路功能。
在实践中,我选择了设计和实现一个多功能计数器作为我的项目。
该多功能计数器能够实现多种计数模式,并且能够通过外部输入信号进行控制。
在设计的过程中,我首先进行了功能需求的分析和设计,然后结合Verilog语言的特点,采用模块化设计的思路,将计数器分为了多个子模块,分别实现不同的功能。
最后,我进行了仿真和综合验证,确保设计的正确性和稳定性。
在实现的过程中,我遇到了一些困难和问题,但通过查阅资料和与同学的讨论,我逐渐解决了这些问题。
例如,在设计过程中,我遇到了一些时序逻辑的问题,通过调整时钟信号和状态转移的顺序,最终解决了这些问题。
另外,在测试和验证的过程中,我遇到了一些功能异常的情况,通过对代码的仔细分析和调试,最终找到了问题的源头并进行了修复。
通过这个实训项目,我不仅深入理解了数字电路与逻辑设计的原理,还提高了我的实践能力和问题解决能力。
我学会了如何使用Verilog语言来描述和实现数字电路,如何进行功能需求的分析和设计,如何进行仿真和综合验证。
这对于我今后的学习和工作都具有重要的意义。
实验心得体会
实验心得体会
本次实验,我们一行七人分别尝试使用 Verilog 来编写数字门电路的代码,我们通
过改变门的类型,并结合它们的波形图来理解 Verilog 的运行方式。
首先,我们学习了 Verilog 编程语言的基础知识,对于我们来说,这是个新的体验,学习的过程也有一定的困难度,但是一旦开始动手实践,我们就会非常快乐。
之后,我们开始用 Verilog 编写代码,在随後的实验中,我们实现了一个更为复杂
的电路,并且通过改变门的类型分别了解了各个门的特征,比如说 nand 和 nor 的功能,以及 not 的倒置功能。
接下来,我们又使用 Altera DE1 板,和 Quartus II 软件来模拟实验结果,再一次
接触了到了这个新的工具,最后在嵌入式实验室在 DE1 板上搭建了实验的电路,并长到
了实验的最终成功结果。
总的来说,这次实验对我们有着很大的收获,首先,我们对 Verilog 编程有了初步
的认识,同时也有很大的兴趣;而在软件和硬件上,我们也了解到了 FPGA 的模拟示波器
使用,以及 Quartus II 软件的基本操作,感受到了编程的乐趣,并能够在实践中体会到
其的用处,提高了自己的能力。
希望在今后的学习中,能够更加深入地掌握编程以及硬件知识,用到多样的工具去构
建自己的作品,拓展自己的视野,实践自己的想法,也希望有更多的机会,可以在实验室
里踩着电路,跟上技术的发展,掌握未来发展的领域,朝着不断提高自己的目标前进。
verilog综合心得
综合:不可综合的运算符:= = = ,!= =,/(除法),%(取余数)。
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 过程块内,被赋值的每一个信号都必须定义成寄存器型。
