Verilog HDL编程举例.docx
《Verilog HDL编程举例.docx》由会员分享,可在线阅读,更多相关《Verilog HDL编程举例.docx(25页珍藏版)》请在冰豆网上搜索。
![Verilog HDL编程举例.docx](https://file1.bdocx.com/fileroot1/2022-11/20/e0935309-6571-48bc-8cf6-f6e562eae9b2/e0935309-6571-48bc-8cf6-f6e562eae9b21.gif)
VerilogHDL编程举例
设计示范和上机习题
练习一.简单的组合逻辑设计
//(方法一):
//---------------文件名compare.v-----------------
modulecompare(equal,a,b);
inputa,b;
outputequal;
assignequal=(a==b)?
1:
0;
//a等于b时,equal输出为1;a不等于b时,equal输出为0。
endmodule
//(方法二):
modulecompare(equal,a,b);
inputa,b;
outputequal;
regequal;
always@(aorb)
if(a==b)//a等于b时,equal输出为1;
equal=1;
else//a不等于b时,equal输出为0。
equal=0;//思考:
如果不写else部分会产生什么逻辑?
endmodule
//-------------------------------------------------------------
//----------测试模块源代码(方法之一):
`timescale1ns/1ns//定义时间单位。
`include"./compare.v"//包含模块文件。
在有的仿真调试环境中并不需要此语句。
//而需要从调试环境的菜单中键入有关模块文件的路径和名称
modulet;
rega,b;
wireequal;
initial//initial常用于仿真时信号的给出。
begin
a=0;
b=0;
#100a=0;b=1;
#100a=1;b=1;
#100a=1;b=0;
#100a=0;b=0;
#100$stop;//系统任务,暂停仿真以便观察仿真波形。
end
comparem(.equal(equal),.a(a),.b(b));//调用被测试模块t.m
endmodule
//----------测试模块源代码(方法之二):
-------------------------
`timescale1ns/1ns//定义时间单位。
`include"./compare.v"//包含模块文件。
在有的仿真调试环境中并不需要此语句。
//而需要从调试环境的菜单中键入有关模块文件的路径和名称
modulet;
rega,b;
regclock;
wireequal;
initial//initial常用于仿真时信号的给出。
begin
a=0;
b=0;
clock=0;//定义一个时钟变量
end
always#50clock=~clock;//产生周期性的时钟
always@(posedgeclock)//在每次时钟正跳变沿时刻产生不同的a和b
begin
a={$random}%2;//每次a是0还是1是随机的。
b={$random}%2;//每次b是0还是1是随机的。
end
initial
begin#100000$stop;end//系统任务,暂停仿真以便观察仿真波形。
comparem(.equal(equal),.a(a),.b(b));//调用被测试模块t.m
endmodule
练习二.简单分频时序逻辑电路的设计
//-------------------------文件名:
half_clk.v--------------------------------
modulehalf_clk(reset,clk_in,clk_out);
inputclk_in,reset;
outputclk_out;
regclk_out;
always@(posedgeclk_in)
begin
if(!
reset)clk_out=0;
elseclk_out=~clk_out;
end
endmodule
//----------测试模块的源代码:
------------------------
//-------------------文件名top.v-----------------------------
`timescale1ns/100ps
`defineclk_cycle50
moduletop;
regclk,reset;
wireclk_out;
always#`clk_cycleclk=~clk;//产生测试时钟
initial
begin
clk=0;
reset=1;
#10reset=0;
#110reset=1;
#100000$stop;
end
half_clkm0(.reset(reset),.clk_in(clk),.clk_out(clk_out));
endmodule
练习三.利用条件语句实现计数分频时序电路
//--------------模块源代码:
-----------------------------
//---------------fdivision.v-----------------------------
modulefdivision(RESET,F10M,F500K);
inputF10M,RESET;
outputF500K;
regF500K;
reg[7:
0]j;
always@(posedgeF10M)
if(!
RESET)//低电平复位。
begin
F500K<=0;
j<=0;
end
else
begin
if(j==19)//对计数器进行判断,以确定F500K信号是否反转。
begin
j<=0;
F500K<=~F500K;
end
else
j<=j+1;
end
endmodule
//-------------测试模块源代码:
-------------------------
//---------------fdivision_Top.v------------------------
`timescale1ns/100ps
`defineclk_cycle50
moduledivision_Top;
regF10M,RESET;
wireF500K_clk;
always#`clk_cycleF10M=~F10M;
initial
begin
RESET=1;
F10M=0;
#100RESET=0;
#100RESET=1;
#10000$stop;
end
fdivisionfdivision(.RESET(RESET),.F10M(F10M),.F500K(F500K_clk));
endmodule
练习四.阻塞赋值与非阻塞赋值的区别
//----------模块源代码:
----------------------
//-------------blocking.v---------------
moduleblocking(clk,a,b,c);
output[3:
0]b,c;
input[3:
0]a;
inputclk;
reg[3:
0]b,c;
always@(posedgeclk)
begin
b=a;
c=b;
$display("Blocking:
a=%d,b=%d,c=%d",a,b,c);
end
endmodule
//-------------non_blocking.v-------------------
modulenon_blocking(clk,a,b,c);
output[3:
0]b,c;
input[3:
0]a;
inputclk;
reg[3:
0]b,c;
always@(posedgeclk)
begin
b<=a;
c<=b;
$display("Non_Blocking:
a=%d,b=%d,c=%d",a,b,c);
end
endmodule
//----------测试模块源代码:
--------------------------
//-------------compareTop.v-----------------------------
`timescale1ns/100ps
`include"./blocking.v"
`include"./non_blocking.v"
modulecompareTop;
wire[3:
0]b1,c1,b2,c2;
reg[3:
0]a;
regclk;
initial
begin
clk=0;
forever#50clk=~clk;//思考:
如果在本句后还有语句,能否执行?
为什么?
end
initial
begin
a=4'h3;
$display("____________________________");
#100a=4'h7;
$display("____________________________");
#100a=4'hf;
$display("____________________________");
#100a=4'ha;
$display("____________________________");
#100a=4'h2;
$display("____________________________");
#100$display("____________________________");
$stop;
end
non_blockingnon_blocking(clk,a,b2,c2);
blockingblocking(clk,a,b1,c1);
endmodule
练习五.用always块实现较复杂的组合逻辑电路
//---------------文件名alu.v--------------------------
`defineplus3'd0`defineminus3'd1`defineband3'd2
`definebor3'd3
`defineunegate3'd4
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)
`plus:
out=a+b;//加操作。
`minus:
out=a-b;//减操作。