1、Verilog HDL 程序设计教程Verilog HDL 程序设计教程代码例子- 1 -【例 3.1】4 位全加器module adder4(cout,sum,ina,inb,cin);output3:0 sum;output cout;input3:0 ina,inb;input cin;assign cout,sum=ina+inb+cin;endmodule【例 3.2】4 位计数器module count4(out,reset,clk);output3:0 out;input reset,clk;reg3:0 out;always (posedge clk)beginif (rese
2、t) out=0; /同步复位else out=out+1; /计数endendmodule【例 3.3】4 位全加器的仿真程序timescale 1ns/1nsinclude adder4.vmodule adder_tp; /测试模块的名字reg3:0 a,b; /测试输入信号定义为reg 型reg cin;wire3:0 sum; /测试输出信号定义为wire 型wire cout;integer i,j;adder4 adder(sum,cout,a,b,cin); /调用测试对象always #5 cin=cin; /设定cin 的取值initialbegina=0;b=0;cin=
3、0;for(i=1;i16;i=i+1)#10 a=i; /设定a 的取值end程序文本- 2 -initialbeginfor(j=1;j16;j=j+1)#10 b=j; /设定b 的取值endinitial /定义结果显示格式begin$monitor($time,%d + %d + %b=%b,%d,a,b,cin,cout,sum);#160 $finish;endendmodule【例 3.4】4 位计数器的仿真程序timescale 1ns/1nsinclude count4.vmodule coun4_tp;reg clk,reset; /测试输入信号定义为reg 型wire3
4、:0 out; /测试输出信号定义为wire 型parameter DELY=100;count4 mycount(out,reset,clk); /调用测试对象always #(DELY/2) clk = clk; /产生时钟波形initialbegin /激励信号定义clk =0; reset=0;#DELY reset=1;#DELY reset=0;#(DELY*20) $finish;end/定义结果显示格式initial $monitor($time,clk=%d reset=%d out=%d, clk, reset,out);endmodule【例 3.5】“与-或-非”门电路
5、module AOI(A,B,C,D,F); /模块名为AOI(端口列表A,B,C,D,F)input A,B,C,D; /模块的输入端口为A,B,C,Doutput F; /模块的输出端口为F王金明:Verilog HDL 程序设计教程- 3 -wire A,B,C,D,F; /定义信号的数据类型assign F= (A&B)|(C&D); /逻辑功能描述endmodule【例 5.1】用case 语句描述的4 选1 数据选择器module mux4_1(out,in0,in1,in2,in3,sel);output out;input in0,in1,in2,in3;input1:0 se
6、l;reg out;always (in0 or in1 or in2 or in3 or sel) /敏感信号列表case(sel)2b00: out=in0;2b01: out=in1;2b10: out=in2;2b11: out=in3;default: out=2bx;endcaseendmodule【例 5.2】同步置数、同步清零的计数器module count(out,data,load,reset,clk);output7:0 out;input7:0 data;input load,clk,reset;reg7:0 out;always (posedge clk) /clk
7、上升沿触发beginif (!reset) out = 8h00; /同步清0,低电平有效else if (load) out = data; /同步预置else out = out + 1; /计数endendmodule【例 5.3】用always 过程语句描述的简单算术逻辑单元define add 3d0define minus 3d1define band 3d2define bor 3d3define bnot 3d4程序文本- 4 -module alu(out,opcode,a,b);output7:0 out;reg7:0 out;input2:0 opcode; /操作码in
8、put7:0 a,b; /操作数always(opcode or a or b) /电平敏感的always 块begincase(opcode)add: out = a+b; /加操作minus: out = a-b; /减操作band: out = a&b; /求与bor: out = a|b; /求或bnot: out=a; /求反default: out=8hx; /未收到指令时,输出任意态endcaseendendmodule【例 5.4】用initial 过程语句对测试变量A、B、C 赋值timescale 1ns/1nsmodule test;reg A,B,C;initialbe
9、ginA = 0; B = 1; C = 0;#50 A = 1; B = 0;#50 A = 0; C = 1;#50 B = 1;#50 B = 0; C = 0;#50 $finish ;endendmodule【例 5.5】用begin-end 串行块产生信号波形timescale 10ns/1nsmodule wave1;reg wave;parameter cycle=10;initialbegin王金明:Verilog HDL 程序设计教程- 5 -wave=0;#(cycle/2) wave=1;#(cycle/2) wave=0;#(cycle/2) wave=1;#(cyc
10、le/2) wave=0;#(cycle/2) wave=1;#(cycle/2) $finish ;endinitial $monitor($time,wave=%b,wave);endmodule【例 5.6】用fork-join 并行块产生信号波形timescale 10ns/1nsmodule wave2;reg wave;parameter cycle=5;initialforkwave=0;#(cycle) wave=1;#(2*cycle) wave=0;#(3*cycle) wave=1;#(4*cycle) wave=0;#(5*cycle) wave=1;#(6*cycle
11、) $finish;joininitial $monitor($time,wave=%b,wave);endmodule【例 5.7】持续赋值方式定义的2 选1 多路选择器module MUX21_1(out,a,b,sel);input a,b,sel;output out;assign out=(sel=0)?a:b;/持续赋值,如果sel 为0,则out=a ;否则out=bendmodule【例 5.8】阻塞赋值方式定义的2 选1 多路选择器module MUX21_2(out,a,b,sel);input a,b,sel;程序文本- 6 -output out;reg out;alw
12、ays(a or b or sel)beginif(sel=0) out=a; /阻塞赋值else out=b;endendmodule【例 5.9】非阻塞赋值module non_block(c,b,a,clk);output c,b;input clk,a;reg c,b;always (posedge clk)beginb=a;c=b;endendmodule【例 5.10】阻塞赋值module block(c,b,a,clk);output c,b;input clk,a;reg c,b;always (posedge clk)beginb=a;c=b;endendmodule【例 5
13、.11】模为60 的BCD 码加法计数器module count60(qout,cout,data,load,cin,reset,clk);output7:0 qout;output cout;input7:0 data;input load,cin,clk,reset;reg7:0 qout;always (posedge clk) /clk 上升沿时刻计数王金明:Verilog HDL 程序设计教程- 7 -beginif (reset) qout=0; /同步复位else if(load) qout=data; /同步置数else if(cin)beginif(qout3:0=9) /低
14、位是否为9,是则beginqout3:0=0; /回0,并判断高位是否为5if (qout7:4=5) qout7:4=0;elseqout7:4=qout7:4+1; /高位不为5,则加1endelse /低位不为9,则加1qout3:0=qout3:0+1;endendassign cout=(qout=8h59)&cin)?1:0; /产生进位输出信号endmodule【例 5.12】BCD 码七段数码管显示译码器module decode4_7(decodeout,indec);output6:0 decodeout;input3:0 indec;reg6:0 decodeout;al
15、ways (indec)begincase(indec) /用case 语句进行译码4d0:decodeout=7b1111110;4d1:decodeout=7b0110000;4d2:decodeout=7b1101101;4d3:decodeout=7b1111001;4d4:decodeout=7b0110011;4d5:decodeout=7b1011011;4d6:decodeout=7b1011111;4d7:decodeout=7b1110000;4d8:decodeout=7b1111111;4d9:decodeout=7b1111011;default: decodeout
16、=7bx;endcaseend程序文本- 8 -endmodule【例 5.13】用casez 描述的数据选择器module mux_casez(out,a,b,c,d,select);output out;input a,b,c,d;input3:0 select;reg out;always (select or a or b or c or d)begincasez(select)4b?1: out = a;4b?1?: out = b;4b?1?: out = c;4b1?: out = d;endcaseendendmodule【例 5.14】隐含锁存器举例module buried
17、_ff(c,b,a);output c;input b,a;reg c;always (a or b)beginif(b=1)&(a=1) c=a&b;endendmodule【例 5.15】用for 语句描述的七人投票表决器module voter7(pass,vote);output pass;input6:0 vote;reg2:0 sum;integer i;reg pass;always (vote)beginsum=0;王金明:Verilog HDL 程序设计教程- 9 -for(i=0;i=6;i=i+1) /for 语句if(votei) sum=sum+1;if(sum2)
18、pass=1; /若超过4 人赞成,则pass=1else pass=0;endendmodule【例 5.16】用for 语句实现2 个8 位数相乘module mult_for(outcome,a,b);parameter size=8;inputsize:1 a,b; /两个操作数output2*size:1 outcome; /结果reg2*size:1 outcome;integer i;always (a or b)beginoutcome=0;for(i=1; i=size; i=i+1) /for 语句if(bi) outcome=outcome +(a (i-1);enden
19、dmodule【例 5.17】用repeat 实现8 位二进制数的乘法module mult_repeat(outcome,a,b);parameter size=8;inputsize:1 a,b;output2*size:1 outcome;reg2*size:1 temp_a,outcome;regsize:1 temp_b;always (a or b)beginoutcome=0;temp_a=a;temp_b=b;repeat(size) /repeat 语句,size 为循环次数beginif(temp_b1) /如果temp_b 的最低位为1,就执行下面的加法outcome=o
20、utcome+temp_a;temp_a=temp_a1; /操作数b 右移一位endendendmodule【例 5.18】同一循环的不同实现方式module loop1; /方式1integer i;initialfor(i=0;i4;i=i+1) /for 语句begin$display(“i=%h”,i);endendmodulemodule loop2; /方式2integer i;initial begini=0;while(i=0;i=i-1)outi=ai&bi; /按位与endendtaskalways(code or a or b)begincase(code)2b00:
21、my_and(a,b,c);/* 调用任务my_and,需注意端口列表的顺序应与任务定义中的一致,这里的a,b,c分别对应任务定义中的a,b,out */2b01: c=a|b; /或2b10: c=a-b; /相减2b11: c=a+b; /相加endcaseendendmodule王金明:Verilog HDL 程序设计教程- 13 -【例 6.3】测试程序include alutask.vmodule alu_tp;reg3:0 a,b;reg1:0 code;wire4:0 c;parameter DELY = 100;alutask ADD(code,a,b,c); /调用被测试模块
22、initial begincode=4d0; a= 4b0000; b= 4b1111;#DELY code=4d0; a= 4b0111; b= 4b1101;#DELY code=4d1; a= 4b0001; b= 4b0011;#DELY code=4d2; a= 4b1001; b= 4b0011;#DELY code=4d3; a= 4b0011; b= 4b0001;#DELY code=4d3; a= 4b0111; b= 4b1001;#DELY $finish;endinitial $monitor($time,code=%b a=%b b=%b c=%b, code,a,
23、b,c);endmodule【例 6.4】函数function7:0 get0;input7:0 x;reg7:0 count;integer i;begincount=0;for (i=0;i=7;i=i+1)if (xi=1b0) count=count+1;get0=count;endendfunction【例 6.5】用函数和case 语句描述的编码器(不含优先顺序)module code_83(din,dout);input7:0 din;output2:0 dout;程序文本- 14 -function2:0 code; /函数定义input7:0 din; /函数只有输入,输出为
24、函数名本身casex (din)8b1xxx_xxxx : code = 3h7;8b01xx_xxxx : code = 3h6;8b001x_xxxx : code = 3h5;8b0001_xxxx : code = 3h4;8b0000_1xxx : code = 3h3;8b0000_01xx : code = 3h2;8b0000_001x : code = 3h1;8b0000_000x : code = 3h0;default: code = 3hx;endcaseendfunctionassign dout = code(din) ; /函数调用endmodule【例 6.6】阶乘运算函数module funct(clk,n,result,reset);output31:0 result;input
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1