电子课程设计——基于Verilog的乒乓游戏设计电路学院:专业、班级:姓名:学号:指导教师:2014年12月引言可编程器件的广泛应用,为数字系统的设计带来了极大的灵活性。
可编程器件可以通过软件编程对硬件的结构和工作方式进行重构,使得硬件的设计可以如同软件设计那样快捷方便。
高速发展的FPGA、CPLD兼有串、并行工作方式和高速、高可靠性的特点,在电子系统设计中得到了广泛应用。
通常使用硬件描述语言(Hardware Description Language,HDL)进行数字电子系统设计。
目前应用广泛的硬件描述语言有:VHDL语言,Verilog HDL语言,AHDL语言。
Verilog语言由于具有强大的行为描述能力和丰富的仿真语句从而成为系统设计领域最佳的硬件描述语言。
鉴于如上所述,本系统使用Verilog语言进行设计,采用自上向下的设计方法。
利用Quartus II 9.1 进行Verilog程序的编译与综合,然后用Modelism SE 6.0进行功能仿真和时序仿真,并使用EDA实验箱进行下载验证。
基于Verilog的乒乓游戏设计电路一、设计任务与要求任务:设计一个乒乓球游戏机,模拟乒乓球比赛的基本过程和规则,并能裁判和自动计分。
要求如下:1.使用乒乓球游戏机的甲乙双方在不同的位置罚球或击球。
2.乒乓球的位置和移动方向可由发光二极管和依次点亮的方向决定,为球的移动速度为一定值(我们设计中设为0.5秒移动一位)。
使用者可按乒乓球的位置发出相应的动作,在其他时候击球视为犯规,给对方加一分;都犯规双方各加一分。
二、总体框图设计思路根据乒乓球比赛的过程和规则,首先游戏开始,如果一方非正确击球则另一方加分,当分数大于11时获胜,游戏结束,系统设计流程图如图1所示。
图2给出了乒乓球游戏机的原理图。
用5个发光二极管代表乒乓球,在游戏机两侧各设置二个开关,一个是发球开关,一个是击球开关。
即若A方按动发球开关时,靠近A方的第一灯亮,然后二极管由A向B逐次点亮,代表乒乓球在移动。
当过网后,B就可以击球,否则判B方失分,A方自动加分,重新发球比赛继续进行到一方计分到11分,该局结束,计分牌清零,可以开始新的一局比赛。
反之B发球时也一样。
将核心模块分俩个进程:第一个实现逻辑功能,第二个将整数记分转换为十进制数,便于译码显示;得分显示模块用七段译码器。
各个状态间的转移控制要根据要求来改变转移的状态由于设计要求实现LED灯依此从左到右,或从右到左的移动,同时球拍击球。
若击中,则球向相反方向移动,若未击中,则对方得1分。
就其功能,若要实现记分,就得用到7段数码管,考虑到硬件要求,考虑用动态扫描技术来解决。
动态扫描前要进行译码,即把记数得分的结果译码成七段码。
设计方案完全用Verilog HDL语言编写程序。
三、器件选择1、装有QuartusII软件的计算机一台。
2、EDA实验箱一个(1)7段数码显示管。
(2)5个LED灯。
(3)芯片:使用Altera公司生产的CycloneIV芯片,选用EP4CE6E22C8片。
四、功能模块1、实现整个设计的逻辑功能,当游戏开始时,先通过clr对整个系统进行清零,在输入clk上升沿有效的条件下,甲方开始发球,LED灯从距离甲方最近的一个开始闪亮,并依次向乙方移动,过了网后乙方就可以击球,若乙方击球成功,则球按原路返回,再次过网后甲方就可击球,若甲击球成功,则按以上游戏一直进行下去,若有一方击球失败或提前击球,对方在记分牌上自动记一分;当其中的一方记满11分时比赛结束,清零后可开始下一局。
2、将整数计分转换为十进制数,便于译码显示。
当甲乙双方的记分低位到达9时使低位清零,同时使高位加1,以便正确地在数码管上显示得分。
clr为乒乓球游戏清零键,af为A方发球控制键,aj接球键;bf为乙方发球控制键,bj接球键;clk为控制乒乓球行进速度的时钟信号,接50MHZ时钟信号源;shift为LED灯显示输出端,接5个LED显示灯;计分要经过译码器译码后接8位共阴极数码显示管。
Verilog HDL程序module lqq (shift,scan,seg7,clk50Mhz,clr,af,aj,bf,bj); output[4:0] shift;output[3:0] scan;output[6:0] seg7;input clk50Mhz; //50Mhz时钟信号input af; //A方发球input aj; //A方击球input bf; //B方发球input bj; //B方击球input clr;//系统复位段reg[4:0] shift; //5个LED代表乒乓球甲左乙右)reg[3:0] scan; //数码管地址选择信号reg[6:0] seg7; //7段显示控制信号(abcdefg)reg clk1,clk2;reg[3:0] a_score,b_score;reg[1:0] cnt;reg[3:0] data;reg[3:0] a_one,a_ten,b_one,b_ten;reg[23:0] count,count1;reg a,b; //A和B的控制位reg[4:0] shift_1;//-------------2hz分频--------------always@(posedge clk50Mhz)beginif(count==24'd25000)begin clk1<=~clk1;count=0;endelse begin count<=count+1;endendalways@(posedge clk1)beginif(count1==24'd250)begin clk2<=~clk2;count1=0;endelse begin count1<=count1+1;endif(cnt==2'b11)begin cnt<=2'b00;endelsebegin cnt<=cnt+1;endend//乒乓球游戏规则always@(posedge clk2)beginif(clr)begin a_score<=0;b_score<=0;a<=0;b<=0;shift_1<=0;endelsebeginif(!a&&!b&&af) //如果A发球begin a<=1;shift_1<=5'b10000;end //A的控制位置1else if(!a&&!b&&bf)begin b<=1;shift_1<=5'b00001;end //B的控制位置1 else if(a&&!b) //球从A向B移动beginif(shift_1>5'b00100) //如果没到球网B击球,则A加分beginif(bj)begina_score<=a_score+1;a<=0;b<=0;shift_1<=5'b00000;endelse //如果B一直没有接球,则A加分begin shift_1[4:0]<=shift_1[4:0]>>1;endendelse if(shift_1==5'b0)begin a_score<=a_score+1;a<=0;b<=0;endelsebeginif(bj) //如果B击球成功,则B的控制位置1,A的控制位清零begin a<=0;b<=1;endelsebegin shift_1[4:0]<=shift_1[4:0]>>1;endendendelse if(b&&!a) // 球从B向A移动beginif(shift_1<5'b00100&&shift_1!=5'b0)beginif(aj) //如果没到球网A击球,则B加分beginb_score<=b_score+1;a<=0;b<=0;shift_1<=5'b00000;endelsebegin shift_1[4:0]<=shift_1[4:0]<<1;endendelse if(shift_1==5'b0) //如果A一直没接球,则B加分begin b_score<=b_score+1;a<=0;b<=0;endelsebeginif(aj) //如果A击球成功,则A的控制位置1,B的控制位置清零begin a<=1;b<=0;endelsebegin shift_1[4:0]<=shift_1[4:0]<<1;endendendendshift<=shift_1;if(a_score==4'b1011&&!clr)begin a_score<=a_score;b_score<=b_score;endif(b_score==4'b1011&&!clr)begin a_score<=a_score;b_score<=b_score;endend//---------将A和B的计分换成BCD码---------- always@(posedge clk2)begincase(a_score[3:0])4'b0000:begin a_one<=4'b0000;a_ten<=4'b0000;end 4'b0001:begin a_one<=4'b0001;a_ten<=4'b0000;end 4'b0010:begin a_one<=4'b0010;a_ten<=4'b0000;end 4'b0011:begin a_one<=4'b0011;a_ten<=4'b0000;end 4'b0100:begin a_one<=4'b0100;a_ten<=4'b0000;end 4'b0101:begin a_one<=4'b0101;a_ten<=4'b0000;end 4'b0110:begin a_one<=4'b0110;a_ten<=4'b0000;end 4'b0111:begin a_one<=4'b0111;a_ten<=4'b0000;end 4'b1000:begin a_one<=4'b1000;a_ten<=4'b0000;end 4'b1001:begin a_one<=4'b1001;a_ten<=4'b0000;end 4'b1010:begin a_one<=4'b0000;a_ten<=4'b0001;end 4'b0011:begin a_one<=4'b0001;a_ten<=4'b0001;end default:begin a_one<=4'bx;a_ten<=4'bx;end endcaseendalways@(b_score[3:0])case(b_score[3:0])4'b0000:begin b_one<=4'b0000;b_ten<=4'b0000;end4'b0001:begin b_one<=4'b0001;b_ten<=4'b0000;end 4'b0010:begin b_one<=4'b0010;b_ten<=4'b0000;end 4'b0011:begin b_one<=4'b0011;b_ten<=4'b0000;end 4'b0100:begin b_one<=4'b0100;b_ten<=4'b0000;end 4'b0101:begin b_one<=4'b0101;b_ten<=4'b0000;end 4'b0110:begin b_one<=4'b0110;b_ten<=4'b0000;end 4'b0111:begin b_one<=4'b0111;b_ten<=4'b0000;end 4'b1000:begin b_one<=4'b1000;b_ten<=4'b0000;end 4'b1001:begin b_one<=4'b1001;b_ten<=4'b0000;end 4'b1010:begin b_one<=4'b0000;b_ten<=4'b0001;end 4'b0011:begin b_one<=4'b0001;b_ten<=4'b0001;end default:begin b_one<=8'bx;b_ten<=8'bx;end endcase//----------数码管动态扫描--------------always@(posedge clk1)begincase(cnt[1:0])2'b00:begin data<=b_one;scan<=4'b1110;end2'b01:begin data<=b_ten;scan<=4'b1101;end2'b10:begin data<=a_one;scan<=4'b1011;end2'b11:begin data<=a_ten;scan<=4'b0111;end default:begin data<=4'bx;scan<=4'bx;endendcase//----------------七段译码---------------- case(data[3:0])4'b0000: seg7[6:0]=7'h3f;4'b0001: seg7[6:0]=7'h06;4'b0010: seg7[6:0]=7'h5b;4'b0011: seg7[6:0]=7'h4f;4'b0100: seg7[6:0]=7'h66;4'b0101: seg7[6:0]=7'h6d;4'b0110: seg7[6:0]=7'h7d;4'b0111: seg7[6:0]=7'h07;4'b1000: seg7[6:0]=7'h7f;4'b1001: seg7[6:0]=7'h6f;default: seg7[6:0]=7'hx;endcaseendendmodule五、总体设计电路图硬件连接情况:af、aj、bf、bj连接实验箱上的K1、K2、K4、K5 clr连接K12作为系统复位端shift[0]……shift[4]连接实验箱上的L1、L2、L3、L4、L5scan[0]……scan[3]连接实验箱上的LED_C1 、LED_C2、 LED_C3、LED_C4seg[0]……seg[6]连接实验箱上的LED_A、LED_B、LED_C、LED_D、LED_E、LED_F、LED_G管脚分配图波形仿真图A方发球B方不接球A方发球B提前接球犯规B方发球A不接球B方发球A提前接球犯规AB僵持球实验箱连接图:六、心得体会Verilog HDL硬件描述语言打破了硬件和软件设计人员之间互不干涉的界限,可使用语言的形式来进行数字系统的硬件结构、行为的描述,直接设计数字电路硬件系统,通过编程、下载后,该芯片已经具备了原来需要使用复杂的数字电路实现的功能;这样,使用语言描述大大缩短了开发周期,减少了开发难度,并使得系统更加灵活、稳健。