EDA技术与verilog语言练习题.docx

上传人:b****5 文档编号:7845294 上传时间:2023-01-26 格式:DOCX 页数:20 大小:31.23KB
下载 相关 举报
EDA技术与verilog语言练习题.docx_第1页
第1页 / 共20页
EDA技术与verilog语言练习题.docx_第2页
第2页 / 共20页
EDA技术与verilog语言练习题.docx_第3页
第3页 / 共20页
EDA技术与verilog语言练习题.docx_第4页
第4页 / 共20页
EDA技术与verilog语言练习题.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

EDA技术与verilog语言练习题.docx

《EDA技术与verilog语言练习题.docx》由会员分享,可在线阅读,更多相关《EDA技术与verilog语言练习题.docx(20页珍藏版)》请在冰豆网上搜索。

EDA技术与verilog语言练习题.docx

EDA技术与verilog语言练习题

设计示范和上机习题

练习一.简单的组合逻辑设计

〃(方法一):

//文件名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

//

//测试模块源代码(方法之一):

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

//包含模块文件。

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

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

modulet;rega,b;wireequal;initialbegina=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;initialbegina=0;b=0;

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

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

练习二.简单分频时序逻辑电路的设计

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_cycle50moduletop;

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_clk=~F10M_clk;

initial

begin

RESET=1;

F10M=0;

#100RESET=0;

#100RESET=1;

#10000$stop;

end

fdivisionfdivision(.RESET(RESET),.F10M(F10M),.F500K(F500K_clk));

endmodule

练习四.阻塞赋值与非阻塞赋值的区别

〃模块源代码:

-

//blocking.vmoduleblocking(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;

〃减操作。

'band:

out

=a&b;

〃求与。

'bor:

out:

=a|b;

//求或。

'unegate:

out=~a;/求反。

default:

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

endcase

end

endmodule

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

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

练习六・在VerilogHDL中使用函数

//模块源代码:

//文件名tryfunct.v

moduletryfunct(clk,n,result,reset);output[31:

0]result;

input[3:

0]n;

inputreset,clk;

reg[31:

0]result;

always@(posedgeclk)//clk的上沿触发同步运算。

begin

if(!

reset)//reset为低时复位。

result<=0;

else

begin

result<=n*factorial(n)/((n*2)+1);

end//verilog在整数除法运算结果中不考虑余数

//函数定义,返回的是一个32位的数

//输入只有一个四位的操作数

//函数内部计数用中间变量

//先定义操作数为零时函数的输岀为零,不为零时为

end

function[31:

0]factorial;input[3:

0]operand;reg[3:

0]index;

begin

factorial=operand?

1:

0;

for(index=2;index<=operand;index=index+1)factorial=index*factorial;//表示阶乘的算术迭代运算

end

endfunctionendmodule

//测试模块源代码:

'include"./tryfunct.v"'timescale1ns/100ps'defineclk_cycle50

moduletryfuctTop;

reg[3:

0]n,i;

regreset,clk;

wire[31:

0]result;

initial

begin

clk=0;

n=0;

reset=1;

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

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

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

begin

#200n=i;

end

#100$stop;

end

always#'clk_cycleclk=~clk;

tryfunctm(.clk(clk),.n(n),.result(result),.reset(reset));

endmodule

练习七・在VerilogHDL中使用任务(task)

//模块源代码:

//文件名sort4.v

modulesort4(ra,rb,rc,rd,a,b,c,d);output[3:

0]ra,rb,rc,rd;

input[3:

0]a,b,c,d;

reg[3:

0]ra,rb,rc,rd;

reg[3:

0]va,vb,vc,vd;

always@(aorborcord)begin

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

sort2(va,vc);

//va

与vc互换。

sort2(vb,vd);

//vb

与vd互换。

sort2(va,vb);

//va

与vb互换。

sort2(vc,vd);

//vc

与vd互换。

sort2(vb,vc);〃vb与vc互换。

{ra,rb,rc,rd}={va,vb,vc,vd};

end

tasksort2;

inout[3:

0]x,y;

reg[3:

0]tmp;

if(x>y)

begin

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

x=y;

y=tmp;

end

endtask

endmodule

//测试模块源代码:

'timescale1ns/100ps

'include"sort4.v"

moduletask_Top;

reg[3:

0]a,b,c,d;

wire[3:

0]ra,rb,rc,rd;

initial

begin

a=O;b=O;c=O;d=O;

repeat(50)

begin

#100a={$random}%15;

b={$random}%15;

c={$random}%15;

d={$random}%15;

end

#100$stop;

sort4sort4(.a(a),.b(b),.c(c),.d(d),.ra(ra),.rb(rb),.rc(rc),.rd(rd));

endmodule

练习八.利用有限状态机进行时序逻辑的设计

〃模块源代码:

-

//文件名seqdet.v---

moduleseqdet(x,z,clk,rst,state);inputx,clk,rst;

outputz;output[2:

0]state;

reg[2:

0]state;wirez;

A='d1,B='d2,

C='d3,D='d4

E='d5,F='d6,

G='d7;

parameterIDLE='dO,assignz=(state==E&&x==0)?

1:

0;

//当x序列10010最后一个0刚到时刻,时钟沿立刻将状态变为E,此时z应该变为高

always@(posedgeclk)

if(!

rst)

begin

state<=IDLE;

end

else

casex(state)

IDLE:

if(x==1)//第一个码位对,记状态A

begin

state<=A;

end

A:

if(x==0)〃第二个码位对,记状态B

begin

state<=B;

end

B:

if(x==0)〃第三个码位对,记状态C

begin

state<=C;

end

else//第三个码位不对,前功尽弃,记状态为F

begin

state<=F;

end

C:

if(x==1)//第四个码位对

begin

state<=D;

end

else//第四个码位不对,前功尽弃,记状态为G

begin

state<=G;

end

D:

if(x==O)//第五个码位对,记状态E

begin

state<=E;〃此时开始应有z的输出

end

else

〃第五个码位不对,前功尽弃,只有刚进入的1有用,回到第一个码位对状态,记状态A

begin

state<=A;

end

E:

if(x==0)

〃连着前面已经输入的x序列10010考虑,又输入了0码位可以认为第三个码位已对,记状态C

begin

state<=C;

end

else//前功尽弃,只有刚输入的1码位对,记状态为A

begin

state<=A;

end

F:

if(x==1)〃只有刚输入的1码位对,记状态为A

begin

state<=A;

end

else//又有1码位对,记状态为B

begin

state<=B;

end

G:

if(x==1)〃只有刚输入的1码位对,记状态为A

begin

state<=F;

end

default:

state=IDLE;〃缺省状态为初始状态。

endcase

endmodule

//测试模块源代码:

//文件名seqdet.v

'timescale1ns/1ns

'inelude"./seqdet.v"

moduleseqdet_Top;

regclk,rst;

reg[23:

0]data;

wire[2:

0]state;

wire乙x;

assignx=data[23];

always#10clk=~clk;

always@(posedgeclk)

data={data[22:

0],data[23]};〃形成数据向左移环行流,最高位与x连接

initial

begin

clk=0;

rst=1;

#2rst=0;

#30rst=1;

data='b1100_1001_0000_1001_0100;

#500$stop;

end

seqdetm(x,z,clk,rst,state);

endmodule

练习九•利用状态机实现比较复杂的接口设计

//模块源代码:

modulewriting(reset,clk,address,data,sda,ack);inputreset,clk;

input[7:

0]data,address;

outputsda,ack;//sda负责串行数据输出;

//ack是一个对象操作完毕后,模块给出的应答信号reglink_write;//link_write决定何时输出。

reg[3:

0]state;//主状态机的状态字。

reg[4:

0]sh8out_state;//从状态机的状态字。

reg[7:

0]sh8out_buf;//输入数据缓冲。

regfinish_F;//用以判断是否处理完一个操作对象。

regack;

parameter

idle=0,addr_write=1,data_write=2,stop_ack=3;

parameter

bit0=1,bit1=2,bit2=3,bit3=4,bit4=5,bit5=6,bit6=7,bit7=8;

assignsda=link_write?

sh8out_buf[7]:

1'bz;

always@(posedgeclk)

begin

if(!

reset)〃复位。

begin

link_write<=0;//挂起串行单总线

state<=idle;

finish_F<=0;//结束标志清零

sh8out_state<=idle;

ack<=0;

sh8out_buf<=0;

end

else

case(state)

idle:

begin

link_write<=0;〃断开串行单总线

finish_F<=0;

sh8out_state<=idle;

ack<=0;

sh8out_buf<=address;〃并行地址存入寄存器state<=addr_write;//进入下一个状态

end

addr_write:

〃地址的输入。

begin

if(finish_F==O)

beginshift8_out;end//地址的串行输出

else

begin

sh8out_state<=idle;

sh8out_buf<=data;〃并行数据存入寄存器state<=data_write;

finish_F<=0;

end

end

begin

if(finish_F==O)

beginshift8_out;end//数据的串行输出

else

begin

link_write<=0;

state<=stop_ack;

finish_F<=0;

ack<=1;〃向信号源发出应答。

end

end

stop_ack:

//向信号源发出应答结束。

begin

ack<=0;

state<=idle;

end

endcase

end

taskshift8_out;//地址和数据的串行输出。

begin

case(sh8out_state)

idle:

MSB)

begin

link_write<=1;〃连接串行单总线,立即输出地址或数据的最高位(

sh8out_state<=bit7;

end

bit7:

begin

link_write<=1;〃连接串行单总线

sh8out_state<=bit6;

sh8out_buf<=sh8out_buf<<1;〃输出地址或数据的次高位(bit6)end

bit6:

begin

sh8out_state<=bit5;

sh8out_buf<=sh8out_buf<<1;

end

begin

sh8out_state<=bit4;

sh

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

当前位置:首页 > 求职职场 > 面试

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

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