目录
某为杯数字赛题:AES加密模块设计
题目
设计思路
1、题目中的重点要求是面积要小,而对于频率要求不太高,一次轮秘钥计算不大于10拍即可。
2、观察题目中的算法发现,大量使用了32位异或门,因此考虑尽可能复用32位的异或门来减小面积。
3、由于需要满足10拍一次轮秘钥的要求,发现至少需要2个异或门完成10拍之内出数据。因此在设计中有一个0-9的计数器来严格控制数据流。
** 具体流程如下:**
代码:
1、AES模块
`timescale 1ns/1ps
module AES(
input clk_sys,
input reset_sys_n,
input[127:0] crypto_key,
input key_expansion_run,
output reg key_expansion_busy,
output reg crypto_rnd_key_vld,
output[31:0] crypto_rnd_key
);
reg[4:0] rnd_cnt;
reg first_two_cycle;
reg[3:0] cnt;
always@(posedge clk_sys or negedge reset_sys_n)
begin
if(!reset_sys_n)
cnt <= 4'b0;
else if (cnt == 4'd9)
cnt <= 4'b0;
else if (key_expansion_busy)
cnt <= cnt+1'b1;
end
always@(posedge clk_sys or negedge reset_sys_n)
begin
if(!reset_sys_n)
key_expansion_busy <= 1'b0;
else if (key_expansion_run)
key_expansion_busy <= 1'b1;
else if (rnd_cnt == 5'd31 && crypto_rnd_key_vld)
key_expansion_busy <= 1'b0;
end
always@(posedge clk_sys or negedge reset_sys_n)
begin
if(!reset_sys_n)
rnd_cnt <= 0;
else if (crypto_rnd_key_vld)
rnd_cnt <= rnd_cnt + 1'b1;
else if (rnd_cnt == 5'd31)
rnd_cnt <= 0;
end
always@(posedge clk_sys or negedge reset_sys_n)
begin
if(!reset_sys_n)
first_two_cycle <= 1'b0;
else if (crypto_key != 128'b0)
first_two_cycle <= 1'b1;
end
parameter fk0 = 32'hA3B1BAC6,
fk1 = 32'h56AA3350,
fk2 = 32'h677D9197,
fk3 = 32'hB27022DC;
reg[31:0] ki,
ki1,
ki2,
ki3,
ki4,
temp1,
temp2,
sbox_input,
sbox_out,
sbox_out_13,
sbox_out_23;
reg[31:0] x1,
y1,
x2,
y2;
wire[31:0] rlt1,
rlt2;
reg[7:0] din;
wire[7:0] dout;
xor_32bit xor1(x1,y1,rlt1);
xor_32bit xor2(x2,y2,rlt2);
sbox sbox_u(din,dout);
always@(*)
begin
if(!(key_expansion_run | key_expansion_busy))
begin
case(first_two_cycle)
1'b0:
begin
x1 = crypto_key[127:96];
y1 = fk0;
ki = rlt1;
x2 = crypto_key[95:64];
y2 = fk1;
ki1 = rlt2;
end
1'b1:
begin
x1 = crypto_key[63:32];
y1 = fk2;
ki2 = rlt1;
x2 = crypto_key[31:0];
y2 = fk3;
ki3 = rlt2;
end
default;
endcase
end
else if(key_expansion_busy)
begin
case(cnt)
4'd0:
begin
crypto_rnd_key_vld = 1'b0;
x1 = GetCK(rnd_cnt);
y1 = ki3;
temp1 = rlt1;
x2 = ki2;
y2 = ki1;
temp2 = rlt2;
end
4'd1:
begin
x1 = temp1;
y1 = temp2;
sbox_input = rlt1;
end
4'd2:
begin
din = sbox_input[7:0];
sbox_out[7:0] = dout;
end
4'd3:
begin
din = sbox_input[15:8];
sbox_out[15:8] = dout;
end
4'd4:
begin
din = sbox_input[23:16];
sbox_out[23:16] = dout;
end
4'd5:
begin
din = sbox_input[31:24];
sbox_out[31:24] = dout;
end
4'd6:
begin
sbox_out_13 = {sbox_out[18:0],sbox_out[31:19]};
sbox_out_23 = {sbox_out[8:0],sbox_out[31:9]};
end
4'd7:
begin
x1 = sbox_out_13;
y1 = sbox_out_23;
temp1 = rlt1;
x2 = temp1;
y2 = sbox_out;
temp2 = rlt2;
end
4'd8:
begin
x1 = ki;
y1 = temp2;
ki4 = rlt1;
end
4'd9:
begin
crypto_rnd_key_vld = 1'b1;
ki = ki1;
ki1 = ki2;
ki2 = ki3;
ki3 = ki4;
end
default;
endcase
end
end
assign crypto_rnd_key = ki4;
parameter CK0 = 32'h00070E15;
parameter CK1 = 32'h1C232A31;
parameter CK2 = 32'h383F464D;
parameter CK3 = 32'h545B6269;
parameter CK4 = 32'h70777E85;
parameter CK5 = 32'h8C939AA1;
parameter CK6 = 32'hA8AFB6BD;
parameter CK7 = 32'hC4CBD2D9;
parameter CK8 = 32'hE0E7EEF5;
parameter CK9 = 32'hFC030A11;
parameter CK10 = 32'h181F262D;
parameter CK11 = 32'h343B4249;
parameter CK12 = 32'h50575E65;
parameter CK13 = 32'h6C737A81;
parameter CK14 = 32'h888F969D;
parameter CK15 = 32'hA4ABB2B9;
parameter CK16 = 32'hC0C7CED5;
parameter CK17 = 32'hDCE3EAF1;
parameter CK18 = 32'hF8FF060D;
parameter CK19 = 32'h141B2229;
parameter CK20 = 32'h30373E45;
parameter CK21 = 32'h4C535A61;
parameter CK22 = 32'h686F767D;
parameter CK23 = 32'h848B9299;
parameter CK24 = 32'hA0A7AEB5;
parameter CK25 = 32'hBCC3CAD1;
parameter CK26 = 32'hD8DFE6ED;
parameter CK27 = 32'hF4FB0209;
parameter CK28 = 32'h10171E25;
parameter CK29 = 32'h2C333A41;
parameter CK30 = 32'h484F565D;
parameter CK31 = 32'h646B7279;
//define CK function
function [31:0] GetCK;
input [4:0] rnd_cnt;
begin
case(rnd_cnt)
5'd0 : GetCK = CK0 ;
5'd1 : GetCK = CK1 ;
5'd2 : GetCK = CK2 ;
5'd3 : GetCK = CK3 ;
5'd4 : GetCK = CK4 ;
5'd5 : GetCK = CK5 ;
5'd6 : GetCK = CK6 ;
5'd7 : GetCK = CK7 ;
5'd8 : GetCK = CK8 ;
5'd9 : GetCK = CK9 ;
5'd10 : GetCK = CK10 ;
5'd11 : GetCK = CK11 ;
5'd12 : GetCK = CK12 ;
5'd13 : GetCK = CK13 ;
5'd14 : GetCK = CK14 ;
5'd15 : GetCK = CK15 ;
5'd16 : GetCK = CK16 ;
5'd17 : GetCK = CK17 ;
5'd18 : GetCK = CK18 ;
5'd19 : GetCK = CK19 ;
5'd20 : GetCK = CK20 ;
5'd21 : GetCK = CK21 ;
5'd22 : GetCK = CK22 ;
5'd23 : GetCK = CK23 ;
5'd24 : GetCK = CK24 ;
5'd25 : GetCK = CK25 ;
5'd26 : GetCK = CK26 ;
5'd27 : GetCK = CK27 ;
5'd28 : GetCK = CK28 ;
5'd29 : GetCK = CK29 ;
5'd30 : GetCK = CK30 ;
5'd31 : GetCK = CK31 ;
default: GetCK = 32'd0;
endcase
end
endfunction
endmodule
2、sbox
`timescale 1ns/1ps
module sbox(
input[7:0] din,
output reg[7:0] dout
);
always@(din)
begin
case(din)
8'h00: dout = 8'hd6;
8'h01: dout = 8'h90;
8'h02: dout = 8'he9;
8'h03: dout = 8'hfe;
8'h04: dout = 8'hcc;
8'h05: dout = 8'he1;
8'h06: dout = 8'h3d;
8'h07: dout = 8'hb7;
8'h08: dout = 8'h16;
8'h09: dout = 8'hb6;
8'h0a: dout = 8'h14;
8'h0b: dout = 8'hc2;
8'h0c: dout = 8'h28;
8'h0d: dout = 8'hfb;
8'h0e: dout = 8'h2c;
8'h0f: dout = 8'h05;
8'h10: dout = 8'h2b;
8'h11: dout = 8'h67;
8'h12: dout = 8'h9a;
8'h13: dout = 8'h76;
8'h14: dout = 8'h2a;
8'h15: dout = 8'hbe;
8'h16: dout = 8'h04;
8'h17: dout = 8'hc3;
8'h18: dout = 8'haa;
8'h19: dout = 8'h44;
8'h1a: dout = 8'h13;
8'h1b: dout = 8'h26;
8'h1c: dout = 8'h49;
8'h1d: dout = 8'h86;
8'h1e: dout = 8'h06;
8'h1f: dout = 8'h99;
8'h20: dout = 8'h9c;
8'h21: dout = 8'h42;
8'h22: dout = 8'h50;
8'h23: dout = 8'hf4;
8'h24: dout = 8'h91;
8'h25: dout = 8'hef;
8'h26: dout = 8'h98;
8'h27: dout = 8'h7a;
8'h28: dout = 8'h33;
8'h29: dout = 8'h54;
8'h2a: dout = 8'h0b;
8'h2b: dout = 8'h43;
8'h2c: dout = 8'hed;
8'h2d: dout = 8'hcf;
8'h2e: dout = 8'hac;
8'h2f: dout = 8'h62;
8'h30: dout = 8'he4;
8'h31: dout = 8'hb3;
8'h32: dout = 8'h1c;
8'h33: dout = 8'ha9;
8'h34: dout = 8'hc9;
8'h35: dout = 8'h08;
8'h36: dout = 8'he8;
8'h37: dout = 8'h95;
8'h38: dout = 8'h80;
8'h39: dout = 8'hdf;
8'h3a: dout = 8'h94;
8'h3b: dout = 8'hfa;
8'h3c: dout = 8'h75;
8'h3d: dout = 8'h8f;
8'h3e: dout = 8'h3f;
8'h3f: dout = 8'ha6;
8'h40: dout = 8'h47;
8'h41: dout = 8'h07;
8'h42: dout = 8'ha7;
8'h43: dout = 8'hfc;
8'h44: dout = 8'hf3;
8'h45: dout = 8'h73;
8'h46: dout = 8'h17;
8'h47: dout = 8'hba;
8'h48: dout = 8'h83;
8'h49: dout = 8'h59;
8'h4a: dout = 8'h3c;
8'h4b: dout = 8'h19;
8'h4c: dout = 8'he6;
8'h4d: dout = 8'h85;
8'h4e: dout = 8'h4f;
8'h4f: dout = 8'ha8;
8'h50: dout = 8'h68;
8'h51: dout = 8'h6b;
8'h52: dout = 8'h81;
8'h53: dout = 8'hb2;
8'h54: dout = 8'h71;
8'h55: dout = 8'h64;
8'h56: dout = 8'hda;
8'h57: dout = 8'h8b;
8'h58: dout = 8'hf8;
8'h59: dout = 8'heb;
8'h5a: dout = 8'h0f;
8'h5b: dout = 8'h4b;
8'h5c: dout = 8'h70;
8'h5d: dout = 8'h56;
8'h5e: dout = 8'h9d;
8'h5f: dout = 8'h35;
8'h60: dout = 8'h1e;
8'h61: dout = 8'h24;
8'h62: dout = 8'h0e;
8'h63: dout = 8'h5e;
8'h64: dout = 8'h63;
8'h65: dout = 8'h58;
8'h66: dout = 8'hd1;
8'h67: dout = 8'ha2;
8'h68: dout = 8'h25;
8'h69: dout = 8'h22;
8'h6a: dout = 8'h7c;
8'h6b: dout = 8'h3b;
8'h6c: dout = 8'h01;
8'h6d: dout = 8'h21;
8'h6e: dout = 8'h78;
8'h6f: dout = 8'h87;
8'h70: dout = 8'hd4;
8'h71: dout = 8'h00;
8'h72: dout = 8'h46;
8'h73: dout = 8'h57;
8'h74: dout = 8'h9f;
8'h75: dout = 8'hd3;
8'h76: dout = 8'h27;
8'h77: dout = 8'h52;
8'h78: dout = 8'h4c;
8'h79: dout = 8'h36;
8'h7a: dout = 8'h02;
8'h7b: dout = 8'he7;
8'h7c: dout = 8'ha0;
8'h7d: dout = 8'hc4;
8'h7e: dout = 8'hc8;
8'h7f: dout = 8'h9e;
8'h80: dout = 8'hea;
8'h81: dout = 8'hbf;
8'h82: dout = 8'h8a;
8'h83: dout = 8'hd2;
8'h84: dout = 8'h40;
8'h85: dout = 8'hc7;
8'h86: dout = 8'h38;
8'h87: dout = 8'hb5;
8'h88: dout = 8'ha3;
8'h89: dout = 8'hf7;
8'h8a: dout = 8'hf2;
8'h8b: dout = 8'hce;
8'h8c: dout = 8'hf9;
8'h8d: dout = 8'h61;
8'h8e: dout = 8'h15;
8'h8f: dout = 8'ha1;
8'h90: dout = 8'he0;
8'h91: dout = 8'hae;
8'h92: dout = 8'h5d;
8'h93: dout = 8'ha4;
8'h94: dout = 8'h9b;
8'h95: dout = 8'h34;
8'h96: dout = 8'h1a;
8'h97: dout = 8'h55;
8'h98: dout = 8'had;
8'h99: dout = 8'h93;
8'h9a: dout = 8'h32;
8'h9b: dout = 8'h30;
8'h9c: dout = 8'hf5;
8'h9d: dout = 8'h8c;
8'h9e: dout = 8'hb1;
8'h9f: dout = 8'he3;
8'ha0: dout = 8'h1d;
8'ha1: dout = 8'hf6;
8'ha2: dout = 8'he2;
8'ha3: dout = 8'h2e;
8'ha4: dout = 8'h82;
8'ha5: dout = 8'h66;
8'ha6: dout = 8'hca;
8'ha7: dout = 8'h60;
8'ha8: dout = 8'hc0;
8'ha9: dout = 8'h29;
8'haa: dout = 8'h23;
8'hab: dout = 8'hab;
8'hac: dout = 8'h0d;
8'had: dout = 8'h53;
8'hae: dout = 8'h4e;
8'haf: dout = 8'h6f;
8'hb0: dout = 8'hd5;
8'hb1: dout = 8'hdb;
8'hb2: dout = 8'h37;
8'hb3: dout = 8'h45;
8'hb4: dout = 8'hde;
8'hb5: dout = 8'hfd;
8'hb6: dout = 8'h8e;
8'hb7: dout = 8'h2f;
8'hb8: dout = 8'h03;
8'hb9: dout = 8'hff;
8'hba: dout = 8'h6a;
8'hbb: dout = 8'h72;
8'hbc: dout = 8'h6d;
8'hbd: dout = 8'h6c;
8'hbe: dout = 8'h5b;
8'hbf: dout = 8'h51;
8'hc0: dout = 8'h8d;
8'hc1: dout = 8'h1b;
8'hc2: dout = 8'haf;
8'hc3: dout = 8'h92;
8'hc4: dout = 8'hbb;
8'hc5: dout = 8'hdd;
8'hc6: dout = 8'hbc;
8'hc7: dout = 8'h7f;
8'hc8: dout = 8'h11;
8'hc9: dout = 8'hd9;
8'hca: dout = 8'h5c;
8'hcb: dout = 8'h41;
8'hcc: dout = 8'h1f;
8'hcd: dout = 8'h10;
8'hce: dout = 8'h5a;
8'hcf: dout = 8'hd8;
8'hd0: dout = 8'h0a;
8'hd1: dout = 8'hc1;
8'hd2: dout = 8'h31;
8'hd3: dout = 8'h88;
8'hd4: dout = 8'ha5;
8'hd5: dout = 8'hcd;
8'hd6: dout = 8'h7b;
8'hd7: dout = 8'hbd;
8'hd8: dout = 8'h2d;
8'hd9: dout = 8'h74;
8'hda: dout = 8'hd0;
8'hdb: dout = 8'h12;
8'hdc: dout = 8'hb8;
8'hdd: dout = 8'he5;
8'hde: dout = 8'hb4;
8'hdf: dout = 8'hb0;
8'he0: dout = 8'h89;
8'he1: dout = 8'h69;
8'he2: dout = 8'h97;
8'he3: dout = 8'h4a;
8'he4: dout = 8'h0c;
8'he5: dout = 8'h96;
8'he6: dout = 8'h77;
8'he7: dout = 8'h7e;
8'he8: dout = 8'h65;
8'he9: dout = 8'hb9;
8'hea: dout = 8'hf1;
8'heb: dout = 8'h09;
8'hec: dout = 8'hc5;
8'hed: dout = 8'h6e;
8'hee: dout = 8'hc6;
8'hef: dout = 8'h84;
8'hf0: dout = 8'h18;
8'hf1: dout = 8'hf0;
8'hf2: dout = 8'h7d;
8'hf3: dout = 8'hec;
8'hf4: dout = 8'h3a;
8'hf5: dout = 8'hdc;
8'hf6: dout = 8'h4d;
8'hf7: dout = 8'h20;
8'hf8: dout = 8'h79;
8'hf9: dout = 8'hee;
8'hfa: dout = 8'h5f;
8'hfb: dout = 8'h3e;
8'hfc: dout = 8'hd7;
8'hfd: dout = 8'hcb;
8'hfe: dout = 8'h39;
8'hff: dout = 8'h48;
default : dout = 8'h00;
endcase
end
endmodule
3、XOR
`timescale 1ns/1ps
module xor_32bit(
input[31:0] x,
input[31:0] y,
output[31:0] rlt
);
assign rlt = x^y;
endmodule
4、TB
//tb for AES 128bit
`timescale 1ns/1ns
module tb;
reg clk_sys ;
reg reset_sys_n ;
reg[127:0] crypto_key ;
reg key_expansion_run ;
wire key_expansion_busy ;
wire crypto_rnd_key_vld ;
wire[31:0] crypto_rnd_key ;
AES u0_AES
(
.clk_sys (clk_sys ),
.reset_sys_n (reset_sys_n ),
.crypto_key (crypto_key ),
.key_expansion_run (key_expansion_run ),
.key_expansion_busy (key_expansion_busy),
.crypto_rnd_key_vld (crypto_rnd_key_vld),
.crypto_rnd_key (crypto_rnd_key )
);
always #5 clk_sys = ~clk_sys;
initial begin
clk_sys = 0;
reset_sys_n = 0;
crypto_key = 0;
key_expansion_run = 0;
#105
reset_sys_n = 1;
crypto_key = 128'h01234567_89ABCDEF_FEDCBA98_76543210;
#20
key_expansion_run = 1;
#10
key_expansion_run = 0;
#10000
crypto_key = 0;
#10
crypto_key = 128'h01234567_89ABCDEF_FEDCBA98_76543210;
#20
key_expansion_run = 1;
#10
key_expansion_run = 0;
end
endmodule