EDA课程设计报告

EDA/SOPC课程设计报告

题目: DES密码算法硬件设计与验证             


目录

目录... I

第1章 课程设计的要求... 1

1.1 课程设计的目的... 1

1.2 课程设计的条件... 1

1.3 课程设计的要求... 1

第2章 课程设计的内容... 2

2.1 DES密码算法简介... 2

2.2 DES密码算法原理... 2

2.3 DES密码设计方案... 5

2.4 HDL代码阐述... 7

2.4.1 顶层模块... 7

2.4.2 初始置换模块... 8

2.4.3 F函数模块... 9

2.4.4 子密钥生成模块... 19

2.4.5 逆初始置换模块... 21

2.5 .ModelSim验证... 21

第3章 课程设计的心得... 24

         


第1章  课程设计的要求

1.1 课程设计的目的

l  了解掌握DES密码算法的原理

l  硬件实现DES密码算法并验证功能

l  掌握较大工程的基本开发技能

l  培养综合运用Modelsim,Quartus II工具进行硬件开发的能力

l  培养数字系统设计的基本能力

1.2 课程设计的条件

l  PC机

l  Nexys 4 实验板一套

l  ISE/modelsim开发平台

1.3 课程设计的要求

l  实现DES密码算法加密/解密功能

l  电路实现尽可能简单

l  要求电路设计具备可移植性

第2章  课程设计的内容

2.1 DES密码算法简介

DES (Data Encryption Standard)密码是1977年由美国国家标准局公布的第一个分组密码算法,在成为加密标准到今天,经历了长期的考验。实践证明DES算法的安全性是能够满足大部分的安全要求的。采用软件方式实现的DES算法会在很大程度上占用系统资源,造成系统性能的严重下降,而DES算法本身并没有大量的复杂数学计算,在加/解密过程和密钥生成过程中仅有逻辑运算和查表运算,因而,无论是从系统性能还是加/解密速度的角度来看,采用硬件实现都是一个理想的方案。

DES是一个分组加密算法,它以64位为分组对数据加密。64位一组的明文从算法的一端输入,64位的密文从另一端输出。DES是一个对称算法:加密和解密用的是同一种算法。密钥的长度为56位。(密钥通常表示为64的数,但每个第8位都用作奇偶校验,可以忽略。)密钥可以是任意的56为的数,且可在任意的时候改变。其中极少量的数被认为是弱密钥,但能容易地避开它们。所有的保密性依赖于密钥。

2.2 DES密码算法原理

DES运算的明文(加密前数据)和加密密钥都是64位的,将原始数据经过初始的置换,然后与子密钥(由加密密钥产生)经过一系列迭代运算,最后再经过逆置换,即可到密文(加密后数据)。解密过程与此类似。分组密码是将明文消息编码表示后的数字序列X1,X2,…Xi.划分成长为m的组X=(X1,X2,…Xi),各组(长为m的矢量)分别在密钥K的控制下变换成等长度的输出数字序列Y(长为n的矢量)。

如图2-1所示,DES算法是64位明文由一个初始序列变换(IP)开始,经过16轮的加密运算再通过初始序列变换的逆变换(IIP)得到所需的密文。在每一轮中,数列块的右边32位数据R和密钥(KEY)一起传送给函数f,函数f运算的结果再和数列块左边32位数据L进行异或操作。其中S盒(选择函数)是DES算法的心脏,靠它实现非线性变换。

图 2-1 DES密码算法流程图

其中,f函数的结构如图2-2所示

图 2-2 f函数结构

Ø  初始置换:输入分组按照初始置换表重新排序,进行初始置换。

Ø  16轮循环:DES对经过初始置换的64位长的明文进行16轮类似的子加密过程,每一轮的子加密过程要经过DES的f函数,其过程如下:

将64位明文从中间一分为二,左半部分记作L,右半部分记作R,然后对R进行如下操作:

   扩展置换:将32位的输入数据根据扩展置换表扩展成为48位的输出数据。

   异或运算:将扩展得到的48位输出数据域48位子密钥进行异或运算。

   S盒置换:S盒置换是非线性的,48位输入数据根据S盒置换表置换成32位输出数据。

   直接置换:S盒置换后的32位输出数据根据直接置换表进行直接置换。

经过直接置换的32位输出数据域本轮的L部分进行异或运算,结果作为下一轮子加密过程的R部分,本轮的R部分直接作为下一轮子加密过程的L部分。然后进入下一轮子加密过程,直到16轮全部完成。

Ø  逆初始置换:按照逆初始置换表进行终结置换,64位输出就是密文。

子密钥的产生过程如下:

Ø  循环左移:根据循环左移表对C和D进行循环移位,循环移位后的C和D作为下一轮子密钥生成的输入数据,直到16轮全部完成。

Ø  将C和D合并成为56位数据。

Ø  压缩型换位2:56位的输入数据根据压缩型换位2表输出48位的子密钥,这48位的子密钥将与48位的明文数据进行异或操作。

表2-1 初始置换表

表2-2 逆初始置换表

表2-3 S盒置换表

表2-4 扩展置换表

表2-5 直接置换表

表2-6 压缩型换位1置换表

表2-6压缩换位2置换表

表2-7 循环左移表

2.3 DES密码设计方案

通过对DES密码算法原理的学习了解,分析了DES加密解密的工作流程,初步拟定的设计方案如图2-3所示。

图 2-3 DES初步设计方案

其中,16轮循环子加密过程按部就班地依照图2-4子密钥生成结构和图2-5 F函数设计实现,S盒变换部分采用查找表LUB方式实现,快捷方便。

图 2-4 子密钥生成结构

图 2-5 F函数结构

在按照此结构设计时序电路时,需注意满足子密钥生成电路和F函数从输入到输出的时间片段一致性,即同时输入则同时输出,否则会产生不必要的时序错乱,从而导致运算结果出错。结合数字电路设计的技巧,在编写Verilog代码时将各个模块的运算部分采用组合逻辑实现,而各部分的输出采用触发器锁存输出结构,从而既防止了输出抖动,又提高了电路的速度。

但是,上述的电路实现占用了大量的逻辑资源,而且效率不高,每16各时钟周期才输出一个数据,耗时耗力。经过对DES加密流程的进一步分析,对最初的设计方案进行了如下改进:

Ø  总体框架采用流水线结构,16级流水完成16轮子加密过程,再考虑上输入输出锁存结构,从数据输入到运算结果输出一共需要18个时钟周期,但是一旦流水线建立起来之后,每个时钟周期都可以输出一个运算结果,处理速率大大提高。

Ø  子密钥生成模块采用组合逻辑,通过分析压缩型变换1和16轮循环移位,最终得到子密钥与原始密钥的直接关系,从而一步实现子密钥生成步骤,简化了电路结构,且16轮子密钥同时产生,这对于同一模块既可以完成加密处理又可以实现解密运算的双用电路设计提供了方便,节约了电路资源。

Ø  增加使能信号,只有当真正的运算结果产生后才输出,否则输出全零,以避免流水线建立过程中间结果的不必要输出。

改进后的设计方案如下:

图 2-6 改进后总体结构

图 2-7 改进后F函数

其中,S盒采用查找表方式实现,其结构框图如图2-8所示。

图 2-8 S盒的查找表实现

2.4 HDL代码阐述

本文所述的DES密码算法硬件设计实现采用分模块设计的策略,包括顶层模块、初始置换模块、F函数模块、子密钥生成模块和逆初始置换模块,下面将就各个模块的硬件实现展开论述。

2.4.1 顶层模块

`include "firstchange.v"

`include "endchange.v"

`include "subkey_generate_better.v"

`include "Encryption.v"

module top(

    input [64:1] key,      

    input [64:1] data_in,  

input mode,            

input clk,            

input rst_n,

input En,          

    output [64:1] data_out 

        );

wire [64:1] fstchgedout;

firstchange fstchge_u1(.data_in(data_in),.clk(clk),.rst_n(rst_n),.firstchangedout(fstchgedout));

wire [48:1] k1,k2,k3,k4,k5,k6,k7,k8,k9,k10,k11,k12,k13,k14,k15,k16;

subkey_generate_better subkey_generate_u2(.key_in(key),.mode_in(mode),.subkey_out1(k1),.subkey_out2(k2),.subkey_out3(k3),.

subkey_out4(k4),.subkey_out5(k5),.subkey_out6(k6),.subkey_out7(k7),.subkey_out8(k8),.subkey_out9(k9),.subkey_out10(k10),

.subkey_out11(k11),.subkey_out12(k12),.subkey_out13(k13),.subkey_out14(k14),.subkey_out15(k15),.subkey_out16(k16));

wire [32:1] L2,R2,L3,R3,L4,R4,L5,R5,L6,R6,L7,R7,L8,R8,L9,R9,L10,R10,L11,R11,L12,R12,L13,R13,L14,R14,L15,R15,L16,R16,

L17,R17;

Encryption f1 (.L(fstchgedout[64:33]),.R(fstchgedout[32:1]),.subkey(k1),.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R2),.new_L(L2));

Encryption f2 (.L(L2) ,.R(R2) ,.subkey(k2) ,.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R3) ,.new_L(L3)) ;

Encryption f3 (.L(L3) ,.R(R3) ,.subkey(k3) ,.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R4) ,.new_L(L4)) ;

Encryption f4 (.L(L4) ,.R(R4) ,.subkey(k4) ,.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R5) ,.new_L(L5)) ;

Encryption f5 (.L(L5) ,.R(R5) ,.subkey(k5) ,.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R6) ,.new_L(L6)) ;

Encryption f6 (.L(L6) ,.R(R6) ,.subkey(k6) ,.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R7) ,.new_L(L7)) ;

Encryption f7 (.L(L7) ,.R(R7) ,.subkey(k7) ,.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R8) ,.new_L(L8)) ;

Encryption f8 (.L(L8) ,.R(R8) ,.subkey(k8) ,.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R9) ,.new_L(L9)) ;

Encryption f9 (.L(L9) ,.R(R9) ,.subkey(k9) ,.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R10),.new_L(L10));

Encryption f10(.L(L10),.R(R10),.subkey(k10),.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R11),.new_L(L11));

Encryption f11(.L(L11),.R(R11),.subkey(k11),.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R12),.new_L(L12));

Encryption f12(.L(L12),.R(R12),.subkey(k12),.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R13),.new_L(L13));

Encryption f13(.L(L13),.R(R13),.subkey(k13),.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R14),.new_L(L14));

Encryption f14(.L(L14),.R(R14),.subkey(k14),.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R15),.new_L(L15));

Encryption f15(.L(L15),.R(R15),.subkey(k15),.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(R16),.new_L(L16));

/*notice the last time sbox change specially*/

Encryption f16(.L(L16),.R(R16),.subkey(k16),.Encryp_clk(clk),.Encryp_rst_n(rst_n),.new_R(L17),.new_L(R17));

reg [4:0] cnt;

wire en_out;

always @(posedge clk or negedge rst_n)

if(!rst_n)

  cnt <= 5'b0;

else

  if(!En)

    cnt <= 5'b00000;

  else

    cnt <= (cnt == 5'b10001) ? cnt : cnt + 5'b1;

assign en_out = (cnt ==5'b10001) ? 1 : 0;

endchange endchange_u3(.endchange_L(L17),.endchange_R(R17),.endchange_clk(clk),.endchange_rst_n(rst_n),.en_out(en_out),.endchange_dout(data_out));

endmodule

2.4.2 初始置换模块

module firstchange(

  //input [64:1] key,

    input [64:1] data_in,

    input clk,

    input rst_n,

    output reg [64:1] firstchangedout

     );

always @(posedge clk or negedge rst_n)

if(!rst_n)

   begin

               firstchangedout <= 64'h0000000000000000;

                          end

else

   begin

     firstchangedout <= { data_in[58],data_in[50],data_in[42],data_in[34],data_in[26],data_in[18],data_in[10],data_in[2],

                       data_in[60],data_in[52],data_in[44],data_in[36],data_in[28],data_in[20],data_in[12],data_in[4],

                       data_in[62],data_in[54],data_in[46],data_in[38],data_in[30],data_in[22],data_in[14],data_in[6],

                       data_in[64],data_in[56],data_in[48],data_in[40],data_in[32],data_in[24],data_in[16],data_in[8],

                                       data_in[57],data_in[49],data_in[41],data_in[33],data_in[25],data_in[17],data_in[9], data_in[1],

                       data_in[59],data_in[51],data_in[43],data_in[35],data_in[27],data_in[19],data_in[11],data_in[3],

                       data_in[61],data_in[53],data_in[45],data_in[37],data_in[29],data_in[21],data_in[13],data_in[5],

                       data_in[63],data_in[55],data_in[47],data_in[39],data_in[31],data_in[23],data_in[15],data_in[7]};

end                     

endmodule

2.4.3 F函数模块

module Encryption(

    input [32:1] L,  //connected to the firstchangedout [63:32]

    input [32:1] R,  //connected to the firstchangedout [31:0 ]

    input [48:1] subkey,  //connected to the subkey_out [47:0 ]

    input Encryp_clk,     //same to the subkey_clk

    input Encryp_rst_n,   //same to the subkey_rst_n

    output reg [32:1] new_R,

    output reg [32:1] new_L

    );

wire [48:1] Expend_R_out;

wire [48:1] subkey_xor_Expend_R;

/*Expend the R from 32bit to 48 bit*/

assign Expend_R_out = { R[32],R[1] ,R[2] ,R[3] ,R[4] ,R[5],R[4] ,R[5] ,R[6] ,R[7] ,R[8] ,R[9],

                                       R[8] ,R[9] ,R[10],R[11],R[12],R[13],R[12],R[13],R[14],R[15],R[16],R[17],

R[16],R[17],R[18],R[19],R[20],R[21],R[20],R[21],R[22],R[23],R[24],R[25],

                                       R[24],R[25],R[26],R[27],R[28],R[29],R[28],R[29],R[30],R[31],R[32],R[1] };

/*subkey xor Expend_R*/                                                                                                  

assign subkey_xor_Expend_R = (subkey ^ Expend_R_out);                                                                                    

/*devide subkey_xor_Expend_R into 8 group*/

wire [6:1] S_xor_R_1;

wire [6:1] S_xor_R_2;

wire [6:1] S_xor_R_3;

wire [6:1] S_xor_R_4;

wire [6:1] S_xor_R_5;

wire [6:1] S_xor_R_6;

wire [6:1] S_xor_R_7;

wire [6:1] S_xor_R_8;

assign {S_xor_R_1,S_xor_R_2,S_xor_R_3,S_xor_R_4,S_xor_R_5,S_xor_R_6,S_xor_R_7,S_xor_R_8} = subkey_xor_Expend_R[48:1];

reg [4:1]s1_out,s2_out,s3_out,s4_out,s5_out,s6_out,s7_out,s8_out; /*8 output from sbox*/

wire [32:1] s_out;

assign s_out = {s1_out,s2_out,s3_out,s4_out,s5_out,s6_out,s7_out,s8_out};

//sbox_1 change                                                     

always @(S_xor_R_1)                 

  begin

    case (S_xor_R_1)

      6'b000000 : s1_out = 4'd14;

      6'b000001 : s1_out = 4'd0 ;

      6'b000010 : s1_out = 4'd4 ;

      6'b000011 : s1_out = 4'd15;

      6'b000100 : s1_out = 4'd13;

      6'b000101 : s1_out = 4'd7 ;

      6'b000110 : s1_out = 4'd1 ;

      6'b000111 : s1_out = 4'd4 ;

      6'b001000 : s1_out = 4'd2 ;

      6'b001001 : s1_out = 4'd14;

      6'b001010 : s1_out = 4'd15;

      6'b001011 : s1_out = 4'd2 ;

      6'b001100 : s1_out = 4'd11;

      6'b001101 : s1_out = 4'd13;

      6'b001110 : s1_out = 4'd8 ;

      6'b001111 : s1_out = 4'd1 ;

      6'b010000 : s1_out = 4'd3 ;

      6'b010001 : s1_out = 4'd10;

      6'b010010 : s1_out = 4'd10;

      6'b010011 : s1_out = 4'd6 ;

      6'b010100 : s1_out = 4'd6 ;

      6'b010101 : s1_out = 4'd12;

      6'b010110 : s1_out = 4'd12;

      6'b010111 : s1_out = 4'd11;

      6'b011000 : s1_out = 4'd5 ;

      6'b011001 : s1_out = 4'd9 ;

      6'b011010 : s1_out = 4'd9 ;

      6'b011011 : s1_out = 4'd5 ;

      6'b011100 : s1_out = 4'd0 ;

      6'b011101 : s1_out = 4'd3 ;

      6'b011110 : s1_out = 4'd7 ;

      6'b011111 : s1_out = 4'd8 ;

      6'b100000 : s1_out = 4'd4 ;

      6'b100001 : s1_out = 4'd15;

      6'b100010 : s1_out = 4'd1 ;

      6'b100011 : s1_out = 4'd12;

      6'b100100 : s1_out = 4'd14;

      6'b100101 : s1_out = 4'd8 ;

      6'b100110 : s1_out = 4'd8;

      6'b100111 : s1_out = 4'd2 ;

      6'b101000 : s1_out = 4'd13;

      6'b101001 : s1_out = 4'd4 ;

      6'b101010 : s1_out = 4'd6 ;

      6'b101011 : s1_out = 4'd9 ;

      6'b101100 : s1_out = 4'd2 ;

      6'b101101 : s1_out = 4'd1 ;

      6'b101110 : s1_out = 4'd11;

      6'b101111 : s1_out = 4'd7 ;

      6'b110000 : s1_out = 4'd15;

      6'b110001 : s1_out = 4'd5 ;

      6'b110010 : s1_out = 4'd12;

      6'b110011 : s1_out = 4'd11;

      6'b110100 : s1_out = 4'd9 ;

      6'b110101 : s1_out = 4'd3 ;

      6'b110110 : s1_out = 4'd7 ;

      6'b110111 : s1_out = 4'd14;

      6'b111000 : s1_out = 4'd3 ;

      6'b111001 : s1_out = 4'd10;

      6'b111010 : s1_out = 4'd10;

      6'b111011 : s1_out = 4'd0 ;

      6'b111100 : s1_out = 4'd5 ;

      6'b111101 : s1_out = 4'd6 ;

      6'b111110 : s1_out = 4'd0 ;

      6'b111111 : s1_out = 4'd13; 

    endcase

  end

//sbox_2 change

always @(S_xor_R_2)                 

  begin

    case (S_xor_R_2)

      6'b000000 : s2_out = 4'd15;

      6'b000001 : s2_out = 4'd3 ;

      6'b000010 : s2_out = 4'd1 ;

      6'b000011 : s2_out = 4'd13;

      6'b000100 : s2_out = 4'd8 ;

      6'b000101 : s2_out = 4'd4 ;

      6'b000110 : s2_out = 4'd14;

      6'b000111 : s2_out = 4'd7 ;

      6'b001000 : s2_out = 4'd6 ;

      6'b001001 : s2_out = 4'd15;

      6'b001010 : s2_out = 4'd11;

      6'b001011 : s2_out = 4'd2 ;

      6'b001100 : s2_out = 4'd3 ;

      6'b001101 : s2_out = 4'd8 ;

      6'b001110 : s2_out = 4'd4 ;

      6'b001111 : s2_out = 4'd14;

      6'b010000 : s2_out = 4'd9 ;

      6'b010001 : s2_out = 4'd12;

      6'b010010 : s2_out = 4'd7 ;

      6'b010011 : s2_out = 4'd0 ;

      6'b010100 : s2_out = 4'd2 ;

      6'b010101 : s2_out = 4'd1 ;

      6'b010110 : s2_out = 4'd13;

      6'b010111 : s2_out = 4'd10;

      6'b011000 : s2_out = 4'd12;

      6'b011001 : s2_out = 4'd6 ;

      6'b011010 : s2_out = 4'd0 ;

      6'b011011 : s2_out = 4'd9 ;

      6'b011100 : s2_out = 4'd5 ;

      6'b011101 : s2_out = 4'd11;

      6'b011110 : s2_out = 4'd10;

      6'b011111 : s2_out = 4'd5 ;

      6'b100000 : s2_out = 4'd0 ;

      6'b100001 : s2_out = 4'd13;

      6'b100010 : s2_out = 4'd14;

      6'b100011 : s2_out = 4'd8 ;

      6'b100100 : s2_out = 4'd7 ;

      6'b100101 : s2_out = 4'd10;

      6'b100110 : s2_out = 4'd11;

      6'b100111 : s2_out = 4'd1 ;

      6'b101000 : s2_out = 4'd10;

      6'b101001 : s2_out = 4'd3 ;

      6'b101010 : s2_out = 4'd4 ;

      6'b101011 : s2_out = 4'd15;

      6'b101100 : s2_out = 4'd13;

      6'b101101 : s2_out = 4'd4 ;

      6'b101110 : s2_out = 4'd1 ;

      6'b101111 : s2_out = 4'd2 ;

      6'b110000 : s2_out = 4'd5 ;

      6'b110001 : s2_out = 4'd11;

      6'b110010 : s2_out = 4'd8 ;

      6'b110011 : s2_out = 4'd6 ;

      6'b110100 : s2_out = 4'd12;

      6'b110101 : s2_out = 4'd7 ;

      6'b110110 : s2_out = 4'd6 ;

      6'b110111 : s2_out = 4'd12;

      6'b111000 : s2_out = 4'd9 ;

      6'b111001 : s2_out = 4'd0 ;

      6'b111010 : s2_out = 4'd3 ;

      6'b111011 : s2_out = 4'd5 ;

      6'b111100 : s2_out = 4'd2 ;

      6'b111101 : s2_out = 4'd14;

      6'b111110 : s2_out = 4'd15;

      6'b111111 : s2_out = 4'd9 ; 

    endcase

  end

  //sbox_3 change

  always @(S_xor_R_3)              

  begin

    case (S_xor_R_3)

      6'b000000 : s3_out = 4'd10;

      6'b000001 : s3_out = 4'd13;

      6'b000010 : s3_out = 4'd0 ;

      6'b000011 : s3_out = 4'd7 ;

      6'b000100 : s3_out = 4'd9 ;

      6'b000101 : s3_out = 4'd0 ;

      6'b000110 : s3_out = 4'd14;

      6'b000111 : s3_out = 4'd9 ;

      6'b001000 : s3_out = 4'd6 ;

      6'b001001 : s3_out = 4'd3 ;

      6'b001010 : s3_out = 4'd3 ;

      6'b001011 : s3_out = 4'd4 ;

      6'b001100 : s3_out = 4'd15;

      6'b001101 : s3_out = 4'd6 ;

      6'b001110 : s3_out = 4'd5 ;

      6'b001111 : s3_out = 4'd10;

      6'b010000 : s3_out = 4'd1 ;

      6'b010001 : s3_out = 4'd2 ;

      6'b010010 : s3_out = 4'd13;

      6'b010011 : s3_out = 4'd8 ;

      6'b010100 : s3_out = 4'd12;

      6'b010101 : s3_out = 4'd5 ;

      6'b010110 : s3_out = 4'd7 ;

      6'b010111 : s3_out = 4'd14;

      6'b011000 : s3_out = 4'd11;

      6'b011001 : s3_out = 4'd12;

      6'b011010 : s3_out = 4'd4 ;

      6'b011011 : s3_out = 4'd11;

      6'b011100 : s3_out = 4'd2 ;

      6'b011101 : s3_out = 4'd15;

      6'b011110 : s3_out = 4'd8 ;

      6'b011111 : s3_out = 4'd1 ;

      6'b100000 : s3_out = 4'd13;

      6'b100001 : s3_out = 4'd1 ;

      6'b100010 : s3_out = 4'd6 ;

      6'b100011 : s3_out = 4'd10;

      6'b100100 : s3_out = 4'd4 ;

      6'b100101 : s3_out = 4'd13;

      6'b100110 : s3_out = 4'd9 ;

      6'b100111 : s3_out = 4'd0 ;

      6'b101000 : s3_out = 4'd8 ;

      6'b101001 : s3_out = 4'd6 ;

      6'b101010 : s3_out = 4'd15;

      6'b101011 : s3_out = 4'd9 ;

      6'b101100 : s3_out = 4'd3 ;

      6'b101101 : s3_out = 4'd8 ;

      6'b101110 : s3_out = 4'd0 ;

      6'b101111 : s3_out = 4'd7 ;

      6'b110000 : s3_out = 4'd11;

      6'b110001 : s3_out = 4'd4 ;

      6'b110010 : s3_out = 4'd1 ;

      6'b110011 : s3_out = 4'd15;

      6'b110100 : s3_out = 4'd2 ;

      6'b110101 : s3_out = 4'd14;

      6'b110110 : s3_out = 4'd12;

      6'b110111 : s3_out = 4'd3 ;

      6'b111000 : s3_out = 4'd5 ;

      6'b111001 : s3_out = 4'd11;

      6'b111010 : s3_out = 4'd10;

      6'b111011 : s3_out = 4'd5 ;

      6'b111100 : s3_out = 4'd14 ;

      6'b111101 : s3_out = 4'd2 ;

      6'b111110 : s3_out = 4'd7 ;

      6'b111111 : s3_out = 4'd12; 

    endcase

  end

  //sbox_4 change

  always @(S_xor_R_4)              

  begin

    case (S_xor_R_4)

      6'b000000 : s4_out = 4'd7;

      6'b000001 : s4_out = 4'd13;

      6'b000010 : s4_out = 4'd13;

      6'b000011 : s4_out = 4'd8 ;

      6'b000100 : s4_out = 4'd14;

      6'b000101 : s4_out = 4'd11;

      6'b000110 : s4_out = 4'd3 ;

      6'b000111 : s4_out = 4'd5 ;

      6'b001000 : s4_out = 4'd0 ;

      6'b001001 : s4_out = 4'd6 ;

      6'b001010 : s4_out = 4'd6 ;

      6'b001011 : s4_out = 4'd15;

      6'b001100 : s4_out = 4'd9 ;

      6'b001101 : s4_out = 4'd0 ;

      6'b001110 : s4_out = 4'd10;

      6'b001111 : s4_out = 4'd3 ;

      6'b010000 : s4_out = 4'd1 ;

      6'b010001 : s4_out = 4'd4 ;

      6'b010010 : s4_out = 4'd2 ;

      6'b010011 : s4_out = 4'd7 ;

      6'b010100 : s4_out = 4'd8 ;

      6'b010101 : s4_out = 4'd2 ;

      6'b010110 : s4_out = 4'd5 ;

      6'b010111 : s4_out = 4'd12;

      6'b011000 : s4_out = 4'd11;

      6'b011001 : s4_out = 4'd1 ;

      6'b011010 : s4_out = 4'd12;

      6'b011011 : s4_out = 4'd10;

      6'b011100 : s4_out = 4'd4 ;

      6'b011101 : s4_out = 4'd14;

      6'b011110 : s4_out = 4'd15;

      6'b011111 : s4_out = 4'd9 ;

      6'b100000 : s4_out = 4'd10;

      6'b100001 : s4_out = 4'd3 ;

      6'b100010 : s4_out = 4'd6 ;

      6'b100011 : s4_out = 4'd15;

      6'b100100 : s4_out = 4'd9 ;

      6'b100101 : s4_out = 4'd0 ;

      6'b100110 : s4_out = 4'd0 ;

      6'b100111 : s4_out = 4'd6 ;

      6'b101000 : s4_out = 4'd12;

      6'b101001 : s4_out = 4'd10;

      6'b101010 : s4_out = 4'd11;

      6'b101011 : s4_out = 4'd1 ;

      6'b101100 : s4_out = 4'd7 ;

      6'b101101 : s4_out = 4'd13;

      6'b101110 : s4_out = 4'd13;

      6'b101111 : s4_out = 4'd8 ;

      6'b110000 : s4_out = 4'd15;

      6'b110001 : s4_out = 4'd9 ;

      6'b110010 : s4_out = 4'd1 ;

      6'b110011 : s4_out = 4'd4 ;

      6'b110100 : s4_out = 4'd3 ;

      6'b110101 : s4_out = 4'd5;

      6'b110110 : s4_out = 4'd14;

      6'b110111 : s4_out = 4'd11;

      6'b111000 : s4_out = 4'd5 ;

      6'b111001 : s4_out = 4'd12;

      6'b111010 : s4_out = 4'd2 ;

      6'b111011 : s4_out = 4'd7 ;

      6'b111100 : s4_out = 4'd8 ;

      6'b111101 : s4_out = 4'd2 ;

      6'b111110 : s4_out = 4'd4 ;

      6'b111111 : s4_out = 4'd14; 

    endcase

  end

  //sbox_5 change

  always @(S_xor_R_5)              

  begin

    case (S_xor_R_5)

      6'b000000 : s5_out = 4'd2;

      6'b000001 : s5_out = 4'd14;

      6'b000010 : s5_out = 4'd12;

      6'b000011 : s5_out = 4'd11;

      6'b000100 : s5_out = 4'd4 ;

      6'b000101 : s5_out = 4'd2 ;

      6'b000110 : s5_out = 4'd1 ;

      6'b000111 : s5_out = 4'd12;

      6'b001000 : s5_out = 4'd7 ;

      6'b001001 : s5_out = 4'd4 ;

      6'b001010 : s5_out = 4'd10;

      6'b001011 : s5_out = 4'd7 ;

      6'b001100 : s5_out = 4'd11;

      6'b001101 : s5_out = 4'd13;

      6'b001110 : s5_out = 4'd6 ;

      6'b001111 : s5_out = 4'd1 ;

      6'b010000 : s5_out = 4'd8 ;

      6'b010001 : s5_out = 4'd5 ;

      6'b010010 : s5_out = 4'd5 ;

      6'b010011 : s5_out = 4'd0 ;

      6'b010100 : s5_out = 4'd3 ;

      6'b010101 : s5_out = 4'd15;

      6'b010110 : s5_out = 4'd15;

      6'b010111 : s5_out = 4'd10;

      6'b011000 : s5_out = 4'd13 ;

      6'b011001 : s5_out = 4'd3 ;

      6'b011010 : s5_out = 4'd0 ;

      6'b011011 : s5_out = 4'd9 ;

      6'b011100 : s5_out = 4'd14;

      6'b011101 : s5_out = 4'd8 ;

      6'b011110 : s5_out = 4'd9 ;

      6'b011111 : s5_out = 4'd6 ;

      6'b100000 : s5_out = 4'd4 ;

      6'b100001 : s5_out = 4'd11;

      6'b100010 : s5_out = 4'd2 ;

      6'b100011 : s5_out = 4'd8 ;

      6'b100100 : s5_out = 4'd1 ;

      6'b100101 : s5_out = 4'd12;

      6'b100110 : s5_out = 4'd11;

      6'b100111 : s5_out = 4'd7 ;

      6'b101000 : s5_out = 4'd10;

      6'b101001 : s5_out = 4'd1 ;

      6'b101010 : s5_out = 4'd13;

      6'b101011 : s5_out = 4'd14;

      6'b101100 : s5_out = 4'd7 ;

      6'b101101 : s5_out = 4'd2 ;

      6'b101110 : s5_out = 4'd8 ;

      6'b101111 : s5_out = 4'd13;

      6'b110000 : s5_out = 4'd15;

      6'b110001 : s5_out = 4'd6 ;

      6'b110010 : s5_out = 4'd9 ;

      6'b110011 : s5_out = 4'd15;

      6'b110100 : s5_out = 4'd12;

      6'b110101 : s5_out = 4'd0 ;

      6'b110110 : s5_out = 4'd5 ;

      6'b110111 : s5_out = 4'd9 ;

      6'b111000 : s5_out = 4'd6 ;

      6'b111001 : s5_out = 4'd10;

      6'b111010 : s5_out = 4'd3 ;

      6'b111011 : s5_out = 4'd4 ;

      6'b111100 : s5_out = 4'd0 ;

      6'b111101 : s5_out = 4'd5 ;

      6'b111110 : s5_out = 4'd14;

      6'b111111 : s5_out = 4'd3 ; 

    endcase

  end

  //sbox_6 change

  always @(S_xor_R_6)              

  begin

    case (S_xor_R_6)

      6'b000000 : s6_out = 4'd12;

      6'b000001 : s6_out = 4'd10;

      6'b000010 : s6_out = 4'd1 ;

      6'b000011 : s6_out = 4'd15;

      6'b000100 : s6_out = 4'd10;

      6'b000101 : s6_out = 4'd4 ;

      6'b000110 : s6_out = 4'd15;

      6'b000111 : s6_out = 4'd2 ;

      6'b001000 : s6_out = 4'd9 ;

      6'b001001 : s6_out = 4'd7 ;

      6'b001010 : s6_out = 4'd2 ;

      6'b001011 : s6_out = 4'd12;

      6'b001100 : s6_out = 4'd6 ;

      6'b001101 : s6_out = 4'd9 ;

      6'b001110 : s6_out = 4'd8 ;

      6'b001111 : s6_out = 4'd5 ;

      6'b010000 : s6_out = 4'd0 ;

      6'b010001 : s6_out = 4'd6 ;

      6'b010010 : s6_out = 4'd13;

      6'b010011 : s6_out = 4'd1 ;

      6'b010100 : s6_out = 4'd3 ;

      6'b010101 : s6_out = 4'd13;

      6'b010110 : s6_out = 4'd4 ;

      6'b010111 : s6_out = 4'd14;

      6'b011000 : s6_out = 4'd14;

      6'b011001 : s6_out = 4'd0 ;

      6'b011010 : s6_out = 4'd7 ;

      6'b011011 : s6_out = 4'd11;

      6'b011100 : s6_out = 4'd5 ;

      6'b011101 : s6_out = 4'd3 ;

      6'b011110 : s6_out = 4'd11;

      6'b011111 : s6_out = 4'd8 ;

      6'b100000 : s6_out = 4'd9 ;

      6'b100001 : s6_out = 4'd4 ;

      6'b100010 : s6_out = 4'd14;

      6'b100011 : s6_out = 4'd3 ;

      6'b100100 : s6_out = 4'd15;

      6'b100101 : s6_out = 4'd2 ;

      6'b100110 : s6_out = 4'd5 ;

      6'b100111 : s6_out = 4'd12;

      6'b101000 : s6_out = 4'd2 ;

      6'b101001 : s6_out = 4'd9 ;

      6'b101010 : s6_out = 4'd8 ;

      6'b101011 : s6_out = 4'd5 ;

      6'b101100 : s6_out = 4'd12;

      6'b101101 : s6_out = 4'd15;

      6'b101110 : s6_out = 4'd3 ;

      6'b101111 : s6_out = 4'd10;

      6'b110000 : s6_out = 4'd7 ;

      6'b110001 : s6_out = 4'd11;

      6'b110010 : s6_out = 4'd0 ;

      6'b110011 : s6_out = 4'd14;

      6'b110100 : s6_out = 4'd4 ;

      6'b110101 : s6_out = 4'd1 ;

      6'b110110 : s6_out = 4'd10;

      6'b110111 : s6_out = 4'd7 ;

      6'b111000 : s6_out = 4'd1 ;

      6'b111001 : s6_out = 4'd6 ;

      6'b111010 : s6_out = 4'd13;

      6'b111011 : s6_out = 4'd0 ;

      6'b111100 : s6_out = 4'd11;

      6'b111101 : s6_out = 4'd8 ;

      6'b111110 : s6_out = 4'd6 ;

      6'b111111 : s6_out = 4'd13; 

    endcase

  end

  //sbox_7 change

  always @(S_xor_R_7)              

  begin

    case (S_xor_R_7)

      6'b000000 : s7_out = 4'd4 ;

      6'b000001 : s7_out = 4'd13;

      6'b000010 : s7_out = 4'd11;

      6'b000011 : s7_out = 4'd0 ;

      6'b000100 : s7_out = 4'd2 ;

      6'b000101 : s7_out = 4'd11;

      6'b000110 : s7_out = 4'd14;

      6'b000111 : s7_out = 4'd7 ;

      6'b001000 : s7_out = 4'd15;

      6'b001001 : s7_out = 4'd4 ;

      6'b001010 : s7_out = 4'd0 ;

      6'b001011 : s7_out = 4'd9 ;

      6'b001100 : s7_out = 4'd8 ;

      6'b001101 : s7_out = 4'd1 ;

      6'b001110 : s7_out = 4'd13;

      6'b001111 : s7_out = 4'd10;

      6'b010000 : s7_out = 4'd3 ;

      6'b010001 : s7_out = 4'd14;

      6'b010010 : s7_out = 4'd12;

      6'b010011 : s7_out = 4'd3 ;

      6'b010100 : s7_out = 4'd9 ;

      6'b010101 : s7_out = 4'd5 ;

      6'b010110 : s7_out = 4'd7 ;

      6'b010111 : s7_out = 4'd12;

      6'b011000 : s7_out = 4'd5 ;

      6'b011001 : s7_out = 4'd2 ;

      6'b011010 : s7_out = 4'd10;

      6'b011011 : s7_out = 4'd15;

      6'b011100 : s7_out = 4'd6 ;

      6'b011101 : s7_out = 4'd8 ;

      6'b011110 : s7_out = 4'd1 ;

      6'b011111 : s7_out = 4'd6 ;

      6'b100000 : s7_out = 4'd1 ;

      6'b100001 : s7_out = 4'd6 ;

      6'b100010 : s7_out = 4'd4 ;

      6'b100011 : s7_out = 4'd11;

      6'b100100 : s7_out = 4'd11;

      6'b100101 : s7_out = 4'd13;

      6'b100110 : s7_out = 4'd13;

      6'b100111 : s7_out = 4'd8 ;

      6'b101000 : s7_out = 4'd12;

      6'b101001 : s7_out = 4'd1 ;

      6'b101010 : s7_out = 4'd3 ;

      6'b101011 : s7_out = 4'd4 ;

      6'b101100 : s7_out = 4'd7 ;

      6'b101101 : s7_out = 4'd10;

      6'b101110 : s7_out = 4'd14;

      6'b101111 : s7_out = 4'd7 ;

      6'b110000 : s7_out = 4'd10;

      6'b110001 : s7_out = 4'd9 ;

      6'b110010 : s7_out = 4'd15;

      6'b110011 : s7_out = 4'd5 ;

      6'b110100 : s7_out = 4'd6 ;

      6'b110101 : s7_out = 4'd0 ;

      6'b110110 : s7_out = 4'd8 ;

      6'b110111 : s7_out = 4'd15;

      6'b111000 : s7_out = 4'd0 ;

      6'b111001 : s7_out = 4'd14;

      6'b111010 : s7_out = 4'd5 ;

      6'b111011 : s7_out = 4'd2 ;

      6'b111100 : s7_out = 4'd9 ;

      6'b111101 : s7_out = 4'd3 ;

      6'b111110 : s7_out = 4'd2 ;

      6'b111111 : s7_out = 4'd12; 

    endcase

  end

  //sbox_8 change

  always @(S_xor_R_8)              

  begin

    case (S_xor_R_8)

      6'b000000 : s8_out = 4'd13;

      6'b000001 : s8_out = 4'd1 ;

      6'b000010 : s8_out = 4'd2 ;

      6'b000011 : s8_out = 4'd15;

      6'b000100 : s8_out = 4'd8 ;

      6'b000101 : s8_out = 4'd13;

      6'b000110 : s8_out = 4'd4 ;

      6'b000111 : s8_out = 4'd8 ;

      6'b001000 : s8_out = 4'd6 ;

      6'b001001 : s8_out = 4'd10;

      6'b001010 : s8_out = 4'd15;

      6'b001011 : s8_out = 4'd3 ;

      6'b001100 : s8_out = 4'd11;

      6'b001101 : s8_out = 4'd7 ;

      6'b001110 : s8_out = 4'd1 ;

      6'b001111 : s8_out = 4'd4 ;

      6'b010000 : s8_out = 4'd10;

      6'b010001 : s8_out = 4'd12;

      6'b010010 : s8_out = 4'd9 ;

      6'b010011 : s8_out = 4'd5 ;

      6'b010100 : s8_out = 4'd3 ;

      6'b010101 : s8_out = 4'd6 ;

      6'b010110 : s8_out = 4'd14;

      6'b010111 : s8_out = 4'd11;

      6'b011000 : s8_out = 4'd5 ;

      6'b011001 : s8_out = 4'd0 ;

      6'b011010 : s8_out = 4'd0 ;

      6'b011011 : s8_out = 4'd14;

      6'b011100 : s8_out = 4'd12;

      6'b011101 : s8_out = 4'd9 ;

      6'b011110 : s8_out = 4'd7 ;

      6'b011111 : s8_out = 4'd2 ;

      6'b100000 : s8_out = 4'd7 ;

      6'b100001 : s8_out = 4'd2 ;

      6'b100010 : s8_out = 4'd11;

      6'b100011 : s8_out = 4'd1 ;

      6'b100100 : s8_out = 4'd4 ;

      6'b100101 : s8_out = 4'd14;

      6'b100110 : s8_out = 4'd1 ;

      6'b100111 : s8_out = 4'd7 ;

      6'b101000 : s8_out = 4'd9 ;

      6'b101001 : s8_out = 4'd4 ;

      6'b101010 : s8_out = 4'd12;

      6'b101011 : s8_out = 4'd10;

      6'b101100 : s8_out = 4'd14;

      6'b101101 : s8_out = 4'd8 ;

      6'b101110 : s8_out = 4'd2 ;

      6'b101111 : s8_out = 4'd13;

      6'b110000 : s8_out = 4'd0 ;

      6'b110001 : s8_out = 4'd15;

      6'b110010 : s8_out = 4'd6 ;

      6'b110011 : s8_out = 4'd12;

      6'b110100 : s8_out = 4'd10;

      6'b110101 : s8_out = 4'd9 ;

      6'b110110 : s8_out = 4'd13;

      6'b110111 : s8_out = 4'd0 ;

      6'b111000 : s8_out = 4'd15;

      6'b111001 : s8_out = 4'd3 ;

      6'b111010 : s8_out = 4'd3 ;

      6'b111011 : s8_out = 4'd5 ;

      6'b111100 : s8_out = 4'd5 ;

      6'b111101 : s8_out = 4'd6 ;

      6'b111110 : s8_out = 4'd8 ;

      6'b111111 : s8_out = 4'd11; 

    endcase

  end

//direct change

wire [32:1] directchange_out;

assign directchange_out = {s_out[16],s_out[7],s_out[20],s_out[21],s_out[29],s_out[12],s_out[28],s_out[17],

                         s_out[1],s_out[15],s_out[23],s_out[26],s_out[5],s_out[18],s_out[31],s_out[10],

                         s_out[2],s_out[8],s_out[24],s_out[14],s_out[32],s_out[27],s_out[3],s_out[9],

                         s_out[19],s_out[13],s_out[30],s_out[6],s_out[22],s_out[11],s_out[4],s_out[25]};

/*directchange_out xor L*/

wire [32:1] directchange_xor_L;

assign  directchange_xor_L = directchange_out ^ L;          

/*regist-output*/

always @(posedge Encryp_clk or negedge Encryp_rst_n)

if (!Encryp_rst_n)

    begin

                 new_R <= 32'h0;

                 new_L <= 32'h0;

              end

else

    begin

      new_R <= directchange_xor_L;

      new_L <= R;

               end

endmodule

2.4.4 子密钥生成模块

module subkey_generate_better(

               key_in,

               mode_in,//mode_in=1, Encryption; mode_in=0, Decryption.

               subkey_out1,subkey_out2,subkey_out3,subkey_out4,

               subkey_out5,subkey_out6,subkey_out7,subkey_out8,

               subkey_out9,subkey_out10,subkey_out11,subkey_out12,subkey_out13,

               subkey_out14,subkey_out15,subkey_out16   //16 subkey generated the same time

    );

input  [64:1] key_in;

input         mode_in;

output [48:1] subkey_out1,subkey_out2,subkey_out3,subkey_out4,subkey_out5;

output [48:1] subkey_out6,subkey_out7,subkey_out8,subkey_out9,subkey_out10,subkey_out11;

output [48:1] subkey_out12,subkey_out13,subkey_out14,subkey_out15,subkey_out16;

wire   [48:1] subkey1,subkey2,subkey3,subkey4,subkey5,subkey6,subkey7,subkey8;

wire   [48:1] subkey9,subkey10,subkey11,subkey12,subkey13,subkey14,subkey15,subkey16;

/* generate 16 subkey*/

assign subkey1 = {key_in[10],key_in[51],key_in[34],key_in[60],key_in[49],key_in[17],key_in[33],key_in[57],key_in[2] ,key_in[9] ,

key_in[19],key_in[42],key_in[3] ,key_in[35],key_in[26],key_in[25],key_in[44],key_in[58],key_in[59],key_in[1] ,key_in[36],key_in[27],

key_in[18],key_in[41],key_in[22],key_in[28],key_in[39],key_in[54],key_in[37],key_in[4] ,key_in[47],key_in[30],key_in[5] ,key_in[53],

key_in[23],key_in[29],key_in[61],key_in[21],key_in[12],key_in[63],key_in[15],key_in[20],key_in[45],key_in[28],key_in[13],key_in[62],

key_in[2] ,key_in[5] };

assign subkey2 = {key_in[2] ,key_in[43],key_in[26],key_in[52],key_in[41],key_in[9] ,key_in[25],key_in[49],key_in[59],key_in[1] ,

key_in[11],key_in[34],key_in[60],key_in[27],key_in[18],key_in[17],key_in[36],key_in[50],key_in[51],key_in[58],key_in[57],

key_in[19],key_in[10],key_in[33],key_in[14],key_in[20],key_in[31],key_in[46],key_in[29],key_in[63],key_in[39],key_in[22],

key_in[28],key_in[45],key_in[15],key_in[21],key_in[53],key_in[13],key_in[30],key_in[55],key_in[7] ,key_in[12],key_in[37],key_in[20],

key_in[5] ,key_in[54],key_in[47],key_in[23] };

assign subkey3 = {key_in[51],key_in[27],key_in[10],key_in[36],key_in[25],key_in[58],key_in[9] ,key_in[33],key_in[43],key_in[50],

key_in[60],key_in[18], key_in[44],key_in[11],key_in[2] ,key_in[1] ,key_in[49],key_in[34],key_in[35],key_in[42],key_in[41],

key_in[3] ,key_in[59],key_in[17],key_in[61],key_in[4] ,key_in[15],key_in[30],key_in[13],key_in[47],key_in[23],key_in[6] ,

key_in[12],key_in[29],key_in[62],key_in[5] ,key_in[37],key_in[28],key_in[14],key_in[39],key_in[54],key_in[63],key_in[21],key_in[4] ,

key_in[20],key_in[38],key_in[31],key_in[7]  };

assign subkey4 = {key_in[35],key_in[11],key_in[59],key_in[49],key_in[9] ,key_in[42],key_in[58],key_in[17],key_in[27],

key_in[34],key_in[44],key_in[2] ,key_in[57],key_in[60],key_in[51],key_in[50],key_in[33],key_in[18],key_in[19],key_in[26],

key_in[25],key_in[52],key_in[43],key_in[1] ,key_in[45],key_in[55],key_in[62],key_in[14],key_in[28],key_in[31],key_in[7] ,

key_in[53],key_in[63],key_in[13],key_in[46],key_in[20],key_in[21],key_in[12],key_in[61],key_in[23],key_in[38],key_in[47],key_in[5],

key_in[55],key_in[4] ,key_in[22],key_in[15],key_in[54] };

assign subkey5 = {key_in[19],key_in[60],key_in[43],key_in[33],key_in[58],key_in[26],key_in[42],key_in[1] ,key_in[11],key_in[18],

key_in[57],key_in[51],key_in[41],key_in[44],key_in[35],key_in[34],key_in[17],key_in[2] ,key_in[3] ,key_in[10],key_in[9] ,

key_in[36],key_in[27],key_in[50],key_in[29],key_in[39],key_in[46],key_in[61],key_in[12],key_in[15],key_in[54],key_in[37],

key_in[47],key_in[28],key_in[30],key_in[4] ,key_in[5] ,key_in[63],key_in[45],key_in[7] ,key_in[22],key_in[31],key_in[20],key_in[39],

key_in[55],key_in[6] ,key_in[62],key_in[38]};

assign subkey6 = {key_in[3] ,key_in[44],key_in[27],key_in[17],key_in[42],key_in[10],key_in[26],key_in[50],key_in[60],key_in[2] ,

key_in[41],key_in[35],key_in[25],key_in[57],key_in[19],key_in[18],key_in[1] ,key_in[51],key_in[57],key_in[59],key_in[58],

key_in[49],key_in[11],key_in[34],key_in[13],key_in[23],key_in[30],key_in[45],key_in[63],key_in[62],key_in[38],key_in[21],key_in[31],

key_in[12],key_in[14],key_in[55],key_in[20],key_in[47],key_in[29],key_in[54],key_in[6] ,key_in[15],key_in[4] ,key_in[23],key_in[39],

key_in[53],key_in[46],key_in[22] };

assign subkey7 = {key_in[52],key_in[57],key_in[11],key_in[1] ,key_in[26],key_in[59],key_in[10],key_in[34],key_in[44],key_in[51],

key_in[25],key_in[19],key_in[9] ,key_in[41],key_in[3] ,key_in[2] ,key_in[50],key_in[35],key_in[36],key_in[43],key_in[42],key_in[33],

key_in[60],key_in[10],key_in[28],key_in[7] ,key_in[13],key_in[29],key_in[47],key_in[46],key_in[22],key_in[5] ,key_in[15],key_in[63],

key_in[61],key_in[39] ,key_in[4] ,key_in[31],key_in[13],key_in[38],key_in[53],key_in[62],key_in[55],key_in[7] ,key_in[23],key_in[37],

key_in[30],key_in[6] };

assign subkey8 = {key_in[36],key_in[41],key_in[60],key_in[50],key_in[10],key_in[43],key_in[59],key_in[18],key_in[57],key_in[35],

key_in[9] ,key_in[3] ,key_in[58],key_in[25],key_in[52],key_in[51],key_in[34],key_in[19],key_in[49],key_in[27],key_in[26],key_in[17],

key_in[44],key_in[2] ,key_in[12],key_in[54],key_in[61],key_in[13],key_in[31],key_in[30],key_in[6] ,key_in[20],key_in[62],key_in[47],

key_in[45],key_in[23],key_in[55],key_in[15],key_in[28],key_in[22],key_in[37],key_in[46],key_in[39],key_in[54],key_in[7] ,key_in[21],

key_in[14],key_in[53] };

assign subkey9 = {key_in[57],key_in[33],key_in[52],key_in[42],key_in[2] ,key_in[35],key_in[51],key_in[10],key_in[49],key_in[27],

key_in[1] ,key_in[60],key_in[50],key_in[17],key_in[44],key_in[43],key_in[26],key_in[11],key_in[41],key_in[19],key_in[18],key_in[9] ,

key_in[36],key_in[59],key_in[4] ,key_in[46],key_in[53],key_in[5] ,key_in[23],key_in[22],key_in[61],key_in[12],key_in[54],key_in[39],

key_in[37],key_in[15],key_in[47],key_in[7] ,key_in[20],key_in[14],key_in[29],key_in[38],key_in[31],key_in[46],key_in[62],key_in[13],

key_in[6] ,key_in[45] };

assign subkey10= {key_in[41],key_in[17],key_in[36],key_in[26],key_in[51],key_in[19],key_in[35],key_in[59],key_in[33],key_in[11],

key_in[50],key_in[44],key_in[34],key_in[1] ,key_in[57],key_in[27],key_in[10],key_in[60],key_in[25],key_in[3] ,key_in[2] ,key_in[58],

key_in[49],key_in[43],key_in[55],key_in[30],key_in[37],key_in[20],key_in[7] ,key_in[6] ,key_in[45],key_in[63],key_in[38],key_in[23],

key_in[21],key_in[62],key_in[31],key_in[54],key_in[4] ,key_in[61],key_in[13],key_in[22],key_in[15],key_in[30],key_in[46],key_in[28],k

ey_in[53],key_in[29] };

assign subkey11= {key_in[25],key_in[1] ,key_in[49],key_in[10],key_in[35],key_in[3] ,key_in[19],key_in[43],key_in[17],key_in[60],

key_in[34],key_in[57],key_in[18],key_in[50],key_in[41],key_in[11],key_in[59],key_in[44],key_in[9] ,key_in[52],key_in[51],key_in[42],

key_in[33],key_in[27],key_in[39],key_in[14],key_in[21],key_in[4] ,key_in[54],key_in[53],key_in[29],key_in[47],key_in[22],key_in[7] ,

key_in[5] ,key_in[46],key_in[15],key_in[38],key_in[55],key_in[45],key_in[28],key_in[6] ,key_in[62],key_in[14],key_in[30],key_in[12],

key_in[37],key_in[13] };

assign subkey12= {key_in[9] ,key_in[50],key_in[33],key_in[59],key_in[19],key_in[52],key_in[3] ,key_in[27],key_in[1] ,key_in[44],

key_in[18],key_in[41],key_in[2] ,key_in[34],key_in[25],key_in[60],key_in[43],key_in[57],key_in[58],key_in[36],key_in[35],key_in[26],

key_in[17],key_in[11],key_in[23],key_in[61],key_in[5] ,key_in[55],key_in[38],key_in[37],key_in[13],key_in[31],key_in[6] ,key_in[54],

key_in[20],key_in[30],key_in[62],key_in[22],key_in[39],key_in[29],key_in[12],key_in[53],key_in[46],key_in[61],key_in[14],key_in[57],

key_in[19],key_in[60] };

assign subkey13= {key_in[58],key_in[34],key_in[17],key_in[43],key_in[3] ,key_in[36],key_in[52],key_in[11],key_in[50],key_in[57],

key_in[2] ,key_in[25],key_in[51],key_in[18],key_in[9] ,key_in[44],key_in[27],key_in[41],key_in[42],key_in[49],key_in[19],key_in[10],

key_in[1] ,key_in[60],key_in[7] ,key_in[45],key_in[20],key_in[39],key_in[22],key_in[21],key_in[28],key_in[15],key_in[53],key_in[38],

key_in[4] ,key_in[14],key_in[46],key_in[6] ,key_in[23],key_in[13],key_in[63],key_in[37],key_in[30],key_in[45],key_in[61],key_in[47],

key_in[5] ,key_in[12] };

assign subkey14= {key_in[42],key_in[18],key_in[1] ,key_in[27],key_in[52],key_in[49],key_in[36],key_in[60],key_in[34],key_in[41],

key_in[51],key_in[9] ,key_in[35],key_in[2] ,key_in[58],key_in[57],key_in[11],key_in[25],key_in[26],key_in[33],key_in[3] ,key_in[59],

key_in[50],key_in[44],key_in[54],key_in[29],key_in[4] ,key_in[23],key_in[6] ,key_in[5] ,key_in[12],key_in[62],key_in[37],key_in[22],

key_in[55],key_in[61],key_in[30],key_in[53],key_in[7] ,key_in[28],key_in[47],key_in[21],key_in[14],key_in[29],key_in[45],key_in[31],

key_in[20],key_in[63] };

assign subkey15= {key_in[26],key_in[2] ,key_in[50],key_in[11],key_in[36],key_in[33],key_in[49],key_in[44],key_in[18],key_in[25],

key_in[35],key_in[58],key_in[19],key_in[51],key_in[42],key_in[41],key_in[60],key_in[9] ,key_in[10],key_in[17],key_in[52],key_in[43],k

ey_in[34],key_in[57],key_in[38],key_in[13],key_in[55],key_in[7] ,key_in[53],key_in[20],key_in[63],key_in[46],key_in[21],key_in[6] ,

key_in[39],key_in[45],key_in[14],key_in[37],key_in[54],key_in[12],key_in[31],key_in[5] ,key_in[61],key_in[13],key_in[29],key_in[15],

key_in[4] ,key_in[47] };

assign subkey16= {key_in[18],key_in[59],key_in[42],key_in[3] ,key_in[57],key_in[25],key_in[41],key_in[36],key_in[10],key_in[17],

key_in[27],key_in[50],key_in[11],key_in[43],key_in[34],key_in[33],key_in[52],key_in[1] ,key_in[2] ,key_in[9] ,key_in[44],key_in[35],

key_in[26],key_in[49],key_in[30],key_in[5] ,key_in[47],key_in[62],key_in[45],key_in[12],key_in[55],key_in[38],key_in[13],key_in[61],

key_in[31],key_in[37],key_in[6] ,key_in[29],key_in[46],key_in[4] ,key_in[23],key_in[28],key_in[53],key_in[5] ,key_in[21],key_in[7] ,

key_in[63],key_in[39] };

assign   subkey_out1 = mode_in ? subkey1 : subkey16;//mode_in=1, Encryption; mode_in=0, Decryption.

assign  subkey_out2 = mode_in ? subkey2 : subkey15;

assign   subkey_out3 = mode_in ? subkey3 : subkey14;

assign   subkey_out4 = mode_in ? subkey4 : subkey13;

assign   subkey_out5 = mode_in ? subkey5 : subkey12;

assign   subkey_out6 = mode_in ? subkey6 : subkey11;

assign   subkey_out7 = mode_in ? subkey7 : subkey10;

assign   subkey_out8 = mode_in ? subkey8 : subkey9;

assign   subkey_out9 = mode_in ? subkey9 : subkey8;

assign   subkey_out10= mode_in ? subkey10: subkey7;

assign   subkey_out11= mode_in ? subkey11: subkey6;

assign   subkey_out12= mode_in ? subkey12: subkey5;

assign   subkey_out13= mode_in ? subkey13: subkey4;

assign   subkey_out14= mode_in ? subkey14: subkey3;

assign   subkey_out15= mode_in ? subkey15: subkey2;

assign   subkey_out16= mode_in ? subkey16: subkey1;

endmodule

2.4.5 逆初始置换模块

module endchange(

    input [32:1] endchange_L,

    input [32:1] endchange_R,

    input        endchange_clk,

    input        endchange_rst_n,

    input        en_out,

               output reg [64:1] endchange_dout

    );

/*combine L and R,as to endchange_din*/

wire [64:1] endchange_din;

assign endchange_din = { endchange_L , endchange_R };

always @(posedge endchange_clk or negedge endchange_rst_n)

if (!endchange_rst_n)

    begin

                endchange_dout <= 64'h0000000000000000;

end

else

    begin

    if(en_out)

endchange_dout <= { endchange_din[40],endchange_din[8] ,endchange_din[48],endchange_din[16],endchange_din[56],

endchange_din[24],endchange_din[64],endchange_din[32],endchange_din[39],endchange_din[7],endchange_din[47],、endchange_din[15],endchange_din[55],endchange_din[23],endchange_din[63],endchange_din[31],endchange_din[38],

endchange_din[6] ,endchange_din[46],endchange_din[14],endchange_din[54],endchange_din[22],endchange_din[62],

endchange_din[30],endchange_din[37],endchange_din[5] ,endchange_din[45],endchange_din[13],endchange_din[53],

endchange_din[21],endchange_din[61],endchange_din[29],endchange_din[36],endchange_din[4] ,endchange_din[44],

endchange_din[12],endchange_din[52],endchange_din[20],endchange_din[60],endchange_din[28],endchange_din[35],

endchange_din[3] ,endchange_din[43],endchange_din[11],endchange_din[51],endchange_din[19],endchange_din[59],

endchange_din[27],endchange_din[34],endchange_din[2] ,endchange_din[42],endchange_din[10],endchange_din[50],

endchange_din[18],endchange_din[58],endchange_din[26],endchange_din[33],endchange_din[1] ,endchange_din[41],

endchange_din[9] ,endchange_din[49],endchange_din[17],endchange_din[57],endchange_din[25] };

end

endmodule

2.5 .ModelSim验证

加密验证模块:

`include "top.v"

module tb_uDES();

  reg clk;

  reg rst_n;

  reg [64:1] key;

  reg [64:1] d_in;

  reg mode;

  reg En;

  wire [64:1] d_out;

    top tb_top(.key(key),.data_in(d_in),.mode(mode),.clk(clk),.rst_n(rst_n),.En(En),.data_out(d_out));

    initial

    begin

        clk   = 1'b0;

        rst_n = 1'b1;

        key   = 64'h0;

        d_in  = 64'h0;

        mode  =1'b1;

    #55 rst_n = 1'b0;

    #58 rst_n = 1'b1;

    #15 key   = 64'hbb336ce41890dd55;

        d_in  = 64'h303dea612aabc854;

        En    = 1'b1;

    #20 d_in  = 64'h002d482d01e50a7e;

    #20 d_in  = 64'h00ae6909026f98c2;

    #20 d_in  = 64'h004aca776f81aed7;

    #20 d_in  = 64'h123456789abcdef0;

    #20 d_in  = 64'h0618061006100618;

    #1000 $stop;     

    end

  always #10 clk = ~clk;

 endmodule

运行加密算法测试程序,可得到如图2-9所示的输出波形。

图 2-9 加密算法测试

利用经过加密算法处理得到的密文编写解密算法测试程序:

`include "top.v"

module tb_DES();

  reg clk;

  reg rst_n;

  reg [64:1] key;

  reg [64:1] d_in;

  reg mode;

  reg En;

  wire [64:1] d_out; 

  top tb_top(.key(key),.data_in(d_in),.mode(mode),.clk(clk),.rst_n(rst_n),.En(En),.data_out(d_out));

  initial

    begin

        clk   = 1'b0;

        rst_n = 1'b1;

        key   = 64'h0;

        d_in  = 64'h0;

        mode  =1'b0;

    #55 rst_n = 1'b0;

    #58 rst_n = 1'b1;

    #20 key   = 64'hbb336ce41890dd55;

        d_in  = 64'h32e4148212d395e4;

        En    = 1'b1;

    #20 d_in  = 64'h7b4dfc64cbe73c1b;

    #20 d_in  = 64'hd3b1d21d13a4336b;

    #20 d_in  = 64'h1eddd9596d3aeade;

    #20 d_in  = 64'h1d4bd5d2da241612;

    #20 d_in  = 64'h7052901d30502f81;

    #1000 $stop;     

    end

  always #10 clk = ~clk;

endmodule

运行解密算法测试程序,可得到如图所示的运算结果。

图 2-10 解密算法测试

通过分析加密算法测试结果和解密算法测试结果,我们发现明文经过加密处理得到密文输出,而密文再经过解密算法进行解密,得到的明文输出和原始输入的明文完全一致,从而验证了本次DES密码算法设计方案的正确性。从图中我们还可以看到,当加密/解密流水线结构建立起来之后,每一个时钟周期可以得到一个处理结果,这也充分证明了流水结构设计方案的可行性和高效性。

第3章  课程设计的心得

本次课程设计完成了DES密码算法的硬件设计实现,通过对DES密码算法的学习了解,将DES密码算法的运算流程“翻译”式的用Verilog硬件描述语言实现,但这并不具有使用性,因为无论在速度还是所用电路资源上都是没有任何优势的,所以必须加以优化处理,简化电路复杂度,提高系统处理速度。经过此次课程设计,我总结了以下几点经验:

Ø  认知性设计 

在进行电路设计之前,我们必须对所要设计实现的任务系统有全面的了解与熟悉,掌握任务系统每一个分支的原理,在此基础上才能完成更好的电路设计,包括简单化设计、功能优化设计、低功耗设计等等。

Ø  模块化设计 

无论完成任何一个电路系统设计,模块化设计很重要,除了可以使系统设计简单方便之外,最重要的是具有良好的可移植性和可修正性,为电路的设计节省了很大的工作量。

Ø  实用性设计 

很多时候我们所做的工作都是要真切的用到实际生活中的,实用性要求我们不仅要正确实现电路功能,更多的是高效性、简单化、低成本、低功耗等,所以我们在完成系统设计时,要充分考虑实际应用时的具体环境,分析电路结构的复杂性,统筹效率和成本的关系,以求在最好的完成电路功能的同时尽可能使电路结构简单化、占用资源较小化,减小学术研究和实际应用间的差距。

Ø  统筹化设计 

我们所进行的所有电路系统设计,几乎全部都是时序电路与逻辑电路适当组合,组合逻辑不需要考虑先后顺序的问题,在忽略电路延迟的情况下,可以认为组合逻辑给定输入就同时产生输出;而时序电路则不同,必须按部就班分清顺序,否则就会出现时序错乱,就如同对号入座一样,会出现号不对人的混乱排序,最终的结果当然就是错误的。所以,凡涉及到时序电路的时候,一定要兼顾所有的电路分支,如果有两个分支要求同时输入下产生同时输出,则要以最长时序分支为基准,对另外的一个分支进行时序补充,以达到输入输出同步。

当然,除上述所列项之外,还有很多细节之处,需要在系统设计时谨慎处理,这些也都是需要在实战性设计中学习总结出来的,正所谓学无止境,知识永远没有满足的一天,总要适时补充能量,为自己的知识树添枝加叶,才能开出更完美的花,结出更甘甜的果实。

最后,感谢指导老师的细心教导和帮助,也向为完成此次课程设计而出谋划策的师兄们表示谢意,是大家的热心帮助才让我顺利的完成任务。当然,也要感谢自己的坚持不懈,世间难事,唯坚持无不破者。

相关推荐