module lab4 # (
	parameter WIDTH = 50,
	localparam WIDTH_M1 = WIDTH - 1
)(
	input clk, input rst_n,
	input ld,
	input [19:0] key,
	input [WIDTH-1:0] plaintext,
	output reg [WIDTH-1:0] ciphertext,
	output reg done
);

localparam ROUNDS = 4;

localparam ST_INIT = 3'd0;
localparam ST_PART1 = 3'd1;
localparam ST_PART2 = 3'd2;
localparam ST_PART3 = 3'd3;
localparam ST_PART4 = 3'd4;

reg [2:0] state, next_state;
reg [19:0] mykey, next_mykey;
reg [49:0] mytext, next_mytext;
reg [49:0] next_ciphertext;
reg next_done;

always @(posedge clk) begin
	if (rst_n == 1'b0) begin
		state <= ST_INIT;
		mykey <= 20'd0;
		mytext <= 50'd0;
		ciphertext <= 50'd0;
		done <= 1'b0;
	end
	else begin
		state <= next_state;
		mykey <= next_mykey;
		mytext <= next_mytext;
		ciphertext <= next_ciphertext;
		done <= next_done;
	end
end

reg [4:0] rot1, rot2, rot3, rot4, rot5, rot6, rot7, rot8, rot9, rot10;
reg [4:0] current_key;

always @(*) begin
	next_state = ST_INIT;
	next_mykey = 20'd0;
	next_mytext = 50'd0;
	next_ciphertext = 50'd0;
	next_done = 1'b0;
	rot1 = 5'd0;
	rot2 = 5'd0;
	rot3 = 5'd0;
	rot4 = 5'd0;
	rot5 = 5'd0;
	rot6 = 5'd0;
	rot7 = 5'd0;
	rot8 = 5'd0;
	rot9 = 5'd0;
	rot10 = 5'd0;
	current_key = 0;

	case (state)
		ST_INIT: begin
			if (ld) begin 
				next_state = ST_PART1;
				next_mykey = key;
				next_mytext = plaintext;
			end
		end
		ST_PART1: begin 
			next_state = ST_PART2;
			current_key = mykey[4:0];
			rot1 = mytext[4:0] + current_key;
			rot2 = mytext[9:5] + current_key;
			rot3 = mytext[14:10] + current_key;
			rot4 = mytext[19:15] + current_key;
			rot5 = mytext[24:20] + current_key;
			rot6 = mytext[29:25] + current_key;
			rot7 = mytext[34:30] + current_key;
			rot8 = mytext[39:35] + current_key;
			rot9 = mytext[44:40] + current_key;
			rot10 = mytext[49:45] + current_key;
			next_mytext = {rot10, rot9, rot8, rot7, rot6, rot5, rot4, rot3, rot2, rot1};
		end
		ST_PART2: begin 
			next_state = ST_PART3;
			current_key = mykey[9:5];
			rot1 = mytext[4:0] + current_key;
			rot2 = mytext[9:5] + current_key;
			rot3 = mytext[14:10] + current_key;
			rot4 = mytext[19:15] + current_key;
			rot5 = mytext[24:20] + current_key;
			rot6 = mytext[29:25] + current_key;
			rot7 = mytext[34:30] + current_key;
			rot8 = mytext[39:35] + current_key;
			rot9 = mytext[44:40] + current_key;
			rot10 = mytext[49:45] + current_key;
			next_mytext = {rot10, rot9, rot8, rot7, rot6, rot5, rot4, rot3, rot2, rot1};
		end
		ST_PART3: begin 
			next_state = ST_PART4;
			current_key = mykey[14:9];
			rot1 = mytext[4:0] + current_key;
			rot2 = mytext[9:5] + current_key;
			rot3 = mytext[14:10] + current_key;
			rot4 = mytext[19:15] + current_key;
			rot5 = mytext[24:20] + current_key;
			rot6 = mytext[29:25] + current_key;
			rot7 = mytext[34:30] + current_key;
			rot8 = mytext[39:35] + current_key;
			rot9 = mytext[44:40] + current_key;
			rot10 = mytext[49:45] + current_key;
			next_mytext = {rot10, rot9, rot8, rot7, rot6, rot5, rot4, rot3, rot2, rot1};
		end
		ST_PART4: begin 
			next_state = ST_INIT;
			next_done = 1'b1;
			current_key = mykey[19:14];
			rot1 = mytext[4:0] + current_key;
			rot2 = mytext[9:5] + current_key;
			rot3 = mytext[14:10] + current_key;
			rot4 = mytext[19:15] + current_key;
			rot5 = mytext[24:20] + current_key;
			rot6 = mytext[29:25] + current_key;
			rot7 = mytext[34:30] + current_key;
			rot8 = mytext[39:35] + current_key;
			rot9 = mytext[44:40] + current_key;
			rot10 = mytext[49:45] + current_key;
			next_mytext = {rot10, rot9, rot8, rot7, rot6, rot5, rot4, rot3, rot2, rot1};
			next_ciphertext = mytext;
		end
	endcase
end

endmodule