Verilog HDL 程序设计教程.docx

上传人:b****5 文档编号:5626922 上传时间:2022-12-29 格式:DOCX 页数:40 大小:24.35KB
下载 相关 举报
Verilog HDL 程序设计教程.docx_第1页
第1页 / 共40页
Verilog HDL 程序设计教程.docx_第2页
第2页 / 共40页
Verilog HDL 程序设计教程.docx_第3页
第3页 / 共40页
Verilog HDL 程序设计教程.docx_第4页
第4页 / 共40页
Verilog HDL 程序设计教程.docx_第5页
第5页 / 共40页
点击查看更多>>
下载资源
资源描述

Verilog HDL 程序设计教程.docx

《Verilog HDL 程序设计教程.docx》由会员分享,可在线阅读,更多相关《Verilog HDL 程序设计教程.docx(40页珍藏版)》请在冰豆网上搜索。

Verilog HDL 程序设计教程.docx

VerilogHDL程序设计教程

《VerilogHDL程序设计教程》代码例子

-1-

【例3.1】4位全加器

moduleadder4(cout,sum,ina,inb,cin);

output[3:

0]sum;

outputcout;

input[3:

0]ina,inb;

inputcin;

assign{cout,sum}=ina+inb+cin;

endmodule

【例3.2】4位计数器

modulecount4(out,reset,clk);

output[3:

0]out;

inputreset,clk;

reg[3:

0]out;

always@(posedgeclk)

begin

if(reset)out<=0;//同步复位

elseout<=out+1;//计数

end

endmodule

【例3.3】4位全加器的仿真程序

`timescale1ns/1ns

`include"adder4.v"

moduleadder_tp;//测试模块的名字

reg[3:

0]a,b;//测试输入信号定义为reg型

regcin;

wire[3:

0]sum;//测试输出信号定义为wire型

wirecout;

integeri,j;

adder4adder(sum,cout,a,b,cin);//调用测试对象

always#5cin=~cin;//设定cin的取值

initial

begin

a=0;b=0;cin=0;

for(i=1;i<16;i=i+1)

#10a=i;//设定a的取值

end

程序文本

-2-

initial

begin

for(j=1;j<16;j=j+1)

#10b=j;//设定b的取值

end

initial//定义结果显示格式

begin

$monitor($time,,,"%d+%d+%b={%b,%d}",a,b,cin,cout,sum);

#160$finish;

end

endmodule

【例3.4】4位计数器的仿真程序

`timescale1ns/1ns

`include"count4.v"

modulecoun4_tp;

regclk,reset;//测试输入信号定义为reg型

wire[3:

0]out;//测试输出信号定义为wire型

parameterDELY=100;

count4mycount(out,reset,clk);//调用测试对象

always#(DELY/2)clk=~clk;//产生时钟波形

initial

begin//激励信号定义

clk=0;reset=0;

#DELYreset=1;

#DELYreset=0;

#(DELY*20)$finish;

end

//定义结果显示格式

initial$monitor($time,,,"clk=%dreset=%dout=%d",clk,reset,out);

endmodule

【例3.5】“与-或-非”门电路

moduleAOI(A,B,C,D,F);//模块名为AOI(端口列表A,B,C,D,F)

inputA,B,C,D;//模块的输入端口为A,B,C,D

outputF;//模块的输出端口为F

王金明:

《VerilogHDL程序设计教程》

-3-

wireA,B,C,D,F;//定义信号的数据类型

assignF=~((A&B)|(C&D));//逻辑功能描述

endmodule

【例5.1】用case语句描述的4选1数据选择器

modulemux4_1(out,in0,in1,in2,in3,sel);

outputout;

inputin0,in1,in2,in3;

input[1:

0]sel;

regout;

always@(in0orin1orin2orin3orsel)//敏感信号列表

case(sel)

2'b00:

out=in0;

2'b01:

out=in1;

2'b10:

out=in2;

2'b11:

out=in3;

default:

out=2'bx;

endcase

endmodule

【例5.2】同步置数、同步清零的计数器

modulecount(out,data,load,reset,clk);

output[7:

0]out;

input[7:

0]data;

inputload,clk,reset;

reg[7:

0]out;

always@(posedgeclk)//clk上升沿触发

begin

if(!

reset)out=8'h00;//同步清0,低电平有效

elseif(load)out=data;//同步预置

elseout=out+1;//计数

end

endmodule

【例5.3】用always过程语句描述的简单算术逻辑单元

`defineadd3'd0

`defineminus3'd1

`defineband3'd2

`definebor3'd3

`definebnot3'd4

程序文本

-4-

modulealu(out,opcode,a,b);

output[7:

0]out;

reg[7:

0]out;

input[2:

0]opcode;//操作码

input[7:

0]a,b;//操作数

always@(opcodeoraorb)//电平敏感的always块

begin

case(opcode)

`add:

out=a+b;//加操作

`minus:

out=a-b;//减操作

`band:

out=a&b;//求与

`bor:

out=a|b;//求或

`bnot:

out=~a;//求反

default:

out=8'hx;//未收到指令时,输出任意态

endcase

end

endmodule

【例5.4】用initial过程语句对测试变量A、B、C赋值

`timescale1ns/1ns

moduletest;

regA,B,C;

initial

begin

A=0;B=1;C=0;

#50A=1;B=0;

#50A=0;C=1;

#50B=1;

#50B=0;C=0;

#50$finish;

end

endmodule

【例5.5】用begin-end串行块产生信号波形

`timescale10ns/1ns

modulewave1;

regwave;

parametercycle=10;

initial

begin

王金明:

《VerilogHDL程序设计教程》

-5-

wave=0;

#(cycle/2)wave=1;

#(cycle/2)wave=0;

#(cycle/2)wave=1;

#(cycle/2)wave=0;

#(cycle/2)wave=1;

#(cycle/2)$finish;

end

initial$monitor($time,,,"wave=%b",wave);

endmodule

【例5.6】用fork-join并行块产生信号波形

`timescale10ns/1ns

modulewave2;

regwave;

parametercycle=5;

initial

fork

wave=0;

#(cycle)wave=1;

#(2*cycle)wave=0;

#(3*cycle)wave=1;

#(4*cycle)wave=0;

#(5*cycle)wave=1;

#(6*cycle)$finish;

join

initial$monitor($time,,,"wave=%b",wave);

endmodule

【例5.7】持续赋值方式定义的2选1多路选择器

moduleMUX21_1(out,a,b,sel);

inputa,b,sel;

outputout;

assignout=(sel==0)?

a:

b;

//持续赋值,如果sel为0,则out=a;否则out=b

endmodule

【例5.8】阻塞赋值方式定义的2选1多路选择器

moduleMUX21_2(out,a,b,sel);

inputa,b,sel;

程序文本

-6-

outputout;

regout;

always@(aorborsel)

begin

if(sel==0)out=a;//阻塞赋值

elseout=b;

end

endmodule

【例5.9】非阻塞赋值

modulenon_block(c,b,a,clk);

outputc,b;

inputclk,a;

regc,b;

always@(posedgeclk)

begin

b<=a;

c<=b;

end

endmodule

【例5.10】阻塞赋值

moduleblock(c,b,a,clk);

outputc,b;

inputclk,a;

regc,b;

always@(posedgeclk)

begin

b=a;

c=b;

end

endmodule

【例5.11】模为60的BCD码加法计数器

modulecount60(qout,cout,data,load,cin,reset,clk);

output[7:

0]qout;

outputcout;

input[7:

0]data;

inputload,cin,clk,reset;

reg[7:

0]qout;

always@(posedgeclk)//clk上升沿时刻计数

王金明:

《VerilogHDL程序设计教程》

-7-

begin

if(reset)qout<=0;//同步复位

elseif(load)qout<=data;//同步置数

elseif(cin)

begin

if(qout[3:

0]==9)//低位是否为9,是则

begin

qout[3:

0]<=0;//回0,并判断高位是否为5

if(qout[7:

4]==5)qout[7:

4]<=0;

else

qout[7:

4]<=qout[7:

4]+1;//高位不为5,则加1

end

else//低位不为9,则加1

qout[3:

0]<=qout[3:

0]+1;

end

end

assigncout=((qout==8'h59)&cin)?

1:

0;//产生进位输出信号

endmodule

【例5.12】BCD码—七段数码管显示译码器

moduledecode4_7(decodeout,indec);

output[6:

0]decodeout;

input[3:

0]indec;

reg[6:

0]decodeout;

always@(indec)

begin

case(indec)//用case语句进行译码

4'd0:

decodeout=7'b1111110;

4'd1:

decodeout=7'b0110000;

4'd2:

decodeout=7'b1101101;

4'd3:

decodeout=7'b1111001;

4'd4:

decodeout=7'b0110011;

4'd5:

decodeout=7'b1011011;

4'd6:

decodeout=7'b1011111;

4'd7:

decodeout=7'b1110000;

4'd8:

decodeout=7'b1111111;

4'd9:

decodeout=7'b1111011;

default:

decodeout=7'bx;

endcase

end

程序文本

-8-

endmodule

【例5.13】用casez描述的数据选择器

modulemux_casez(out,a,b,c,d,select);

outputout;

inputa,b,c,d;

input[3:

0]select;

regout;

always@(selectoraorborcord)

begin

casez(select)

4'b?

?

?

1:

out=a;

4'b?

?

1?

:

out=b;

4'b?

1?

?

:

out=c;

4'b1?

?

?

:

out=d;

endcase

end

endmodule

【例5.14】隐含锁存器举例

moduleburied_ff(c,b,a);

outputc;

inputb,a;

regc;

always@(aorb)

begin

if((b==1)&&(a==1))c=a&b;

end

endmodule

【例5.15】用for语句描述的七人投票表决器

modulevoter7(pass,vote);

outputpass;

input[6:

0]vote;

reg[2:

0]sum;

integeri;

regpass;

always@(vote)

begin

sum=0;

王金明:

《VerilogHDL程序设计教程》

-9-

for(i=0;i<=6;i=i+1)//for语句

if(vote[i])sum=sum+1;

if(sum[2])pass=1;//若超过4人赞成,则pass=1

elsepass=0;

end

endmodule

【例5.16】用for语句实现2个8位数相乘

modulemult_for(outcome,a,b);

parametersize=8;

input[size:

1]a,b;//两个操作数

output[2*size:

1]outcome;//结果

reg[2*size:

1]outcome;

integeri;

always@(aorb)

begin

outcome=0;

for(i=1;i<=size;i=i+1)//for语句

if(b[i])outcome=outcome+(a<<(i-1));

end

endmodule

【例5.17】用repeat实现8位二进制数的乘法

modulemult_repeat(outcome,a,b);

parametersize=8;

input[size:

1]a,b;

output[2*size:

1]outcome;

reg[2*size:

1]temp_a,outcome;

reg[size:

1]temp_b;

always@(aorb)

begin

outcome=0;

temp_a=a;

temp_b=b;

repeat(size)//repeat语句,size为循环次数

begin

if(temp_b[1])//如果temp_b的最低位为1,就执行下面的加法

outcome=outcome+temp_a;

temp_a=temp_a<<1;//操作数a左移一位

程序文本

-10-

temp_b=temp_b>>1;//操作数b右移一位

end

end

endmodule

【例5.18】同一循环的不同实现方式

moduleloop1;//方式1

integeri;

initial

for(i=0;i<4;i=i+1)//for语句

begin

$display(“i=%h”,i);

end

endmodule

moduleloop2;//方式2

integeri;

initialbegin

i=0;

while(i<4)//while语句

begin

$display("i=%h",i);

i=i+1;

end

end

endmodule

moduleloop3;//方式3

integeri;

initialbegin

i=0;

repeat(4)//repeat语句

begin

$display("i=%h",i);

i=i+1;

end

end

endmodule

【例5.19】使用了`include语句的16位加法器

王金明:

《VerilogHDL程序设计教程》

-11-

`include"adder.v"

moduleadder16(cout,sum,a,b,cin);

outputcout;

parametermy_size=16;

output[my_size-1:

0]sum;

input[my_size-1:

0]a,b;

inputcin;

addermy_adder(cout,sum,a,b,cin);//调用adder模块

endmodule

//下面是adder模块代码

moduleadder(cout,sum,a,b,cin);

parametersize=16;

outputcout;

output[size-1:

0]sum;

inputcin;

input[size-1:

0]a,b;

assign{cout,sum}=a+b+cin;

endmodule

【例5.20】条件编译举例

modulecompile(out,A,B);

outputout;

inputA,B;

`ifdefadd//宏名为add

assignout=A+B;

`else

assignout=A-B;

`endif

endmodule

【例6.1】加法计数器中的进程

modulecount(data,clk,reset,load,cout,qout);

outputcout;

output[3:

0]qout;

reg[3:

0]qout;

input[3:

0]data;

inputclk,reset,load;

程序文本

-12-

always@(posedgeclk)//进程1,always过程块

begin

if(!

reset)qout=4'h00;//同步清0,低电平有效

elseif(load)qout=data;//同步预置

elseqout=qout+1;//加法计数

end

assigncout=(qout==4'hf)?

1:

0;//进程2,用持续赋值产生进位信号

endmodule

【例6.2】任务举例

modulealutask(code,a,b,c);

input[1:

0]code;

input[3:

0]a,b;

output[4:

0]c;

reg[4:

0]c;

taskmy_and;//任务定义,注意无端口列表

input[3:

0]a,b;//a,b,out名称的作用域范围为task任务内部

output[4:

0]out;

integeri;

begin

for(i=3;i>=0;i=i-1)

out[i]=a[i]&b[i];//按位与

end

endtask

always@(codeoraorb)

begin

case(code)

2'b00:

my_and(a,b,c);

/*调用任务my_and,需注意端口列表的顺序应与任务定义中的一致,这里的a,b,c

分别对应任务定义中的a,b,out*/

2'b01:

c=a|b;//或

2'b10:

c=a-b;//相减

2'b11:

c=a+b;//相加

endcase

end

endmodule

王金明:

《VerilogHDL程序设计教程》

-13-

【例6.3】测试程序

`include"alutask.v"

modulealu_tp;

reg[3:

0]a,b;

reg[1:

0]code;

wire[4:

0]c;

parameterDELY=100;

alutaskADD(code,a,b,c);//调用被测试模块

initialbegin

code=4'd0;a=4'b0000;b=4'b1111;

#DELYcode=4'd0;a=4'b0111;b=4'b1101;

#DELYcode=4'd1;a=4'b0001;b=4'b0011;

#DELYcode=4'd2;a=4'b1001;b=4'b0011;

#DELYcode=4'd3;a=4'b0011;b=4'b0001;

#DELYcode=4'd3;a=4'b0111;b=4'b1001;

#DELY$finish;

end

initial$monitor($time,,,"code=%ba=%bb=%bc=%b",code,a,b,c);

endmodule

【例6.4】函数

function[7:

0]get0;

input[7:

0]x;

reg[7:

0]count;

integeri;

begin

count=0;

for(i=0;i<=7;i=i+1)

if(x[i]=1'b0)count=count+1;

get0=count;

end

endfunction

【例6.5】用函数和case语句描述的编码器(不含优先顺序)

modulecode_83(din,dout);

input[7:

0]din;

output[2:

0]dout;

程序文本

-14-

function[2:

0]code;//函数定义

input[7:

0]din;//函数只有输入,输出为函数名本身

casex(din)

8'b1xxx_xxxx:

code=3'h7;

8'b01xx_xxxx:

code=3'h6;

8'b001x_xxxx:

code=3'h5;

8'b0001_xxxx:

code=3'h4;

8'b0000_1xxx:

code=3'h3;

8'b0000_01xx:

code=3'h2;

8'b0000_001x:

code=3'h1;

8'b0000_000x:

code=3'h0;

default:

code=3'hx;

endcase

endfunction

assigndout=code(din);//函数调用

endmodule

【例6.6】阶乘运算函数

modulefunct(clk,n,result,reset);

output[31:

0]result;

input[

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

当前位置:首页 > 解决方案 > 营销活动策划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1