前言 EDA是电子设计自动化(Electronic Design Automation)的缩写,在20世纪90年代初从计算机辅助设计(CAD)、计算机辅助制造(CAM)、计算机辅助测试(CAT)和计算机辅助工程(CAE)的概念发展而来的。EDA技术就是以计算机为工具,设计者在EDA软件平台上,用硬件描述语言VHDL完成设计文件,然后由计算机自动地完成逻辑编译、化简、分割、综合、优化、布局、布线和仿真, 直至对于特定目标芯片的适配编译、逻辑映射和编程下载等工作。EDA技术在进入21世纪后,得到了更大的发展,突出表现在以下几个方面: (1)使电子设计成果以自主知识产权(IP)的方式得以明确表达和确认成为可能。
(2)在仿真验证和设计两方面都支持标准硬件描述语言的功能强大的EDA软件不断推出。
(3)电子技术全方位进入EDA时代。除了日益成熟的数字技术外,传统的电路系统设计建模理念发生了重大的变化:软件无线电技术的崛起,模拟电路系统硬件描述语言的表达和设计的标准化,系统可编程模拟器件的出现,软硬件技术,软硬件功能及其结构的进一步融合等。 一、课程设计目的 本课程设计是在《CPLD技术及应用》课程的基础上,通过软件编程及仿真调试的实践,进一步掌握使用Verilog HDL语言描述数字电路的原理和应用方法,是毕业设计前的一次重要实践,为今后从事EDA设计相关工作岗位打下良好的基础。 二、设计题目及要求 2.1 设计题目: 乒乓球游戏机数字电路系统设计 2.2 功能实现: 运用状态机技术完成一个乒乓球游戏机的数字电路系统设计,将游戏双方的得分通过两个数码管进行显示。 乒乓球游戏规则: (1)乒乓球游戏双方各使用1个按键为“球拍”,开发板的8个LED用于指示乒乓球移动轨迹,点亮的那个LED为当前乒乓球所在位置。 (2)发球方按下按键表示发球,LED灯按一定的时间间隔,依次向对方移动。当LED亮到离对方最近的一个,之后的时间间隔内,对方按下按键表示成功接球,接球后LED向对方移动;否则,表示对方输球。 (3)接球时,LED没有亮到最近的一个时就按下按键,视为犯规,对方加1分。 (4)用两个数码管分别表示双方得分,最先到9分者胜出。
2.3 设计要求: 理解和熟练使用Quartus II软件、状态机、顶层文件和例化语句,用Quartus II完成编程和调试,下载到开发板中实现设定的功能,并完成课程设计报告。 1.LED移动间隔为1s。 2.数码管DP1和DP2用于显示双方比分。
三、设计原理说明 3.1 显示模块 使用数码管驱动芯片CH452来驱动各数码管显示,两个数码管显示乒乓球游戏双方的比分。 3.2 乒乓游戏模块 乒乓球游戏双方各使用1个按键为“球拍”,开发板的8个LED用于指示乒乓球移动轨迹,点亮的那个LED为当前乒乓球所在位置。发球方按下按键表示发球,LED灯按一定的时间间隔,依次向对方移动。当LED亮到离对方最近的一个,之后的时间间隔内,对方按下按键表示成功接球,接球后LED向对方移动;否则,表示对方输球。 3.3 按键模块 用两个按键分别表示乒乓球游戏双方的“球拍”,用一个按键作为系统的复位信号。 3.4 设计方案 整个设计方案可以分成时钟分频、乒乓球游戏机、显示数据转换、数码管显示控制和顶层模块等5大模块。 时钟分频:产生100Khz的输出时钟,为其他4个模块提供时钟。 乒乓球游戏机:完成乒乓球游戏设计,并将双方得分输出给显示数据转换模块。 显示数据转换:接收来自乒乓球游戏机模块和时间数据读取模块的得分和时间数据,转换成数码管显示地址和数据。 数码管显示控制:接收显示数据转换模块的数据,并送到各数码管显示。 顶层模块:连接各个模块。 四、软件设计 (含状态转换图、带注释的程序清单)
1.乒乓球游戏机状态转换: S0:复位状态,判断发球权。如果左右键同时为0或1→S0,如果左键为1→S1,如果右键为1→S4。 S1:左方发球或成功接球; S2:球从左方向右方右移;移动过程中,如果右方接球就给左方加一分,并将球权给左方; S3:判断右方是否在规定时间内内接球; S4:右方发球或成功接球; S5:球从右方向左方左移;移动过 程中,如果左方接球就给右方加一分,并将球权给右方; S6:判断左方是否在规定时间内接球; 2.各模块程序设计 (1)时钟分频模块 - module clk_div(clk_in, clk_out);
- input clk_in;
- output clk_out;
-
- reg [25:0] cnter;
- reg clk_out;
-
- parameter m=500;
-
- always @(posedge clk_in)
- begin
- if(cnter == m)
- begin
- clk_out<=1;
- cnter<=0;
- end
- else
- begin
- clk_out<=0;
- cnter<=cnter+1;
- end
- end
- endmodule
复制代码
//产生一个时钟信号,作为其他语句模块的时钟输入。
- [color=rgb(0, 0, 0)]module pingpang(clk,rst,cycle,keyL,keyR,leds,score);
- //rst异步复位, keyL和keyR是比赛双方按键
- //leds是一排8个发光二极管代表乒乓球运动轨迹
- //score是得分的分数
- input clk,rst,cycle;
- input keyL,keyR;
- output leds;
- output [7:0] score;
-
- reg [7:0] leds;
- reg [3:0] scoreL,scoreR;
- reg [2:0] state;
- reg clk_out;
- reg [16:0] cnter;
-
- wire [3:0] D_ADDR;
- wire [7:0] D_DATA;
- wire [7:0] score = {scoreL,scoreR};
-
- parameter m=100_000;
-
- parameter s0=3'b000,//复位状态,也是判断发球权的状态;
-
- s1=3'b001,//左方发球或成功接球;
- s2=3'b010,//球从左方向右方右移,若此时右方接球就给左方加一分,并将球权给左方;
- s3=3'b011,//判断右方是否在规定时间内内接球
-
- s4=3'b100,//右方发球或成功接球;
- s5=3'b101,//球从右方向左方左移;移动过 程中,如果左方接球就给右方加一分,并将球权给右方;
-
- s6=3'b110;//判断左方是否在规定时间内接球;
-
-
-
- //游戏逻辑控制
-
- always @(posedge clk or negedge rst)
-
- begin
-
- if(!rst)
- begin
- clk_out<=0;
- cnter<=0;
- end
- else
- begin
- if(cnter == m)
- begin
- clk_out<=1;
- cnter<=0;
- end
- else
- begin
- clk_out<=0;
- cnter<=cnter+1;
- end
- end
- end
- //产生一个时钟脉冲clk_out给下面的语句块作为时钟输入使用。
-
- always @(posedge clk_out or negedge rst )
-
- begin
-
- if(!rst)
- begin
- state<=s0;
- leds<=8'b00000000;
- scoreL<=4'b0000;
- scoreR<=4'b0000;
- end//当rst为0时,使各个变量成为原始状态。
- else
-
- begin
-
- case(state)
-
- s0: begin
- leds<=8'b00000000;//使LED灯处于全灭状态。
- scoreL<=4'b0000;
- scoreR<=4'b0000;//给左右双方的分数复位;
- if(keyL)
- begin
- state<=s1;//如果左方获得发球权,则跳转到s1状态。
- end
- else if(keyR)
- state<=s4;//如果右方获得发球权,则跳转到s4状态。
-
- end
- s1: begin
- if(keyL)
- begin
- if(leds==8'b00000000)
- leds<=8'b10000000;//如果左方发球或成功接球,点亮的灯出现在最左边。
- state<=s2;//跳转到s2状态。
- end
- else if(keyR)
- begin
- state<=s1;//在这个过程中,如果右方击球,则LED灯闪烁,表示发生错误,状态一直重复在s1。
- end
-
-
- end
- s2: begin
- if(leds==8'b00000001)//判断LED灯是否向右移动到最后一个灯亮。
- begin
- leds<=leds>>1;//使LED灯向右移动一位。
- state<=s3;//进入判断右方接球的状态。
- end
- else
- begin
- leds<=leds>>1;//使LED灯向右移动一位。
- state<=s2;//重复s2状态。
- if(keyR)
- begin
- scoreL<=scoreL+1;
- state<=s1;
-
- leds<=8'b00000000;//如果右方在灯向右移动的过程中击球,表示右方犯规,左方加一分,球权给左方,并使LED灯复位。
- end
- end
-
- end
- s3: begin
- if(keyR)
- begin
- state<=s4;//右方接球成功,并进入右方发球的s4状态;
- leds<=8'b00000000;//使LED灯复位。
- end
- else
- begin
- scoreL<=scoreL+1;
- state<=s1;//右方接球不成功,则左方加一分,并进入左方发球的s1状态;
- leds<=8'b00000000;//使LED灯复位。
- end
- end
- s4: begin
- if(keyR)
- begin
- if(leds==8'b00000000)
- leds<=8'b00000001;//如果右方发球或成功接球,点亮的灯出现在最右边。
- state<=s5;//跳转到s5状态
- end
- else if(keyL)
- begin
- state<=s4;//在这个过程中,如果左方击球,则LED灯闪烁,表示发生错误,状态一直重复在s4。
- end
-
-
- end
- s5: begin
- if(leds==8'b10000000)//判断LED灯是否向左移动到最后一个灯亮。
- begin
- leds<=leds<<1;//使LED灯向左移动一位。
- state<=s6;//进入判断左方接球的状态;
- end
- else
- begin
- leds<=leds<<1;//使LED灯向左移动一位
- state<=s5;//重复s5状态。
- if(keyL)
- begin
- scoreR<=scoreR+1;
- state<=s4;
- leds<=8'b00000000;//如果左方在灯向左移动的过程中击球,表示左方犯规,右方加一分,球权给右方,并使LED灯复位。
- end
- end
-
- end
- s6: begin
- if(keyL)
- begin
- state<=s1;//左方接球成功,并进入左方发球的s1状态;
- leds<=8'b00000000;//使LED灯复位。
- end
- else
- begin
- scoreR<=scoreR+1;
- state<=s4;//左方接球不成功,则右方加一分,并进入右方发球的s4状态;
- leds<=8'b00000000;//使LED灯复位。
- end
- end
- default: state<=s0;
- endcase
- end
- end
-
- endmodule
- (3)显示数据转换模块
- module tube_data(clk,rst,cycle,score,D_ADDR,D_DATA);
-
- input clk,rst,cycle;
- input [7:0] score;
- output [3:0] D_ADDR;
- output [7:0] D_DATA;
-
- reg [14:0] cnter;
- reg [2:0] state;
-
- reg [3:0] D_ADDR;
- reg [7:0] D_DATA;
-
- parameter m=250;
-
- always @(posedge clk or negedge rst)
- begin
- if(!rst)
- begin
- cnter<=0;
- state<=0;//当rst为0时,给各变量赋初值。
- end
- else
- begin
- if(cnter==m)
- cnter<=0;//每当cnter加到与m相等,使cnter变回0
- else
- cnter<=cnter+1;
- case(cnter)
- 0 : state<=0;//当cnter为0时,使state为0。
- m/2 : state<=1;//当cnter为125时,使state为1。
-
- <font color="rgb(0, 0, 0)">…………限于本文篇幅 余下代码请从51黑下载附件…………</font>
复制代码
(4)数码管显示控制模块 - module ch452 (scl, sda,clk,rst,cycle,DIG_ADDR, DIG_DATA);
-
- input clk,rst;
- input [3:0] DIG_ADDR;
- input [7:0] DIG_DATA;
- output scl,sda,cycle;
-
- reg scl, sda,cycle;
- reg [5:0] cnt_cycle;
- reg [5:0] CST;
- reg [5:0] NST;
- reg [5:0] i;
-
- reg [3:0] D_ADDR;
- reg [7:0] D_DATA;
-
-
- parameter DA0 =1'b0;
- parameter DA1 =1'b1;
- parameter ADDR =1'b1;
- parameter s0=0,s1=1,s2=2,s3=3;
-
-
- always @( posedge clk or negedge rst)
- begin
- if(!rst)
- begin
- CST <= s0;
- cycle<=0;
- i<=0;
- end
- else
- begin
- CST <= NST;
-
- if(i==38)
- begin
- i<=0;
- cycle <= 1;
- end
- else
- begin
- i<=i+1;
- cycle <= 0;
- end
- end
- end
-
- always @ (posedge cycle or negedge rst)
- begin
- if(!rst) begin
- cnt_cycle<=0;
- D_ADDR<=4'b0000;
- D_DATA<=8'b00000000;//当rst为0时,为数码管赋初值。
- end
- else begin
- cnt_cycle<=cnt_cycle+1;
- if(cnt_cycle==0) begin
- D_ADDR<=4'b0100;
- D_DATA<=8'b00000001;//数码管第一次驱动,在第4'b0100个数码管输出数值8'b00000001
- end
- else if(cnt_cycle==1) begin
- D_ADDR<=4'b0101;
- D_DATA<=8'b10000000;//数码管第二次驱动,在第4'b0101个数码管输出数值8'b10000000
- end
- else begin
- D_ADDR<=DIG_ADDR;
- D_DATA<=DIG_DATA;//数码管第三次驱动,在自己想要的数码管位置输出自己想要的值
- end
- end
- end
-
- always @ (CST or D_ADDR or D_DATA or i)
- case (CST)
- s0 : begin scl = 1; sda = 1; NST <= s1; end//数码管准备启动
- s1 : begin scl = 1; sda = 0; NST <= s2; end//数码管开始启动
- s2 : begin scl = 0; sda = 0; NST <= s3; end//数码管启动完成
- s3 : begin
- if(i%2==1) scl=0;
- else scl=1;
- case ((i-1)/2)
- 1:sda=DA0;
- 2:sda=DA1;
- 3:sda=ADDR;//输出固定值011。
- 4:sda=D_ADDR[3];
- 5:sda=D_ADDR[2];
- 6:sda=D_ADDR[1];
- 7:sda=D_ADDR[0];//输出数码管位置。
- 8:sda=0;
- 9:sda=1;//输出固定值01。
- 10:sda=D_DATA[7];
- 11:sda=D_DATA[6];
- 12:sda=D_DATA[5];
- 13:sda=D_DATA[4];
- 14:sda=D_DATA[3];
- 15:sda=D_DATA[2];
- 16:sda=D_DATA[1];
- 17:sda=D_DATA[0];//输出数码管显示的数字。
- 18:sda=1;
- default:sda=0;
- endcase
- if(i==38) NST = s0;
- else NST = s3;
- end
- default : begin scl = 1; sda = 1; NST <= s0;end
- endcase
- endmodule
- (5)顶层模块
- module top(clk,rst,keyL,keyR,leds,scl_ch452,sda_ch452);
-
- input keyL,keyR,clk,rst;
- output[7:0] leds;
- output scl_ch452,sda_ch452;
-
- …………限于本文篇幅 余下代码请从51黑下载附件…………
- endmodule
复制代码
| | | | 理解题目,理清思路,学习 CH452 和 DS1340 的数据手册,画出设计框图和乒乓球的状态转换图。 | | | 编写和调试乒乓球游戏机分数显示相关模块,能实现乒乓球双方得分数据的显示。 | | | 编写和调试乒乓球游戏机球拍控制和乒乓球移动相关模块 | | | | | | | |
五、设计总结
设计成绩:教师签名:
完整论文下载(word格式 可编辑):
EDA课设报告——乒乓球模拟.doc
(206.93 KB, 下载次数: 34)
|