资源描述
Verilog数字电路设计实验名称Verilog数字电路设计班级130324姓名张先炳13031205同组者廖瑞13031191自动化与电气工程学院2016年 4月25 日目录目录目录2实验一 简单组合逻辑设计11 实验目的12 实验设备13 实验内容14 实验代码15 仿真结果2选作一:设计一个字节的比较器31 实验要求32 模块代码33 测试代码34 仿真结果4实验二 简单分频时序逻辑电路的设计41 实验目的42 实验设备43 实验内容54 实验代码55 仿真结果6选作二:七段数码管译码电路61 实验要求62 模块代码73 测试代码84 仿真结果8实验三:利用条件语句实现计数分频时序电路91 实验目的92 实验设备93 实验内容94 实验代码95 仿真结果116 实验分析11选作三:设计一个单周期形状的周期波形。111 实验要求112 模块代码113 测试代码124 仿真结果13实验四:用always块实现较复杂的组合逻辑131 实验目的132 实验设备133 实验内容144 实验代码145 仿真结果16选作四:运用always块设计一个8路数据选择器。161 实验要求162 模块代码163 测试代码174 仿真结果18实验五:在 Verilog HDL中使用函数191 实验目的192 实验设备193 实验内容194 实验代码195 仿真结果21选作五:设计一个带控制端的逻辑运算电路221 实验要求222 模块代码223 测试代码234 仿真结果25实验六:在Verilog HDL中使用任务(task)251 实验目的252 实验设备253 实验内容254 实验代码255 仿真结果28选作六:冒泡法排序281 实验要求282 模块代码283 测试代码294 仿真结果30选作七:串行输入排序311 实验要求312 模块代码313 测试代码334 仿真结果345 实验分析34实验七:利用有限状态机进行时序逻辑的设计351 实验目的352 实验设备353 实验内容354 实验代码355 仿真结果376 实验分析37选作八:楼梯灯381 实验要求382 模块代码383 测试代码454 仿真结果475 实验分析47附:分工明细49Verilog仿真实验报告 第49页实验一 简单组合逻辑设计1 实验目的1、掌握基本组合逻辑电路的实现方法。2、初步了解两种基本组合逻辑电路的生成方法。3、学习测试模块的编写。4、通过综合和布局布线了解不同层次仿真的物理意义。2 实验设备安装Modelsim-6.5c的PC机。3 实验内容描述一个可综合的数据比较器,比较数据a 、b的大小,若相同,则给出结果1,否则给出结果0。4 实验代码模块源代码:module compare(equal,a,b); input a,b; output equal; assign equal=(a=b)?1:0; endmodule测试代码:timescale 1ns/1ns;include compare.vmodule compare_tb; reg a,b; wire equal; initial begin a=0; b=0; #100 a=0;b=1; #100 a=1;b=1; #100 a=1;b=0; #100 a=0;b=0; #100 $stop; #100 a=0;b=1; end compare m(.equal(equal),.a(a),.b(b); endmodule5 仿真结果选作一:设计一个字节的比较器1 实验要求比较两个字节的大小,如a7:0大于b7:0,则输出高电平,否则输出低电平;并改写测试模型,使其能进行比较全面的测试。2 模块代码module compare_8bit(result,a,b); input 7:0a,b; output result; assign result = (ab)?1:0; endmodule3 测试代码timescale 1ns/1nsinclude compare_8bit.vmodule test; reg7:0a,b; wire result; initial begin a=8d0; b=8d0; #100 a=8d6;b=8d5; #100 a=8d9;b=8d9; #100 a=8d12;b=8d15; #100 $stop; end compare_8bit m(.result(result),.a(a),.b(b); endmodule4 仿真结果实验二 简单分频时序逻辑电路的设计1 实验目的1、掌握最基本组合逻辑电路的实现方法。2、学习时序电路测试模块的编写。3、学习综合和不同层次的仿真。2 实验设备安装Modelsim-6.5c的PC机。 3 实验内容用always块和(posedge clk)或(negedge clk)的结构表述一个1/2分频器的可综合模型,观察时序仿真结果。4 实验代码模块代码:module half_clk(reset,clk_in,clk_out); input clk_in,reset; output clk_out; reg clk_out; always (posedge clk_in) begin if(!reset)clk_out=0; else clk_out =clk_out; end endmodule测试代码:timescale 1ns/100psdefine clk_cycle 50module text; reg clk,reset; wire clk_out; always #clk_cycle clk=clk; initial begin clk=0; reset=1; #10 reset=0; #110 reset=1; #100000 $stop; end half_clk m(.reset(reset),.clk_in(clk),.clk_out(clk_out); endmodule5 仿真结果选作二:七段数码管译码电路1 实验要求设计一个七段数码管译码电路。2 模块代码module qiduanma(in,out); input 3:0in; output6:0out; reg6:0out; always(in) begin case(in) 4b0000:out= 7b1111110; 4b0001:out= 7b0110000; 4b0010:out= 7b1101101; 4b0011:out= 7b1111011; 4b0100:out= 7b0110011; 4b0101:out= 7b1011011; 4b0110:out= 7b0011111; 4b0111:out= 7b1110000; 4b1000:out= 7b1111111; 4b1001:out= 7b1110011; 4b1010:out= 7b0001101; 4b1011:out= 7b0011001; 4b1100:out= 7b0100011; 4b1101:out= 7b1001011; 4b1110:out= 7b0001111; 4b1111:out= 7b0000000; endcase end endmodule3 测试代码timescale 1ns/1ns;include qiduanma.vmodule test; reg3:0 in; wire6:0 out; integer t; initial begin in=4b0000; for(t=0;t4b1111;t=t+1) #100 in=in+1; end qiduanma m(.in(in),.out(out); endmodule4 仿真结果实验三:利用条件语句实现计数分频时序电路1 实验目的1、掌握条件语句在简单时序模块设计中的使用。2、学习在Verilog模块中应用计数器。3、学习测试模块的编写、综合和不同层次的仿真。2 实验设备安装Modelsim-6.5c的PC机。3 实验内容仿真一个可综合风格的分频器,将10MB的时钟分频为500KB的时钟,定义一个计数器,原理同1/2分频器一样,只不过分频变为1/20。4 实验代码模块代码:module fdivision(RESET,F10M,F500K); input F10M,RESET; output F500K; reg F500K; reg7:0j; always(posedge F10M) if(!RESET) begin F500K=0; j=0; end else begin if(j=9) begin j=0; F500K=F500K; end else j=j+1; end endmodule测试代码:timescale 1ns/100psdefine clk_cycle 50module test_fdivision; reg F10M,RESET; wire F500K_clk; always #clk_cycle F10M=F10M; initial begin RESET=1; F10M=0; #100 RESET=0; #100 RESET=1; #10000 $stop; end fdivision m(.RESET(RESET),.F10M(F10M),.F500K(F500K_clk);endmodule5 仿真结果6 实验分析书中程序if(j=19)段应改为if(j=9)选作三:设计一个单周期形状的周期波形。1 实验要求利用10MHZ的时钟,设计一个单周期形状的周期波形。2 模块代码module exp3(RESET,F10M,F_OUT); input F10M,RESET; output F_OUT; reg F_OUT; reg15:0j; always(posedge F10M) if(!RESET) begin F_OUT=0; j=0; end else begin j=j+1; case(j) 199:F_OUT=1; 299:F_OUT=0; 499:j=0; endcase end endmodule3 测试代码timescale 1ns/100psdefine clk_cycle 50module test_exp3; reg F10M,RESET; wire F; always #clk_cycle F10M=F10M; initial begin RESET=1; F10M=0; #100 RESET=0; #100 RESET=1; #1000000 $stop; end exp3 m2(.RESET(RESET),.F10M(F10M),.F_OUT(F);endmodule4 仿真结果实验四:用always块实现较复杂的组合逻辑1 实验目的1、掌握用always实现较大组合逻辑电路的方法。2、进一步了解assign与always两种组合电路实现方法的区别和注意点。3、学习测试模块中随机数的产生和应用。4、学习综合不同层次的仿真,并比较结果。2 实验设备安装Modelsim-6.5c的PC机。3 实验内容设计一个简单的指令译码电路,该电路通过对指令的判断,对输入数据执行相应的操作,包括加、减、与、或和求反,并且无论是指令作用的数据还是指令本身发生变化,都有要作出及时的反应。4 实验代码模块代码:/-alu.v-define plus 3d0define minus 3d1define band 3d2define bor 3d3define unegate 3d4module alu(out,opcode,a,b);output7:0 out;reg7:0 out;input2:0 opcode;input7:0 a,b; /?always(opcode or a or b)begincase(opcode)plus: out = a + b; /?minus: out = a - b; /?band: out = a & b; /?bor: out = a | b; /?unegate: out = a; /?default: out = 8hx; /?endcaseendendmodule测试代码:/-alutest.v-timescale 1ns/1nsinclude ./alu.vmodule alutest;wire7:0 out;reg7:0 a,b;reg2:0 opcode;parameter times=5;initialbegina =$random%256; /?0,255?b =$random%256; /?0,255?opcode = 3h0;repeat(times)begin#100 a =$random%256; b =$random%256; opcode = opcode+1;end#100 $stop;endalu alu1(out,opcode,a,b);endmodule5 仿真结果选作四:运用always块设计一个8路数据选择器。1 实验要求每路输入数据与输出数据均为4位2进制数,当选择开关(至少3位)或输入数据发生变化时,输出数据也相应地变化。2 模块代码module exp5(slt,in0,in1,in2,in3,in4,in5,in6,in7,out); input2:0slt; input3:0in0,in1,in2,in3,in4,in5,in6,in7; output 3:0out; reg 3:0out;always(in0 or in1 or in2 or in3 or in4 or in5 or in6 or in7 or slt) case (slt) 3d0: out = in0; 3d1: out = in1; 3d2: out = in2; 3d3: out = in3; 3d4: out = in4; 3d5: out = in5; 3d6: out = in6; 3d7: out = in7; endcaseendmodule3 测试代码timescale 1ns/1nsmodule test_exp5_2; reg3:0in0,in1,in2,in3,in4,in5,in6,in7; reg2:0slt=0; reg clk; wire 3:0out; always #10 clk=clk; always(posedge clk) slt=slt+1; initial begin clk=0; begin in0=1; in1=3; in2=5; in3=7; in4=9; in5=11; in6=13; in7=15; end #160 begin in0=0; in1=2; in2=4; in3=6; in4=8; in5=10; in6=12; in7=14; end end exp5 m(.slt(slt),.in0(in0),.in1(in1),.in2(in2),.in3(in3),.in4(in4),.in5(in5),.in6(in6),.in7(in7),.out(out);endmodule4 仿真结果实验五:在 Verilog HDL中使用函数1 实验目的1、了解函数的定义和在模块设计中的使用。2、了解函数的可综合性问题。3、了解许多综合器不能综合复杂的算术运算。2 实验设备安装Modelsim-6.5c的PC机。3 实验内容做一个函数调用的示例,采用同步时钟触发运算的执行,每个clk时钟周期执行一次运算,在测试模块中,调用系统任务$display及在时钟的下降沿显示每次运算的结果。4 实验代码模块代码:module tryfunct(clk,n,result,reset); output31:0result; input3:0n; input reset,clk; reg31:0result; always(posedge clk) begin if(!reset) result=0; else begin result=n*factorial(n)/(n*2)+1); end end function31:0factorial; input3:0operand; reg3:0index; begin factorial=operand?1:0; for(index=2;index=operand;index=index+1) factorial=index*factorial; end endfunction endmodule测试代码:includetryfunct.vtimescale 1ns/100psdefine clk_cycle 50module test_tryfunct; reg3:0n,i; reg reset,clk; wire31:0result; initial begin clk=0; n=0; reset=1; #100 reset=0; #100 reset=1; for(i=0;i=15;i=i+1) begin #200 n=i; end #100 $stop; end always #clk_cycle clk=clk; tryfunct m(.clk(clk),.n(n),.result(result),.reset(reset); endmodule5 仿真结果选作五:设计一个带控制端的逻辑运算电路1 实验要求分别完成正整数的平方、立方和最大数为5的阶乘的运算,要求可综合。编写测试模块,并给出各种层次的仿真波形,比较它们的不同。2 模块代码module tryfunct2(clk,n,result,reset,select); output31:0result; input3:0n; input1:0select; input reset,clk; reg31:0result; always(posedge clk) begin if(!reset) result=0; else begin case(select) 0:result=square(n); 1:result=cube(n); 2:result=factorial(n); default:result=32hx; endcase end end function31:0square; input3:0operand; square=operand*operand; endfunction function31:0cube; input3:0operand; cube=operand*operand*operand; endfunction function31:0factorial; input3:0operand; reg3:0index; begin factorial=(operand&(operand=5)?1:0; for(index=2;index=operand;index=index+1) factorial=index*factorial; end endfunction endmodule3 测试代码includetryfunct2.vtimescale 1ns/100psdefine clk_cycle 50module test_tryfunct2; reg1:0 select; reg3:0n,i; reg reset,clk; wire31:0result; initial begin clk=0; n=0; reset=1; #100 reset=0; #100 reset=1; for(select=0;select=2;select=select+1) for(i=0;i=6;i=i+1) begin for(select=0;selecty) begin tmp = x; x = y; y = tmp; endendtaskendmodule测试代码:/-? sort4.v-module sort4(ra,rb,rc,rd,a,b,c,d); output3:0 ra,rb,rc,rd; input3:0 a,b,c,d; reg3:0 ra,rb,rc,rd; reg3:0 va,vb,vc,vd;always (a or b or c or d) begin va,vb,vc,vd=a,b,c,d; sort2(va,vc);/va?vc? sort2(vb,vd); sort2(va,vb); sort2(vc,vd); sort2(vc,vd); sort2(vb,vc); ra,rb,rc,rd=va,vb,vc,vd; endtask sort2; inout3:0 x,y; reg3:0 tmp; if(xy) begin tmp = x; x = y; y = tmp; endendtaskendmodule5 仿真结果选作六:冒泡法排序1 实验要求模仿上面的例子用纯组合逻辑实现,用冒泡法设计一个能完成四个8位2进制数输入数据的模块。2 模块代码/-? sort4.v-module sort4_2(ra,rb,rc,rd,a,b,c,d); output7:0 ra,rb,rc,rd; input7:0 a,b,c,d; reg7:0 ra,rb,rc,rd; reg7:0 va,vb,vc,vd;always (a or b or c or d) begin va,vb,vc,vd=a,b,c,d; sort2(va,vb);/va?vc? sort2(va,vc); sort2(va,vd); sort2(vb,vc); sort2(vb,vd); sort2(vc,vd); ra,rb,rc,rd=va,vb,vc,vd; endtask sort2; inout7:0 x,y; reg7:0 tmp; if(xy) begin tmp = x; x = y; y = tmp; endendtaskendmodule3 测试代码timescale 1ns/100psinclude sort4_2.vmodule test_sort4_2; reg7:0 a,b,c,d; wire7:0 ra,rb,rc,rd; initial begin a=0;b=0;c=0;d=0; repeat(50) begin #100 a=$random%255;b=$random%255;c=$random%255;d=$random%255;end#100 $stop; endsort4_2 m(.a(a),.b(b),.c(c),.d(d),.ra(ra),.rb(rb),.rc(rc),.rd(rd);endmodule4 仿真结果选作七:串行输入排序1 实验要求假设8位数据是按照时钟节拍串行输入的,要求用时钟触发任务的执行法,每个时钟周期完成一次数据交换的操作。比较两种方法的运行速度和消耗资源的不同。2 模块代码module sort4_3(ra,rb,rc,rd,in,clk); output7:0 ra,rb,rc,rd; input7:0 in; input clk; reg7:0 ra,rb,rc,rd; reg7:0 va,vb,vc,vd; reg3:0i=0; always (posedge clk)begin case(i) 0:va=in; 1:vb=in; 2:vc=in; 3:vd=in; 4:sort2(va,vb); 5:sort2(va,vc); 6:sort2(va,vd); 7:sort2(vb,vc); 8:sort2(vb,vd); 9:begin sort2(vc,vd);ra,rb,rc,rd=va,vb,vc,vd;end default:i=15;/* 0:vay) begin tmp = x; x = y; y = tmp; endendtaskendmodule3 测试代码timescale 1ns/100psinclude sort4_3.vdefine clk_cycle 50module test_sort4_3; reg7:0 in; reg clk; wire7:0 ra,rb,rc,rd; initial begin begin clk=0; repeat(50) #100 in=$random%255; end #100 $stop; end always #clk_cycle clk=clk;sort4_3 m(.in(in),.clk(clk),.ra(ra),.rb(rb),.rc(rc),.rd(rd);endmodule4 仿真结果5 实验分析在模块程序的case语句中用到了10句,4句输入,6句排序,这说明从输入到排序完成在输出,需要10个clk,其实可以通过改进缩短这个时间,可改为:case(i) 0:va=in; 1:begin vb=in;sort2(va,vb);end 2:begin vc=in;sort2(va,vc);end 3:begin vd=in;sort2(va,vd);end 4:sort2(vb,vc); 5:sort2(vb,vd); 6:begin sort2(vc,vd);ra,rb,rc,rd=va,vb,vc,vd;end default:i=15; endcase仿真结果一样,不过这里只用了7个clk,相比上面的方法节约了三个时钟,速度得到提升,相比第一个并行输入的方法,少了3个接口和一些寄存器,但时间却差不多(第一个方法也是7个clk执行完一次循环)。实验七:利用有限状态机进行时序逻辑的设计1 实验目的1、掌握利用有限状态机实现一般时序逻辑分析的方法。2、掌握用Verilog编写可综合的有限状态机的标准模板。3、掌握用Verilog编写状态机模块的测试文件的一般方法。2 实验设备安装Modelsim-6.2b的PC机。3 实验内容编写状态机程序检测5位二进制系列“10010”。4 实验代码模块代码:module seqdet(x,z,clk,rst,state); input x,clk,rst; output z; output 2:0state; reg2:0state; wire z; parameter IDLE=d0,A=d1,B=d2,C=d3,D=d4,E=d5,F=d6,G=d7; assign z= (state=D&x=0)?1:0; always (posedge clk) if(!rst) state=IDLE; else casex(state) IDLE:if(x=1) state=A; A: if(x=0) state=B; B: if(x=0) state=C;else state=F; C: if(x=1) state=D;else state=G; D: if(x=0) state=E;else state=A; E: if(x=0) state=C;else state=A; F: if(x=1) state=A;else state=B; G: if(x=1) state=F; default:state=IDLE; endcase endmodule测试代码:timescale 1ns/1nsinclude seqdet.vmodule test_seqdet; reg clk,rst; reg23:0data; wire2:0state; wire z,x; assign x=data23; always #10 clk=clk; always(posedge clk) data=data22:0,data23; initial begin clk=0; rst=1; #2 rst=0; #30 rst=1; data =b1100_1001_0000_1001_0100; #500 $stop; end seqdet m(.x(x),.z(z),.clk(clk),.rst(rst),.state(state); endmodule5 仿真结果6 实验分析书中程序中的F、G状态其实有些多余,F其实就对应的A,G对应的IDLE,因此完全可以将这两个状态去掉。另外,书中有个要求是:当x序列10010的最后一个0到达时刻,z立刻输出高电平,而书中程序assign z= (state=E&x=0)?1:0;并不能满足这个要求,若改成assign z= (state=D&x=0)?1:0;便可实现。进一步可以看出,其实E状态也其实可以去掉,因为在状态D里输入0便需要输出1并切换到状态C,输入1则切换到状态A,这样亦可实现原功能。选作八:楼梯灯1 实验要求 楼下到楼上依次有3个感应灯:灯1、灯2、灯3。当行人上下楼梯时,各个灯感应到后自动点亮,若在8s内感应信号消失,则点亮8s,若感应信号存在时间超过8s,则感应信号消失4s后灯自动关闭。 任务1:做出如上逻辑电路设计并仿真; 任务2:考虑去抖情况,对于感应信号到达存在毛刺(小于0.5s),设计合适逻辑并剔出。 任务3:若为节约能源,下一个灯点亮的同时将自动关闭上一个灯,做出如上逻辑设计并仿真(仅考虑一个人的情况); 任务4:考虑存在多个人上下楼梯的情况,比如:行人1已经从灯1到达灯2,灯2受感应自动点亮,但此时行人2刚上楼梯到达灯1的位置,则灯1和灯2都须点亮,更加复杂一点,如果行人2是下楼梯刚到达灯3位置,做出如上逻辑设计并仿真; 注意:1.上下楼梯顺序 2.时钟频率为10Hz 3.感应信号为电平信号2 模块代码module stair_light(light1,light2,light3,s1,s2,s3,rst,state,clk); input s1,s2,s3,rst,clk; output light1,light2,light3; output2:0state; reg2:0state; reg7:0i1,i2,i3,t11,t12,t21,t22,t31,t32; reg e1,e2,e3,e1_d,e2_d,e3_d; wire light1,light2,light3,s1,s2,s3; assign light1=state2; assign light2=state1; assign light3=state0; /light1 always(posedge clk) begin if(s1) begin i1=i1+1; if(i15) begin if(i180) begin t12=t12-1; if(t12=0) begin e1=0;i1=0;end end end end end /light2 always(posedge clk) begin if(s2) begin i2=i2+1; if(i25) begin if(i280) begin t22=t22-1; if(t22=0) begin e2=0;i2=0;end end end end end /light3 always(posedge clk) begin if(s3) begin i3=i3+1; if(i35) begin if(i380) begin t32=t32-1; if(t32=0) begin e3=0;i3=0;end end end end end/delay signals always(posedge clk
展开阅读全文