基于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) beginif(!rst_n) beginled_time_warnning<=1'b0;endelse if(data_time<=8'h10 && count==25000000 || count==49999999)beginled_time_warnning<=~led_time_warnning;endelse if(data_time >8'h10)beginled_time_warnning<=1'b0;endelse beginled_time_warnning<=led_time_warnning;endend
展示总积分的标志
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginled_display_score<=1'b0;endelse if(led_time==1'b0 && led_score==1'b0 && key_score==1'b1)beginled_display_score<=~led_display_score;endelse beginled_display_score<=led_display_score;endend
正反方交替进行 正反方次数各自累加
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginpo_count<=4'd0;ne_count<=4'd0;endelse if((state==TEST_1 || state==TEST_2|| state==TEST_3|| state==TEST_4)&& key_start==1'b1&&flag_po_ne==1'b0)beginpo_count<=po_count+1;endelse if((state==TEST_1 || state==TEST_2|| state==TEST_3|| state==TEST_4)&& key_start==1'b1&&flag_po_ne==1'b1)beginne_count<=ne_count+1;endelse if(state==IDLE)beginpo_count<=4'd0;ne_count<=4'd0;endend
总分计算
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginne_score<=8'h40;po_score<=8'h40;endelse if(state== DABIAN)beginne_score<=8'h40;po_score<=8'h40;endelse if((state==TEST_1 || state==TEST_2|| state==TEST_3|| state==TEST_4)&& key_down==1'b1&& flag_po_ne==1'b0)beginif(po_score[3:0]==4'h0 && po_score[7:4]>4'h0)beginpo_score[3:0]<=4'h9;po_score[7:4]<=po_score[7:4]-4'd1;endelse if(po_score[3:0]>4'h0 && po_score[7:4]>=4'h0)beginpo_score[3:0]<=po_score[3:0]-4'd1;po_score[7:4]<=po_score[7:4];endelse if(po_score[3:0]==4'h0 && po_score[7:4]==4'h0)beginpo_score[3:0]<=po_score[3:0];po_score[7:4]<=po_score[7:4];endendelse if((state==TEST_1 || state==TEST_2|| state==TEST_3|| state==TEST_4)&& key_down==1'b1&& flag_po_ne==1'b1)beginif(ne_score[3:0]==4'h0 && ne_score[7:4]>4'h0)beginne_score[3:0]<=4'h9;ne_score[7:4]<=ne_score[7:4]-4'd1;endelse if(ne_score[3:0]>4'h0 && ne_score[7:4]>=4'h0)beginne_score[3:0]<=ne_score[3:0]-4'd1;ne_score[7:4]<=ne_score[7:4];endelse if(ne_score[3:0]==4'h0 && ne_score[7:4]==4'h0)beginne_score[3:0]<=ne_score[3:0];ne_score[7:4]<=ne_score[7:4];endendend
单人评分
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginscore<=8'h10;endelse if(state==TALK_1 || state==TALK_2|| state==TALK_3|| state==TALK_4)beginscore<=8'h10;endelse if((state==TEST_1 || state==TEST_2|| state==TEST_3|| state==TEST_4)&& key_down==1'b1)beginif(score[3:0]==4'h0 && score[7:4]>4'h0)beginscore[3:0]<=4'h9;score[7:4]<=score[7:4]-4'd1;endelse if(score[3:0]>4'h0 && score[7:4]>=4'h0)beginscore[3:0]<=score[3:0]-4'd1;score[7:4]<=score[7:4];endelse if(score[3:0]==4'h0 && score[7:4]==4'h0)beginscore[3:0]<=score[3:0];score[7:4]<=score[7:4];endendend
倒计时30S 记得把count改成49999999 应该就是1秒
always @(posedge clk or negedge rst_n) beginif(!rst_n) begindata_time<=8'h30;endelse if(count==499 && (state==TALK_1 || state==TALK_2|| state==TALK_3|| state==TALK_4))beginif(data_time[3:0]==4'h0 && data_time[7:4]>4'h0)begindata_time[3:0]<=4'h9;data_time[7:4]<=data_time[7:4]-4'd1;endelse if(data_time[3:0]>4'h0 && data_time[7:4]>=4'h0)begindata_time[3:0]<=data_time[3:0]-4'd1;data_time[7:4]<=data_time[7:4];endelse if(data_time[3:0]==4'h0 && data_time[7:4]==4'h0)begindata_time[3:0]<=data_time[3:0];data_time[7:4]<=data_time[7:4];endendelse if(state==TEST_1 || state==TEST_2|| state==TEST_3|| state==TEST_4)begindata_time<=8'h30;endend always @(posedge clk or negedge rst_n) beginif(!rst_n) begincount<=26'd0;endelse if(state==TALK_1 || state==TALK_2|| state==TALK_3|| state==TALK_4)beginif(count<499)begincount<=count+1;endelse begincount<=26'd0;endendelse begincount<=26'd0;endend
状态机切换 ,好像有一些用不到的、、
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginstate <= 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;endelse begincase(state)IDLE:beginif(key_start==1'b1)beginstate<=DABIAN;endelse beginstate<=IDLE;endendDABIAN:beginstate<=TALK_1;endTALK_1:beginif(data_time==8'h00)beginstate<=TEST_1;endelse beginstate<=TALK_1;endendTEST_1:beginif(key_start==1'b1 && po_count==0)beginstate<=TALK_2;flag_po_ne<=~flag_po_ne;po_1_score<=score;endelse if(key_start==1'b1 && po_count==2)beginstate<=TALK_2;flag_po_ne<=~flag_po_ne;po_3_score<=score;endelse beginstate<=TEST_1;endendTALK_2:beginif(data_time==8'h00)beginstate<=TEST_2;endelse beginstate<=TALK_2;endendTEST_2:beginif(key_start==1'b1 && ne_count==0)beginstate<=TALK_3;flag_po_ne<=~flag_po_ne;ne_1_score<=score;endelse if(key_start==1'b1 && ne_count==2)beginstate<=TALK_3;flag_po_ne<=~flag_po_ne;ne_3_score<=score;endelse beginstate<=TEST_2;endendTALK_3:beginif(data_time==8'h00)beginstate<=TEST_3;endelse beginstate<=TALK_3;endendTEST_3:beginif(key_start==1'b1 && po_count==1)beginstate<=TALK_4;flag_po_ne<=~flag_po_ne;po_2_score<=score;endelse if(key_start==1'b1 && po_count==3)beginstate<=TALK_4;flag_po_ne<=~flag_po_ne;po_4_score<=score;endelse beginstate<=TEST_3;endendTALK_4:beginif(data_time==8'h00)beginstate<=TEST_4;endelse beginstate<=TALK_4;endendTEST_4:beginif(key_start==1'b1 && ne_count==1)beginstate<=TALK_1;flag_po_ne<=~flag_po_ne;ne_2_score<=score;endelse if(key_start==1'b1 && ne_count==3)beginstate<=IDLE;flag_po_ne<=~flag_po_ne;po_4_score<=score;endelse beginstate<=TEST_4;endenddefault:state<=IDLE;endcaseendendendmodule
按键消抖模块 还有数码管模块在我其他文章里面有,去复制一下吧,上面是一个模块,全部连起来就是。
`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的辩论赛计分器