资源描述
直接上源码,不解释,自己建工程运行即可看到功能!
module control(cp1024hz,started,reset,k1,k2,k3,k4,k5,k6,
zero1,zero2,zero3,zero4,zero5,zero6,time_out,
mode,flag_pressed,sound_en,latch_en);//yesd
input cp1024hz,started,reset;
input k1,k2,k3,k4,k5,k6;//抢答的6个按键,由cp1024hz扫描是否有按键
input zero1,zero2,zero3,zero4,zero5,zero6;//6个用?的分数是否为0,并将分数为0的淘汰
input time_out;//倒计时已完
output flag_pressed,sound_en,latch_en,mode;//是否已按键;声音控制;模式控制;输出模式
reg flag_pressed,sound_en,latch_en;
reg[3:0] mode;
always @(posedge cp1024hz)
begin
if(!started)//当started=0时,对系统进行初始化,同时将mode置0;
begin
mode<=0;
flag_pressed<=1; //利用设置这个将k1~k6屏蔽
sound_en<=0;
latch_en<=0;
end
else
begin
if(reset) //started=1已开始,reset=1新一轮抢答
begin
flag_pressed<=0;
sound_en<=0;
latch_en<=0;
mode<=7; //mode置为抢答模式
end
else
begin
if(time_out)
begin
sound_en<=1;//时间完了之后,响声提示
end
else
begin
if(!flag_pressed && k1 && !zero1)//当started=1时,按下key1
begin
flag_pressed<=1;
sound_en<=1;
latch_en<=1; //按键之后,产生相应电平
mode<=1;
end
else if(started && !flag_pressed && k2 && !zero2)
begin
flag_pressed<=1;
sound_en<=1;
latch_en<=1; //按键之后,产生相应电平
mode<=2;
end
else if(!flag_pressed && k3 && !zero3)
begin
flag_pressed<=1;
sound_en<=1;
latch_en<=1; //按键之后,产生相应电平
mode<=3;
end
else if(!flag_pressed && k4 && !zero4)
begin
flag_pressed<=1;
sound_en<=1;
latch_en<=1; //按键之后,产生相应电平
mode<=4;
end
else if(!flag_pressed && k5 && !zero5)
begin
flag_pressed<=1;
sound_en<=1;
latch_en<=1; //按键之后,产生相应电平
mode<=5;
end
else if(!flag_pressed && k6 && !zero6)
begin
flag_pressed<=1;
sound_en<=1;
latch_en<=1; //按键之后,产生相应电平
mode<=6;
end
end
end
end
end
endmodule
module display(cp1024hz,mode,setted_score,score1,score2,score3,score4,score5,score6,time_countdown,
disp);//yesd
input cp1024hz;
input[3:0] mode,time_countdown;//从time_count引出
input[7:0] setted_score,score1,score2,score3,score4,score5,score6;
output disp;
reg [3:0]mode_disp;
reg[7:0] disp;
always @(posedge cp1024hz)
begin
case(mode)
4'b0000 : disp<=setted_score;
4'b0001 : disp<=score1;
4'b0010 : disp<=score2;
4'b0011 : disp<=score3;
4'b0100 : disp<=score4;
4'b0101 : disp<=score5;
4'b0110 : disp<=score6;
4'b0111 :
begin
disp[3:0]<=time_countdown;
disp[7:4]<=0;
end
default : disp<=setted_score;
endcase
end
endmodule
module mode_latch_change(cp1024hz,started,flag_pressed,latch_clk,up_clk,down_clk,mode_in,mode_out);
input cp1024hz,started,flag_pressed;//yesd
input latch_clk;//锁存mode的信号
input up_clk,down_clk;//设置mode按键,上调和下调
input[3:0]mode_in;//从control的mode输出引进
output mode_out;
reg[3:0] mode_out;
reg up_clk1,down_clk1,latch_clk1;
always @(posedge cp1024hz)
begin
up_clk1<=up_clk;
down_clk1<=down_clk;
latch_clk1<=latch_clk;
end
wire up_clk2,down_clk2,latch_clk2;//对输入的信号的变化,便于cp1024hz的脉冲捕获
assign up_clk2=up_clk1&(~up_clk);
assign down_clk2=down_clk1&(~down_clk);
assign latch_clk2=latch_clk1&(~latch_clk);
always @(posedge cp1024hz)
begin
if(!started)//started=0,设置分数模式,mode_out=mode_in=0;
begin
mode_out<=0;
end
else//正常工作
begin
if(!flag_pressed)//抢答模式
begin
mode_out<=mode_in;
end
else if(latch_clk2)//锁存模式
begin
mode_out<=mode_in;
end
else if(flag_pressed && up_clk2)//查看各个分数,mode加计数
begin
if(mode_out>=6)
begin
mode_out<=0;
end
else
begin
mode_out<=mode_out+1;
end
end
else if(flag_pressed && down_clk2)//查看各个分数,mode减计数
begin
if(mode_out<=0)
begin
mode_out<=6;
end
else
begin
mode_out<=mode_out-1;
end
end
else
begin
// mode_out<=mode_in;
end
end
end
endmodule
module restart(cp1024hz,start_clk,started);//started==0设置初始分数,started==1开始工作
input cp1024hz,start_clk; //yesd
output started;
reg started;
reg start_clk1;
always @(posedge cp1024hz)
begin
start_clk1<=start_clk;
end
wire start_clk2;
assign start_clk2=start_clk1&(~start_clk);//变换start_clk信号,防止抖动以及便于cp1024hz扫描
always @(posedge cp1024hz)//start正常工作抢答_clk翻转,started翻转,为0时设置分数,为1时
begin
if(start_clk2)
begin
started<=~started;
end
end
endmodule
module score_count(cp1024hz,started,reset,mode,time_out,right_key,wrong_key,setted_score,
score1,score2,score3,score4,score5,score6,
zero1,zero2,zero3,zero4,zero5,zero6);//yesd
input cp1024hz,started,reset;
input time_out;//时间完了之后却没有是抢答
input right_key,wrong_key;//每次抢答之后主持人用于判断抢答者回答是否正确,从而设置分数
input[3:0] mode;//从control的mode输出引进
input[7:0] setted_score;//mode=0时设置的厨师分数
output score1,score2,score3,score4,score5,score6;//各玩家分数
output zero1,zero2,zero3,zero4,zero5,zero6;//玩家分数是否为0
reg zero1,zero2,zero3,zero4,zero5,zero6;
reg [7:0]score1,score2,score3,score4,score5,score6;
reg right1,wrong1;
always @(posedge cp1024hz)
begin
right1<=right_key;
wrong1<=wrong_key;
end
wire right2,wrong2;//将判断回答对错的信号变换,消除抖动以及便于扫描识别
assign right2=right1&(~right_key);
assign wrong2=wrong1&(~wrong_key);
reg temp_flag;//用于消除多次判断回答对错,防止扣分错误
always @(posedge cp1024hz)
begin
if(!started)//设置分数时,对各个玩家分数初始化
begin
score1<=setted_score;
score2<=setted_score;
score3<=setted_score;
score4<=setted_score;
score5<=setted_score;
score6<=setted_score;
zero1<=0;
zero2<=0;
zero3<=0;
zero4<=0;
zero5<=0;
zero6<=0;
temp_flag<=0;
end
else //started=1,正常工作模式
begin
if(reset) //reset之后初始化参数
begin
temp_flag<=0;
end
else //进行回答判断
begin
if(!time_out && !temp_flag && wrong2)//回答错误,减1分
begin
temp_flag<=1;//标志位置1,防止再次按键
case(mode)
4'b0001 : //如果抢答为玩家1
begin
if(score1[3:0]==0 && score1[7:4]>=1)
begin
score1[3:0]<=9;
score1[7:4]<=score1[7:4]-1;
end
else if(score1[3:0]==1 && score1[7:4]==0)
begin
score1[7:0]<=0;
zero1<=1;//玩家1的分数减少到0,淘汰
end
else
begin
if(score1[7:0]!=0)
begin
score1[3:0]<=score1[3:0]-1;
end
end
end
4'b0010 : //如果抢答为玩家2
begin
if(score2[3:0]==0 && score2[7:4]>=1)
begin
score2[3:0]<=9;
score2[7:4]<=score2[7:4]-1;
end
else if(score2[3:0]==1 && score2[7:4]==0)
begin
score2[7:0]<=0;
zero2<=1;
end
else
begin
if(score2[7:0]!=0)
begin
score2[3:0]<=score2[3:0]-1;
end
end
end
4'b0011 : //如果抢答为玩家3
begin
if(score3[3:0]==0 && score3[7:4]>=1)
begin
score3[3:0]<=9;
score3[7:4]<=score3[7:4]-1;
end
else if(score3[3:0]==1 && score3[7:4]==0)
begin
score3[7:0]<=0;
zero3<=1;
end
else
begin
if(score3[7:0]!=0)
begin
score3[3:0]<=score3[3:0]-1;
end
end
end
4'b0100 : //如果抢答为玩家4
begin
if(score4[3:0]==0 && score4[7:4]>=1)
begin
score4[3:0]<=9;
score4[7:4]<=score4[7:4]-1;
end
else if(score4[3:0]==1 && score4[7:4]==0)
begin
score4[7:0]<=0;
zero4<=1;
end
else
begin
if(score4[7:0]!=0)
begin
score4[3:0]<=score4[3:0]-1;
end
end
end
4'b0101 : //如果抢答为玩家5
begin
if(score5[3:0]==0 && score5[7:4]>=1)
begin
score5[3:0]<=9;
score5[7:4]<=score5[7:4]-1;
end
else if(score5[3:0]==1 && score5[7:4]==0)
begin
score5[7:0]<=0;
zero5<=1;
end
else
begin
if(score5[7:0]!=0)
begin
score5[3:0]<=score5[3:0]-1;
end
end
end
4'b0110 : //如果抢答为玩家6
begin
if(score6[3:0]==0 && score6[7:4]>=1)
begin
score6[3:0]<=9;
score6[7:4]<=score6[7:4]-1;
end
else if(score6[3:0]==1 && score6[7:4]==0)
begin
score6[7:0]<=0;
zero6<=1;
end
else
begin
if(score6[7:0]!=0)
begin
score6[3:0]<=score6[3:0]-1;
end
end
end
default : ;
endcase
end
if(!time_out && !temp_flag && right2)//回答正确,相应加1分
begin
temp_flag<=1;
case(mode)
4'b0001 : //玩家1
if(score1[3:0]==9)
begin
score1[3:0]<=0;
score1[7:4]<=score1[7:4]+1;
end
else
begin
score1[3:0]<=score1[3:0]+1;
end
4'b0010 : //玩家2
if(score2[3:0]==9)
begin
score2[3:0]<=0;
score2[7:4]<=score2[7:4]+1;
end
else
begin
score2[3:0]<=score2[3:0]+1;
end
4'b0011 : //玩家3
if(score3[3:0]==9)
begin
score3[3:0]<=0;
score3[7:4]<=score3[7:4]+1;
end
else
begin
score3[3:0]<=score3[3:0]+1;
end
4'b0100 : //玩家4
if(score4[3:0]==9)
begin
score4[3:0]<=0;
score4[7:4]<=score4[7:4]+1;
end
else
begin
score4[3:0]<=score4[3:0]+1;
end
4'b0101 : //玩家5
if(score5[3:0]==9)
begin
score5[3:0]<=0;
score5[7:4]<=score5[7:4]+1;
end
else
begin
score5[3:0]<=score5[3:0]+1;
end
4'b0110 : //玩家6
if(score6[3:0]==9)
begin
score6[3:0]<=0;
score6[7:4]<=score6[7:4]+1;
end
else
begin
score6[3:0]<=score6[3:0]+1;
end
default : ;
endcase
end
end
end
end
endmodule
module set_score(cp1024hz,started,set_up,set_down,setted_score);//抢答前设置玩家分数yes
input cp1024hz,started,set_up,set_down;
output setted_score;
reg [7:0]setted_score;
reg cp_up,cp_down;
always @(posedge cp1024hz)
begin
cp_up <=set_up;
cp_down <=set_down;
end
wire cp_up_pos,cp_down_pos;
assign cp_up_pos=cp_up&(~set_up);
assign cp_down_pos=cp_down&(~set_down) ;//设置分数的cp,防止抖动
always @(posedge cp1024hz) //设置初始分数
begin
if(!started) //当stared=0,设置模式,开始设置分数
begin
if(cp_up_pos&&(!cp_down_pos)) //加分设置
begin
if(setted_score[3:0]==9)
begin
setted_score[3:0]<=0;
if(setted_score[7:4]==9)
begin
setted_score[7:4]<=0;
end
else
begin
setted_score[7:4]<=setted_score[7:4]+1;
end
end
else
begin
setted_score[3:0]<=setted_score[3:0]+1;
end
end
else if((!cp_up_pos)&&cp_down_pos) //减分设置
begin
if(setted_score[3:0]==0)
begin
setted_score[3:0]<=9;
if(setted_score[7:4]==0)
begin
setted_score[7:4]<=9;
end
else
begin
setted_score[7:4]<=setted_score[7:4]-1;
end
end
else
begin
setted_score[3:0]<=setted_score[3:0]-1;
end
end
end
end
endmodule
module sound_alarm(reset,sound_en,cp1024hz,time_less_alarm,alarm);//yesd
input reset,sound_en,cp1024hz;
input time_less_alarm;
output alarm;
reg [9:0] temp_count;
reg temp;
always @(posedge cp1024hz)//(包括倒计时完,已抢答两种情况的声音提示)
begin
if(reset)//对中间变量进行初始化
begin
temp<=1;
temp_count<=0;
end
if(sound_en==1)
begin
if(temp_count==1023)//sound_en==1时,响1s钟提示
begin
temp<=0;
end
else
begin
temp_count<=temp_count+1;
end
end
end
wire alarm_time;
assign alarm_time=temp & sound_en;
reg[9:0] temp1;
reg time_left_alarm;
always @(posedge cp1024hz)//时间到三秒时 提示声0.5s
begin
if(reset)//对中间变量进行初始化
begin
temp1<=1;
time_left_alarm<=0;
end
else
begin
if(time_less_alarm==0)
begin
temp1<=0;
time_left_alarm<=0;
end
else
begin//时间少于3s时 提示
if(temp1<=512)
begin
temp1<=temp1+1;
time_left_alarm<=1;
end
else
begin
time_left_alarm<=0;
end
end
end
end
assign alarm=(time_left_alarm|alarm_time)&cp1024hz;
endmodule
module time_count(cp1024hz,started,reset,flag_pressed,time_left,time_less_alarm,time_out);//yesd
input cp1024hz,started,reset,flag_pressed;
output time_left;
output time_less_alarm;//倒计时到3s之后发出提醒信号
output time_out;//倒计时完了之后发出信号
reg [3:0] time_left;
reg time_less_alarm;
reg time_out;
reg[9:0] temp_count;
always @(posedge cp1024hz)
begin
if(!started)
begin
time_left<=0;
end
else
begin
if(reset)
begin
time_left<=9;
time_less_alarm<=0;
time_out<=0;
temp_count<=0;
end
else
begin
if(time_left==3)//当倒计时剩3s时,发出警报
begin
time_less_alarm<=1;
end
if(time_left==0)//当倒计时完了了,发出信号
begin
time_out<=1;
end
if(flag_pressed)//已抢答,则终止倒计时,并置为初值
begin
time_left<=9;
end
else//还未抢答,进行倒计时
begin
if(temp_count==1023)
begin
temp_count<=0;
if(time_left>1)
begin
time_left<=time_left-1;
if(time_left==4)
begin
time_less_alarm<=1;
end
end
else
begin
time_out<=1;
time_left<=0;
end
end
else
begin
temp_count<=temp_count+1;
end
end
end
end
end
endmodule
使用的连线组装的模块!如下图所示!
展开阅读全文