基于FPGA的辩论赛系统设计-8名选手-正反两方-支持单选手评分-正反两方评分总和
基于FPGA的辩论赛系统设计
- 功能描述
- 一、系统概述
- 二、仿真波形
- 视频
功能描述
1.答辩倒计时功能,当正反任意一方开始答辩后,倒计时30S。在倒计时最后10S后,LED灯开始闪烁。
2.答辩评分和计分功能,当答辩方结束答辩后,评委可以通过按键进行评分,基础分数为10分(满分),可以通过按键减少分数,最后通过确认按键确定评分。同时正方和反方的评分总数可以通过按键进行显示,达到一个计分的功能。
3.请看vcr
一、系统概述
控制模块:负责状态切换,应用状态机
数码管数据显示:负责显示数据切换
按键消抖:防止按键抖动
变量声明
module control(
input clk,
input rst_n,
input key_start,
input key_score,
input key_down,
output wire led_time,
output wire led_score,
output reg led_display_score,
output reg led_time_warnning,
output reg flag_po_ne,
output wire[3:0] display_count,
output reg [7:0] score,
output reg [7:0] data_time,
output reg [7:0] po_score,
output reg [7:0] ne_score
);
parameter IDLE =8'd0;
parameter DABIAN =8'd1;
parameter TALK_1 =8'd2;
parameter TEST_1 =8'd3;
parameter TALK_2 =8'd4;
parameter TEST_2 =8'd5;
parameter TALK_3 =8'd6;
parameter TEST_3 =8'd7;
parameter TALK_4 =8'd8;
parameter TEST_4 =8'd9;
reg [4:0] state;
reg [25:0] count;
reg [3:0] po_count;
reg [3:0] ne_count;
reg [7:0] po_1_score;
reg [7:0] po_2_score;
reg [7:0] po_3_score;
reg [7:0] po_4_score;
reg [7:0] ne_1_score;
reg [7:0] ne_2_score;
reg [7:0] ne_3_score;
reg [7:0] ne_4_score;
倒计时 还剩10秒 灯闪烁 还有其他一些指示灯
assign led_time=(state==TALK_1 || state==TALK_2 || state==TALK_3 || state==TALK_4)?1'b1:1'b0;
assign led_score=(state==TEST_1 || state==TEST_2|| state==TEST_3|| state==TEST_4)?1'b1:1'b0;
assign display_count=(flag_po_ne==1'b0)?po_count:ne_count;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
led_time_warnning<=1'b0;
end
else if(data_time<=8'h10 && count==25000000 || count==49999999)begin
led_time_warnning<=~led_time_warnning;
end
else if(data_time >8'h10)begin
led_time_warnning<=1'b0;
end
else begin
led_time_warnning<=led_time_warnning;
end
end
展示总积分的标志
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
led_display_score<=1'b0;
end
else if(led_time==1'b0 && led_score==1'b0 && key_score==1'b1)begin
led_display_score<=~led_display_score;
end
else begin
led_display_score<=led_display_score;
end
end
正反方交替进行 正反方次数各自累加
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
po_count<=4'd0;
ne_count<=4'd0;
end
else if((state==TEST_1 || state==TEST_2|| state==TEST_3|| state==TEST_4)&& key_start==1'b1&&flag_po_ne==1'b0)begin
po_count<=po_count+1;
end
else if((state==TEST_1 || state==TEST_2|| state==TEST_3|| state==TEST_4)&& key_start==1'b1&&flag_po_ne==1'b1)begin
ne_count<=ne_count+1;
end
else if(state==IDLE)begin
po_count<=4'd0;
ne_count<=4'd0;
end
end
总分计算
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
ne_score<=8'h40;
po_score<=8'h40;
end
else if(state== DABIAN)begin
ne_score<=8'h40;
po_score<=8'h40;
end
else if((state==TEST_1 || state==TEST_2|| state==TEST_3|| state==TEST_4)&& key_down==1'b1&& flag_po_ne==1'b0)begin
if(po_score[3:0]==4'h0 && po_score[7:4]>4'h0)begin
po_score[3:0]<=4'h9;
po_score[7:4]<=po_score[7:4]-4'd1;
end
else if(po_score[3:0]>4'h0 && po_score[7:4]>=4'h0)begin
po_score[3:0]<=po_score[3:0]-4'd1;
po_score[7:4]<=po_score[7:4];
end
else if(po_score[3:0]==4'h0 && po_score[7:4]==4'h0)begin
po_score[3:0]<=po_score[3:0];
po_score[7:4]<=po_score[7:4];
end
end
else if((state==TEST_1 || state==TEST_2|| state==TEST_3|| state==TEST_4)&& key_down==1'b1&& flag_po_ne==1'b1)begin
if(ne_score[3:0]==4'h0 && ne_score[7:4]>4'h0)begin
ne_score[3:0]<=4'h9;
ne_score[7:4]<=ne_score[7:4]-4'd1;
end
else if(ne_score[3:0]>4'h0 && ne_score[7:4]>=4'h0)begin
ne_score[3:0]<=ne_score[3:0]-4'd1;
ne_score[7:4]<=ne_score[7:4];
end
else if(ne_score[3:0]==4'h0 && ne_score[7:4]==4'h0)begin
ne_score[3:0]<=ne_score[3:0];
ne_score[7:4]<=ne_score[7:4];
end
end
end
单人评分
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
score<=8'h10;
end
else if(state==TALK_1 || state==TALK_2|| state==TALK_3|| state==TALK_4)begin
score<=8'h10;
end
else if((state==TEST_1 || state==TEST_2|| state==TEST_3|| state==TEST_4)&& key_down==1'b1)begin
if(score[3:0]==4'h0 && score[7:4]>4'h0)begin
score[3:0]<=4'h9;
score[7:4]<=score[7:4]-4'd1;
end
else if(score[3:0]>4'h0 && score[7:4]>=4'h0)begin
score[3:0]<=score[3:0]-4'd1;
score[7:4]<=score[7:4];
end
else if(score[3:0]==4'h0 && score[7:4]==4'h0)begin
score[3:0]<=score[3:0];
score[7:4]<=score[7:4];
end
end
end
倒计时30S 记得把count改成49999999 应该就是1秒
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
data_time<=8'h30;
end
else if(count==499 && (state==TALK_1 || state==TALK_2|| state==TALK_3|| state==TALK_4))begin
if(data_time[3:0]==4'h0 && data_time[7:4]>4'h0)begin
data_time[3:0]<=4'h9;
data_time[7:4]<=data_time[7:4]-4'd1;
end
else if(data_time[3:0]>4'h0 && data_time[7:4]>=4'h0)begin
data_time[3:0]<=data_time[3:0]-4'd1;
data_time[7:4]<=data_time[7:4];
end
else if(data_time[3:0]==4'h0 && data_time[7:4]==4'h0)begin
data_time[3:0]<=data_time[3:0];
data_time[7:4]<=data_time[7:4];
end
end
else if(state==TEST_1 || state==TEST_2|| state==TEST_3|| state==TEST_4)begin
data_time<=8'h30;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
count<=26'd0;
end
else if(state==TALK_1 || state==TALK_2|| state==TALK_3|| state==TALK_4)begin
if(count<499)begin
count<=count+1;
end
else begin
count<=26'd0;
end
end
else begin
count<=26'd0;
end
end
状态机切换 ,好像有一些用不到的、、
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
state <= IDLE;
po_1_score<=8'h10;
po_2_score<=8'h10;
po_3_score<=8'h10;
po_4_score<=8'h10;
ne_1_score<=8'h10;
ne_2_score<=8'h10;
ne_3_score<=8'h10;
ne_4_score<=8'h10;
flag_po_ne<=1'b0;
end
else begin
case(state)
IDLE:begin
if(key_start==1'b1)begin
state<=DABIAN;
end
else begin
state<=IDLE;
end
end
DABIAN:begin
state<=TALK_1;
end
TALK_1:begin
if(data_time==8'h00)begin
state<=TEST_1;
end
else begin
state<=TALK_1;
end
end
TEST_1:begin
if(key_start==1'b1 && po_count==0)begin
state<=TALK_2;
flag_po_ne<=~flag_po_ne;
po_1_score<=score;
end
else if(key_start==1'b1 && po_count==2)begin
state<=TALK_2;
flag_po_ne<=~flag_po_ne;
po_3_score<=score;
end
else begin
state<=TEST_1;
end
end
TALK_2:begin
if(data_time==8'h00)begin
state<=TEST_2;
end
else begin
state<=TALK_2;
end
end
TEST_2:begin
if(key_start==1'b1 && ne_count==0)begin
state<=TALK_3;
flag_po_ne<=~flag_po_ne;
ne_1_score<=score;
end
else if(key_start==1'b1 && ne_count==2)begin
state<=TALK_3;
flag_po_ne<=~flag_po_ne;
ne_3_score<=score;
end
else begin
state<=TEST_2;
end
end
TALK_3:begin
if(data_time==8'h00)begin
state<=TEST_3;
end
else begin
state<=TALK_3;
end
end
TEST_3:begin
if(key_start==1'b1 && po_count==1)begin
state<=TALK_4;
flag_po_ne<=~flag_po_ne;
po_2_score<=score;
end
else if(key_start==1'b1 && po_count==3)begin
state<=TALK_4;
flag_po_ne<=~flag_po_ne;
po_4_score<=score;
end
else begin
state<=TEST_3;
end
end
TALK_4:begin
if(data_time==8'h00)begin
state<=TEST_4;
end
else begin
state<=TALK_4;
end
end
TEST_4:begin
if(key_start==1'b1 && ne_count==1)begin
state<=TALK_1;
flag_po_ne<=~flag_po_ne;
ne_2_score<=score;
end
else if(key_start==1'b1 && ne_count==3)begin
state<=IDLE;
flag_po_ne<=~flag_po_ne;
po_4_score<=score;
end
else begin
state<=TEST_4;
end
end
default:state<=IDLE;
endcase
end
end
endmodule
按键消抖模块 还有数码管模块在我其他文章里面有,去复制一下吧,上面是一个模块,全部连起来就是。
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2024/12/25 22:38:47
// Design Name:
// Module Name: top
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module top(
input sys_clk,
input rst_n,
input key_start,
input key_dowm,
input key_score,
output wire [3:0] LED,
output wire [5:0] sel,
output wire [7:0] dig
);
wire button1_negedge;
wire button2_negedge;
wire button3_negedge;
wire flag_po_ne;
wire led_time;
wire led_score;
wire led_display_score;
wire [3:0] count;
wire [3:0] display_count;
wire [7:0] po_score;
wire [7:0] ne_score;
wire [7:0] data_time;
wire [7:0] score;
wire [7:0] display_data;
wire [23:0] din;
wire [23:0] seg_data;
wire [23:0] display_score;
assign LED={led_time,flag_po_ne,led_display_score,led_time_warnning};
assign display_data=(led_time==1'b1)?data_time:(led_score==1'b1)?score:8'hDD;
assign count=(led_score==1'b1)?display_count:4'hD;
assign din={display_data,4'hD,count,8'hDD};
assign display_score={4'h0,po_score,4'h1,ne_score};
assign seg_data=(led_display_score==1'b1)?display_score:din;
control u_control(
.clk(sys_clk),
.rst_n(rst_n),
.key_start(key_start),
.key_score(key_score),
.key_down(key_down),
.score(score),
.po_score(po_score),
.ne_score(ne_score),
.flag_po_ne(flag_po_ne),
.display_count(display_count),
.led_display_score(led_display_score),
.led_time(led_time),
.led_time_warnning(led_time_warnning),
.led_score(led_score),
.data_time(data_time)
);
key_debounce u_key_debounce1
(
.sys_clk(sys_clk),
.rst_n(rst_n),
.key(key_start),
.button_negedge(button1_negedge) //Key falling edgz
);
key_debounce u_key_debounce2
(
.sys_clk(sys_clk),
.rst_n(rst_n),
.key(key_dowm),
.button_negedge(button2_negedge) //Key falling edgz
);
key_debounce u_key_debounce3
(
.sys_clk(sys_clk),
.rst_n(rst_n),
.key(key_score),
.button_negedge(button3_negedge) //Key falling edgz
);
seg_ctrl u_seg_ctrl(
.clk(sys_clk) ,
.rst_n(rst_n) ,
.din(seg_data) ,//输入6位数码管显示数据,每位数码管占4位
.point_n(6'b111111) ,//输入小数点控制位
.sel(sel) ,//输出位选
.dig(dig) //输出段选
);
endmodule
二、仿真波形
当主持人无操作时,无法进行辩论赛,倒计时、评分、计分功能无法显示;当主持人按下答辩开关,第一及第二个数码管显示30秒倒计时,并且开始倒计时,当倒计时10S后,LED灯闪烁报警;依次按照正方1辩,反方1辩,正方2辩,反方2辩,正方3辩,反方3辩,正方4辩,反方4辩顺序进行辩论。辩论完时,评委进行选手评分,第一个和第二个数码管显示选手的当前分数(满分10分),随后第三数码管显示横杠,第四个数码管显示选手编号。评委可以通过按键手动进行减分,确定好分数后按下确认键。结束答辩后,展示评分阶段,数码管显示:0(代表正方)-正方分数-1(代表反方)-反方分数。
视频
基于FPGA的辩论赛计分器