第一篇:北航_电子实习_数字部分实验报告
报告名称:电子电路设计训练数字部
分
学院:仪器科学与光电工程学院
目录
实验报告概述:...............................................................................................................3
一、选做实验总结:.................................................................................................3(1)补充练习2:楼梯灯设计.............................................................................3(2)练习题6:用两种不同的设计方法设计一个功能相同的模块,完成4个数据的冒泡排序...................................................................................................................5(3)(4)(5)
二、(1)(2)(3)(4)(5)练习题3:利用10MB的时钟,设计一个单周期形状的周期波形..................6 练习题4:运用always块设计一个8路数据选择器......................................6 练习题5:设计一个带控制端的逻辑运算电路.............................................7 练习一:简单组合逻辑设计.........................................................................7 练习三:利用条件语句实现计数分频失序电路.............................................7 练习四:阻塞赋值与非阻塞赋值得区别.......................................................8 练习五:用always块实现较复杂的组合逻辑电路........................................8 练习六:在verilog HDL中使用函数..............................................................9 必做实验总结:.................................................................................................7(6)练习七:在verilog HDL中使用任务..............................................................9(7)练习八:利用有限状态机进行时许逻辑设计..............................................10
三、实验总结及体会:............................................................................................10
四、选作程序源代码...............................................................................................11(1)练习题3:利用10MB的时钟,设计一个单周期形状的周期波形................11(2)练习题4:运用always块设计一个8路数据选择器....................................12(3)练习题5:设计一个带控制端的逻辑运算电路...........................................13(4)练习题6:用两种不同的设计方法设计一个功能相同的模块,完成4个数据的冒泡排序.................................................................................................................14(5)补充练习2:楼梯灯设计...........................................................................16
图表目录
Figure 1 楼梯灯任务4..............................................................................................5 Figure 2 组合逻辑.....................................................................................................5 Figure 3 时序逻辑.....................................................................................................6 Figure 4 周期波形....................................................................................................6 Figure 5 8路数据选择器..........................................................................................6 Figure 6 逻辑运算电路.............................................................................................7 Figure 7 组合逻辑设计.............................................................................................7 Figure 8 计数分频时序电路......................................................................................8 Figure 9 阻塞赋值与非阻塞赋值得区别....................................................................8 Figure 10 always块组合逻辑电路.............................................................................9 Figure 11 使用函数..................................................................................................9 Figure 12 使用任务................................................................................................10 Figure 13 有限状态机............................................................................................10
电子电路设计训练(数字部分)实验报告
实验报告概述:
本实验报告为对四次电子电路设计训练(数字部分)实验的总结,主要包括以下四部分:
第一部分为选做实验总结,主要包括每个选择实验的设计思路、运行结果、注意事项、心得体会;
第二部分为必做实验总结,包括运行结果、总结、心得体会; 第三部分为课程总结和体会,是对全部实验及课程的总结; 第四部分为选做实验部分源代码;
一、选做实验总结:
(1)补充练习2:楼梯灯设计
设计思路:
本题给出楼梯的运行规则,并分别给与四个相应任务进行编程设计,考虑到程序的通用性及FPGA高速并行处理的优点,主要思路如下:
根据运行规则(8s内和大于8s等),对每个灯的相应状态进行编程,设计时序逻辑及有限状态机;由于在总体上看,每个灯的状态变化相对独立(只有一个人上楼除外),故对每个灯编程所得到的程序代码可通用于其它灯(只需要改变相应寄存器定义即可),此即为灯控制模块,对4个不同的任务,只需设计其它部分判断逻辑,即可完成任务要求;如此设计,可大大提高程序设计效率、易用性,同时如果面对更多的灯控制需要,也可快速进行修改部署。
下面针对不同任务给出不同处理方法:
任务1/任务3:由于任务1和任务3在定义上有很大相同点,比如同样是一个人走楼梯,若不考虑一个人同时在两层使两个灯亮,则事实上就是一个人始终只能使一盏灯亮,亮起后盏时熄灭前一盏;在保持每个灯控制模块不改变的情况下,利用非阻塞赋值,判断该人目前所处状态及位置(上楼/下楼,楼层),同时规定输出,同时只能亮一盏灯;
任务2:由于输入信号已被赋值给寄存器变量,此时只需在系统时钟作用下对寄存器中输入变量进行判断,满足要求即为正确信号,再输入灯控制模块;
任务4:由于已有灯控制模块,此时只需结合任务2防抖电路,直接输出状态信号所对应的结果即可;
(单个)灯控制模块代码:
always @(posedgeclk)begin signal_test[0]<=signal[0];if(signal_test[0]==signal[0])
begin
i0=i0+1;
end else
i0=0;if(i0>=5)
begin signal_reg[0]=signal[0];
end
if(state0==light_off)
begin
k0=0;
k0a=0;
k0b=0;
end else
k0=k0+1;
case(signal_reg[0])
1: if(!reset)
begin
state0=light_off;
end
else
begin
k0a=k0a+1;*分栏显示,详细代码见报告第四部分;
运行结果:
if((k0a >= 79)&&(k0<=119))
state0=light_on12;
else
state0=light_on8;
end
0:if(!reset)
begin
state0=light_off;
end
else if(k0a==0)
state0=light_off;endcase
case(state0)
light_off:light_reg[0]=0;
light_on8:
begin light_reg[0]=1;
if(k0b==79)
state0=light_off;
else
k0b=k0b+1;
end
light_on12:
begin
light_reg[0]=1;
if(k0b==119)
state0=light_off;
else
k0b=k0b+1;
end endcase end
Figure 1楼梯灯任务4
Figure 2楼梯灯信号防抖部分放大结果
(2)练习题6:用两种不同的设计方法设计一个功能相同的模块,完成4个数据的冒泡排序
设计思路:
纯组合排序中,设计sort排序任务对数列中的元素进行排序,通过调用任务实现对不同元素的排序功能,并将排序完成的结果直接输出;
冒泡排序即为每次将两个相邻数进行比较,大的数后“浮”,每一趟比较获得较大值并置于数列末位;
根据题目要求,每比较一次,即将调换位置的数字进行输出;同样设计sort任务,对两数字进行比较并排序;
通过排序控制和逻辑判断代码,控制sort任务的有效调用,进而实现冒泡排序功能;
根据设计要求,程序中只设计有一个输入端口,通过对输入信号不断移位,模拟串并行信号转换,从而完成穿行输入,并行比较的功能;
运行结果:
Figure 3组合逻辑
Figure 4时序逻辑
(3)练习题3:利用10MB的时钟,设计一个单周期形状的周期波形
设计思路:
对输入时钟进行计数,通过if语句进行判断,若满足判断条件,则按要求改变输出信号;如此循环往复,即可产生所需单周期形状的周期波形;
运行结果:
Figure 5周期波形
(4)练习题4:运用always块设计一个8路数据选择器
设计思路:
利用define宏定义预先定义,利于后期程序功能的扩充和调整;同时利用case语句判断信号,并将相对应信号输出,进而完成系统目标功能;
运行结果:
Figure 68路数据选择器
(5)练习题5:设计一个带控制端的逻辑运算电路
设计思路:
设计三个函数分别完成三个要求的计算,通过函数调用实现相应功能;设计的控制端为同步控制端,需要通过时钟信号从而进行检测复位;
运行结果:
Figure 7逻辑运算电路
二、必做实验总结:
(1)练习一:简单组合逻辑设计
语法要点:
Assign语句构成的组合逻辑电路,若输入a,b改变,则输出equal;
利用assign equal=(a==b)?1:0语句,可同时完成判断赋值功能,大大减少代码量; 运行结果:
Figure 8组合逻辑设计
(2)练习三:利用条件语句实现计数分频时序电路
语法要点:
此程序主要练习了对输入时钟进行计数,判断,从而实现分频输出;
在实际应用中,可以通过该方式获得不同占空比或频率的信号供系统使用;
课本程序问题修改:
课本测试程序中未定义F10M_clk变量,故应将测试程序fdivision_TOP中出现的该变量改为已定义的F10M;
运行结果:
Figure 9计数分频时序电路
(3)练习四:阻塞赋值与非阻塞赋值的区别
语法要点:
阻塞赋值呈现的是一种立即赋值的状态,即同一个变量在前后语句中用到,语句间的顺序会影响到输出的结果;
非阻塞赋值对每一个块中语句间的相对位置没有要求,只在该块语句全部运行完成后同一进行赋值;
运行结果:
Figure 10阻塞赋值与非阻塞赋值得区别
(4)练习五:用always块实现较复杂的组合逻辑电路
语法要点:
Always@实现了对若干输入信号的敏感,即只要有一个信号改变,输出即改变; 通过case语句,实现了选择性输出,对不同功能进行综合;
运行结果:
Figure 11 always块组合逻辑电路
(5)练习六:在verilog HDL中使用函数
语法要点:
函数最基本功能即实现计算,通过对不同函数定义,实现不同的计算功能;同时定义函数,可以利于在该模块外对某函数功能的调用,增强了程序的通用性和功能性,同时可以使程序结构更加清晰,易读易懂;
运行结果:
Figure 12使用函数
(6)练习七:在verilog HDL中使用任务
语法要点:
相比函数,任务的调用功能更强大,可以实现运算并输出多个结果的功能,同时任务并不返回计算值,只通过类似C语言中的形参和实参的数据交换,实现功能;任务的定义和调用可
以只程序结构更明晰,功能更丰富;
程序中通过对比较顺序的设计,实现了对4个数字,进行5次比较即可成功完成排序功能的目的;
运行结果:
Figure 13使用任务
(7)练习八:利用有限状态机进行时许逻辑设计
语法要点:
设计有限状态机主要需要进行状态分配,状态编码,然后利用case语句进行判断,从而改变相应状态,实现状态转移和输出变换;
对涉及时钟的一般时序逻辑,主要运用非阻塞(〈=)赋值完成功能;
课本程序问题修改:
在modelsim 10中,测试文件时钟无法仿真,故只能保持与课本测试文件相同的思路,重新编写测试文件,仿真结果如下,与课本完全一致;
运行结果:
Figure 14有限状态机
三、实验总结及体会:
通过半个学期的学习和实验,我初步掌握了verilogHDL语言和modelsim软件,可以通过编程实现数字电路基础中几乎全部简单逻辑芯片的功能,同时可以用编程实现相对复杂一点的逻辑电路和功能.总体而言,四次实验内容相对简单,几乎是在课后实验的基础上稍稍做了提高,以利于我们掌握并巩固课上学习的知识。有几个课后实验内容,按照程序输入后无法进行波形仿真,在改正一些错误定义,或者重写测试程序后,都能顺利完成实验任务。通过实验上机,巩固了我们的理论知识,加强了实际运用的能力,对整个课程的学习起到了很好的作用。
最后一个补充实验相对复杂,但实现的方法却可以有很多,在实际写代码前进行构思分析,在这个实验中显得尤为重要,例如,如何发挥FPGA并行处理的能力,如何提高程序的通用性,能够将所设计的模块结构同时完成四个任务,如何设计代码提高效率的同时节省硬件资源„„都是在设计构思中不得不考虑的环节,因此,通过最后一个实验的设计,能够很好的锻炼我们解决实际生活中问题的能力,使我们对所学的知识能够真正有所使用。
运用verilog HDL语言进行硬件电路设计,已成为未来电路设计的主要趋势,学习这门语言及相应软件,能够帮助我们在以后的学习及科研中,大大提高我们的效率,使我们能够快速搭建实验平台,完成目标功能。
虽然8周的课,时间相对较短,但通过这8周的学习,我对verilog HDL语言有了全面的认识,对基本的语法都有了很好的掌握,虽然时间有限,不能对verilog HDL语言有更深入的认识,但通过这8周的学习,我为我将来进一步深化使用这个工具打下了坚实的基础。
四、选作程序源代码(1)练习题3:利用10MB的时钟,设计一个单周期形状的周期波形 主程序:
module fdivison_2(RESET,F10M,clk_out,j);input F10M,RESET;output clk_out;output[12:0] j;
regclk_out;
reg[12:0] j;always @(posedge F10M)begin if(!RESET)begin clk_out<=0;j<=0;end
else begin if(j==199)
begin
j<=j+1;clk_out<=1;
end
else if(j==299)
begin
j<=j+1;clk_out<=0;
end
else if(j==499)
j<=0;
else j<=j+1;end end
endmodule
output[3:0] out;
reg[3:0] out;
always @(a or b or c or d or e or f or g or h or selet)
begin
case(selet)
`s1:out=a;
`s2:out=b;
`s3:out=c;
`s4:out=d;
`s5:out=e;
`s6:out=f;
`s7:out=g;
`s8:out=h;default:out=4'hz;endcase
end
endmodule
测试程序: `timescale 1 ns/1 ns
module muxtest;
wire[3:0] out;reg[3:0] a,b,c,d,e,f,g,h;reg[2:0] selet;
parameter times1=8;
initial
begin
a=0;
b=1;
c=2;d=3;
e=4;
f=5;
g=6;
h=7;selet=3'h0;
repeat(5)测试程序:
`timescale 1ns/100ps `define clk_cycle 50 module TOP_2;reg F10M,RESET;wire clk;wire[12:0] j;always #`clk_cycle
F10M = ~F10M;
initial
begin
RESET=1;
F10M=0;
#100 RESET=0;
#100 RESET=1;
#10000 $stop;
end
fdivison_2 fdivison_2(.RESET(RESET),.F10M(F10M),.clk_out(clk),.j(j));
endmodule
(2)练习题4:运用always块设计一个8路数据选择器
主程序: `define s1 3'd0 `define s2 3'd1 `define s3 3'd2 `define s4 3'd3 `define s5 3'd4 `define s6 3'd5 `define s7 3'd6 `define s8 3'd7
module mux_8(a,b,c,d,e,f,g,h,selet,out);
input[3:0] a,b,c,d,e,f,g,h;
input[2:0] selet;
begin
#100 selet=selet+1;
end
selet=0;repeat(times1)
begin
#100 selet=selet+1;
a={$random}%16;
b={$random}%16;
c={$random}%16;
d={$random}%16;
e={$random}%16;
f={$random}%16;
g={$random}%16;
h={$random}%16;
end
#100 $stop;
end
mux_8 m0(a,b,c,d,e,f,g,h,selet,out);endmodule
(3)练习题5:设计一个带控制端的逻辑运算电路
主程序:
`define sqrR 4'd0 `define triR 4'd0 `define factR 4'd0
module sqr(a,reset,clk,sqr_out,tri_out,fact_out);
input[3:0] a;input reset,clk;output[7:0] sqr_out,tri_out,fact_out;reg[7:0] sqr_out,tri_out,fact_out;
always @(posedgeclk)begin
if(!reset)
{sqr_out,tri_out,fact_out}={`sqrR,`triR,`factR};
else
begin
sqr_out=sqr_cal(a);tri_out=tri_cal(a);fact_out=fact_cal(a);
end end
function[7:0] sqr_cal;
input[3:0] a;
begin sqr_cal=a*a;
end endfunction
function[7:0] tri_cal;
input[3:0] a;
begin tri_cal=a*a*a;
end endfunction
function[7:0] fact_cal;
input[3:0] a;
begin
if(a>5)fact_cal=0;
else
begin
case(a)
0:fact_cal=1;
1:fact_cal=1;
2:fact_cal=2;
3:fact_cal=6;
4:fact_cal=24;
5:fact_cal=120;endcase
end
end endfunction
endmodule
测试程序:
`timescale 1 ns/100 ps `define clk_cycle 50
module sqrTEST;
reg[3:0] a,i;regreset,clk;
wire[7:0] sqr_out,tri_out,fact_out;
initial
begin clk=0;
a=0;
reset=1;
#100 reset=0;
#100 reset=1;
for(i=0;i<=6;i=i+1)
begin
#200 a=i;
end
#100 $stop;
end
always #`clk_cycleclk=~clk;
sqr m(a,reset,clk,sqr_out,tri_out,fact_out);
endmodule
(4)练习题6:用两种不同的设计方法设计一个功能相同的模块,完成4个数据的冒泡排序
组合逻辑实现程序:
module bub(ai,bi,ci,di,ao,bo,co,do);
input[7:0] ai,bi,ci,di;output[7:0] ao,bo,co,do;reg[7:0] ao,bo,co,do;reg[7:0] ar,br,cr,dr;reg[3:0] n;
parameter so=4;
//
always @(ai or bi or ci or di)begin
{ar,br,cr,dr}={ai,bi,ci,di};
for(n=so;n>1;n=n-1)
//
bb(ar,br,cr,dr,n);
{ao,bo,co,do}={ar,br,cr,dr};end
task bb;
// inout[7:0] x1,x2,x3,x4;
input[3:0] n;
// reg[7:0] temp;reg[3:0] s;
if(n>0)
for(s=1;s begin case(s) 1:sort2(x1,x2);2:sort2(x2,x3); 3:sort2(x3,x4);endcase end endtask task sort2;inout[7:0] x,y;reg[7:0] temp; if(x>y) begin temp=x; x=y; y=temp; end endtask endmodule 组合逻辑测试程序: `timescale 1 ns/100 ps module bubTEST;reg[7:0] ai,bi,ci,di;wire[7:0] ao,bo,co,do; initial begin ai=0;bi=0;ci=0;di=0; repeat(4) begin #100 ai={$random}%256; bi={$random}%256; ci={$random}%256; di={$random}%256; end #100 $stop; end bub m0(ai,bi,ci,di,ao,bo,co,do); endmodule 时序逻辑实现程序: module bub_1(in,clk,ar,br,cr,dr,ao,bo,co,do); input[7:0] in;input clk;output[7:0] ao,bo,co,do;output[7:0] ar,br,cr,dr;reg[7:0] ao,bo,co,do;reg[7:0] ar,br,cr,dr;reg[3:0] n,s,q; parameter so=4; initial begin n=0; s=0; q=0; end always @(posedgeclk)begin if(n<=so) begin n=n+1;ar<=in;br<=ar;cr<=br;dr<=cr; end if(n==so+1) begin n<=so+2; s<=so; q<=1; end if(s>1) begin {ao,bo,co,do}<={ar,br,cr,dr}; if(q begin case(q) 1:sort2(ar,br); 2:sort2(br,cr); 3:sort2(cr,dr);endcase q<=q+1; end else begin s<=s-1; q<=1; end end end task sort2;inout[7:0] x,y;reg[7:0] temp; if(x>y) begin temp=x; x=y; y=temp; end endtask endmodule 时序逻辑测试程序: `timescale 1 ns/100 ps module bubTEST_1;reg[7:0] in;regclk; wire[7:0] ao,bo,co,do,ar,br,cr,dr; initial begin clk=0; in=0; begin repeat(4) #100 in={$random}%256; end #100 $stop; end always #50 clk=~clk; bub_1 m0(in,clk,ar,br,cr,dr,ao,bo,co,do); endmodule (5)补充练习2:楼梯灯设计 主程序: module final2(signal,reset,clk,light); input[2:0] signal; input reset,clk; output[2:0] light; reg[2:0] signal_reg,light_reg,light_test,signal_test; reg[11:0] k0,k1,k2,k0a,k1a,k2a,k0b,k1b,k2b; reg[1:0] state0,state1,state2; reg[3:0] i0,i1,i2; parameter light_off=2'b00,light_on8=2'b01,light_on12=2'b10;initial begin k0=0;k1=0;k2=0; k0a=0;k1a=0;k2a=0; k0b=0;k1b=0;k2b=0; i0=0;i1=0;i2=0;light_reg=3'b000; state0=light_off; state1=light_off; state2=light_off;signal_reg=0;signal_test=signal;end // // always @(posedgeclk)begin signal_test[0]<=signal[0];if(signal_test[0]==signal[0]) begin i0=i0+1; end else i0=0;if(i0>=5) begin signal_reg[0]=signal[0]; end if(state0==light_off) begin k0=0; k0a=0; k0b=0; end else k0=k0+1; case(signal_reg[0]) 1: if(!reset) begin state0=light_off; end else begin k0a=k0a+1; if((k0a >= 79)&&(k0<=119)) state0=light_on12; else state0=light_on8; end 0:if(!reset) begin state0=light_off; end else if(k0a==0) state0=light_off;endcase case(state0) light_off:light_reg[0]=0; light_on8: begin light_reg[0]=1; if(k0b==79) state0=light_off; else k0b=k0b+1; end light_on12: begin light_reg[0]=1; if(k0b==119) state0=light_off; else k0b=k0b+1; end endcase end always @(posedgeclk)begin signal_test[1]<=signal[1];if(signal_test[1]==signal[1]) begin i1=i1+1; end else i1=0; if(i1>=5) begin signal_reg[1]=signal[1]; end if(state1==light_off) begin k1=0; k1a=0; k1b=0; end else k1=k1+1; case(signal_reg[1]) 1: if(!reset) begin state1=light_off; end else begin k1a=k1a+1; if((k1a >= 79)&&(k1<=119)) state1=light_on12; else state1=light_on8; end 0:if(!reset) begin state1=light_off; end else if(k1a==0) state1=light_off;endcase case(state1) light_off:light_reg[1]=0; light_on8: begin light_reg[1]=1; if(k1b==79) state1=light_off; else k1b=k1b+1; end light_on12: begin light_reg[1]=1; if(k1b==119) state1=light_off; else k1b=k1b+1; end endcase end // // always @(posedgeclk)begin signal_test[2]<=signal[2];if(signal_test[2]==signal[2]) begin i2=i2+1; end else i2=0;if(i2>=5) begin signal_reg[2]=signal[2]; end if(state2==light_off) begin k2=0; k2a=0; k2b=0; end else k2=k2+1; case(signal_reg[2]) 1: if(!reset) begin state2=light_off; end else begin k2a=k2a+1; if((k2a >= 79)&&(k2<=119)) state2=light_on12; else state2=light_on8; end 0:if(!reset) begin state2=light_off; end else if(k2a==0) state2=light_off;endcase case(state2) light_off:light_reg[2]=0; light_on8: begin light_reg[2]=1; if(k2b==79) state2=light_off; else k2b=k2b+1; end light_on12: begin light_reg[2]=1; if(k2b==119) state2=light_off; else k2b=k2b+1; end endcase casex(light_reg) 3'b000:light_test=000; 3'b001:light_test=001; 3'b01x:light_test=010; 3'b1xx:light_test=100;endcase end assign light=light_test;endmodule 测试程序: `timescale 10ms/10ms module final_TOP2;reg[2:0] signal;regclk,reset; wire[2:0] light; initial begin clk=0; reset=1; #2 reset=0; #10 reset=1; #10 signal=3'b111; #10 signal=3'b000; #900 signal=3'b111; #100 signal=3'b000; #900 signal=3'b011; #100 signal=3'b000; #900 signal=3'b001; #900 signal=3'b000; #100 $stop;end always #5 clk=~clk; final2 m(signal,reset,clk,light);endmodule Verilog数字电路设计 实验报告 院系: 组员: 年月日 Verilog实验报告 目录 分组概况....................................................................................................................................3 分组概况................................................................................................................................3 实验概况................................................................................................................................4 实验感想................................................................................................................................5 实验内容....................................................................................................................................9 实验一....................................................................................................................................9 实验二..................................................................................................................................15 实验三..................................................................................................................................25 实验四..................................................................................................................................33 Verilog实验报告 一、分组概况 组长: 主要负责各次实验的总体进程,以及选做实验的代码编译。在实验报告中负责统筹规划及后期编排。 组员: 负责各次实验必做实验源代码的录入及仿真。在实验报告中负责报告前期录入,包括各次实验的简要内容、步骤等。 Verilog实验报告 二、实验概况 本课程共安排四次实验,其内容是: 1、练习 一、简单的组合逻辑设计 练习 二、简单分频时序逻辑电路的设计 选做 一、设计一个字节(8位)的比较器 2、练习 三、利用条件语句实现计数分频时序电路 练习 五、用always块实现较复杂组合逻辑电路 选做 一、利用10MB时钟设计一个单周期波形 选做 二、运用always块设计一个8路数据选择器 3、练习 四、阻塞赋值与非阻塞赋值的区别 练习 六、在Verilog中使用函数 练习 七、在Verilog中使用任务 练习题 5、综合一个可以计算正整数平方、立方、阶乘的函数 思考题 3、在blocking模块中实现对两种写法的仿真 4、必做 一、设计一个串行数据检测器 必做 二、楼梯灯——基本任务 选做 一、楼梯灯——扩展任务 Verilog实验报告 三、感想 通过这4次的实验,我们基本熟悉Modelsim 软件,掌握了Modelsim 软件的编译、仿真方法。同时在编写程序的过程中,加深了我们对课上所讲的语法的认识以及学会了测试模块的编写。经过实验一,我们掌握了基本组合逻辑电路,基本时序电路;经过实验二,我们掌握条件语句在简单时序模块设计中的使用、在Verilog模块中应用计数器以及用always实现较大组合逻辑电路;经过实验三,我们掌握阻塞赋值与非阻塞赋值的概念与区别,了解函数的定义和在模块设计中的使用,掌握任务在verilog模块设计中的应用;经过实验四,我们掌握利用有限状态机实现一般时序逻辑分析的方法。在实验过程中,我们也遇到过程序编写以及软件仿真上的问题。程序编写时,要注意一些细节,比如符号,全角与半角等。软件仿真过程中,我们出现过程序无错,但添加波形运行后,却没有波形的情况,最后上网百度,找到了解决方法。实验总体来说,都比较顺利。对于难度较大的实验四,只要思路清晰,考虑到所有的情况,就能做出来。 Verilog实验报告 四、实验内容 第一次实验课: 练习一 简单的组合逻辑设计 实验目的:(1)掌握基本组合逻辑电路的实现方法(2)初步了解两种基本组合逻辑电路的生成方法(3)学习测试模块的编写(4)通过综合和布局布线了解不同层次仿真的物理意义 实验原理: 实验代码提供的是一个可综合的数据比较器。从语句中可以看出是比较数据a,b的结果,结果相同输出1,否则输出0.测试模块用于检测模块设计是否正确,给出输入信号,观察模块的内部信号和输出信号以确定设计是否正确。综合就是把compare.v文件送到synplify或其他综合器进行处理,启动综合器编译。布局布线就是把综合后的另一种文件(EDIF),在布线工具控制下进行处理,启动布局布线的编译。实验内容: 模块源代码的组合逻辑仿真与测试 实验代码: module compare(equal,a,b);inputa,b;output equal; assign equal =(a==b)?1:0; endmodule 实验仿真: 测试程序: `timescale 1ns/1ns `include “./compare.v” module t;rega,b;wire equal;initial begin a=0;b=0;#100 a=0;b=1;#100 a=1;b=1;#100 a=1;b=0; Verilog实验报告 #100 a=0;b=0;#100 $stop;end compare m(.equal(equal),.a(a),.b(b)); endmodule 仿真结果: 练习二 简单分频时序逻辑电路的设计 实验目的:(1)掌握最基本时序电路的实现方法(2)学习时序电路测试模块的编写(3)学习综合和不同层次的仿真 实验原理: 对于组合逻辑电路,可综合成具体电路结构的时序逻辑电路也有准确的表达方式。在可综合的模型中,通常用always块或者@(posedgeclk)或(negedgeclk)结构表达时序逻辑。实验为二分之一分频器模型。 在always块中,被赋值信号都必须定义为reg型,对于reg型数据,如果未对它进行赋值,仿真工具会认为它是不定态的。为了正确观察结果,在可综合模块中,常定义一个复位信号reset,其为低电平时对寄存器进行复位。实验内容: 分频时序电路的仿真测试 实验代码: 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 实验仿真: 测试程序: Verilog实验报告 `timescale 1ns/100ps `define clk_cycle 50 module top;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 m0(.reset(reset),.clk_in(clk),.clk_out(clk_out));endmodule 仿真结果: 选做一 设计一个字节(8位)比较器 实验内容: 比较两个字节的大小,若a[7:0]大于b[7:0],则输出高电平,否则输出低电平。 实验代码: module compare8(equal,a,b);input [7:0]a,b;output equal;reg equal;always@(a or b)if(a>b)equal=1;else equal=0;endmodule 实验仿真: 测试程序: `timescale 1ns/1ns Verilog实验报告 `include “./compare8.v” module test8;reg [7:0]a;reg [7:0]b;wire equal;initial begin a=8'b10000000;b=8'b00000000;#100 a=8'b00001000;b=8'b00001111;#100 a=8'b00001111;b=8'b00011111;#100 a=8'b11111111;b=8'b11111111;#100 a=8'b10101010;b=8'b00001111;#100 $stop;end compare8 m(.equal(equal),.a(a),.b(b));endmodule 仿真结果: 第二次实验课 练习三 利用条件语句实现计数分频时序电路 实验目的:(1)掌握条件语句在简单时序模块设计中的使用(2)学习在Verilog模块中应用计数器(3)学习测试模块的编写、综合和不同层次的仿真 实验原理: 在可综合的Verilog HDL模型中,常用的条件语句有if „else和case„endcase两种结构,用法和C语言相似。1.if语句(1)if(表达式)语句 (2)if(表达式)语句1 else语句2(3)if(表达式1)语句1; else if(表达式2)语句2; else if(表达式3)语句3; Verilog实验报告 „„ 2.case语句 (1)case(表达式) 进行所给代码计数分频器的仿真测试并观察输出波形 实验代码: modulefdivsion(RESET,F10M,F500K);input F10M,RESET;output F500K;reg F500K;reg [7:0]j;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/100ps `defineclk_cycle 50 moduledivision_top;reg F10M,RESET;wire F500K_clk;always #`clk_cycle F10M=~F10M;initial Verilog实验报告 begin RESET=1;F10M=0;#100 RESET=0;#100 RESET=1;#10000 $stop;end fdivsion m0(.RESET(RESET),.F10M(F10M),.F500K(F500K_clk));endmodule 仿真结果: 练习五 用always块实现较复杂的组合逻辑电路 实验目的: (1)掌握用always实现较大组合逻辑电路的方法; (2)进一步了解assign与always两种组合电路实现方法的区别和注意点;(3)学习测试模块中随机数的产生和应用;(4)学习综合不同层次的仿真,并比较结果。实验原理: (1)自触发always块: 例:采用非阻塞赋值的自触发振荡器 module osc2(clk);outputclk;regclk;initial #10 clk=0;always @(clk)#10 clk<=~clk;endmodule @(clk)的第一次触发之后,非阻塞赋值的RHS表达式便计算出来,并把值赋给LHS的时间并安排在更新事件队列中。在非阻塞赋值更新事件队列被激活之前,又遇到了@(clk)触发语句,并且always块再次对clk的值变化产生反应。当非阻塞LHS的值在同一时刻被更新时,@(clk)再一次触发。 本实验示例中使用了电平敏感的always块,所谓电平敏感的触发条件:@后的括号内电平里表中的任何一个电平发生变化(与时序逻辑不同,它在@后的括号内没有沿敏感关键词,如posedge或negedge),就能触发always块的动作。(2)assign与always Verilog实验报告 使用assign结构来实现组合逻辑电路,如果逻辑关系比较复杂,不容易理解语句的功能,而适当采用always来设计组合逻辑,使源代码语句的功能容易理解。 同一组合逻辑电路分别用always块和连续赋值语句assign描述时,代码的形式大相径庭,但在always中,若适当运用default(在case结构中)和else(在if„else结构中)语句时,通常可以综合为纯组合逻辑,尽管被赋值的变量一定要定义为reg型;若不使用default或else对默认项进行说明,则易生成意想不到的锁存器,这一点一定注意! 实验代码: `define plus 3'd0 `define minus 3'd1 `define band 3'd2 `definebor 3'd3 `defineunegate 3'd4 modulealu(out,opcode,a,b);output[7:0] out;reg[7:0] out;input[2:0] opcode;input[7:0] a,b;always@(opcode or a or b)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 实验仿真: 测试程序: `timescale 1ns/1ns `include “./alu.v” moduleaultest;wire[7:0] out;reg[7:0] a,b;reg[2:0] opcode;parameter times=5;initial begin a={$random}%256; Verilog实验报告 b={$random}%256;opcode=3'h0;repeat(times)begin #100 a={$random}%256;b={$random}%256;opcode=opcode+1;end #100 $stop;end alu alu1(out,opcode,a,b);endmodule 仿真结果: 选做 一、利用10MB时钟设计一个单周期波形 实验内容: 利用原有代码,自己编写模块源代码和测试模块代码,利用10M时钟,设计一个单周期形状的周期波形 实验代码: module fdivision2(RESET,clk,out);inputclk,RESET;output out;reg out;reg [15:0]j;always @(posedgeclk)if(!RESET)begin out<=0;j<=0;end else begin if(j==199)begin j<=j+1;out<=~out;end Verilog实验报告 else begin if(j==299)begin j<=j+1;out<=~out;end else if(j==499)j<=0;else j<=j+1;end end endmodule 实验仿真: 测试程序: `timescale 1ns/100ps `defineclk_cycle 50 modulefdivision_top;regclk,RESET;wireout_clk;always #`clk_cycleclk=~clk;initial begin RESET=1;clk=0;#1000 RESET=0;#1000 RESET=1;#100000 $stop;end fdivision2fdivision(.RESET(RESET),.clk(clk),.out(out_clk));endmodule 仿真结果: Verilog实验报告 选做 二、用always块实现较复杂的组合逻辑电路 实验内容: 运用always块设计一个8路数据选择器。要求:每路输入数据与输出数据均为4位2进制数,当选择开关(至少3位)或输入数据变化时,输出数据也相应的变化。 实验代码: module lianxi4(out,opcode,a,b,c,d,e,f,g,h);output[3:0] out;reg[3:0] out;input[2:0] opcode;input[3:0] a,b,c,d,e,f,g,h; always@(opcode or a or b or c or d or e or f or g or h)begin case(opcode)3'd0:out=a;3'd1:out=b;3'd2:out=c;3'd3:out=d;3'd4:out=e;3'd5:out=f;3'd6:out=g;3'd7:out=h;endcase end endmodule 实验仿真: 测试程序: `timescale 1ns/1ns `include “./lianxi4.v” module lianxi4_t;wire[3:0] out;reg[3:0] a,b,c,d,e,f,g,h;reg[2:0] opcode;parameter times=8;initial begin a={$random}%16;b={$random}%16;c={$random}%16;d={$random}%16;e={$random}%16; Verilog实验报告 f={$random}%16;g={$random}%16;h={$random}%16;opcode=3'b0;repeat(times)begin #100 a={$random}%16;b={$random}%16;c={$random}%16;d={$random}%16;e={$random}%16;f={$random}%16;g={$random}%16;h={$random}%16;opcode=opcode+1;仿真结果: Verilog实验报告 第三次实验课 练习四 阻塞赋值与非阻塞赋值的区别 实验目的: (1)通过实验,掌握阻塞赋值与非阻塞赋值的概念与区别;(2)了解非阻塞与阻塞赋值的不同使用场合; (3)学习测试模块的编写、综合和不同层次的仿真。实验原理: 非阻塞赋值方式:在语句块中,上面语句所赋的变量值不能立即就为下面的语句所用;块结束后才能完成这次赋值操作,而所赋的变量值是上一次赋值所得;在编写可综合的时序逻辑模块时,这是最常用的赋值方法。 阻塞赋值方式:赋值语句执行完后,块才结束;被赋的值才赋值语句执行完后立刻就改变;在时序逻辑中使用时,可能会产生意想不到的结果。 在always块中,阻塞赋值可以理解为赋值语句是顺序执行的,而非阻塞赋值可以理解为赋值语句是并发执行的。在时序逻辑设计中,通常使用非阻塞赋值语句,而在实现组合逻辑的assign结构中,或者always块结构中都必须采用阻塞赋值语句。 实验代码: module 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(“blocking:a=%d,b=%d,c=%d.”,a,b,c);end endmodule modulenonblocking(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(“nonblocking:a=%d,b=%d,c=%d.”,a,b,c);end endmodule 实验仿真: Verilog实验报告 测试程序: `timescale 1ns/100ps `include“./blocking.v” `include“./nonblocking.v” modulecomparetop;wire [3:0] b1,c1,b2,c2;reg[3:0] a;regclk;initial begin clk=0;forever #50 clk=~clk;end initial begin a=4'h3;$display(“_”);#100 a=4'h7;$display(“_”);#100 a=4'hf;$display(“_”);#100 a=4'ha;$display(“_”);#100 a=4'h2;$display(“_”);$stop;end nonblockingnonblocking(clk,a,b2,c2);blocking blocking(clk,a,b1,c1);endmodule 测试结果: 思考题3在blocking模块中实现对两种写法的仿真 实验内容: 在blocking模块中按如下两种写法,仿真与综合的结果会有什么样的变化?做出仿真波形。 实验代码: Verilog实验报告 module blocking1(clk,a,b,c);output[3:0] b,c;input [3:0] a;inputclk;reg [3:0] b,c;always@(posedgeclk)begin c=b;b=a;end endmodule module blocking2(clk,a,b,c);output[3:0] b,c;input [3:0] a;inputclk;reg [3:0] b,c;always@(posedgeclk)b=a;always@(posedgeclk)c=b;endmodule 实验仿真: 测试程序: `include“./blocking1.v” `include“./blocking2.v” module top;wire [3:0] b1,c1,b2,c2;reg[3:0] a;regclk;initial begin clk=0;forever #50 clk=~clk;end initial begin a=4'h3;$display(“_”);#100 a=4'h7;$display(“_”);#100 a=4'hf;$display(“_”);#100 a=4'ha;$display(“_”); Verilog实验报告 #100 a=4'h2;$display(“_”);$stop;end blocking2 blocking2(clk,a,b2,c2);blocking1 blocking1(clk,a,b1,c1);endmodule 测试结果: 练习六 在Verilog HDL中使用函数 实验目的: (1)了解函数的定义和在模块设计中的使用;(2)了解函数的综合性问题; (3)了解许多综合器不能综合复杂的算术运算。实验原理: 与一般的程序设计语言一样,Verilog HDL中也可使用函数以适应对不同变量采取同一种运算的操作。Verilog HDL函数在综合时被理解成具有独立运算功能的电路,每调用一次函数相当于改变这部分电路的输入以得到相应的计算结果。函数的目的是返回一个用于表达式的值。(1)函数定义 Function<返回值的类型或范围>(函数名); <端口说明语句> <变量类型说明语句> Begin <语句> „„ End Endfuction(2)函数调用 <函数名>(<表达式>,„<表达式>)实验内容: 采用同步时钟触发运算的执行,每个clk时钟周期都会执行一次运算,并且在测试模块中,通过调用系统任务$display及在时钟的下降沿显示每次计算的结果。 实验代码: moduletryfunct(clk,n,result,reset);output [31:0] result;input [3:0] n; Verilog实验报告 inputreset,clk;reg [31:0] result; always @(posedgeclk)begin if(!reset)result<=0;else begin result<=n*factorial(n)/((n*2)+1);end 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 endfunction endmodule 实验仿真: 测试程序: `include “./tryfunct.v” `timescale 1ns/1ns `define clk_cycle 50 module tryfunct_test;reg[3:0] n,i;reg reset,clk;wire [31:0] result; initial begin clk=0;n=0;reset=1;#100 reset=0;#100 reset=1;for(i=0;i<=15;i=i+1) Verilog实验报告 begin #200 n=i;end #100 $stop;end always #`clk_cycle clk=~clk; tryfunct m(.clk(clk),.n(n),.result(result),.reset(reset)); endmodule 测试结果: 练习七 在Verilog HDL中使用任务(task) 实验目的: (1)掌握任务在verilog模块设计中的应用; (2)学会在电平敏感列表的always中使用拼接操作、任务和阻塞赋值等语句,并生成复杂组合逻辑的高级方法。实验原理: 当我们希望能够将一些信号进行运算并输出多个结果时,采用函数结构就显得非常不方便,而任务结构在这方面的优势则十分突出。任务本身并不返回计算值,但它通过类似C语言中的形参与实参的数据变换,非常容易实现运算结果的调用。此外,还常常利用任务来包装模块设计中的许多复杂的过程,将许多复杂的操作步骤用一个命名清晰易懂的任务隐藏起来,大大提高程序可读性。(1)任务和函数的不同 函数只能与主模块共用同一个仿真时间单位,而任务可以定义自己的仿真时间单位;函数不能启动任务但任务能启动其他任务和函数;函数至少要有一个输入变量,而任务可以没有或有多个任何类型的变量;函数返回一个值,任务则不返回值。(2)任务定义 Task<任务名> <端口及数据类型声明语句> <语句1> „„ Endtask(3)任务调用 <任务名>(端口1,端口2,„端口n); 实验内容: Verilog实验报告 利用电平敏感的always快和一个比较两变量大小排序的任务,设计出四个(4位)并行输入数的高速排序组合逻辑。 实验代码: module sort4(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 @(a or b or c or d)begin {va,vb,vc,vd}={a,b,c,d};sort2(va,vc);sort2(vb,vd);sort2(va,vb);sort2(vc,vd);sort2(vb,vc);{ra,rb,rc,rd}={va,vb,vc,vd};end task sort2;inout[3:0] x,y;reg[3:0] tmp;if(x>y)begin tmp=x;x=y;y=tmp;end endtask endmodule 实验仿真: 测试程序: `timescale 1ns/100ps `include “sort4.v” moduletask_test;reg[3:0] a,b,c,d;wire[3:0] ra,rb,rc,rd; initial Verilog实验报告 begin a=0;b=0;c=0;d=0;repeat(50)begin #100 a={$random}%15;b={$random}%15;c={$random}%15;d={$random}%15;end #100 $stop;end sort4 sort4(.a(a),.b(b),.c(c),.d(d),.ra(ra),.rb(rb),.rc(rc),.rd(rd)); endmodule 测试结果: 选做一 综合一个可以计算整数平方、立方、阶乘的函数 实验内容: 设计一个函数,可以计算整数平方、立方、以及不大于5的阶乘 实验代码: modulelianxi(clk,n,opcode,result,reset);output [7:0] result;input [3:0] n,opcode;inputreset,clk;reg [7:0] result; always @(posedgeclk)begin if(!reset)result<=0;else begin case(opcode)3'd0: result<=pingfang(n); Verilog实验报告 3'd1: result<=lifang(n);3'd2: result<=jiecheng(n);default: result=8'hx;endcase end end function [7:0] jiecheng;input [3:0] operand;reg [3:0] index;begin jiecheng=operand?1:0;for(index=2;index<=operand;index=index+1)jiecheng=index*jiecheng;end endfunction function [7:0] pingfang;input [3:0] operand;pingfang=operand*operand;endfunction function [7:0] lifang;input [3:0] operand;lifang=operand*operand*operand;endfunction endmodule 实验仿真: 测试程序: `include “./lianxi.v” `timescale 1ns/1ns `define clk_cycle 50 module lianxi_test;reg[3:0] n,opcode;regreset,clk;wire [7:0] result;parameter times=20; initial begin clk=0; Verilog实验报告 n=0;reset=1;opcode=0;#100 reset=0;#100 reset=1;begin n={$random}%6;opcode={$random}%3;repeat(times)begin #100 n={$random}%6;opcode={$random}%3;end end #1000 $stop;end always #`clk_cycleclk=~clk; lianxi lian(.clk(clk),.n(n),.opcode(opcode),.result(result),.reset(reset)); endmodule 仿真结果: 第四次实验课 必做一[练习题七]设计一个串行数据检测器 实验目的: (1)掌握利用有限状态机实现一般时序逻辑分析的方法;(2)掌握用Verilog编写可综合的有限状态机的标准模板;(3)掌握用Verilog编写状态机模块的测试文件的一般方法。实验原理: (1)有限状态机 有限状态机是指输出取决于过去输入部分和当前输入部分的时序逻辑电路。一般来说,除了输入部分和输出部分外,有限状态机还含有一组具有“记忆”功能的寄存器,这些寄存器的功能是记忆有限状态机的内部状态,它们常被称为状态寄存 Verilog实验报告 器。在有限状态机中,状态寄存器的的下一个状态不仅与输入信号有关,而且还与该寄存器的当前状态有关,因此有限状态机又可以认为是组合逻辑和寄存器逻辑的一种组合。其中,寄存器逻辑的功能是存储有限状态机的内部状态;而组合逻辑又可以分为次态逻辑和输出逻辑两部分,次态逻辑的功能是确定有限状态机的下一个状态,输出逻辑的功能是确定有限状态机的输出。(2)有限状态机设计 逻辑抽象,得出状态装换图;状态化简;状态分配;选定触发器的类型并求出状态方程、驱动方程和输出方程;按照方程得出逻辑图。 在数字电路中我们已经学习过通过建立有限状态机来进行数字逻辑的设计,而在Verilog HDL硬件描述语言中,这种设计方法得到进一步的发展。通过Verilog HDL提供的语句,我们可以直观地设计出适合更为复杂的时序逻辑的电路。实验内容: 设计一个串行数据检测器。要求是:连续4个或4个以上为1时输出为1,其他输入情况下为0。编写测试模块对设计的模块进行各种层次的仿真,并观察波形,编写实验报告。 实验代码: module lianxiti7(x,z,clk,rst,state);inputx,clk,rst;output z;output[2:0]state;reg[2:0]state;wire z; parameter IDLE='d0,A='d1,B='d2,C='d3,D='d4; always@(posedgeclk)if(!rst)begin state<=IDLE;end else case(state)IDLE: state<=x ?A : IDLE;A: state<=x ?B : IDLE;B: state<=x ?C : IDLE;C: state<=x ?D :IDLE;D: state<=x ?state : IDLE; default:state=IDLE;endcase assign z=(state==D);endmodule Verilog实验报告 实验仿真: 测试程序: `timescale 1ns/1ns `include “./lianxiti7.v” modulelianxititop;regclk,rst;reg[23:0] data;wire[2:0] state;wirez,x;assign x=data[23];always #10 clk=~clk;always @(posedgeclk)data={data[22:0],data[23]}; initial begin clk=0;rst=1;#2 rst=0;#30 rst=1;data='b1001_1110_0111_1101_0101;#500 $stop;end lianxiti7 m(x,z,clk,rst,state);endmodule 仿真结果: 必做二 楼梯灯——基本任务 实验内容: 楼下到楼上依次有3个感应灯:灯 1、灯 2、灯3。当行人上下楼梯时,各个灯感应到后自动点亮,若在8s内感应信号消失,则点亮8s,若感应信号存在时间超过8s,则感应信号消失4s后灯自动关闭。 任务1:做出如上逻辑电路设计并仿真; 任务2:考虑去抖,对于感应信号到达存在毛刺(小于0.5s),设计逻辑并剔出。 实验代码: module loutid1(clk10,rst,switch,light); input clk10,rst;input[2:0]switch;output[2:0]light; reg[2:0]state1,state2,state3;reg[7:0]count1,count2,count3;reg[2:0]count_1,count_2,count_3;reg[2:0]light; parameter state1_start=3'b000,state2_start=3'b000,state3_start=3'b000,state1_work=3'b001,state2_work=3'b001,state3_work=3'b001,state1_up=3'b010,state2_up=3'b010,state3_up=3'b010,state1_down=3'b011,state2_down=3'b011,state3_down=3'b011,state1_other=3'b100,state2_other=3'b100,state3_other=3'b100; always@(posedge clk10)if(!rst)begin state1<=state1_start;count1<=8'b0;count_1<=3'b0;end else if(switch[0]=='b1&&count_1<4)count_1<=count_1+1;else case(state1) state1_start: if(switch[0]=='b1)begin state1<=state1_up;count1<=78;end Verilog实验报告 else begin state1<=state1_start;light[0]<='b0;end state1_up: begin light[0]<='b1; state1<=state1_work;end state1_work: if(count1>0)begin count1<=count1-1;end else if(switch[0]=='b0)begin state1<=state1_down;end else begin state1<=state1_other; count1<=39;end state1_other: if(switch[0]=='b1) state1<=state1_other;else if(count1>0)begin count1<=count1-1;end else state1<=state1_down; state1_down: begin light[0]<='b0;count_1<=3'b0;state1<=state1_start;end default: state1<=state1_start; endcase always@(posedge clk10)if(!rst)begin state2<=state2_start;count2<=8'b0;count_2<=3'b0;end else if(switch[1]=='b1&&count_2<4)count_2<=count_2+1;else case(state2) state2_start: if(switch[1]=='b1)begin state2<=state2_up;count2<=78;end else begin state2<=state2_start;light[1]<='b0;end state2_work: if(count2>0)begin count2<=count2-1;end else if(switch[1]=='b0)begin Verilog实验报告 state2<=state2_down;end else begin state2<=state2_other; count2<=39;end state2_other: if(switch[1]=='b1) state2<=state2_other;else if(count2>0)begin count2<=count2-1;end else state2<=state2_down; state2_down: begin light[1]<='b0; count_2<=3'b0; state2<=state2_start;end state2_up: begin light[1]<='b1; state2<=state2_work;end default: state2<=state2_start; endcase always@(posedge clk10)if(!rst)begin state3<=state3_start;count3<=8'b0;count_3<=3'b0;end else if(switch[2]=='b1&&count_3<4)count_3<=count_3+1;else case(state3) state3_start: if(switch[2]=='b1)begin state3<=state3_up;count3<=78;end else begin state3<=state3_start;light[2]<='b0;end state3_work: if(count3>0)begin count3<=count3-1;end else if(switch[2]=='b0)begin state3<=state3_down;end else begin state3<=state3_other; 实验仿真: 测试程序: `timescale 10ms/1ms module loutid1_t;reg clk10,rst;reg[2:0] swh;wire[2:0] light; Verilog实验报告 count3<=39;end state3_other: if(switch[2]=='b1) state3<=state3_other;else if(count3>0)begin count3<=count3-1;end else state3<=state3_down; state3_down: begin light[2]<='b0; count_3<=3'b0; state3<=state3_start;end state3_up: begin light[2]<='b1; state3<=state3_work;end default: state3<=state3_start; endcase endmodule Verilog实验报告 parameter HALF_PERIOD = 5; always #HALF_PERIOD clk10=~clk10; initial begin clk10 = 0; rst = 1; swh=3'b000; #1 rst = 0; #10 rst = 1; #100 swh=3'b000; #100 swh=3'b001;#400 swh=3'b000;#40 swh=3'b001;#500 swh=3'b010;#900 swh=3'b000;#400 swh=3'b100;#400 swh=3'b000;#600 swh=3'b001;#40 swh=3'b000; #1000 $stop;end 仿真结果: 选做一:楼梯灯——拓展任务 实验内容: 任务3:若为节约能源,下一个灯点亮的同时将自动关闭上一个灯,作出如上逻辑设计并仿真(仅考虑一个人的情况); 任务4:考虑存在多个人上下楼梯的情况,比如: 行人1已经从灯1到达灯2,灯2受感应自动点亮,但此时行人2刚上楼梯到达灯1的位置,则灯1和灯2都须点亮,更加复杂一点,如果行人2是下楼梯刚到达灯3位置,作出如上逻辑设计并仿真; 实验代码: modulelight_All(clk10,rst,switch,light); input clk10,rst;input[2:0]switch;output[2:0]light; reg[2:0]state1,state2,state3;reg[7:0]count1,count2,count3;reg[2:0]count_1,count_2,count_3;reg[2:0]light; parameter state1_start=3'b000,state2_start=3'b000,state3_start=3'b000,state1_work=3'b001,state2_work=3'b001,state3_work=3'b001,state1_up=3'b010,state2_up=3'b010,state3_up=3'b010,state1_down=3'b011,state2_down=3'b011,state3_down=3'b011,state1_other=3'b100,state2_other=3'b100,state3_other=3'b100; always@(posedge clk10)if(!rst)begin state1<=state1_start;count1<=8'b0;count_1<=3'b0;end else if(switch[0]=='b1&&count_1<4)count_1<=count_1+1;else case(state1) state1_start: if(switch[0]=='b1) Verilog实验报告 begin state1<=state1_up;count1<=78;end else begin state1<=state1_start;light[0]<='b0;end state1_work: if(count1>0)begin count1<=count1-1; if(switch[0]=='b0&&(state2==3'b010||state3==3'b010))begin light[0]<='b0;state1<=state1_down;end end else if(switch[0]=='b0)begin state1<=state1_down;end else begin state1<=state1_other;count1<=39;end state1_other: if(switch[0]=='b1) state1<=state1_other;else if(count1>0)begin count1<=count1-1;if(switch[0]=='b0&&(state2==3'b010||state3==3'b010))begin light[0]<='b0;state1<=state1_down;end end else state1<=state1_down; state1_down: begin light[0]<='b0;count_1<=3'b0;state1<=state1_start;end state1_up: begin light[0]<='b1;state1<=state1_work;end default: state1<=state1_start; endcase always@(posedge clk10)if(!rst)begin state2<=state2_start;count2<=8'b0;count_2<=3'b0;end else if(switch[1]=='b1&&count_2<4)count_2<=count_2+1;else case(state2) state2_start: if(switch[1]=='b1)begin state2<=state2_up;count2<=78; Verilog实验报告 end else begin state2<=state2_start;light[1]<='b0;end state2_work: if(count2>0)begin count2<=count2-1; if(switch[1]=='b0&&(state1==3'b010||state3==3'b010))begin light[1]<='b0;state2<=state2_down;end end else if(switch[1]=='b0)begin state2<=state2_down;end else begin state2<=state2_other;count2<=39;end state2_other: if(switch[1]=='b1) state2<=state2_other;else if(count2>0)begin count2<=count2-1;if(switch[1]=='b0&&(state1==3'b010||state3==3'b010))begin light[1]<='b0; state2<=state2_down;end end else state2<=state2_down; state2_down: begin light[1]<='b0;count_2<=3'b0;state2<=state2_start;end state2_up: begin light[1]<='b1;state2<=state2_work;end default: state2<=state2_start; endcase always@(posedge clk10)if(!rst)begin state3<=state3_start;count3<=8'b0;count_3<=3'b0;end else if(switch[2]=='b1&&count_3<4)count_3<=count_3+1;else case(state3) state3_start: if(switch[2]=='b1)begin state3<=state3_up;count3<=78;end else begin state3<=state3_start; Verilog实验报告 light[2]<='b0;end state3_work: if(count3>0)begin count3<=count3-1; if(switch[2]=='b0&&(state1==3'b010||state2==3'b010))begin light[2]<='b0;state3<=state3_down;end end else if(switch[2]=='b0)begin state3<=state3_down;end else begin state3<=state3_other;count3<=39;end state3_other: if(switch[2]=='b1) state3<=state3_other;else if(count3>0)begin count3<=count3-1;if(switch[2]=='b0&&(state1==3'b010||state2==3'b010))begin light[2]<='b0; state3<=state3_down;end end else state3<=state3_down; Verilog实验报告 state3_down: begin light[2]<='b0;count_3<=3'b0;state3<=state3_start;end state3_up: begin light[2]<='b1; state3<=state3_work;end default: state3<=state3_start; endcase endmodule实验仿真: 测试程序: `timescale 10ms/1ms moduletest_light_All;reg clk10,rst;reg[2:0] up,down;wire[2:0] swh;wire[2:0] light; parameter HALF_PERIOD = 5; always #HALF_PERIOD clk10=~clk10; initial begin clk10 = 0; rst = 1; up = 3'b000;down = 3'b000; #1 rst = 0; #10 rst = 1; #100 up = 3'b001;down = 3'b000; #300 up =3'b010;down = 3'b000; #600 up = 3'b010;down = 3'b010; #30 up = 3'b010; #900 up = 3'b100;down = 3'b001; #1000 $stop; end assignswh = up | down; light_Allm5(clk10,rst,swh,light);endmodul仿真结果: 华大计科学院 数字逻辑课程设计说明书 题目: 多功能数字钟 专业: 计算机科学与技术 班级: 网络工程1班 姓名: 刘群 学号: 1125111023 完成日期: 2013-9 一、设计题目与要求 设计题目:多功能数字钟 设计要求: 1.准确计时,以数字形式显示时、分、秒的时间。2.小时的计时可以为“12翻1”或“23翻0”的形式。 3.可以进行时、分、秒时间的校正。 二、设计原理及其框图 1.数字钟的构成 数字钟实际上是一个对标准频率1HZ)进行计数的计数电路。由于计数的起始时间不可能与标准时间(如北京时间)一致,故需要在电路上加一个校时电路。图 1 所示为数字钟的一般构成框图。 图1 数字电子时钟方案框图 ⑴多谐振荡器电路 多谐振荡器电路给数字钟提供一个频率1Hz 的信号,可保证数字钟的走时准确及稳定。⑵时间计数器电路 时间计数电路由秒个位和秒十位计数器、分个位和分十位计数器及时个位和时十位计数器电路构成。其中秒个位和秒十位计数器、分个位和分十位计数器为60 进制计数器。而根据设计要求,时个位和时十位计数器为24 进制计数器。⑶译码驱动电路 译码驱动电路将计数器输出的8421BCD 码转换为数码管需要的逻辑状态,并且为保证数码管正常工作提供足够的工作电流。⑷数码管 数码管通常有发光二极管(LED)数码管和液晶(LCD)数码管。本设计提供的为LED数码管。2.数字钟的工作原理 ⑴多谐振荡器电路 555 定时器与电阻R1、R2,电容C1、C2 构成一个多谐振荡器,利用电容的充放电来调节输出V0,产生矩形脉冲波作为时钟信号,因为是数字钟,所以应选择的电阻电容值使频率为1HZ。⑵时间计数单元 六片74LS90 芯片构成计数电路,按时间进制从右到左构成从低位向高位的进位电路,并通过译码显示。在六位LED 七段显示起上显示对应的数值。⑶校时电源电路 当重新接通电源或走时出现误差时都需要对时间进行校正。通常,校正时间的方法是:首先截断正常的计数通路,然后再进行人工出触发计数或将频率较高的方波信号加到需要校正的计数单元的输入端,校正好后,再转入正常计时状态即可。 根据要求,数字钟应具有分校正和时校正功能。因此,应截断分个位和时个位的直接计数通路,并采用正常计时信号与校正信号可以随时切换的电路接入其中。图8所示即为带有基本RS 触发器的校时电路。 三、元器件 1.实验中所需的器材 单刀双掷开关4 个.5V 电源.共阴七段数码管 6 个.74LS90D 集成块 6 块.74HC00D 6个 LM555CM 1个 电阻 6个 10uF 电容 2个 2.芯片内部结构及引脚图 图2 LM555CM集成块 图3 74LS90D集成块 五、各功能块电路图 1秒脉冲发生器主要由555 定时器和一些电阻电容构成,原理是利用555 定时器的特性,通过电容的充放电使VC 在高、低电平之间转换。其中555 定时器的高、低电平的门阀电压分别是2/3VCC 和1/3VCC电容器充电使VC 的电压大于2/3VCC 则VC 就为高电平,然 而由于反馈作用又会使电容放电。当VC 小于1/3VCC 时,VC 就为低电平。同样由于反馈作用又会使电容充电。通过555 定时器的这一性质我们就可以通过计算使他充放电的周期刚好为1S这样我们就会得到1HZ 的信号。其中555 定时器的一些功能对照后面目录。其中 555 定时器组成的脉冲发生器电路见附图4.图4 555 定时器组成的脉冲发生器 由于我们要得到1HZ 的信号,所以我们就可以通过555 定时器充放电一次所需的时间的公式。将那时间设为1S然后设定两个电阻计算出另外那个电容值.在设定电阻值时我们要记住将电阻值设为比较常用的那种电阻值,得到的电容值也尽可能让它是比较普遍使用 的。这样就避免了在实际组装过程中很难买到当初设定的那电阻和计算出 的电容值。 在这次设定中我们设定的电阻值RA=10KΩ,RB=62kΩ,C=10uF 经公式 f = 1.43 ÷【(RA + 2RB)×C 】 可得近似为1HZ。 2、利用一个LED 数码管一块74LS90D 连接成一个十进制计数器,电路在晶振的作用下数码管从0—9 显示见图5。 图5、利用2 片74LS90D 芯片连接成一个六十进制电路,电路可从0—59 显示。第一片74LS90D芯片构成10 进制计数器,第二片74LS90D 芯片构成6 进制计数器。74LS90D 具有异步清零功能。 在第一片74ls90 构成的十进制计数器中,当第十个脉冲来到时。此时他的四级触发器的状态为“1001”。这时他就会自动清零。同时给第二片74ls90 构成的6 进制计数器进一,第六个脉冲进位到来时,此时第二片74ls90 芯片的触发器的状态为“0110”,这时QB,QC 均为高电平。将QB 与RO1 相连,将Ro2 与Qc 相连,就会进行异步清零。如此循环就会构成60 进制计数器.见附图6.图6 十六进制电路 4、利用2 片74LS90D 芯片构成24 进制计数器。一片构成二进制计数器,一片构成四进制计数器。由于74LS90D 芯片清零是由两个清零端控制的,所以当第24 个脉冲到来时,第一片74lLS90D芯片的Qc 为高电平。第二片74LS90D 芯片的Qb 为高电平,让第一片74LS90D 芯片的Qc 与两片芯片的Ro1 相连.让第二片74ls90 芯片的QB 与两片芯片的Ro2 相连。当第24 个脉冲到来时就会进行异步清零。如此循环就会构成24 进制计数器。见附图7.图7 24进制电路 5、数字钟电路由于秒信号的精确性和稳定性不可能坐到完全准确无误,又因为电路中其他的原因数字钟总会产生走时误差的现象。所以,电路中就应该有校准时间功能的电路。在这次设计中教时电路用的是一个RS 基本触发器的单刀双置开关,每搬动开关一次产生一个计数脉冲.实现校时功能。见附图8。 7、利用两个六十进制和一个二十四进制连接成一个时、分、秒都会进位的电路总图。见附图8 图8 总电路图 六、心得体会 在这次设计中我们深深地体会到了理论跟实践的不同,理论学的再好不会动手那也只能是纸上谈兵。我们了解了集成电路芯片的型号命名规律,懂得了没有某种芯片时的替代方法,以及在网上查找电子电路资料的方法,掌握了各芯片的逻辑功能及使用方法,进一步熟悉了集成电路的引脚安排,掌握了数字钟的设计方法,明白了数字钟的组成原理以及工作原理。掌握了计数器的工作原理,以及计数器进制的组成方法和级联方法,实现了一次理论指导实践、理论向实践过渡的跨越,虽然期间遇到一些困难,但这些困难却增强了我们分析问题、解决问题的能力,使我们以后不仅只学习书本中的理论知识,而且知道学以致用,动过动手实践是我们对书本中的理论知识掌握地跟牢固、理解地跟深刻,这对我们今后的工作及学习有积极的影响。这次课程设计不仅再次复习了数字电子和模拟电子,而且让我对于芯片的使用更加了解。增加了我的动手操作能力,加深了对该软件的了解。这就是这次课程设计的成果,相信这些实际的操作经验会是我们以后的宝贵财富。 数字电子技术设计性实验报告 设计题目: 专业 班级 学号 学生姓名 指导教师 教师评分 年月日 数字电子实习报告 班级: 姓名: 学号: 课程设计任务书 一、设计题目 本次课程设计的题目为:汽车尾灯模拟控制电路设计 二、功能要求: 利用开关来控制汽车的运行和转向。 三、设计要求 1.设计过程:先写总体设计方案(包括框图和总电路图),然后是各个模块 的设计(要求有相应的电路图),结果分析。2.完成电路硬件制做。3.最后是设计总结。 四、所需器件 74LS76; 双JK触发器 LED:6个; 74LS04:2个; 六非门 74LS138; 3线8线译码器 74LS00:2个; 2输入四个 与非门 74LS10; 3输入三个 与非门 74LS86; 2输入四 异或门 开关:2个; 电阻:200Ω,8个; 电源:+5v; 要求查阅相关芯片资料,用所给芯片设计电路 设计过程 主电路图 2.电路结构与原理图 (1)开关控制电路(如图2) 图2 开关控制电路 开关两端一端接高电平,一端接地(低电平)。74LS86D与74LS138的输入控制端连接,当开关同时闭合或断开的时候,输入相同,74LS86输出为“0”,则74LS138不译码。若两开关同时断开,则74LS04D的输出为“1”;而74LS10D接有CP脉冲,所以此时74LS00D的输出完全决定于CP脉冲;当两开关同时闭合,74LS00D输出为“1”; B开关打开;B开关闭合,A开关打开时的分析也按照上面的方法来分析实现。 (2)三进制计数器电路(如图3) 图3 三进制计数器电路 三进制计数电路由2个主从JK触发器构成。第一个主从JK触发器的输出Q1端直接接入74LS138译码器的输入端,第二个主从JK触发器的输出Q2端输入也直接接入74LS138的输入端,同时,第二个主从JK触发器的另一端输出直接作为第一个主从JK触发器的J端输入,注意,Q2应比Q1的权高。并且,两个主从JK触发器的K端输入都是接的高电平,这样就能使变化后的脉冲的周期为3,从而实现了三进制计数。 (3)译码电路(如图4) 图4 译码电路 74LS138译码器是一种经常使用的3线8线译码器,如图所示,4、5端接地,6端接控制电路提供的控制信号,1、2、3分别第一个和第二个主从JK触发器的输出信号Q1、Q2、和控制电路的控制信号。由于只要求有6个指示灯,所以在74LS138的输出端只接了6个端口(左转弯:Y0 Y1 Y2;右转弯 :Y4 Y5 Y6)用以控制信号灯。并且,按照以下真值表来实现。 (4)驱动电路:如图5 图5 驱动电路 使用发光二极管来显示运行结果。发光二极管正端接5V电源,当非门的右边输入的是高电平,则经过非门以后变成低电平,则发光二极管亮;当非门的右边输入的为低电平,则经过非门以后变成高电平,则发光二极管熄灭。第二篇:北航eda实验报告数字部分
第三篇:数字电子时钟实验报告
第四篇:数字电子技术设计性实验报告
第五篇:数字电子实习报告