module competition (
	input logic CLOCK_50,
	input logic [3:0] KEY,
	input logic [9:0] SW,

	output logic [6:0] HEX0,
	output logic [6:0] HEX1,
	output logic [6:0] HEX2,
	output logic [6:0] HEX3,
	output logic [6:0] HEX4,
	output logic [6:0] HEX5,
	output logic [9:0] LEDR
);

	typedef enum logic [6:0] {
		BLANK	= 7'b1111111,
		DASH	= 7'b0111111,
		ZERO	= 7'b1000000,
		ONE	= 7'b1111001,
		TWO	= 7'b0100100,
		THREE	= 7'b0110000,
		FOUR	= 7'b0011001,
		FIVE	= 7'b0010010,
		SIX	= 7'b0000010,
		SEVEN	= 7'b1111000,
		EIGHT	= 7'b0000000,
		NINE	= 7'b0010000,
		A	= 7'b0001000,
		B	= 7'b0000011,
		C	= 7'b1000110,
		D	= 7'b0100001,
		E	= 7'b0000110,
		F	= 7'b0001110
	} seven_seg_t;

	logic clk, pll_locked, rst_n, en, rdy, key_valid;
	logic [23:0] key;

	logic [7:0] ct_addr;
	logic [7:0] ct_rddata;

	enum logic [1:0] {
		IDLE,
		CRACK,
		DONE
	} state;

	pll sys_pll (
		.refclk(CLOCK_50),
		.rst(~KEY[3]),
		.outclk_0(clk),
		.locked(pll_locked)
	);

	assign rst_n = KEY[3] & pll_locked;
	assign LEDR[0] = rdy;
	assign LEDR[1] = key_valid;
	assign LEDR[9:2] = '0;

	ct_mem ct (
		.address(ct_addr),
		.clock(clk),
		.data('0),
		.wren('0),
		.q(ct_rddata)
	);

	multicrack mc (
		.clk,
		.rst_n,
		.en,
		.rdy,
		.key,
		.key_valid,
		.ct_addr,
		.ct_rddata
	);

	always_ff @(posedge clk) begin
		if (~rst_n) begin
			state <= IDLE;
		end else unique case (state)
			IDLE: if (rdy) state <= CRACK;
			CRACK: if (rdy) state <= DONE;
			DONE: state <= DONE;
		endcase
	end

	always_comb begin
		if (state == IDLE && rdy) en = '1;
		else en = '0;
	end

	always_comb begin: hex_disp
		if (state != DONE) begin
			HEX0 = BLANK;
			HEX1 = BLANK;
			HEX2 = BLANK;
			HEX3 = BLANK;
			HEX4 = BLANK;
			HEX5 = BLANK;
		end else if (~key_valid) begin
			HEX0 = DASH;
			HEX1 = DASH;
			HEX2 = DASH;
			HEX3 = DASH;
			HEX4 = DASH;
			HEX5 = DASH;
		end else begin
			unique case (key[23:20])
				4'h0: HEX5 = ZERO;
				4'h1: HEX5 = ONE;
				4'h2: HEX5 = TWO;
				4'h3: HEX5 = THREE;
				4'h4: HEX5 = FOUR;
				4'h5: HEX5 = FIVE;
				4'h6: HEX5 = SIX;
				4'h7: HEX5 = SEVEN;
				4'h8: HEX5 = EIGHT;
				4'h9: HEX5 = NINE;
				4'hA: HEX5 = A;
				4'hB: HEX5 = B;
				4'hC: HEX5 = C;
				4'hD: HEX5 = D;
				4'hE: HEX5 = E;
				4'hF: HEX5 = F;
			endcase

			unique case (key[19:16])
				4'h0: HEX4 = ZERO;
				4'h1: HEX4 = ONE;
				4'h2: HEX4 = TWO;
				4'h3: HEX4 = THREE;
				4'h4: HEX4 = FOUR;
				4'h5: HEX4 = FIVE;
				4'h6: HEX4 = SIX;
				4'h7: HEX4 = SEVEN;
				4'h8: HEX4 = EIGHT;
				4'h9: HEX4 = NINE;
				4'hA: HEX4 = A;
				4'hB: HEX4 = B;
				4'hC: HEX4 = C;
				4'hD: HEX4 = D;
				4'hE: HEX4 = E;
				4'hF: HEX4 = F;
			endcase

			unique case (key[15:12])
				4'h0: HEX3 = ZERO;
				4'h1: HEX3 = ONE;
				4'h2: HEX3 = TWO;
				4'h3: HEX3 = THREE;
				4'h4: HEX3 = FOUR;
				4'h5: HEX3 = FIVE;
				4'h6: HEX3 = SIX;
				4'h7: HEX3 = SEVEN;
				4'h8: HEX3 = EIGHT;
				4'h9: HEX3 = NINE;
				4'hA: HEX3 = A;
				4'hB: HEX3 = B;
				4'hC: HEX3 = C;
				4'hD: HEX3 = D;
				4'hE: HEX3 = E;
				4'hF: HEX3 = F;
			endcase

			unique case (key[11:8])
				4'h0: HEX2 = ZERO;
				4'h1: HEX2 = ONE;
				4'h2: HEX2 = TWO;
				4'h3: HEX2 = THREE;
				4'h4: HEX2 = FOUR;
				4'h5: HEX2 = FIVE;
				4'h6: HEX2 = SIX;
				4'h7: HEX2 = SEVEN;
				4'h8: HEX2 = EIGHT;
				4'h9: HEX2 = NINE;
				4'hA: HEX2 = A;
				4'hB: HEX2 = B;
				4'hC: HEX2 = C;
				4'hD: HEX2 = D;
				4'hE: HEX2 = E;
				4'hF: HEX2 = F;
			endcase

			unique case (key[7:4])
				4'h0: HEX1 = ZERO;
				4'h1: HEX1 = ONE;
				4'h2: HEX1 = TWO;
				4'h3: HEX1 = THREE;
				4'h4: HEX1 = FOUR;
				4'h5: HEX1 = FIVE;
				4'h6: HEX1 = SIX;
				4'h7: HEX1 = SEVEN;
				4'h8: HEX1 = EIGHT;
				4'h9: HEX1 = NINE;
				4'hA: HEX1 = A;
				4'hB: HEX1 = B;
				4'hC: HEX1 = C;
				4'hD: HEX1 = D;
				4'hE: HEX1 = E;
				4'hF: HEX1 = F;
			endcase

			unique case (key[3:0])
				4'h0: HEX0 = ZERO;
				4'h1: HEX0 = ONE;
				4'h2: HEX0 = TWO;
				4'h3: HEX0 = THREE;
				4'h4: HEX0 = FOUR;
				4'h5: HEX0 = FIVE;
				4'h6: HEX0 = SIX;
				4'h7: HEX0 = SEVEN;
				4'h8: HEX0 = EIGHT;
				4'h9: HEX0 = NINE;
				4'hA: HEX0 = A;
				4'hB: HEX0 = B;
				4'hC: HEX0 = C;
				4'hD: HEX0 = D;
				4'hE: HEX0 = E;
				4'hF: HEX0 = F;
			endcase
		end
	end: hex_disp

endmodule: competition
