Verilog华为教程.doc

上传人:土8路 文档编号:10326023 上传时间:2021-05-09 格式:DOC 页数:29 大小:148.50KB
返回 下载 相关 举报
Verilog华为教程.doc_第1页
第1页 / 共29页
Verilog华为教程.doc_第2页
第2页 / 共29页
Verilog华为教程.doc_第3页
第3页 / 共29页
Verilog华为教程.doc_第4页
第4页 / 共29页
Verilog华为教程.doc_第5页
第5页 / 共29页
点击查看更多>>
资源描述

《Verilog华为教程.doc》由会员分享,可在线阅读,更多相关《Verilog华为教程.doc(29页珍藏版)》请在三一文库上搜索。

1、1.verilog特点:区分大小写,所有关键字都要求小写不是强类型语言,不同类型数据之间可以赋值和运算/是单行注释 可以跨行注释描述风格有系统级描述、行为级描述、RTL级描述、门级描述,其中RTL级和门级别与具体电路结构有关,行为级描述要遵守可综合原则,门级描述使用门级模型或者用户自定义模型UDP来代替具体基本元件,在IDE中针对不同FPGA器件已经有对应的基本元件原语2.verilog语法要点:module endmodule之间由两部分构成:接口描述和逻辑功能描述IO端口种类: input output inout相同位宽的输入输出信号可以一起声明, input3:0 a,b; 不同位宽的

2、必须分开写内部信号为reg类型,内部信号信号的状态: 0 1 x z, 3bx1=3bxx1 x/z会往左扩展 3b1=3b001 数字不往左扩展逻辑功能描述中常用assign描述组合逻辑电路,always既可以描述组合逻辑电路又可以描述时序逻辑电路,还可以用元件调用方法描述逻辑功能always之间、assign之间、实例引用之间以及它们之间都是并行执行,always内部是顺序执行常量格式: :默认进制为10进制默认位宽为32位位宽是从二进制宽度角度而言的由位宽决定从低位截取二进制数2hFF=2b11,通常由被赋值的reg变量位宽决定parameter常用于定义延迟和变量位宽,可用常量或常量表

3、达式定义变量种类: 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表示信号的寄存,可以保留上次执行的值r

4、eg类型变量与integer变量不同,即使赋负值,实质上也是按二进制无符号数存储的,integer是有符号数verilog中所有内部信号都是静态变量,因为它们的值都在reg中存储起来了memory型只有一维数组,由reg型变量组成memory初始化只能按地址赋值,不能一次性赋值1*256的memory写法: reg mema255:0 mema3=0;不同位宽的变量之间赋值,处理之前都以被赋值的变量位宽为准扩展或截取Aa:b 无论a b谁大,a总是实际电路的信号高位,b总是实际电路的信号低位算术运算中如果有X值则结果为Xfor循环中的变量另外定义成integer,因为它不是实际信号,有正负;r

5、eg则以无符号数存在= 和!=只比较0、1,遇到z或x时结果都为x (x在if中算做假条件),结果可能是1、0、x=和!=比较更加苛刻,包括x和z的精确比较,结果可能是0、1&的结果只有1b1或1b0两种, A&A的结果位宽则是与A相同的1,0为 64h100000000,所以拼接运算中各信号一定要指定位宽移位运算左移将保留 4b10001等于5b10000,右移则舍弃 4b0011等于4b0001数字电路里位运算应用普遍,包括按位逻辑运算、移位运算、拼接运算、缩减运算非阻塞式赋值=与阻塞式赋值=阻塞:在同一个always过程中,后面的赋值语句要等待前一个赋值语句执行完,后面的语句被该赋值语句

6、阻塞非阻塞:在同一个always过程中,非阻塞赋值语句是同时进行的,排在后面的语句不会被该赋值语句阻塞=:块结束后才能完成赋值块内所有=语句在always块结束时刻同时赋值=右边各变量的值是上一次时钟边沿时,这些变量当时的值用于描述可综合的时序电路=:=语句结束之后过程always才可能结束在always过程中,begin end块内按先后顺序立即赋值,在fork join内同时赋值(可能造成冲突)与assign连用描述组合电路begin end中阻塞的含义:begin .(A) B=C.; end 如果A事件不发生则永远不能执行下去,被阻塞了 由于时钟的延时(往往在ps级),多个always

7、(posedge)之间究竟谁先执行是个未知数使用原则:同一个always过程块内建立时序电路用= 纯组合逻辑电路用=,生成的电路结构最简单,执行速度最快同一个always块内不要混用K*(组合逻辑延迟+触发器的建立保持时间/触发时间),即时间片段要长于最大路径延迟体现了面积换速度的思想,在综合时考虑的是以面积小为主还是以速度为主本质上是一种同步逻辑同步时序逻辑和异步时序逻辑:同步时序逻辑指所有寄存器组由唯一时钟触发 always(posedge clk) 或always(negedage clk)异步时序逻辑指触发条件不唯一,任意一个条件都会引起触发 always(posedge clk or

8、 posedage reset)目前的综合器是以同步时序逻辑综合的,因为同步时序逻辑较异步时序逻辑可靠严格的同步要求时钟信号传递速度远远大于各部分的延迟,实际中clk要单独用线,而不要经过反相器等部件always (posedge. ) begin .=. end 表示同步时序逻辑(同时刻赋值)不同速率数据接口的处理方法(异步数据的处理方法):帧同步 FIFO 双端口RAM同步状态机:包括moore和mealy型两种,及其反馈模型(是一种反馈控制系统,当前状态就是其内部状态变量)状态机的开发步骤:根据实际问题列出输入输出变量和状态数画出状态图并化简写出状态转移真值表得到逻辑表达式用D触发器或J

9、K触发器构建电路(目前用D触发器多)verilog描述时只需要得到简化的状态图就可以描述状态编码方式: 独热码 格雷码状态机主体程序有单always描述方式和多always描述方式采用case/casez/casex建立模型最好,因为x是无关态,生成的电路最简单default: state=bx与实际情况更一致,效果等同于 default: state=idle只有同步状态机才能被目前的综合for语句会将所有变量的情况展开,占用巨量逻辑资源,替代办法是用计数器和case语句说明所有情况有优先级的if else结构会消耗更多资源,建议用无优先级的case替代模块的复用往往比代码上修改节省的资源多

10、PLL的分频、倍频、移相操作会增加设计精度同步时序电路的延时:#x通常用于仿真测试,实际硬件延时是:长延迟用计数器,小延迟用D触发器,此方法用来取代延迟链同步电路中,稳定的数据采用必须满足采样寄存器的建立和保持时间reg类型在always中不一定综合成时序电路,也可能是组合逻辑电路乒乓操作与作用 异步时钟域同步问题延迟包括门延迟和线延迟组合逻辑产生的时钟仅能应用在时钟频率较低、精度要求不高的情况下增减敏感信号得到的结果一样补充部分:verilog HDL起初是作为写testbench而产生的verilog 有1995进入IEEE标准,为IEEE-1364, 于2001年进行了扩展,为IEEE

11、1364-2001;verilog AMS可用于模拟电路和数字电路的综合,目前正在不断发展和完善中;verilog的标识符区分大小写,关键字使用小写;用来进行单行注释,用* *来进行跨行注释;标识符由字母、数字、下划线构成,并以字母开头;关键字又叫保留字,只有小写的关键字才是保留字;信号的状态有4种: 0 1 x zx和z在描述电路时不区分大小写,在仿真时大小写有不同意义;常量表达式中:x z不区分大小写;进制符号h o d b与H O D B不区分大小写;十六进制中af不区分大小写;下划线_用于提高可读性;?在数中可以代替z;x和z的左端补位;字符和字符串都以ASICII码形式存在,也可以当

12、成电路内的信号;字符串必须包含在同一行,不能分成多行书写;如果表达式或者赋值语句中将字符串当成操作数,则字符串中的每个字符都被看成8位的ASCII值序列;可综合的信号类型:wire reg memory 它们用来描述数字电路不可综合的数据类型:integer real 它们只用仿真,位于testbench中wire是连线的抽象模型,不能保存数据,其值由驱动元的值决定;wire不能用在always或initial块中;wire的默认值为高阻z;wire的使用情形: 1.作为模块的输出端口 2.用连续赋值语句assign赋值;reg是1位寄存器(触发器)的抽象模型,可以保存数据;reg必须用在al

13、ways或initial块中;reg的默认值为x;reg的使用情形:1.阻塞赋值= 2.非阻塞赋值=memory只能是一维的;memory只能对每个单元分别初始化,方法:1.一个一个赋值 2. 通过系统任务$readmem赋值reg3:0 fc;/一个4位寄存器 reg fc3:0 /4个一位寄存器parameter的作用:仿真开始以前对其进行赋值,整个仿真过程中保持其值不变;关系运算符将以逻辑1或逻辑0返回比较的结果;= !=的返回值有0 1 x三种情况,= !=的返回值只有0 1两种情况;verilog由于是描述电路的,用于位的操作较多,有: 位逻辑操作,移位操作,并置操作,归约操作;位逻

14、辑运算的结果中,位数与原操作数一样多;归约符是在原操作数的所有位上进行操作,并产生1位结果;并置运算可以发生在bit与bit之间 bit与矢量之间 矢量与矢量之间用于仿真的系统任务:所有系统任务都必须在initial或always内;所有系统任务都必须以$开头;常见系统任务:显示任务($diplay系列和$write系列)监控任务($monitor系列)探测任务($strobe系列)文件打开、输入、关闭任务(&fopen &fclose &fdisplay.)读取文件任务($readmemb $readmemh)仿真结束控制任务($finish $stop)随即信号任务($random)过程块

15、: initial块和always块一个module内可以包含多个initial或always模块;所有initial或always块在0时刻开始并行执行,各initial或always块内部顺序执行;initial过程块主要是面向testbench的,通常不具有可综合性;always过程块在描述电路时既可以描述组合逻辑电路(电平敏感)又可以描述时序逻辑电路(边沿敏感);写testbench时initial通常用于初始化以及顺序波形的描述,always通常用于重复波形的描述;任务task与函数function: 为了描述模块中被多次执行的部分以及为了增强代码的易读性verilog中的高级程序语

16、句如for循环语句只用在写testbench中;begin end和fork join是两种特殊的括号if语句的第三种形式适合描述优先编码器,case语句适合描述数据选择器和状态机;case的条件表达式如果与分支项表达式长度不同,则在比较前将所有表达式都统一为这些表达式的最长长度;casez忽略z,casex忽略z和x;assign语句只在右端表达式发生变化时才重新计算并重新赋值,其余时间都是连续赋值;assign语句可以指定bit、vector或是任意拼接操作的结果;assign语句是连续赋值的,用于驱动网线wire, reg类型不需要连续赋值,reg类型一旦被赋值就会一直保存;过程赋值语句

17、有两种:阻塞式=和非阻塞式 45 结果为假(0 )而:52 HERE 用8 位ASCII 值表示的字符可看作是无符号整数。因此字符串是8 位ASCII 值的序列。为存储字符串“INTERNAL ERROR ”,变量需要8 * 1 4 位。r e g 1: 8*14 Message;. . .Message = INTERNAL ERROR7.case如果相应的标记是第一个符合case 表达式的标记case 只会执行这个分支Case 的标记不需要互斥因此当相同的标记被错误地重复使用时Verilog 编译器不会报告出错。练习1: 设计一个字节(8位)比较器。 要求:比较两个字节的大小,如a7:0大

18、于 b7:0输出高电平,否则输出低电平,改写测试模型,使其能进行比较全面的测试 。module compare_8 (a,b,out);parameter WIDTH = 8;inputWIDTH-1:0 a,b;output out;reg out;always (a or b) beginif (ab)out=1;else out=0;endendmodule测试:timescale 1ns/1ns include ./compare_8.v module compare_8test;reg7:0a,b;/这很重要,要是没有这的定义,输入实际就是1比特wire out;initial be

19、gina=8b0;b=8b0;#100 a=8b00000000; b=8b00000001;#100 a=8b00001111; b=8b00000011;#100 a=8b11111111; b=8b11111111;#100 $stop; /系统任务,暂停仿真以便观察仿真波形。endcompare_8 compare_8(.out(out),.a(a),.b(b); /调用模块。Endmodule练习2:六分频module even_6(clk_in,clk_out,rst_n); input clk_in; input rst_n; output clk_out; parameter

20、N=6; reg 3:0 cnt; reg clk_out; always (posedge clk_in or negedge rst_n) beginif(!rst_n) begin cnt=4b0000;clk_out=0;endelse if(cnt=(N/2-1) beginclk_out=clk_out;cnt=4b0000;end else cnt=cnt+1; endendmodule timescale 1ns/100psdefine clk_cycle 50module even_6test;reg clk_in,rst_n;wire clk_out;always #clk

21、_cycle clk_in = clk_in;initialbeginclk_in = 0;rst_n = 1;#100 rst_n = 0;#100 rst_n = 1;#10000 $stop;endeven_6 even_6(.rst_n(rst_n),.clk_in(clk_in),.clk_out(clk_out);endmodule5分频:module div5(clk,clk_out,rst_n);input clk,rst_n;output clk_out;reg 3:0 cnt_p,cnt_n;reg clk_p,clk_n;parameter N=5;always (pos

22、edge clk or negedge rst_n) beginif(!rst_n)cnt_p=4h0;else if(cnt_p=N-1)cnt_p=0;else cnt_p=cnt_p+1;end always (negedge clk or negedge rst_n) beginif(!rst_n) cnt_n=4h0; else if(cnt_n=N-1) cnt_n=0;else cnt_n=cnt_n+1;end always (posedge clk or negedge rst_n) begin if(!rst_n) clk_p=1; else if(cnt_p=(N-1)/

23、2-1) clk_p=clk_p; else if(cnt_p=(N-1) clk_p=clk_p; endalways (negedge clk or negedge rst_n) begin if(!rst_n) clk_n=1; else if(cnt_n=(N-1)/2-1) clk_n=clk_n; else if(cnt_n=(N-1) clk_n=clk_n; end assign clk_out=clk_n|clk_p;endmodule测试代码:timescale 1ns/100psdefine clk_cycle 50module div_oddtest;reg clk,r

24、st_n;wire clk_out;always #clk_cycle clk= clk;initialbeginclk = 0;rst_n = 1;#100 rst_n = 0;#100 rst_n = 1;#10000 $stop;enddiv3 div_odd1(.rst_n(rst_n),.clk(clk),.clk_out(clk_out);endmodule练习3:利用10M的时钟,设计一个单周期形状如下的周期波形module div_500(rst,clk_in,clk_out); input rst,clk_in; output clk_out; reg clk_out; re

25、g 8:0 cnt; /9位计数器计数500个时钟 parameter N=500; always(posedge clk_in) begin if(!rst) begin clk_out=0; cnt=9b0; end else if(cnt2*N/5) begin cnt=cnt+9b1; if(cnt=2*N/5-1) /计数到199后翻转 begin clk_out=clk_out; end end else if(cnt3*N/5) begin cnt=cnt+9b1; if(cnt=3*N/5-1) /计数到299后翻转 begin clk_out=clk_out; end end

26、 else if(cntN-1) cnt=cnt+9b1; else if(cnt=N-1) /计数到499后计数器复位,时钟翻转 begin cnt=9b0; end endendmodule测试代码:timescale 1ns/1nsinclude div_500.vdefine clk_cyc 50module div_500test; reg clk_in,rst; wire clk_out; always #clk_cyc clk_in=clk_in; initial begin clk_in=0; rst=1; #100 rst=0; #100 rst=1; #100000 $st

27、op; end div_500 div_500(.clk_in(clk_in),.rst(rst),.clk_out(clk_out);endmodule练习5:运用always块设计一个八路数据选择器。要求:每路输入数据与输出数据均为4位2进制数,当选择开关(至少3位)或输入数据发生变化时,输出数据也相应地变化。module compare_8(a,b,c,d,e,f,g,h,op,out);input3:0 a,b,c,d,e,f,g,h;input2:0 op;output3:0 out;reg3:0 out;always(op or a or b or c or d or e or f

28、 or g or h)begin case(op) 3b000:out=a; 3b001:out=b; 3b010:out=c; 3b011:out=d; 3b100:out=e; 3b101:out=f; 3b110:out=g; 3b111:out=h; default: out=4bx;endcaseendendmodule测试代码:timescale 1ns/1nsmodule compare_8test; reg3:0 a,b,c,d,e,f,g,h; reg2:0 op; wire3:0 out; parameter times=8; initial begin a=$random

29、%16; b=$random%16; c=$random%16; d=$random%16; e=$random%16; f=$random%16; g=$random%16; h=$random%16; op=3h0; repeat(times) begin #100 a=$random%16; b=$random%16; c=$random%16; d=$random%16; e=$random%16; f=$random%16; g=$random%16; h=$random%16; op=op+1; endendcompare_8 compare_8(.a(a),.b(b),.c(c)

30、,.d(d),.e(e),.f(f),.g(g),.h(h),.op(op),.out(out);endmodule练习6:设计一个带控制端的逻辑运算电路,分别完成正整数的平方、立方和阶乘的运算。编写测试模块,并给出仿真波形。module fun_3(a,rst,clk,opt,result); input2:0 a; input rst,clk; input1:0 opt; output9:0 result; reg9:0 result; parameter squre=2b00; parameter cube=2b01; parameter factorial=2b10; always(p

31、osedge clk) begin if(!rst) result=10b0000000000; else begin case(opt) squre:result=squre1(a); cube:result=cube1(a); factorial:result=factorial1(a); default:result=10bx; endcase end end function 9:0squre1; input2:0a; begin squre1=a*2; /输入a的平方 end endfunction function 9:0cube1; input2:0a; /输入a的立方 begi

32、n cube1=a*3; end endfunction function 9:0factorial1; input2:0 a; reg2:0 i; begin factorial1=a?1:0; for(i=2;i=a;i=i+1) begin factorial1=factorial1*i; end end endfunction endmodule测试代码:timescale 1ns/1nsinclude fun_3.vmodule fun_3test; reg clk,rst; reg 1:0 opt; reg 2:0 a,i; wire 9:0 result; initial begin clk=0; rst=1; #5 rst=0; #100 rst=1; /产生100ns复位信号 for(i=0;i=7;i=i+1) /依次产生07供8个数 begin #100 a=i; opt=$random%3; /随机产生0

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1