숫자 게임 (Simple Number Game)
Rules
Notes
- for FLEX10K, EPF10K10QC208-3
- This is Verilog HDL code.
Source Code
- game.v
verilog
module game_new(CLK,reset,state,player_num,SW,LED,rnd1,rnd2,rnd3,rnd4,Seg_1,Seg_2,Seg_3,Seg_4);
//,Seg_5,Seg_6,Seg_7,Seg_8);LED_5,LED_6,LED_7,LED_8,LED_9,LED_10);
input CLK,reset; // 클락,강제리셋
input [10:0] SW; // 스?치 0~9,A
output [2:0] state; // 현재 state
output [2:0] player_num; // 총 플레이어 수
output [7:0] Seg_1; // 세그먼트1
output [7:0] Seg_2; // 세그먼트2
output [7:0] Seg_3; // 세그먼트3
output [7:0] Seg_4; // 세그먼트4
//reg [7:0] Seg_1;
//reg [7:0] Seg_2;
//reg [7:0] Seg_3;
//reg [7:0] Seg_4;
//output [7:0] Seg_5;
//output [7:0] Seg_6;
//output [7:0] Seg_7;
//output [7:0] Seg_8;
output [10:0] LED; // LED 1~10 , LED[0]은 사용하지않음
reg [10:0] LED;
reg [2:0] state;
reg [3:0] player_num;
reg [3:0] On; // 세그먼트 출력관련 변수
reg [3:0] Off; // 마찬가지..
reg [3:0] Show; // 마찬가지
output [3:0] rnd1; // 카운터1의 output
output [3:0] rnd2; // 카운터2의 output
output [3:0] rnd3; // 카운터3의 output
output [3:0] rnd4; // 카운터4의 output
integer i;
integer j;
reg [2:0] current_player; // 현재 플레이어 변수
reg [2:0] current_game; // 현재 게임 회차 변수 5->4->3->2->1->0
// 점수 계산 관련 변수
integer dup_num;
integer count_num;
integer str_num;
integer str_check;
// 플레이어 스코어
integer score_1,score_2,score_3,score_4;
// 스코어 출력 관련
integer show_score;
wire score_5,score_6,score_7,score_8;
//assign score_5 = (show_score/1000)%10;
//assign score_6 = (show_score/100)%10;
//assign score_7 = (show_score/10)%10;
//assign score_8 = (show_score)%10;
// 카운터 인스턴스
preset_counter c1(CLK, On[0], Off[0], 4'b0000, rnd1);
preset_counter c2(CLK, On[1], Off[1], 4'b0000, rnd2);
preset_counter c3(CLK, On[2], Off[2], 4'b0000, rnd3);
preset_counter c4(CLK, On[3], Off[3], 4'b0000, rnd4);
// 세그먼트 인스턴스
controller_7_segment s1(rnd1,Seg_1,Show[0]);
controller_7_segment s2(rnd2,Seg_2,Show[1]);
controller_7_segment s3(rnd3,Seg_3,Show[2]);
controller_7_segment s4(rnd4,Seg_4,Show[3]);
wire act;
assign act = SW[0] | SW[1] | SW[2] | SW[3] | SW[4] | SW[5] | SW[6] | SW[7] | SW[8] | SW[9] | SW[10];
// 아래 always는 스?치에 인풋값이 들어오거나 강제리셋을 할 경우 작동
always @(posedge act or posedge reset) begin
// 초기화부분 (test)
if(reset == 1) begin
On = 4'b1111;
Off = 4'b1111;
Show = 4'b0000;
current_player = 0;
current_game = 0;
score_1 = 25;
score_2 = 25;
score_3 = 25;
score_4 = 25;
i = 0;
LED = 11'b00000000000;
player_num = 4'b0000;
current_game = 4;
state=3'b001;
end
else begin
// state 별로 case를 나눔
case(state)
// 강제 시작 ->001
default:
state=3'b001;
// 001 : 시작
3'b001:
begin
// 1,2,3,4번 스?치 중 하나 받아서 플레이어 수 결정
if(SW[1] == 1) begin
player_num = 4'b0001;
LED[4:1] = 4'b0001;
state = 3'b010;
end
else if(SW[2] == 1) begin
player_num = 4'b0010;
LED[4:1] = 4'b0011;
state = 3'b010;
end
else if(SW[3] == 1) begin
player_num = 4'b0011;
LED[4:1] = 4'b0111;
state = 3'b010;
end
else if(SW[4] == 1) begin
player_num = 4'b0100;
LED[4:1] = 4'b1111;
state = 3'b010;
end
// 랜덤숫자 표시!
Off = 4'b0000;
// 플레이어 초기화
current_player = 0;
end
// 010 : 준비
3'b010: begin
Show = 4'b1111;
//current_game = current_game - 1;
if(i==4)
state = 3'b011;
// 플레이어 순서 . 게임회차
if(current_player == 0) begin
LED[4:1] = 4'b0001;
show_score = score_1;
end
else if(current_player == 1) begin
LED[4:1] = 4'b0010;
show_score = score_2;
end
else if(current_player == 2) begin
LED[4:1] = 4'b0100;
show_score = score_3;
end
else if(current_player == 3) begin
LED[4:1] = 4'b1000;
show_score = score_4;
end
if(current_game == 4)
LED[10:6] = 5'b11111;
else if(current_game == 3)
LED[10:6] = 5'b01111;
else if(current_game == 2)
LED[10:6] = 5'b00111;
else if(current_game == 1)
LED[10:6] = 5'b00011;
else if(current_game == 0)
LED[10:6] = 5'b00001;
// A 스?치 누를떄마다 카운터 하나씩 정지
if(SW[10] == 1'b1) begin
case(i)
0:
On = 4'b1111;
1:
On = 4'b1110;
2:
On = 4'b1100;
3:
On = 4'b1000;
4:
On = 4'b0000;
default:
;
endcase
if(i==4)
state=3'b011;
if(i==3)
i=4;
if(i==2)
i=3;
if(i==1)
i=2;
if(i==0)
i=1;
// 카운터 4개 멈추면 011 state로 이동
end
end
// 011 : 점수계산 및 저장
3'b011: begin
count_num = 0;
str_num = 0;
for(j=0;j<10;j=j+1) begin
str_check = 0;
dup_num = 0;
if(rnd1 == j) begin
dup_num = dup_num + 1;
str_check = 1;
end
if(rnd2 == j) begin
dup_num = dup_num + 1;
str_check = 1;
end
if(rnd3 == j) begin
dup_num = dup_num + 1;
str_check = 1;
end
if(rnd4 == j) begin
dup_num = dup_num + 1;
str_check = 1;
end
// 연속된 숫자 관련 세팅 str_num이 4가되면 점수가 오? ..
if(str_check == 1)
str_num = str_num + 1;
else
str_num = 0;
// 같은숙자가 4개
if(dup_num == 4) begin
count_num = 3;
case(current_player)
1:
score_1 = score_1 + 200;
2:
score_2 = score_2 + 200;
3:
score_3 = score_3 + 200;
4:
score_4 = score_4 + 200;
endcase
end
// 같은 숫자가 3개
else if(dup_num == 3) begin
count_num = 3;
case(current_player)
1:
score_1 = score_1 + 70;
2:
score_2 = score_2 + 70;
3:
score_3 = score_3 + 70;
4:
score_4 = score_4 + 70;
endcase
end
// 같은숫자가 2개일?는 몇쌍인지 조사
else if(dup_num == 2) begin
count_num = count_num + 1;
end
// 연속된 숫자가 4개 일?..
else if(str_num == 4) begin
case(current_player)
1:
score_1 = score_1 + 100;
2:
score_2 = score_2 + 100;
3:
score_3 = score_3 + 100;
4:
score_4 = score_4 + 100;
endcase
end
end
if(count_num == 1) begin
case(current_player)
1:
score_1 = score_1 + 10;
2:
score_2 = score_2 + 10;
3:
score_3 = score_3 + 10;
4:
score_4 = score_4 + 10;
endcase
end
else if(count_num == 2) begin
case(current_player)
1:
score_1 = score_1 + 30;
2:
score_2 = score_2 + 30;
3:
score_3 = score_3 + 30;
4:
score_4 = score_4 + 30;
endcase
end
else if(count_num == 3)
;
//아무조건도 해당되지않으면 5점 차감
else begin
case(current_player)
1:
score_1 = score_1 - 5;
2:
score_2 = score_2 - 5;
3:
score_3 = score_3 - 5;
4:
score_4 = score_4 - 5;
endcase
end
state = 3'b100;
end
// 100 : 다음 플레이어로 전환
3'b100: begin
i = 0;
//On[0] = 1'b1;
//On[1] = 1'b1;
//On[2] = 1'b1;
//On[3] = 1'b1;
// 게임이 끝나면 결과 state로
if(current_game == 0) begin
state = 3'b101;
end
// 아니면 다시 ?로
state = 3'b010;
current_player = current_player + 1;
if(current_player == player_num) begin
current_player = 0;
current_game = current_game - 1;
end
end
// 101 : 승자결정
3'b101: begin
Off = 4'b1111;
On = 4'b0000;
// 스코어들을 비교해서 가장 스코어가 큰 플레이어의 LED를 켜고
// 그 플레이어의 점수를 십진수의 자릿수마다 분리하여
// 7-Segment로 출력한다 (Seg 5~8)
end
endcase
end
end
endmodule
////////////////////////////////////////////////////////////////////////////////////
// 기타 모듈
////////////////////////////////////////////////////////////////////////////////////
module D_FF(Q, D, Clk);
input D, Clk;
output Q;
reg Q;
always @(posedge Clk)
Q = D;
endmodule
module preset_counter(Clk, up_down, pl, p, OUT);
input Clk, up_down, pl;
input [3:0] p;
output [3:0] OUT;
//reg w2, w1, w0;
reg [3:0] count;
//reg OUT_0, OUT_1, OUT_2;
D_FF D3(OUT[3], count[3], Clk);
D_FF D2(OUT[2], count[2], Clk);
D_FF D1(OUT[1], count[1], Clk);
D_FF D0(OUT[0], count[0], Clk);
always@(posedge Clk)
begin
if(pl == 1'b1) begin
count[0] = 0;
count[1] = 1;
count[2] = 0;
count[3] = 1;
end else begin
if(up_down == 1) begin
if(count == 4'b1001 || count == 4'b1010) begin
count[0] = p[0];
count[1] = p[1];
count[2] = p[2];
count[3] = p[3];
end else
count = count + 1;
end
end
end
endmodule
module controller_7_segment(i,abcdefg,p);
input [0:3]i;
input p;
output [0:6]abcdefg;
reg [0:6]abcdefg;
always@(i)begin
if(p == 1) begin
case(i)
4'b0000:
abcdefg = 7'b1111110;
4'b0001:
abcdefg = 7'b0110000;
4'b0010:
abcdefg = 7'b1101101;
4'b0011:
abcdefg = 7'b1111001;
4'b0100:
abcdefg = 7'b0110011;
4'b0101:
abcdefg = 7'b1011011;
4'b0110:
abcdefg = 7'b1011111;
4'b0111:
abcdefg = 7'b1110000;
4'b1000:
abcdefg = 7'b1111111;
4'b1001:
abcdefg = 7'b1110011;
default:
abcdefg = 7'b0000000;
endcase
end
else begin
abcdefg = 7'b0000000;
end
end
endmodule