`define STATE_DEAL_P1	3'b000
`define STATE_DEAL_D1	3'b001
`define STATE_DEAL_P2	3'b010
`define STATE_DEAL_D2	3'b011
`define STATE_DEAL_P3	3'b100
`define STATE_DEAL_D3	3'b101
`define STATE_END	3'b110

module statemachine(slow_clock, resetb, dscore, pscore, pcard3,
	load_pcard1, load_pcard2, load_pcard3,
	load_dcard1, load_dcard2, load_dcard3,
	player_win_light, dealer_win_light);

	input logic slow_clock, resetb;
	input logic [3:0] dscore, pscore, pcard3;
	output logic load_pcard1, load_pcard2, load_pcard3,
		load_dcard1, load_dcard2, load_dcard3,
		player_win_light, dealer_win_light;

	logic [2:0] state;

	always_ff @(posedge slow_clock) casex ({resetb, state})
		4'b0_xxx:
			state <= `STATE_DEAL_P1;
		{1'b1, `STATE_DEAL_P1}:
			state <= `STATE_DEAL_D1;
		{1'b1, `STATE_DEAL_D1}:
			state <= `STATE_DEAL_P2;
		{1'b1, `STATE_DEAL_P2}:
			state <= `STATE_DEAL_D2;
		{1'b1, `STATE_DEAL_D2}:
			if ((pscore >= 8) || (dscore >= 8)) state <= `STATE_END;
			else if (pscore <= 5) state <= `STATE_DEAL_P3;
			else if (dscore <= 5) state <=`STATE_DEAL_D3;
			else state = `STATE_END;
		{1'b1, `STATE_DEAL_P3}: casex ({dscore, pcard3})
			/* Banker 6 on a player's third card 6 or 7. */
			{4'd6, 4'd6}, {4'd6, 4'd7},
			/* Banker 5 on a player's third card 4 through 7. */
			{4'd5, 4'd4}, {4'd5, 4'd5}, {4'd5, 4'd6}, {4'd5, 4'd7},
			/* Banker 4 on a player's third card 2 through 7. */
			{4'd4, 4'd2}, {4'd4, 4'd3}, {4'd4, 4'd4},
			{4'd4, 4'd5}, {4'd4, 4'd6}, {4'd4, 4'd7},
			/* Banker 3 on a player's third card 1 through 7. */
			{4'd3, 4'd1}, {4'd3, 4'd2}, {4'd3, 4'd3}, {4'd3, 4'd4},
			{4'd3, 4'd5}, {4'd3, 4'd6}, {4'd3, 4'd7},
			/* Banker 0, 1, or 2. */
			{4'd0, 4'bxxxx}, {4'd1, 4'bxxxx}, {4'd2, 4'bxxxx}:
				state <= `STATE_DEAL_D3;
			/* Banker stands otherwise. */
			default: state <= `STATE_END;
		endcase
		{1'b1, `STATE_DEAL_D3}:
			state <= `STATE_END;
		{1'b1, `STATE_END}:
			state <= `STATE_END;
		default:
			state <= `STATE_DEAL_P1;
	endcase

	always_comb begin
		{player_win_light, dealer_win_light,
			load_pcard1, load_pcard2, load_pcard3,
			load_dcard1, load_dcard2, load_dcard3}
			= 8'b0;

		case (state)
			`STATE_DEAL_P1: load_pcard1 = 1'b1;
			`STATE_DEAL_P2: load_pcard2 = 1'b1;
			`STATE_DEAL_P3: load_pcard3 = 1'b1;
			`STATE_DEAL_D1: load_dcard1 = 1'b1;
			`STATE_DEAL_D2: load_dcard2 = 1'b1;
			`STATE_DEAL_D3: load_dcard3 = 1'b1;
			`STATE_END: begin
				if (pscore >= dscore) player_win_light = 1'b1;
				if (dscore >= pscore) dealer_win_light = 1'b1;
			end
		endcase
	end
endmodule: statemachine
