verilog编程151例.docx
《verilog编程151例.docx》由会员分享,可在线阅读,更多相关《verilog编程151例.docx(116页珍藏版)》请在冰豆网上搜索。
![verilog编程151例.docx](https://file1.bdocx.com/fileroot1/2023-1/27/f0510d05-4230-44c0-8dbc-5e0b890c9cc3/f0510d05-4230-44c0-8dbc-5e0b890c9cc31.gif)
verilog编程151例
目录
【例3.1】4位全加器5
【例3.2】4位计数器5
【例3.3】4位全加器的仿真程序5
【例3.4】4位计数器的仿真程序6
【例3.5】“与-或-非”门电路6
【例5.1】用case语句描述的4选1数据选择器6
【例5.2】同步置数、同步清零的计数器7
【例5.3】用always过程语句描述的简单算术逻辑单元7
【例5.4】用initial过程语句对测试变量A、B、C赋值8
【例5.5】用begin-end串行块产生信号波形8
【例5.6】用fork-join并行块产生信号波形8
【例5.7】持续赋值方式定义的2选1多路选择器9
【例5.8】阻塞赋值方式定义的2选1多路选择器9
【例5.9】非阻塞赋值9
【例5.10】阻塞赋值9
【例5.11】模为60的BCD码加法计数器10
【例5.12】BCD码—七段数码管显示译码器10
【例5.13】用casez描述的数据选择器11
【例5.14】隐含锁存器举例11
【例5.15】用for语句描述的七人投票表决器11
【例5.16】用for语句实现2个8位数相乘12
【例5.17】用repeat实现8位二进制数的乘法12
【例5.18】同一循环的不同实现方式13
【例5.19】使用了`include语句的16位加法器13
【例5.20】条件编译举例14
【例6.1】加法计数器中的进程14
【例6.2】任务举例14
【例6.3】测试程序15
【例6.4】函数16
【例6.5】用函数和case语句描述的编码器(不含优先顺序)16
【例6.6】阶乘运算函数16
【例6.7】测试程序17
【例6.8】顺序执行模块117
【例6.9】顺序执行模块218
【例6.10】并行执行模块118
【例6.11】并行执行模块218
【例7.1】调用门元件实现的4选1MUX19
【例7.2】用case语句描述的4选1MUX19
【例7.3】行为描述方式实现的4位计数器19
【例7.4】数据流方式描述的4选1MUX19
【例7.5】用条件运算符描述的4选1MUX20
【例7.6】门级结构描述的2选1MUX20
【例7.7】行为描述的2选1MUX20
【例7.8】数据流描述的2选1MUX20
【例7.9】调用门元件实现的1位半加器20
【例7.10】数据流方式描述的1位半加器21
【例7.11】采用行为描述的1位半加器21
【例7.12】采用行为描述的1位半加器21
【例7.13】调用门元件实现的1位全加器21
【例7.14】数据流描述的1位全加器22
【例7.15】1位全加器22
【例7.16】行为描述的1位全加器22
【例7.17】混合描述的1位全加器22
【例7.18】结构描述的4位级连全加器23
【例7.19】数据流描述的4位全加器23
【例7.20】行为描述的4位全加器23
【例8.1】$time与$realtime的区别23
【例8.2】$random函数的使用24
【例8.3】1位全加器进位输出UDP元件24
【例8.4】包含x态输入的1位全加器进位输出UDP元件24
【例8.5】用简缩符“?
”表述的1位全加器进位输出UDP元件25
【例8.6】3选1多路选择器UDP元件25
【例8.7】电平敏感的1位数据锁存器UDP元件26
【例8.8】上升沿触发的D触发器UDP元件26
【例8.9】带异步置1和异步清零的上升沿触发的D触发器UDP元件27
【例8.12】延迟定义块举例27
【例8.13】激励波形的描述27
【例8.15】用always过程块产生两个时钟信号28
【例8.17】存储器在仿真程序中的应用28
【例8.18】8位乘法器的仿真程序28
【例8.19】8位加法器的仿真程序29
【例8.20】2选1多路选择器的仿真30
【例8.21】8位计数器的仿真30
【例9.1】基本门电路的几种描述方法31
【例9.2】用bufif1关键字描述的三态门32
【例9.3】用assign语句描述的三态门32
【例9.4】三态双向驱动器32
【例9.5】三态双向驱动器32
【例9.6】3-8译码器33
【例9.7】8-3优先编码器33
【例9.8】用函数定义的8-3优先编码器33
【例9.9】七段数码管译码器34
【例9.10】奇偶校验位产生器34
【例9.11】用if-else语句描述的4选1MUX35
【例9.12】用case语句描述的4选1MUX35
【例9.13】用组合电路实现的ROM35
【例9.14】基本D触发器36
【例9.15】带异步清0、异步置1的D触发器36
【例9.16】带同步清0、同步置1的D触发器37
【例9.17】带异步清0、异步置1的JK触发器37
【例9.18】电平敏感的1位数据锁存器38
【例9.19】带置位和复位端的1位数据锁存器38
【例9.20】8位数据锁存器38
【例9.21】8位数据寄存器38
【例9.22】8位移位寄存器38
【例9.23】可变模加法/减法计数器39
【例9.24】4位Johnson计数器(异步复位)39
【例9.25】256×8RAM模块39
【例9.26】256×16RAM块40
【例9.27】4位串并转换器40
【例9.28】用函数实现简单的处理器40
【例9.29】微处理器的测试代码41
【例9.30】乘累加器(MAC)代码42
【例9.31】乘累加器的测试代码43
【例10.1】非流水线方式8位全加器43
【例10.2】4级流水方式的8位全加器44
【例10.3】两个加法器和一个选择器的实现方式45
【例10.4】两个选择器和一个加法器的实现方式45
【例10.5】状态机设计的例子45
【例10.6】自动转换量程频率计控制器46
【例10.7】8位全加器48
【例10.8】8位寄存器48
【例10.9】累加器顶层连接文本描述49
【例10.10】用`include描述的累加器49
【例10.11】阻塞赋值方式描述的移位寄存器149
【例10.12】阻塞赋值方式描述的移位寄存器249
【例10.13】阻塞赋值方式描述的移位寄存器350
【例10.14】非阻塞赋值方式描述的移位寄存器50
【例10.15】长帧同步时钟的产生50
【例10.16】引入了D触发器的长帧同步时钟的产生51
【例11.1】数字跑表51
【例11.2】4位数字频率计控制模块53
【例11.3】4位数字频率计计数子模块53
【例11.4】频率计锁存器模块54
【例11.5】交通灯控制器54
【例11.6】“梁祝”乐曲演奏电路56
【例11.7】自动售饮料机59
【例11.8】多功能数字钟60
【例11.9】电话计费器程序64
【例12.1】8位级连加法器67
【例12.2】8位并行加法器67
【例12.3】8位超前进位加法器67
【例12.4】8位并行乘法器68
【例12.5】4×4查找表乘法器69
【例12.6】8位加法树乘法器70
【例12.7】11阶FIR数字滤波器71
【例12.8】16位高速数字相关器72
【例12.9】(7,4)线性分组码编码器73
【例12.10】(7,4)线性分组码译码器74
【例12.11】(7,4)循环码编码器74
【例12.12】(7,4)循环码纠错译码器75
【例12.13】CRC编码76
王金明:
《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