1.设计描述
此设计为DES加密解密算法的FPGA实现,DES算法为密码体制中的对称密码体制,也被称为美国数据加密标准。明文按64位进行分组,密钥长度为64位,随后按照一系列置换和代替技术进行具体的加密算法。
输入为100MHz的时钟,复位信号。
输出为16位数据D[15:0]。
IP核:v4_dcm进行系统分频
输入时钟首先进行dcm分频为10MHz,再通过分频模块进一步分频为100K时钟,并以此为算法中数据处理的基准时钟。复位信号中对各寄存器值初始化,其中对data_in(加密模式下的明文或解密模式下的密文,64位)和密钥key(64位)赋初值,经过DES算法后产生data_out(加密模式下的密文或解密模式下的明文,64位)。将64位data_out分为8组赋给D的数据输出,同时按时钟循环赋给D控制输出,最终在实验箱8个数码管上显示,每个数码管表示8位输出,目的是验证在可综合以及仿真成功的条件下能够在真实环境中运行。
2.代码设计
2.1时钟模块
//main函数例化模块 系统时间分频
//dcm IP核 输入100MHz,输出10MHz
v4_dcm CLK_DIV_10M(
.CLKIN_IN(CLK),
.RST_IN(!rst_n),
.CLKDV_OUT(CLK_10M),
.CLKIN_IBUFG_OUT(),
.CLK0_OUT(),
.LOCKED_OUT(CLK_LOCKED)
);
//100k模块运行时间分频
wire CLK_100K;
parameter DIV_FACTOR = 100;
CLK_DIV CLK_DIV_100K (
.CLK_IN(CLK_10M),
.nRST(CLK_LOCKED),
.CLK_OUT(CLK_100K)
);
defparam CLK_DIV_100K.DIV_FACTOR =DIV_FACTOR;
wire nRST_USER;
assign nRST_USER= CLK_LOCKED;
//时钟分频模块
moduleCLK_DIV(CLK_IN, nRST, CLK_OUT);
input CLK_IN;
input nRST;
output CLK_OUT;
reg CLK_OUT = 1'b1;
reg [9:0] DIV_counter = 10'h000;
parameter DIV_FACTOR = 1;
always@(posedge CLK_IN)
begin
if(!nRST)
begin
CLK_OUT <= 1'b1;
DIV_counter<= 10'h000;
end
else
begin
if(DIV_counter != DIV_FACTOR >>1)
begin
DIV_counter <= DIV_counter + 1;
end
else
begin
DIV_counter <= 10'h000;
CLK_OUT <= !CLK_OUT;
end
end
end
endmodule
2.2 置换函数
2'b01: //明文初始置换(IP)
begin
data_temp <={data_in[6],data_in[14],data_in[22],data_in[30],data_in[38],data_in[46],data_in[54],data_in[62],
data_in[4],data_in[12],data_in[20],data_in[28],data_in[36],data_in[44],data_in[52],data_in[60],
data_in[2],data_in[10],data_in[18],data_in[26],data_in[34],data_in[42],data_in[50],data_in[58],
data_in[0],data_in[8],data_in[16],data_in[24],data_in[32],data_in[40],data_in[48],data_in[56],
data_in[7],data_in[15],data_in[23],data_in[31],data_in[39],data_in[47],data_in[55],data_in[63],
data_in[5],data_in[13],data_in[21],data_in[29],data_in[37],data_in[45],data_in[53],data_in[61],
data_in[3],data_in[11],data_in[19],data_in[27],data_in[35],data_in[43],data_in[51],data_in[59],
data_in[1],data_in[9],data_in[17],data_in[25],data_in[33],data_in[41],data_in[49],data_in[57]};
step_counter <=step_counter+1;
end
//每一轮加密算法实现
case(round_counter)
4'h0: //第一轮加密
begin
case(inter_counter)
4'h0: //将数据分为左右两部分 各32位
begin
data_L <= data_temp[63:32];
data_R <= data_temp[31:0];
inter_counter <= inter_counter+1;
end
4'h1: //将本轮右半部数据赋值给下一轮左半部
begin
data_temp[63:32] <= data_R;
inter_counter <= inter_counter+1;
end
4'h2: //扩展置换
begin
// 32>48
extend <={data_R[0],data_R[31],data_R[30],data_R[29],data_R[28],data_R[27],
data_R[28],data_R[27],data_R[26],data_R[25],data_R[24],data_R[23],
data_R[24],data_R[23],data_R[22],data_R[21],data_R[20],data_R[19],
data_R[20],data_R[19],data_R[18],data_R[17],data_R[16],data_R[15],
data_R[16],data_R[15],data_R[14],data_R[13],data_R[12],data_R[11],
data_R[12],data_R[11],data_R[10],data_R[9],data_R[8],data_R[7],
data_R[8],data_R[7],data_R[6],data_R[5],data_R[4],data_R[3],
data_R[4],data_R[3],data_R[2],data_R[1],data_R[0],data_R[31]};
inter_counter <=inter_counter+1;
end
4'h3: //和子密钥异或
begin
case(model)
1'b0:
extend<= extend ^ sub_key[0];
1'b1:
extend <= extend ^ sub_key[15];
endcase
inter_counter<= inter_counter+1;
end
4'h4: //S盒代替选择
begin
//S盒 48>32
end
4'hC: //置换函数P
begin
data_R <={data_S[16],data_S[25],data_S[12],data_S[11],data_S[3],data_S[20],data_S[4],data_S[15],
data_S[31],data_S[17],data_S[9],data_S[6],data_S[27],data_S[14],data_S[1],data_S[22],
data_S[30],data_S[24],data_S[8],data_S[18],data_S[0],data_S[5],data_S[29],data_S[23],
data_S[13],data_S[19],data_S[2],data_S[26],data_S[10],data_S[21],data_S[28],data_S[7]};
inter_counter <= inter_counter+1;
end
4'hD: //和左半部异或
begin
data_temp[31:0] <= data_L ^data_R;
inter_counter <= 4'h0;
round_counter <= round_counter+1;
end
endcase
end
2.3 数码管显示
case(round_counter)
4'h0:
begin
select <= 8'hFE; //数码管控制引脚
data<= data_out[7:0]; //数码管数据引脚
round_counter<= round_counter+1;
end
4'h1:
begin
select <= 8'hFD;
data <= data_out[63:56];
round_counter <= round_counter+1;
end
4'h2:
begin
select <= 8'hFB;
data <= data_out[55:48];
round_counter <= round_counter+1;
end
4'h3:
begin
select <= 8'hF7;
data <= data_out[47:40];
round_counter <= round_counter+1;
end
4'h4:
begin
select<= 8'hEF;
data<= data_out[39:32];
round_counter<= round_counter+1;
end
4'h5:
begin
select<= 8'hDF;
data <= data_out[31:24];
round_counter<= round_counter+1;
end
4'h6:
begin
select<= 8'hBF;
data<= data_out[23:16];
round_counter<= round_counter+1;
end
4'h7:
begin
select<= 8'h7F;
data<= data_out[15:8];
round_counter<= 0;
en
default:
round_counter<= round_counter;
endcase