`define STATE_DEAL_P1	3'd0
`define STATE_DEAL_D1	3'd1
`define STATE_DEAL_P2	3'd2
`define STATE_DEAL_D2	3'd3
`define STATE_DEAL_X1	3'd4
`define STATE_DEAL_X2	3'd5
`define STATE_END	3'd6

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, state_next;

	/* Current state register. */
	always_ff @(posedge slow_clock)
		if (~resetb) state <= `STATE_DEAL_P1;
		else state <= state_next;

	/* Next state logic. */
	always_comb case (state)
		`STATE_DEAL_P1: state_next = `STATE_DEAL_D1;
		`STATE_DEAL_D1: state_next = `STATE_DEAL_P2;
		`STATE_DEAL_P2: state_next = `STATE_DEAL_D2;
		`STATE_DEAL_D2: state_next = `STATE_DEAL_X1;
		`STATE_DEAL_X1:
			if ((dscore <= 7) && (pscore <= 5))
				state_next = `STATE_DEAL_X2;
			else
				state_next = `STATE_END;
		default: state_next = `STATE_END;
	endcase

	/* Output logic. */
	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_D1: load_dcard1 = 1'b1;
			`STATE_DEAL_P2: load_pcard2 = 1'b1;
			`STATE_DEAL_D2: load_dcard2 = 1'b1;
			`STATE_DEAL_X1:
				/* Check for natural eight and nines first. */
				if ((dscore <= 7) && (pscore <= 5))
					load_pcard3 = 1'b1;
				else if ((pscore <= 7) && (dscore <= 5))
					load_dcard3 = 1'b1;
			`STATE_DEAL_X2: 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}:
					load_dcard3 = 1'b1;
			endcase
			`STATE_END: begin
				if (pscore >= dscore) player_win_light = 1'b1;
				if (dscore >= pscore) dealer_win_light = 1'b1;
			end
		endcase
	end
endmodule: statemachine
