Verilog HDL举例1.docx

上传人:b****5 文档编号:7446214 上传时间:2023-01-24 格式:DOCX 页数:18 大小:50.97KB
下载 相关 举报
Verilog HDL举例1.docx_第1页
第1页 / 共18页
Verilog HDL举例1.docx_第2页
第2页 / 共18页
Verilog HDL举例1.docx_第3页
第3页 / 共18页
Verilog HDL举例1.docx_第4页
第4页 / 共18页
Verilog HDL举例1.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

Verilog HDL举例1.docx

《Verilog HDL举例1.docx》由会员分享,可在线阅读,更多相关《Verilog HDL举例1.docx(18页珍藏版)》请在冰豆网上搜索。

Verilog HDL举例1.docx

VerilogHDL举例1

组合逻辑设计

数据比较器

//---------------compare.v-----------------

modulecompare(equal,a,b);

inputa,b;

outputequal;

assignequal=(a==b)?

1:

0;//a等于b时,equal输出为1;a不等于b时,

//equal输出为0。

endmodule

测试模块源代码:

`timescale1ns/1ns//定义时间单位。

`include"./compare.v"//包含模块文件。

在有的仿真调试环境中并不需要此语句。

//而需要从调试环境的菜单中键入有关模块文件的路径和名称

modulecomparetest;

rega,b;

wireequal;

initial//initial常用于仿真时信号的给出。

begin

a=0;

b=0;

#100a=0;b=1;

#100a=1;b=1;

#100a=1;b=0;

#100$stop;//系统任务,暂停仿真以便观察仿真波形。

end

comparecompare1(.equal(equal),.a(a),.b(b));//调用模块。

endmodule

仿真波形(部分):

时序逻辑设计

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;

elseclk_out=~clk_out;

end

endmodule

 

测试模块的源代码:

//-------------------clk_Top.v-----------------------------

`timescale1ns/100ps

`defineclk_cycle50

moduleclk_Top.v

regclk_in,reset;

wireclk_out;

always#`clk_cycleclk_in=~clk_in;

initial

begin

clk_in=0;

reset=1;

#100reset=0;

#100reset=1;

#10000$stop;

end

half_clkhalf_clk(.reset(reset),.clk_in(clk_in),.clk_out(clk_out));

endmodule

仿真波形:

 

利用条件语句实现较复杂的时序逻辑电路

 

分频器将20M的时钟分频为500K的时钟。

基本原理与1/2分频器是一样的,但是需要定义一个计数器,以便准确获得1/40分频

模块源代码:

//---------------fdivision.v-----------------------------

modulefdivision(RESET,F20M,F500K);

inputF20M,RESET;

outputF500K;

regF500K;

reg[7:

0]j;

always@(posedgeF20M)

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;

regF20M_clk,RESET;

wireF500K_clk;

always#`clk_cycleF20M_clk=~F20M_clk;

initial

begin

RESET=1;

F20M_clk=0;

#100RESET=0;

#100RESET=1;

#10000$stop;

end

fdivisionfdivision(.RESET(RESET),.F20M(F20M_clk),.F500K(F500K_clk));

endmodule

仿真波形:

设计时序逻辑时采用阻塞赋值与非阻塞赋值的区别

 

通过分别采用阻塞赋值语句和非阻塞赋值语句的两个看上去非常相似的两个模块blocking.v和non_blocking.v来阐明两者之间的区别。

模块源代码:

//-------------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

 

仿真波形(部分):

 

用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

同步置数,同步清零的计数器

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

output[7:

0]out;

input[7:

0]data;

inputload,clk,reset;

reg[7:

0]out;

always@(posedgeclk)

begin

if(!

reset)out=8'h00;

elseif(load)out=data;

elseout=out+1;

end

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;//减操作。

`band:

out=a&b;//求与。

`bor:

out=a|b;//求或。

`unegate:

out=~a;//求反。

default:

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

endcase

end

endmodule

如果不使用default或else对缺省项进行说明,则易生成意想不到的锁存器,这一点一定要加以注意。

指令译码器的测试模块源代码:

//-------------alu_Top.v-----------------

`timescale1ns/1ns

`include"./alu.v"

modulealutest;

wire[7:

0]out;

reg[7:

0]a,b;

reg[2:

0]opcode;

parametertimes=5;

initial

begin

a={$random}%256;//Givearadomnumberblongsto[0,255].

b={$random}%256;//Givearadomnumberblongsto[0,255].

opcode=3'h0;

repeat(times)

begin

#100a={$random}%256;//Givearadomnumber.

b={$random}%256;//Givearadomnumber.

opcode=opcode+1;

end

#100$stop;

end

alualu1(out,opcode,a,b);

endmodule

仿真波形(部分):

用begin-end串行块产生信号波形

`timescale10ns/1ns

modulewave1;

regwave;

parametercycle=10;

initial

begin

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

endmodule

用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

endmodule

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

moduleMUX21_1(out,a,b,sel);

inputa,b,sel;

outputout;

assignout=(sel==0)?

a:

b;

endmodule

2选1多路选择器(else部分写全)

moduleMUX21_2(out,a,b,sel);

inputa,b,sel;

outputout;

regout;

always@(aorborsel)

begin

if(sel==0)out=a;

elseout=b;

end

endmodule

隐含的锁存器

moduleburied_ff(c,b,a);

outputc;

inputb,a;

regc;

always@(aorb)

begin

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

end

endmodule

模为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)

begin

if(reset)qout<=0;

elseif(load)qout<=data;

elseif(cin)

begin

if(qout[3:

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

begin

qout[3:

0]<=0;//回0

if(qout[7:

4]==5)qout[7:

4]<=0;//判断高位是否为5

elseqout[7:

4]<=qout[7:

4]+1;

end

else

qout[3:

0]<=qout[3:

0]+1;

end

end

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

1:

0;

endmodule

BCD码—七段数码管显示译码器

moduledecode4_7(decodeout,indec);

output[6:

0]decodeout;

input[3:

0]indec;

reg[6:

0]decodeout;

always@(indec)

begin

case(indec)

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

endmodule

用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?

?

10:

out=b;

4'b?

100:

out=c;

4'b1000:

out=d;

endcase

end

endmodule

用for语句描述的七人投票表决器

modulevoter7(pass,vote);

outputpass;

input[6:

0]vote;

reg[2:

0]sum;

integeri;

regpass;

always@(vote)

begin

sum=0;

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

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

if(sum[2])pass=1;//至少4人

elsepass=0;

end

endmodule

用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)

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

end

endmodule

用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)

begin

if(temp_b[1])//最低位为1,执行加法

outcome=outcome+temp_a;

temp_a=temp_a<<1;//a左移1位

temp_b=temp_b>>1;//b右移1位

end

end

endmodule

同一循环的不同实现方式

moduleloop1;

integeri;

initial

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

begin

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

end

endmodule

moduleloop2;

integeri;

initialbegin

i=0;

while(i<4)

begin

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

i=i+1;

end

end

endmodule

moduleloop3;

integeri;

initialbegin

i=0;

repeat(4)

begin

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

i=i+1;

end

end

endmodule

输出i=?

使用了`include语句的16位加法器(相对路径、绝对路径)

`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);

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

条件编译举例

modulecompile(out,A,B);

outputout;

inputA,B;

`ifdefadd

assignout=A+B;

`else

assignout=A-B;

`endif

endmodule

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

当前位置:首页 > 高等教育 > 理学

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

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