verilog实例代码2word版本Word格式.docx
《verilog实例代码2word版本Word格式.docx》由会员分享,可在线阅读,更多相关《verilog实例代码2word版本Word格式.docx(38页珍藏版)》请在冰豆网上搜索。
outputq;
inputd0,d1,sel;
wiret1,t2,t3;
n1zxhand2(t1,d0,sel);
n2zxhnot2(t4,sel);
n3zxhand2(t2,d1,t4);
n4zxhor2(t3,t1,t2);
assignq=t1;
endmodule
verilogHDL实例
(一)
练习一.简单的组合逻辑设计
目的:
掌握基本组合逻辑电路的实现方法。
这是一个可综合的数据比较器,很容易看出它的功能是比较数据a与数据b,如果两个数据相同,则给出结果1,否则给出结果0。
在VerilogHDL中,描述组合逻辑时常使用assign结构。
注意equal=(a==b)?
1:
0,这是一种在组合逻辑实现分支判断时常使用的格式。
模块源代码:
//---------------compare.v-----------------
modulecompare(equal,a,b);
outputequal;
assignequal=(a==b)?
0;
//a等于b时,equal输出为1;
a不等于b时,
//equal输出为0。
测试模块用于检测模块设计得正确与否,它给出模块的输入信号,观察模块的内部信号和输出信号,如果发现结果与预期的有所偏差,则要对设计模块进行修改。
测试模块源代码:
`timescale1ns/1ns//定义时间单位。
modulecomparetest;
rega,b;
wireequal;
initial//initial常用于仿真时信号的给出。
begina=0;
b=0;
#100a=0;
b=1;
#100a=1;
#100$stop;
//系统任务,暂停仿真以便观察仿真波形。
end
comparecompare1(.equal(equal),.a(a),.b(b));
//调用模块。
Endmodule
【例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);
0]out;
inputreset,clk;
reg[3:
always@(posedgeclk)
begin
if(reset)out<
=0;
//同步复位
elseout<
=out+1;
//计数
end
09.04.07
【例5.11】模为60的BCD码加法计数器
modulecount60(qout,cout,data,load,cin,reset,clk);
output[7:
0]qout;
input[7:
0]data;
inputload,cin,clk,reset;
reg[7:
always@(posedgeclk)//clk上升沿时刻计数
if(reset)qout<
elseif(load)qout<
=data;
//同步置数
elseif(cin)
if(qout[3:
0]==9)//低位是否为9,是则
qout[3:
0]<
//回0,并判断高位是否为5
if(qout[7:
4]==5)qout[7:
4]<
else
qout[7:
=qout[7:
4]+1;
//高位不为5,则加1
else//低位不为9,则加1
=qout[3:
0]+1;
assigncout=((qout==8'
h59)&
cin)?
//产生进位输出信号
【例9.10】奇偶校验位产生器
moduleparity(even_bit,odd_bit,input_bus);
outputeven_bit,odd_bit;
0]input_bus;
assignodd_bit=^input_bus;
//产生奇校验位
assigneven_bit=~odd_bit;
//产生偶校验位
∙VerilogHDL实例
(二)
练习二.简单时序逻辑电路的设计
目的:
掌握基本时序逻辑电路的实现。
在VerilogHDL中,相对于组合逻辑电路,时序逻辑电路也有规定的表述方式。
在可综合的VerilogHDL模型,我们通常使用always块和@(posedgeclk)(上升沿)或@(negedgeclk)(下降沿)的结构来表述时序逻辑。
下面是一个1/2分频器的可综合模型。
//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;
else
clk_out=~clk_out;
在always块中,被赋值的信号都必须定义为reg型,这是由时序逻辑电路的特点所决定的。
对于reg型数据,如果未对它进行赋值,仿真工具会认为它是不定态。
为了能正确地观察到仿真结果,在可综合风格的模块中我们通常定义一个复位信号reset,当reset为低电平时,对电路中的寄存器进行复位。
测试模块的源代码:
//-------------------
clk_Top.v-----------------------------
`timescale1ns/100ps
`defineclk_cycle50
moduleclk_Top.v;
regclk,reset;
wireclk_out;
always
#`clk_cycle
clk=~clk;
initial
clk=0;
reset=1;
#100reset=0;
#100reset=1;
#10000$stop;
half_clkhalf_clk(.reset(reset),.clk_in(clk),.clk_out(clk_out));
∙VerilogHDL实例(三)
练习三.利用条件语句实现较复杂的时序逻辑电路
掌握条件语句在VerilogHDL中的使用。
与常用的高级程序语言一样,为了描述较为复杂的时序关系,VerilogHDL提供了条件语句供分支判断时使用。
在可综合风格的VerilogHDL模型中常用的条件语句有if…else和case…endcase两种结构,用法和C程序语言中类似。
两者相较,if…else用于不很复杂的分支关系,实际编写可综合风格的模块、特别是用状态机构成的模块时,更常用的是case…endcase风格的代码。
这一节我们给的是有关if…else的范例,有关case…endcase结构的代码已后会经常用到。
下面给出的范例也是一个可综合风格的分频器,是将10M的时钟分频为500K的时钟。
基本原理与1/2分频器是一样的,但是需要定义一个计数器,以便准确获得1/20分频
模块源代码:
//---------------fdivision.v-----------------------------
modulefdivision(reset,f10m,f500k);
inputf10m,reset;
outputf500k;
regf500k;
reg[7:
0]j;
always@(posedgef10m)
RESET)//低电平复位。
f500k<
=0;
j<
else
if(j==19)//对计数器进行判断,以确定F500K信号是否反转。
=~f500k;
else
=j+1;
endmodule测试模块源代码:
//---------------
fdivision_Top.v------------------------
moduledivision_Top;
regf10m=0,reset;
wiref500k;
always#`clk_cyclef10m=~f10m;
begin
reset=1;
#100reset=0;
#100reset=1;
#10000$stop;
fdivisionfdivision(.reset(reset),.f10m(f10m),.f500k(f500k));
endmodule
∙VerilogHDL实例(四)
练习四.设计时序逻辑时采用阻塞赋值与非阻塞赋值的区别
1.明确掌握阻塞赋值与非阻塞赋值的概念和区别;
2.了解阻塞赋值的使用情况。
阻塞赋值与非阻塞赋值,在教材中我们已经了解了它们之间在语法上的区别以及综合后所得到的电路结构上的区别。
在always块中,阻塞赋值可以理解为赋值语句是顺序执行的,而非阻塞赋值可以理解为赋值语句是并发执行的。
实际的时序逻辑设计中,一般的情况下非阻塞赋值语句被更多地使用,有时为了在同一周期实现相互关联的操作,也使