设计目的
使用FPGA实验班设计一个数字逻辑系统,巩固数字逻辑电路的相关知识,锻炼熟练使用FPGA设计软件和硬件和独立完成项目设计的能力。
二、设计内容
2.1摘要
设计一个乒乓球游戏,实现游戏功能和计分功能。
通过开发板的按键实现左右球拍的击拍和游戏的复位;通过数码管显示游戏的比分;通过led显示乒乓球的运动轨迹。
2.2游戏规则
第一步:按下复位,led不亮,数码管显示比分00–00。
第二步:按下左球拍或者右球拍,发球,游戏开始,发球方向随机。
第三步:乒乓球在左半场/右半场并且靠近左侧/右侧的时候,左球拍/右球拍可以击球。如果在错误的时机击球或未成功接球,判负,对方加一分。
第四步:当有一方积得11分,游戏结束。再次开始游戏需要进行复位。
三、设计思路
3.2流程图
3.2顶层框图
3.3接口说明
名称 类型 封装管脚 说明
clk input PIN_AF14 时钟信号
rst_n input PIN_AA15 全局复位
key_left input PIN_Y16 左球拍
key_right input PIN_AA14 右球拍
Seven_segment output 数码管对应管脚 计分器
led output led对应管脚 运球轨迹
3.4分模块框图
四、代码实现
4.1顶层文件
module play_table_tennis (
input wire clk, // 50Mhz
input wire rst_n, // low valid
output wire [41:0] seven_segment, // low valid
output wire [9:0] led, // high valid
input wire key_left, // low valid
input wire key_right // low valid
);
wire flag_left;
wire flag_right;
wire [3:0] left_num;
wire [3:0] right_num;
key_processor key_processor_inst(
.clk (clk),
.rst_n (rst_n),
.key_left (key_left),
.key_right (key_right),
.flag_left (flag_left),
.flag_right (flag_right)
);
controller controller_inst(
.clk (clk),
.rst_n (rst_n),
.flag_left (flag_left),
.flag_right (flag_right),
.left_num (left_num),
.right_num (right_num),
.led (led)
);
seven_tube_drive seven_tube_drive_inst(
.clk (clk),
.rst_n (rst_n),
.left_num (left_num),
.right_num (right_num),
.seven_segment (seven_segment)
);
endmodule
4.2按键
module key_processor (
input wire clk,
input wire rst_n,
input wire key_left,
input wire key_right,
output wire flag_left,
output wire flag_right
);
key_filter key_filter_inst_left(
.clk (clk),
.rst_n (rst_n),
.key (key_left),
.flag (flag_left)
);
key_filter key_filter_inst_right(
.clk (clk),
.rst_n (rst_n),
.key (key_right),
.flag (flag_right)
);
endmodule
module key_filter (
input wire clk,
input wire rst_n,
input wire key,
output reg flag
);
parameter T = 500_000;
reg [18:0] cnt;
reg [2:0] state;
reg key_r;
reg key_rr;
always @ (posedge clk, negedge rst_n) begin
if (rst_n == 1'b0) begin
key_r <= 1'b1;
key_rr <= 1'b1;
end
else begin
key_r <= key;
key_rr <= key_r;
end
end
always @ (posedge clk, negedge rst_n) begin
if (rst_n == 1'b0) begin
state <= 3'd0;
cnt <= 19'd0;
flag <= 1