//game: WOLF-GOAT-CABBAGE
module game_wgc(
input wire reset,
input wire clk,
input wire [3:0]key,
output reg [3:0]state_out,
output reg fail,
output reg win
);
parameter GOAT = 0;
parameter CABBAGE = 1;
parameter WOLF = 2;
parameter MEN = 3;
//fix new key states
reg [3:0]key_fixed;
always @(posedge clk or posedge reset)
begin
if(reset)
key_fixed <= 4'b0000;
else
key_fixed <= key;
end
//detect key press event with simple filter with shift register
reg [3:0]key_was_pressed_sr;
always @(posedge clk or posedge reset)
begin
if(reset)
key_was_pressed_sr <= 4'b0000;
else
key_was_pressed_sr <= { key_was_pressed_sr[2:0], (key_fixed != 4'b0000) };
end
wire key_was_pressed;
assign key_was_pressed = (key_was_pressed_sr==4'b0001);
//each bit for goat/cabbage/wolf/men
//0 mean initial river side
//1 mean target river side
reg [3:0]state;
always @(posedge clk or posedge reset)
begin
if(reset)
state <= 4'b0000;
else
begin
if(key_was_pressed)
begin
if(win | fail)
state <= 4'b0000; //restart game after win or fail
else
if(key_fixed[GOAT] & (state[GOAT]==state[MEN]) )
state <= { ~state[MEN], state[WOLF], state[CABBAGE], ~state[GOAT]}; //move GOAT if it is near men
else
if(key_fixed[CABBAGE] & (state[CABBAGE]==state[MEN]))
state <= { ~state[MEN], state[WOLF], ~state[CABBAGE], state[GOAT]}; //move CABBAGE if it is near men
else
if(key_fixed[WOLF] & (state[WOLF]==state[MEN]))
begin
state <= { ~state[MEN], ~state[WOLF], state[CABBAGE], state[GOAT]}; //move WOLF if it is near men
end
else
if(key_fixed[MEN])
state <= { ~state[MEN], state[WOLF], state[CABBAGE], state[GOAT]}; //men always can move
end
end
end
always @(state)
begin
state_out = state;
win = (state==4'b1111);
fail = (state==4'b0111) || (state==4'b1000) || (state==4'b0011) || (state==4'b1100) || (state==4'b0101) || (state==4'b1010);
end
endmodule
Подробнее...