This repository has been archived by the owner on Dec 9, 2024. It is now read-only.
forked from kisek/fpga_arty_a7_st7789
-
Notifications
You must be signed in to change notification settings - Fork 0
/
two_people_play.v
179 lines (161 loc) · 6.07 KB
/
two_people_play.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
`include "config.vh"
`include "piler.v"
`include "winning_detector.v"
// 赤が先行
module m_two_people_play (
input wire w_clk,
input wire w_rst,
input wire [3:0] i_user_input,
output reg [`COL_SIZE-1:0] o_selecting_col,
output reg [`FIELD_SIZE-1:0] o_red_field,
output reg [`FIELD_SIZE-1:0] o_blue_field,
output reg [1:0] o_settlement_state = 2'b0
);
localparam [3:0] UNSTARTED = 4'b0000;
localparam [3:0] RED_SELECTION = 4'b0001;
localparam [3:0] RED_PILING = 4'b0010;
localparam [3:0] RED_SET_CHECK = 4'b0011;
localparam [3:0] RED_WIN = 4'b0101;
localparam [3:0] BLUE_SELECTION = 4'b0100;
localparam [3:0] BLUE_PILING = 4'b1000;
localparam [3:0] BLUE_SET_CHECK = 4'b1100;
localparam [3:0] BLUE_WIN = 4'b1010;
reg [3:0] r_state = RED_SELECTION;
reg [`PILE_COUNT_ARRAY_SIZE-1:0] r_pile_count_array = 0;
reg [`FIELD_SIZE-1:0] r_red_field = 0, r_blue_field = 0;
reg [`COL_SIZE-1:0] r_selecting_col = 0;
always @(posedge w_clk) begin
if (w_rst) begin
r_state <= UNSTARTED;
r_pile_count_array <= 0;
r_red_field <= 0; r_blue_field <= 0;
r_selecting_col <= 0;
o_red_field <= 0;
o_blue_field <= 0;
o_selecting_col <= 0;
o_settlement_state <= 0;
end begin
if (r_state == UNSTARTED) begin
r_state <= RED_SELECTION;
end
o_selecting_col <= r_selecting_col;
o_red_field <= r_red_field;
o_blue_field <= r_blue_field;
case (r_state)
RED_WIN: begin
o_settlement_state <= 2'b10;
end
BLUE_WIN: begin
o_settlement_state <= 2'b11;
end
default: o_settlement_state <= 0;
endcase
end
end
localparam [3:0] USER_INPUT_INC = 4'b1000;
localparam [3:0] USER_INPUT_DEC = 4'b0100;
localparam [3:0] USER_INPUT_PILE = 4'b0001;
always @(posedge w_clk) begin
if (!w_rst) begin
if (r_state == RED_SELECTION || r_state == BLUE_SELECTION) begin
case (i_user_input)
USER_INPUT_INC: begin
r_selecting_col <= (r_selecting_col + 1) % `COL_COUNT;
end
USER_INPUT_DEC: begin
r_selecting_col <= (r_selecting_col - 1) % `COL_COUNT;
end
USER_INPUT_PILE: begin
if (r_state == RED_SELECTION) begin
r_state <= RED_PILING;
end else begin
r_state <= BLUE_PILING;
end
end
endcase
end
end
end
wire [`FIELD_SIZE-1:0] w_target_field;
assign w_target_field = (r_state == RED_PILING) ? r_red_field :
(r_state == BLUE_PILING) ? r_blue_field :
0;
wire w_pile_valid;
wire [`FIELD_SIZE-1:0] w_pile_processed_field;
wire [`PILE_COUNT_ARRAY_SIZE-1:0] w_pile_processed_array;
m_piler p (
.i_field(w_target_field),
.i_pile_count_array(r_pile_count_array),
.i_pile_col(r_selecting_col),
.o_valid(w_pile_valid),
.o_field(w_pile_processed_field),
.o_pile_count_array(w_pile_processed_array)
);
reg [`FIELD_SIZE-1:0] r_settlement_checked_field;
always @(posedge w_clk) begin
if (!w_rst) begin
case (r_state)
RED_PILING: begin
if (w_pile_valid) begin
r_red_field <= w_pile_processed_field;
r_pile_count_array <= w_pile_processed_array;
r_settlement_checked_field <= w_pile_processed_field;
r_state <= RED_SET_CHECK;
end else begin
r_state <= RED_SELECTION;
end
end
BLUE_PILING: begin
if (w_pile_valid) begin
r_blue_field <= w_pile_processed_field;
r_pile_count_array <= w_pile_processed_array;
r_settlement_checked_field <= w_pile_processed_field;
r_state <= BLUE_SET_CHECK;
end else begin
r_state <= BLUE_SELECTION;
end
end
endcase
end else begin
r_settlement_checked_field <= 0;
end
end
wire w_win_detection_res;
m_winning_detector wd (
.i_field(r_settlement_checked_field),
.o_detected(w_win_detection_res)
);
localparam [9:0] WAIT_COUNT = 2;
// ユーザーがボタンを押して離す前に SELECTION_STATE にいくのを防ぐ
reg [9:0] r_wait_counter = 0;
always @(posedge w_clk) begin
if (!w_rst) begin
case (r_state)
RED_SET_CHECK: begin
r_wait_counter <= r_wait_counter + 1;
if (w_win_detection_res) begin
r_state <= RED_WIN;
end else begin
if (r_wait_counter > WAIT_COUNT) begin
r_state <= BLUE_SELECTION;
r_wait_counter <= 0;
end
end
end
BLUE_SET_CHECK: begin
r_wait_counter <= r_wait_counter + 1;
if (w_win_detection_res) begin
r_state <= BLUE_WIN;
end else begin
if (r_wait_counter > WAIT_COUNT) begin
r_state <= RED_SELECTION;
r_wait_counter <= 0;
end
end
end
endcase
end else begin
r_wait_counter <= 0;
end
end
endmodule