//DESencode and decode
module des(
i_clk,//system clock
i_rst,//system i_rst
i_enable,//when high the data is ready
i_decrypt,//high is encode low is decode
i_data,//data
i_key,//k
o_data,//data output
o_ready//finish signal
);

input i_clk;
input i_rst;
input i_enable;
input i_decrypt;
input [63:0] i_data;
input [63:0] i_key;
output [63:0] o_data;
output o_ready;

reg [63:0] o_data;
reg o_ready;

reg [3:0] reg_stage1;
reg [3:0] reg_next_stage1;
reg reg_next_ready;
reg [63:0] reg_next_data;
reg reg_data_ready;
reg reg_next_data_ready;
reg [31:0] reg_stage_L;
reg [31:0] reg_stage_R;
reg [55:0] reg_stage_round_key;
reg [3:0] reg_stage_iteration;

wire [31:0]reg_stage_Ro;
wire [31:0]reg_stage_Lo;
wire [55:0]reg_stage_round_keyo;

wire [5:0] s1_stag1_i;
wire [5:0] s2_stag1_i;
wire [5:0] s3_stag1_i;
wire [5:0] s4_stag1_i;
wire [5:0] s5_stag1_i;
wire [5:0] s6_stag1_i;
wire [5:0] s7_stag1_i;
wire [5:0] s8_stag1_i;
wire [3:0] s1_stag1_o;
wire [3:0] s2_stag1_o;
wire [3:0] s3_stag1_o;
wire [3:0] s4_stag1_o;
wire [3:0] s5_stag1_o;
wire [3:0] s6_stag1_o;
wire [3:0] s7_stag1_o;
wire [3:0] s8_stag1_o;

reg[31:0] L_i_var;
reg[31:0] R_i_var;
reg[63:0] data_i_var;
reg[63:0] data_o_var;
reg[63:0] data_o_var_t;
reg[63:0] key_i_var;
reg[55:0] key_var_perm;


desround desround_u(
.clk (i_clk),
.reset (i_rst),
.iteration_i (reg_stage_iteration),
.decrypt_i (i_decrypt),
.R_i (reg_stage_R),
.L_i (reg_stage_L),
.Key_i (reg_stage_round_key),
.R_o (reg_stage_Ro),
.L_o (reg_stage_Lo),
.Key_o (reg_stage_round_keyo),
.s1_o (s1_stag1_i),
.s2_o (s2_stag1_i),
.s3_o (s3_stag1_i),
.s4_o (s4_stag1_i),
.s5_o (s5_stag1_i),
.s6_o (s6_stag1_i),
.s7_o (s7_stag1_i),
.s8_o (s8_stag1_i),
.s1_i (s1_stag1_o),
.s2_i (s2_stag1_o),
.s3_i (s3_stag1_o),
.s4_i (s4_stag1_o),
.s5_i (s5_stag1_o),
.s6_i (s6_stag1_o),
.s7_i (s7_stag1_o),
.s8_i (s8_stag1_o)
);

s1 s1_u(
.stage1_input(s1_stag1_i),
.stage1_output(s1_stag1_o)
);

s2 s2_u(
.stage1_input(s2_stag1_i),
.stage1_output(s2_stag1_o)
);

s3 s3_u(
.stage1_input(s3_stag1_i),
.stage1_output(s3_stag1_o)
);

s4 s4_u(
.stage1_input(s4_stag1_i),
.stage1_output(s4_stag1_o)
);

s5 s5_u(
.stage1_input(s5_stag1_i),
.stage1_output(s5_stag1_o)
);

s6 s6_u(
.stage1_input(s6_stag1_i),
.stage1_output(s6_stag1_o)
);

s7 s7_u(
.stage1_input(s7_stag1_i),
.stage1_output(s7_stag1_o)
);

s8 s8_u(
.stage1_input(s8_stag1_i),
.stage1_output(s8_stag1_o)
);


always @(posedge i_clk or negedge i_rst)
begin
if(!i_rst)
begin
o_ready = 1'b0;
o_data = 64'd0;
reg_stage1 = 4'b0000;
reg_data_ready = 1'b1;
end
else begin
o_ready = reg_next_ready;
o_data = reg_next_data;
reg_stage1 = reg_next_stage1;
reg_data_ready = reg_next_data_ready;
end
end


always @(i_data or i_key or i_enable or reg_stage1 or reg_data_ready or reg_stage_Ro or reg_stage_Lo or reg_stage_round_keyo)
begin
L_i_var = 0;
R_i_var = 0;
data_i_var = 0;
reg_next_ready = 0;
reg_next_data_ready = reg_data_ready;
reg_next_stage1 = reg_stage1;
reg_stage_L = 0;
reg_stage_R = 0;
reg_stage_round_key = 0;

key_i_var = i_key;
key_var_perm[55] = key_i_var[7];
key_var_perm[54] = key_i_var[15];
key_var_perm[53] = key_i_var[23];
key_var_perm[52] = key_i_var[31];
key_var_perm[51] = key_i_var[39];
key_var_perm[50] = key_i_var[47];
key_var_perm[49] = key_i_var[55];
key_var_perm[48] = key_i_var[63];

key_var_perm[47] = key_i_var[6];
key_var_perm[46] = key_i_var[14];
key_var_perm[45] = key_i_var[22];
key_var_perm[44] = key_i_var[30];
key_var_perm[43] = key_i_var[38];
key_var_perm[42] = key_i_var[46];
key_var_perm[41] = key_i_var[54];
key_var_perm[40] = key_i_var[62];
key_var_perm[39] = key_i_var[5];
key_var_perm[38] = key_i_var[13];
key_var_perm[37] = key_i_var[21];
key_var_perm[36] = key_i_var[29];
key_var_perm[35] = key_i_var[37];
key_var_perm[34] = key_i_var[45];
key_var_perm[33] = key_i_var[53];
key_var_perm[32] = key_i_var[61];
key_var_perm[31] = key_i_var[4];
key_var_perm[30] = key_i_var[12];
key_var_perm[29] = key_i_var[20];
key_var_perm[28] = key_i_var[28];
key_var_perm[27] = key_i_var[1];
key_var_perm[26] = key_i_var[9];
key_var_perm[25] = key_i_var[17];
key_var_perm[24] = key_i_var[25];
key_var_perm[23] = key_i_var[33];
key_var_perm[22] = key_i_var[41];
key_var_perm[21] = key_i_var[49];
key_var_perm[20] = key_i_var[57];
key_var_perm[19] = key_i_var[2];
key_var_perm[18] = key_i_var[10];
key_var_perm[17] = key_i_var[18];
key_var_perm[16] = key_i_var[26];
key_var_perm[15] = key_i_var[34];
key_var_perm[14] = key_i_var[42];
key_var_perm[13] = key_i_var[50];
key_var_perm[12] = key_i_var[58];
key_var_perm[11] = key_i_var[3];
key_var_perm[10] = key_i_var[11];
key_var_perm[9] = key_i_var[19];
key_var_perm[8] = key_i_var[27];
key_var_perm[7] = key_i_var[35];
key_var_perm[6] = key_i_var[43];
key_var_perm[5] = key_i_var[51];
key_var_perm[4] = key_i_var[59];
key_var_perm[3] = key_i_var[36];
key_var_perm[2] = key_i_var[44];
key_var_perm[1] = key_i_var[52];
key_var_perm[0] = key_i_var[60];
data_i_var =i_data;
L_i_var[31]=data_i_var[6];
L_i_var[30]=data_i_var[14];
L_i_var[29]=data_i_var[22];
L_i_var[28]=data_i_var[30];
L_i_var[27]=data_i_var[38];
L_i_var[26]=data_i_var[46];
L_i_var[25]=data_i_var[54];
L_i_var[24]=data_i_var[62];

L_i_var[23]=data_i_var[4];
L_i_var[22]=data_i_var[12];
L_i_var[21]=data_i_var[20];
L_i_var[20]=data_i_var[28];
L_i_var[19]=data_i_var[36];
L_i_var[18]=data_i_var[44];
L_i_var[17]=data_i_var[52];
L_i_var[16]=data_i_var[60];

L_i_var[15]=data_i_var[2];
L_i_var[14]=data_i_var[10];
L_i_var[13]=data_i_var[18];
L_i_var[12]=data_i_var[26];
L_i_var[11]=data_i_var[34];
L_i_var[10]=data_i_var[42];
L_i_var[9] =data_i_var[50];
L_i_var[8] =data_i_var[58];

L_i_var[7] =data_i_var[0];
L_i_var[6] =data_i_var[8];
L_i_var[5] =data_i_var[16];
L_i_var[4] =data_i_var[24];
L_i_var[3] =data_i_var[32];
L_i_var[2] =data_i_var[40];
L_i_var[1] =data_i_var[48];
L_i_var[0] =data_i_var[56];
R_i_var[31]=data_i_var[7];
R_i_var[30]=data_i_var[15];
R_i_var[29]=data_i_var[23];
R_i_var[28]=data_i_var[31];
R_i_var[27]=data_i_var[39];
R_i_var[26]=data_i_var[47];
R_i_var[25]=data_i_var[55];
R_i_var[24]=data_i_var[63];

R_i_var[23]=data_i_var[5];
R_i_var[22]=data_i_var[13];
R_i_var[21]=data_i_var[21];
R_i_var[20]=data_i_var[29];
R_i_var[19]=data_i_var[37];
R_i_var[18]=data_i_var[45];
R_i_var[17]=data_i_var[53];
R_i_var[16]=data_i_var[61];

R_i_var[15]=data_i_var[3];
R_i_var[14]=data_i_var[11];
R_i_var[13]=data_i_var[19];
R_i_var[12]=data_i_var[27];
R_i_var[11]=data_i_var[35];
R_i_var[10]=data_i_var[43];
R_i_var[9] =data_i_var[51];
R_i_var[8] =data_i_var[59];

R_i_var[7] =data_i_var[1];
R_i_var[6] =data_i_var[9];
R_i_var[5] =data_i_var[17];
R_i_var[4] =data_i_var[25];
R_i_var[3] =data_i_var[33];
R_i_var[2] =data_i_var[41];
R_i_var[1] =data_i_var[49];
R_i_var[0] =data_i_var[57];


data_o_var_t[63:32] = reg_stage_Ro;
data_o_var_t[31:0] = reg_stage_Lo;
data_o_var[63]=data_o_var_t[24];
data_o_var[62]=data_o_var_t[56];
data_o_var[61]=data_o_var_t[16];
data_o_var[60]=data_o_var_t[48];
data_o_var[59]=data_o_var_t[8];
data_o_var[58]=data_o_var_t[40];
data_o_var[57]=data_o_var_t[0];
data_o_var[56]=data_o_var_t[32];
data_o_var[55]=data_o_var_t[25];
data_o_var[54]=data_o_var_t[57];
data_o_var[53]=data_o_var_t[17];
data_o_var[52]=data_o_var_t[49];
data_o_var[51]=data_o_var_t[9];
data_o_var[50]=data_o_var_t[41];
data_o_var[49]=data_o_var_t[1];
data_o_var[48]=data_o_var_t[33];
data_o_var[47]=data_o_var_t[26];
data_o_var[46]=data_o_var_t[58];
data_o_var[45]=data_o_var_t[18];
data_o_var[44]=data_o_var_t[50];
data_o_var[43]=data_o_var_t[10];
data_o_var[42]=data_o_var_t[42];
data_o_var[41]=data_o_var_t[2];
data_o_var[40]=data_o_var_t[34];
data_o_var[39]=data_o_var_t[27];
data_o_var[38]=data_o_var_t[59];
data_o_var[37]=data_o_var_t[19];
data_o_var[36]=data_o_var_t[51];
data_o_var[35]=data_o_var_t[11];
data_o_var[34]=data_o_var_t[43];
data_o_var[33]=data_o_var_t[3];
data_o_var[32]=data_o_var_t[35];
data_o_var[31]=data_o_var_t[28];
data_o_var[30]=data_o_var_t[60];
data_o_var[29]=data_o_var_t[20];
data_o_var[28]=data_o_var_t[52];
data_o_var[27]=data_o_var_t[12];
data_o_var[26]=data_o_var_t[44];
data_o_var[25]=data_o_var_t[4];
data_o_var[24]=data_o_var_t[36];
data_o_var[23]=data_o_var_t[29];
data_o_var[22]=data_o_var_t[61];
data_o_var[21]=data_o_var_t[21];
data_o_var[20]=data_o_var_t[53];
data_o_var[19]=data_o_var_t[13];
data_o_var[18]=data_o_var_t[45];
data_o_var[17]=data_o_var_t[5];
data_o_var[16]=data_o_var_t[37];
data_o_var[15]=data_o_var_t[30];
data_o_var[14]=data_o_var_t[62];
data_o_var[13]=data_o_var_t[22];
data_o_var[12]=data_o_var_t[54];
data_o_var[11]=data_o_var_t[14];
data_o_var[10]=data_o_var_t[46];
data_o_var[9] =data_o_var_t[6];
data_o_var[8] =data_o_var_t[38];
data_o_var[7] =data_o_var_t[31];
data_o_var[6] =data_o_var_t[63];
data_o_var[5] =data_o_var_t[23];
data_o_var[4] =data_o_var_t[55];
data_o_var[3] =data_o_var_t[15];
data_o_var[2] =data_o_var_t[47];
data_o_var[1] =data_o_var_t[7];
data_o_var[0] =data_o_var_t[39];
reg_next_data = data_o_var;
reg_stage_iteration = reg_stage1;

reg_next_ready = 0;
reg_stage_L = reg_stage_Lo;
reg_stage_R = reg_stage_Ro;
reg_stage_round_key = reg_stage_round_keyo;



case(reg_stage1)
0:
begin
if(i_enable)
begin
reg_next_stage1 = 1;
reg_stage_L = L_i_var;
reg_stage_R = R_i_var;
reg_stage_round_key = key_var_perm;
reg_next_data_ready = 0;
end
else if(!reg_data_ready)
begin
reg_next_stage1 = 0;
reg_next_ready = 1;
reg_next_data_ready = 1;
end
end
15:
reg_next_stage1 = 0;

default:
reg_next_stage1 = reg_stage1+1;
endcase
end
endmodule