Verilog实验报告.docx

上传人:b****5 文档编号:11874016 上传时间:2023-04-08 格式:DOCX 页数:31 大小:492.48KB
下载 相关 举报
Verilog实验报告.docx_第1页
第1页 / 共31页
Verilog实验报告.docx_第2页
第2页 / 共31页
Verilog实验报告.docx_第3页
第3页 / 共31页
Verilog实验报告.docx_第4页
第4页 / 共31页
Verilog实验报告.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

Verilog实验报告.docx

《Verilog实验报告.docx》由会员分享,可在线阅读,更多相关《Verilog实验报告.docx(31页珍藏版)》请在冰豆网上搜索。

Verilog实验报告.docx

Verilog实验报告

 

2014-2015-2-G02A3050-1

电子电路设计训练(数字EDA部分)

 

实验报告

(2015年5月20日)

教学班

学号

组长

签名

成绩

 

自动化科学与电气工程学院

实验一、简单组合逻辑和简单时序逻辑

1.1实验任务1——简单组合逻辑

1.1.1实验要求

(1)设计一个两位数据比较器,比较两个数据a和b。

若两数据相同,则给出结果1,否则给出结果0。

(2)设计一个字节(8位)的比较器,比较两个字节a[7:

0]和b[7:

0]的大小。

若a大于b,则输出高电平,否则输出低电平。

1.1.2模块的核心逻辑设计

(1)两位数据比较器

assignequal=(a==b)?

1:

0;//用连续赋值语句assign对结果equal赋值,a=b时,equal输出为1,否则为0

(2)字节数据比较器

assignres=(a>b)?

1:

0;//用连续语句assign对结果equal赋值,a>b时equal输出为1,否则输出为0

1.1.3测试程序的核心逻辑设计

(1)两位数据比较器

always#50clock=~clock;//产生周期性跳变的时钟,50个时间单位跳变一次

always(negedgeclock)//always后的语句表示时序控制,每次时钟下降沿时刻产生不同的a和b

begin

a={$random}%2;

b={$random}%2;//每次随机产生a和b

end

initial

begin#100000000$stop;end//系统任务,暂停仿真以观察波形

(2)字节数据比较器

a={$random}%256;

b={$random}%256;//a和b从0~255共256个数中随机产生,即可生成8位字节数据

1.1.4仿真实验关键结果及其解释

(1)两位数据比较器

图1两位数据比较器波形图

如图1所示,a和b相同时equal输出为高电平,否则输出低电平。

(2)字节数据比较器

图2字节数据比较器波形图

如图2所示,a>b时,res输出高电平,否则res输出低电平。

1.2实验任务2——简单时序逻辑

1.2.1实验要求

设计一个分频器,将时钟波形二分频。

1.2.2模块的核心逻辑设计

always(posedgeclk_in)//always语句后表示时序控制,每次clk_in时钟上升沿时刻进行动作

begin

if(!

reset)clk_out=0;//reset信号为低电平时,输出清零

elseclk_out=~clk_out;//reset为高电平时,输出时钟clk_out在输入时钟clk_in的上升沿时刻翻转

end

1.2.3测试程序的核心逻辑设计

always#`clk_cycleclk=~clk;//产生输入时钟

initial

begin

clk=0;

reset=1;

#10reset=0;//reset给低电平,输出清零

#110reset=1;//reset复位

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

end

1.2.4仿真实验关键结果及其解释

图3二分频器的波形图

如图3所示,输入时钟clk被二分频输出。

1.3实验小结

通过实验一,我掌握了如下容:

1)assign连续赋值语句的使用。

2)always,initial块的使用。

3)reg,wire等数据类型的适用围

4)调用被测试模块的方法

 

实验二、条件语句和always过程块

2.1实验任务1——利用条件语句实现计数分频时序电路

2.1.1实验要求

(1)设计20分频计数器,将10MHz的时钟分频为500kHz的时钟。

(2)利用10MHz的时钟,设计一个给定单周期形状的周期波形。

2.1.2模块的核心逻辑设计

(1)20分频计数器

begin

if(j==9)//对计数器进行判断,计十个数翻转一次,则一个周期计20个数,即实现20分频

begin

j<=0;//输出时钟翻转的同时计数器置零

F500K<=~F500K;

end

else

j<=j+1;//若还没计到十个数,继续计数

end

(2)给定单周期形状的波形

begin

if(j<=20)

begin

FDIV<=0;

j<=j+1;//前20个输入时钟周期,计数器计数,但输出不跳变

end

elseif((j>20)&&(j<=30))

begin

FDIV<=1;

j<=j+1;//中间10个时钟周期输出跳变成高电平,保持计数

end

elseif((j>30)&&(j<=50))

begin

FDIV<=0;

j<=j+1;//后20个时钟周期输出跳变成低电平,保持计数

end

else

j<=0;//计数器清零

end

2.1.3测试程序的核心逻辑设计

(1)20分频计数器

always#`clk_cycleF10M_clk=~F10M_clk;//产生输入的10MHz时钟

initial

begin

RESET=1;

F10M_clk=0;

#100RESET=0;//reset给低电平,输出清零

#100RESET=1;//reset复位

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

end

(2)给定单周期形状的波形

begin

RESET=1;

F10M_clk=0;

#100RESET=0;

#100RESET=1;

#100000$stop;

end//与

(1)一致

2.1.4仿真实验关键结果及其解释

(1)20分频计数器

图420分频计数器波形图

如图4所示,10MHz的时钟F10M被20分频成500kHz的时钟F500k。

(2)给定单周期形状的波形

图5给定单周期形状的波形图

如图5所示,生成了题目要求形状的周期波形图。

2.2实验任务2——用always块实现较复杂的组合逻辑电路

2.2.1实验要求

(1)设计一个指令译码电路,对输入数据执行相应的操作,包括加、减、与、或和求反。

(2)运用always块设计一个8路数据选择器。

要求:

每路输入数据与输出数据均为4位2进制数,当选择开关(至少3位)或输入数据发生变化时,输出数据也相应变化。

2.2.2模块的核心逻辑设计

(1)指令译码电路

always(opcodeoraorb)//电平敏感的always块,当输入数据a,b或控制信号opcode变化时,输出发生变化

begin

case(opcode)

`plus:

out=a+b;//控制信号为'plus时,输出等于a+b

`minus:

out=a-b;//控制信号为'minus时,输出等于a-b

`band:

out=a&b;//控制信号为'band时,输出等于a&b

`bor:

out=a|b;//控制信号为'bor时,输出等于a|b

`unegate:

out=~a;//控制信号为'unegate时,输出等于~a

default:

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

endcase

(2)8路数据选择器

always(ctlora0ora1ora2ora3ora4ora5ora6ora7)//电平敏感模块,控制信号ctl或输入a0~a7变化时,输出发生变化

begin

case(ctl)

`ctl0:

out=a0;

`ctl1:

out=a1;

`ctl2:

out=a2;

`ctl3:

out=a3;

`ctl4:

out=a4;

`ctl5:

out=a5;

`ctl6:

out=a6;

`ctl7:

out=a7;//控制端为ctl0~ctl7对应输出a0~a7

default:

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

endcase

2.2.3测试程序的核心逻辑设计

(1)指令译码电路

begin

a={$random}%256;//从0~255共256个数中随机生成一个数作为输入a

b={$random}%256;//从0~255共256个数中随机生成一个数作为输入b

opcode=3'h0;//控制信号设为初值0,即'plus,求和

repeat(times)//repeat循环语句使控制及输入信号重复变化

begin

#100a={$random}%256;

b={$random}%256;

opcode=opcode+1;//每一时钟到来时,输入a,b改变一随机数,控制信号+1

end

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

end

(2)8路数据选择器

begin

a0={$random}%16;

a1={$random}%16;

a2={$random}%16;

a3={$random}%16;

a4={$random}%16;

a5={$random}%16;

a6={$random}%16;

a7={$random}%16;//从0~15中随机生成输入a0~a7

ctl=3'd0;//控制端置ctl0

repeat(times)//repeat语句重复改变输入

begin

#100a0={$random}%16;

a1={$random}%16;

a2={$random}%16;

a3={$random}%16;

a4={$random}%16;

a5={$random}%16;

a6={$random}%16;

a7={$random}%16;//随机生成a0~a7

ctl=ctl+1;//控制端每次加1

end

#100$stop;

end

2.2.4仿真实验关键结果及其解释

(1)指令译码电路

图6指令译码电路波形

指令译码电路输出波形如图所示。

控制信号opcode为0时,输出为a+b;控制信号opcode为1时,输出为a-b;......以此类推。

(2)8路数据选择器

图78选1数据选择器波形图

8路数据选择器输出波形如图7所示,控制端ctl为0~7时对应输出a0~a7。

2.3实验小结

通过实验二,我掌握了如下容:

1)if...else条件语句的使用。

2)case条件语句的使用

实验三、赋值、函数和任务

3.1实验任务1——阻塞赋值与非阻塞赋值的区别

3.1.1实验要求

本实验中两个模块"blocking"和"non_blocking"分别采用阻塞赋值和非阻塞赋值语句,从实验结果比较他们的区别。

3.1.2模块的核心逻辑设计

(1)阻塞赋值

always(posedgeclk)

begin

b=a;

c=b;//阻塞赋值,a赋给b,b赋给c

$display("Blocking:

a=%d,b=%d,c=%d.",a,b,c);//在Transcript窗口中显示赋值后a,b,c的值

end

(2)非阻塞赋值

always(posedgeclk)

begin

b<=a;

c<=b;//非阻塞赋值,a赋给b,b赋给c

$display("Non_Blocking:

a=%d,b=%d,c=%d.",a,b,c);//在Transcript窗口中显示赋值后a,b,c的值

end

(3)改变阻塞赋值程序的写法,再比较二者的区别(测试程序仅改变调用的阻塞赋值模块)

always(posedgeclk)

begin

c=b;

b=a;//改变阻塞赋值的顺序,b赋给c,a赋给b

$display("Blocking:

a=%d,b=%d,c=%d.",a,b,c);

end

(3)再改变阻塞赋值程序的写法,比较二者的区别(测试程序仅改变调用的阻塞赋值模块)

always(posedgeclk)b=a;

always(posedgeclk)c=b;

3.1.3测试程序的核心逻辑设计

将阻塞与非阻塞赋值模块用同一测试程序测试,比较其输出的不同。

begin

a=4'h3;

$display("____________");

#100a=4'h7;

$display("____________");

#100a=4'hf;

$display("____________");

#100a=4'ha;

$display("____________");

#100a=4'h2;

$display("____________");

#100$display("___________");//每隔100个时间单位改变一次输入a的值,并显示输出

$stop;

end

blockingblocking(clk,a,b1,c1);//阻塞赋值输出用b1,c1表示

non_blockingnon_blocking(clk,a,b2,c2);//非阻塞赋值输出用b2,c2表示

3.1.4仿真实验关键结果及其解释

(1)阻塞赋值写法1

图8阻塞与非阻塞赋值比较波形图

图9阻塞与非阻塞赋值输出结果

如图8所示,b1,c1为阻塞赋值输出,输入a的值改变时,输出b的值随之改变,同时b的值赋给c,即赋值语句执行完后输出b,c值立即改变,然后块才结束。

b2,c2为非阻塞赋值输出,赋值语句之后输出b,c的值并不立即改变,而是在块结束后才进行赋值操作,当下一时钟上升沿到来时,上一个a值才赋给b,同时上一b值赋给c。

以上即阻塞与非阻塞赋值的区别。

a和b的输出结果如图9所示。

(2)阻塞赋值写法2

图10阻塞赋值程序变形1波形图

图11阻塞赋值程序变形1输出结果

改变阻塞赋值程序后的波形图如图10所示,可见将b=a,c=b的顺序调换之后,阻塞赋值程序先将上一次时钟上升沿时b的值赋给c,再将这一次时钟上升沿时a的值赋给b,即b与a同时变化但c的值是上一个b值。

在波形图上看,由于输入a的变化时刻对应的是时钟下降沿,而输出要在下一时钟上升沿才能显示,故阻塞与非阻塞输出c在波形图上看是一致的,实际上在时钟下降沿a发生变化时,阻塞输出c的值已经发生变化。

输出结果如图11

(3)阻塞赋值写法3

图12阻塞赋值程序变形2波形图

图13阻塞赋值程序变形2输出结果

阻塞赋值程序变形2的输出波形与结果如图12、图13所示。

由于两个阻塞操作用同一个时钟沿触发,执行顺序是不确定的。

3.2实验任务2——在VerilogHDL中使用函数

3.2.1实验要求

(1)设计程序实现函数调用

(2)设计一个带控制端的逻辑运算电路,分别完成正整数的平方、立方和最大数为5的阶乘运算。

3.2.2模块的核心逻辑设计

(1)设计程序实现函数调用

always(posedgeclk)//clk上升沿触发同步运算

begin

if(!

reset)

result<=0;//reset为低时复位

else

begin

result<=n*factorial(n)/((n*2)+1);//调用factorial函数,verilog在整数除法运算结果中不考虑余数

end

end

function[31:

0]factorial;//函数定义,返回一个32位的数

input[3:

0]operand;//输入一个4位操作数

reg[3:

0]index;//函数部计数用中间变量

begin

factorial=operand?

1:

0;//操作数为0时函数输出为0,否则为1

for(index=2;index<=operand;index=index+1)

factorial=index*factorial;//表示阶乘的迭代运算

end

endfunction

(2)带控制端的逻辑运算电路

always(posedgeclk)

begin

if(!

reset)

result<=0;

else

begin

if(sel==0)result<=n*n;//控制端输入sel=0时,执行平方操作

elseif(sel==1)result<=n*n*n;//控制端输入sel=1时,执行立方操作

elseif(sel==2&&n<=5)result<=factorial(n);//控制端输入sel=2且输入n小于等于5时,计算n!

elseresult<=factorial(5);//否则计算5!

end

end

function[31:

0]factorial;//函数定义,返回一个32位的数

input[3:

0]operand;//输入一个4位操作数

reg[3:

0]index;//函数部计数用中间变量

begin

factorial=operand?

1:

0;//操作数为0时函数输出为0,否则为1

for(index=2;index<=operand;index=index+1)

factorial=index*factorial;//表示阶乘的迭代运算

end

3.2.3测试程序的核心逻辑设计

(1)设计程序实现函数调用

initial

begin

clk=0;

n=0;

reset=1;

#100reset=0;//产生复位信号的负跳变沿

#100reset=1;//复位信号恢复高电平后输入n

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

begin

#200n=i;//用循环结构,每隔200个时钟周期改变一次输入n的值

end

#100$stop;

end

(2)带控制端的逻辑运算电路

begin

clk=0;

n=0;

reset=1;

#100reset=0;//产生复位信号的负跳变沿

#100reset=1;//复位信号恢复高电平后输入n

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

begin

#200sel={$random}%3;

n={$random}%16;//用循环结构,每隔200个时钟周期改变一次控制端sel和输入n的值,n从0~15中随机生成

end

#100$stop;

end

3.2.4仿真实验关键结果及其解释

(1)设计程序实现函数调用

图14函数调用输出结果波形图

调用函数实现的运算输出结果波形如图14所示。

通过调用函数实现了

的结果输出。

(由于输入n,i为4位二进制数,计算机默认为补码形式,若以十进制显示,9~15将显示负值,为避免混乱,输入用二进制显示)。

(2)带控制端的逻辑运算电路

图15带控制端的逻辑运算电路输出结果波形图

逻辑运算电路输出结果波形如图15所示。

从图中可见,输入n=4,控制端sel=2,输出result=4!

=24;输入n=11,控制端sel=1,输出

;输入n=13,控制端sel=2,输出result=5!

=120;输入n=4,控制端sel=0,输出

3.3实验任务3——在VerilogHDL中使用任务

3.3.1实验要求

使用任务设计4个4位并行输入数的排序组合逻辑。

3.3.2模块的核心逻辑设计

always(aorborcord)

begin

{va,vb,vc,vd}={a,b,c,d};

rank2(va,vb);

rank2(va,vc);

rank2(va,vd);

rank2(vb,vc);

rank2(vb,vd);

rank2(vc,vd);

{ra,rb,rc,rd}={va,vb,vc,vd};//用选择排序法排序

end

taskrank2;//执行排序算法的任务

inout[3:

0]x,y;

reg[3:

0]tmp;

if(x>y)

begin

tmp=x;

x=y;

y=tmp;//x与y变量容互换,要求顺序执行,采用阻塞赋值方式

end

endtask

(实验指导书上采用快速排序算法,我对快速排序不熟悉,故采用选择排序算法)

3.2.3测试程序的核心逻辑设计

begin

a=0;b=0;c=0;d=0;

repeat(50)

begin

#100a={$random}%15;

b={$random}%15;

c={$random}%15;

d={$random}%15;//随机生成参与排序的数a,b,c,d

end

3.2.4仿真实验关键结果及其解释

图16使用任务进行排序输出波形

使用任务进行排序得到的输出波形如图16所示。

输出以16进制显示,可见排序功能实现正确。

3.3实验小结

通过实验三,我掌握了如下容:

(1)深入理解了阻塞与非阻塞赋值的区别。

(2)掌握了在VerilogHDL中使用函数的方法,进一步熟悉了if...else和case分支结构的使用。

(3)掌握了用repeat语句实现for循环结构的方法。

(4)掌握了在VerilogHDL中使用任务的方法,回顾了排序算法。

实验四、有限状态机

4.1实验任务1——基于状态机的串行数据检测器

4.1.1实验要求

设计一个串行数据监测器。

要:

连续4个或4个以上为1时输出1,其他情况下输出0。

4.1.2模块的核心逻辑设计

always(posedgeclk)

if(!

rst)

state<=Q0;

else

state<=nextstate;//复位端为0时输出状态置零,复位端为1时输出状态始终向下一状态变化

always(stateorx)

case(state)

Q0:

if(x==1)

nextstate=Q1;

else

nextstate=Q0;

Q1:

if(x==1)

nextstate=Q2;

else

nextstate=Q0;

Q2:

if(x==1)

nextstate=Q3;

else

nextstate=Q0;

Q3:

if(x==1)

nextstate=Q4;

else

nextstate=Q0;

Q4:

if(x==1)

nextstate=Q4;

else

nextstat

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

当前位置:首页 > 外语学习 > 法语学习

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

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