> 技术文档 > AES算法的Verilog流水线实现(带测试)_aes算法的verilog代码

AES算法的Verilog流水线实现(带测试)_aes算法的verilog代码


一、AES的Verilog流水线实现原理

AES(高级加密标准)是一种对称加密算法,广泛应用于信息安全领域。Verilog流水线实现能够显著提高AES加密的吞吐量,使其适合高速数据处理场景。该实现采用128位密钥(AES-128),通过将加密过程分解为多个流水线阶段,每个时钟周期可以处理不同的数据块。

流水线设计的关键在于将AES的10轮加密操作划分为独立的处理阶段。每个加密轮次由四个基本操作组成:字节替换(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥加(AddRoundKey)。在流水线实现中,这些操作被分配到不同的硬件模块,数据在各模块间流动时可以实现并行处理。

密钥扩展模块采用另一种流水线策略,它预先计算所有轮密钥并存储在寄存器中。这种设计虽然增加了初始延迟,但一旦密钥扩展完成,加密过程可以全速运行,无需等待轮密钥计算。主密钥通过load_mkey信号加载后,模块会在内部生成10个轮密钥。

整个系统采用同步设计,所有操作在时钟上升沿触发。busy信号指示系统状态,防止在密钥扩展或加密过程中加载新数据。这种设计在保证数据安全性的同时,实现了较高的时钟频率和吞吐量,适合FPGA或ASIC实现。

二、Verilog代码解析

1. aes_top模块

aes_top是系统的顶层模块,负责连接密钥扩展和加密模块,并提供统一的外部接口。它包含时钟、复位、主密钥加载、明文输入和密文输出等信号。busy信号由密钥扩展和加密模块的busy信号逻辑或得到,指示系统是否就绪。

该模块实例化了两个主要子模块:key_expand和encrypt。key_expand负责从主密钥生成所有轮密钥,encrypt则执行实际的AES加密操作。round_keys_flatten信号将11个128位轮密钥拼接成1408位宽总线,在模块间传递。

顶层设计采用了清晰的流水线控制策略。当load_mkey有效时加载主密钥,din_valid有效时开始加密过程。dout_valid信号指示输出密文有效,完成了从输入到输出的完整流水线控制。

module aes_top ( input clk, input rst_n, input [127:0] mkey, input load_mkey, input [127:0] plaintext, input din_valid, output [127:0] ciphertext, output dout_valid, output busy); wire [1407:0] round_keys_flatten; wire encrypt_busy; wire key_expand_busy; assign busy = encrypt_busy | key_expand_busy; encrypt u_en ( .clk(clk), .rst_n(rst_n), .din_valid(din_valid), .plaintext(plaintext), .ciphertext(ciphertext), .dout_valid(dout_valid), .busy(encrypt_busy), .round_keys_flatten(round_keys_flatten) ); key_expand u_ke ( .clk(clk), .rst_n(rst_n), .load_mkey(load_mkey), .mkey(mkey), .round_keys_flatten(round_keys_flatten), .busy(key_expand_busy) );endmodule

2. key_expand模块

key_expand模块实现了AES的密钥扩展算法,将128位主密钥扩展为11个128位轮密钥。模块采用状态机控制,round_ctrl寄存器实现10步扩展过程。每次扩展使用rcon常量进行异或操作,并通过sbox进行非线性变换。

密钥扩展算法基于递推关系,每个新密钥字由前一个密钥字和4个周期前的密钥字计算得到。模块中w0-w3寄存器存储中间状态,rcon_new计算下一轮的轮常量。扩展完成后,所有轮密钥存储在round_keys数组中。

该设计优化了时序性能,通过并行计算四个密钥字(w0_new到w3_new)减少关键路径延迟。busy信号在密钥扩展期间保持有效,防止在扩展过程中加载新主密钥。

module key_expand ( input clk, input rst_n, input load_mkey, input [127:0] mkey, output [1407:0] round_keys_flatten, output busy); reg [9:0] round_ctrl; reg [7:0] rcon; reg [31:0] w0, w1, w2, w3; reg [127:0] round_keys[0:10]; wire [31:0] sbox_out; wire [7:0] rcon_new = {rcon[6:0], 1\'b0} ^ (rcon[7] ? 8\'h1b : 8\'h0); wire [31:0] w0_new = w0 ^ {sbox_out[31:24] ^ rcon, sbox_out[23:0]}; wire [31:0] w1_new = w1 ^ w0_new; wire [31:0] w2_new = w2 ^ w1_new; wire [31:0] w3_new = w3 ^ w2_new; wire start_key_expand = load_mkey & ~(|round_ctrl); integer i; assign round_keys_flatten = { round_keys[0], round_keys[1], round_keys[2], round_keys[3], round_keys[4], round_keys[5], round_keys[6], round_keys[7], round_keys[8], round_keys[9], round_keys[10] }; assign busy = load_mkey | (|round_ctrl); always @(posedge clk, negedge rst_n) begin if (~rst_n) begin rcon <= 8\'h00; {w0, w1, w2, w3} <= 128\'h0; end else begin if (start_key_expand) begin {w0, w1, w2, w3} <= mkey; rcon <= 8\'h01; end else if (|round_ctrl) begin {w0, w1, w2, w3} <= {w0_new, w1_new, w2_new, w3_new}; rcon <= rcon_new; end end end always @(posedge clk) begin if (start_key_expand) begin round_keys[0] <= mkey; end else if (|round_ctrl) begin round_keys[10]  1; i = i - 1) begin round_keys[i-1] <= round_keys[i]; end end end always @(posedge clk or negedge rst_n) begin if (~rst_n) begin round_ctrl <= 0; end else begin if (load_mkey) begin round_ctrl <= 1; end else if (busy) begin round_ctrl <= {round_ctrl[8:0], 1\'b0}; end end end sbox sbox1 (.s_in (w3[31:24]), .s_out(sbox_out[7:0])); sbox sbox2 (.s_in (w3[7:0]), .s_out(sbox_out[15:8])); sbox sbox3 (.s_in (w3[15:8]), .s_out(sbox_out[23:16])); sbox sbox4 (.s_in (w3[23:16]), .s_out(sbox_out[31:24]));endmodule

3. encrypt模块

encrypt模块实现了AES加密的流水线结构。它包含11个状态寄存器(state[0]到state[10]),对应初始密钥加和10轮加密。模块使用round_ctrl移位寄存器控制流水线推进,每个时钟周期数据向下一级移动。

加密过程分为三个阶段:初始轮密钥加、9轮标准加密和最后一轮特殊加密。generate语句实例化了9个encrypt_round模块和1个encrypt_round_last模块,形成完整流水线。round_keys_flatten输入被解包为11个轮密钥。

dout_valid信号由round_ctrl的第10位产生,精确指示加密完成时刻。busy信号在加密过程中保持高电平,防止新数据过早进入流水线。这种设计实现了每个时钟周期处理一个新数据块的吞吐量。

module encrypt ( input clk, input rst_n, input din_valid, input [127:0] plaintext, output [127:0] ciphertext, output dout_valid, output busy, input [1407:0] round_keys_flatten); reg [11:0] round_ctrl; reg [127:0] state[0:10]; wire [127:0] round_out[0:9]; wire [127:0] round_keys[0:10]; integer i; genvar j; assign { round_keys[0], round_keys[1], round_keys[2], round_keys[3], round_keys[4], round_keys[5], round_keys[6], round_keys[7], round_keys[8], round_keys[9], round_keys[10] } = round_keys_flatten; assign ciphertext = state[10]; assign busy = din_valid | (|round_ctrl); assign dout_valid = round_ctrl[10]; always @(posedge clk, negedge rst_n) begin if (~rst_n) begin for (i = 0; i < 11; i = i + 1) begin state[i] <= 128\'h0; end end else begin if (din_valid) begin state[0] <= plaintext ^ round_keys[0]; end for (i = 1; i < 11; i = i + 1) begin state[i] <= round_out[i-1]; end end end always @(posedge clk, negedge rst_n) begin if (~rst_n) begin round_ctrl <= 12\'d0; end else begin round_ctrl <= {round_ctrl[10:0], din_valid}; end end generate for (j = 0; j < 9; j = j + 1) begin : enr_instances encrypt_round u_er ( .din(state[j]), .round_key(round_keys[j+1]), .dout(round_out[j]) ); end encrypt_round_last u_er_last ( .din(state[9]), .round_key(round_keys[10]), .dout(round_out[9]) ); endgenerateendmodule

4. encrypt_round模块

encrypt_round实现标准AES加密轮次,包含SubBytes、ShiftRows、MixColumns和AddRoundKey四个步骤。模块使用generate语句实例化16个sbox,并行处理所有字节替换操作。

ShiftRows通过硬连线重新排列字节位置,不消耗逻辑资源。MixColumns使用函数实现,通过gm2和gm3函数计算伽罗瓦域乘法,然后组合成新的列。最后与轮密钥异或完成AddRoundKey操作。

该设计优化了组合逻辑路径,所有步骤在一个时钟周期内完成。模块化设计使得每轮加密可以独立工作,形成高效流水线。

module encrypt_round ( input [127:0] din, input [127:0] round_key, output [127:0] dout); wire [127:0] sbox_out, shift_out, mix_out; genvar i; generate for (i = 0; i < 16; i = i + 1) begin : sbox_instances sbox u_sbox ( .s_in (din[i*8+:8]), .s_out(sbox_out[i*8+:8]) ); end endgenerate assign shift_out[7:0] = sbox_out[39:32]; assign shift_out[15:8] = sbox_out[79:72]; assign shift_out[23:16] = sbox_out[119:112]; assign shift_out[31:24] = sbox_out[31:24]; assign shift_out[39:32] = sbox_out[71:64]; assign shift_out[47:40] = sbox_out[111:104]; assign shift_out[55:48] = sbox_out[23:16]; assign shift_out[63:56] = sbox_out[63:56]; assign shift_out[71:64] = sbox_out[103:96]; assign shift_out[79:72] = sbox_out[15:8]; assign shift_out[87:80] = sbox_out[55:48]; assign shift_out[95:88] = sbox_out[95:88]; assign shift_out[103:96] = sbox_out[7:0]; assign shift_out[111:104] = sbox_out[47:40]; assign shift_out[119:112] = sbox_out[87:80]; assign shift_out[127:120] = sbox_out[127:120]; assign mix_out = mixcolumns(shift_out); assign dout = mix_out ^ round_key; function [7:0] gm2(input [7:0] op); begin gm2 = {op[6:0], 1\'b0} ^ (8\'h1b & {8{op[7]}}); end endfunction function [7:0] gm3(input [7:0] op); begin gm3 = gm2(op) ^ op; end endfunction function [31:0] mixw(input [31:0] w); reg [7:0] b0, b1, b2, b3; reg [7:0] mb0, mb1, mb2, mb3; begin {b0, b1, b2, b3} = w; mb0  = gm2(b0) ^ gm3(b1) ^ b2 ^ b3; mb1  = b0 ^ gm2(b1) ^ gm3(b2) ^ b3; mb2  = b0 ^ b1 ^ gm2(b2) ^ gm3(b3); mb3  = gm3(b0) ^ b1 ^ b2 ^ gm2(b3); mixw = {mb0, mb1, mb2, mb3}; end endfunction function [127:0] mixcolumns(input [127:0] data); reg [31:0] w0, w1, w2, w3; begin {w0, w1, w2, w3} = data; mixcolumns = {mixw(w0), mixw(w1), mixw(w2), mixw(w3)}; end endfunctionendmodulemodule encrypt_round_last ( input [127:0] din, input [127:0] round_key, output [127:0] dout); wire [127:0] sbox_out, shift_out, mix_out; genvar i; generate for (i = 0; i < 16; i = i + 1) begin : sbox_instances sbox u_sbox ( .s_in (din[i*8+:8]), .s_out(sbox_out[i*8+:8]) ); end endgenerate assign shift_out[7:0] = sbox_out[39:32]; assign shift_out[15:8] = sbox_out[79:72]; assign shift_out[23:16] = sbox_out[119:112]; assign shift_out[31:24] = sbox_out[31:24]; assign shift_out[39:32] = sbox_out[71:64]; assign shift_out[47:40] = sbox_out[111:104]; assign shift_out[55:48] = sbox_out[23:16]; assign shift_out[63:56] = sbox_out[63:56]; assign shift_out[71:64] = sbox_out[103:96]; assign shift_out[79:72] = sbox_out[15:8]; assign shift_out[87:80] = sbox_out[55:48]; assign shift_out[95:88] = sbox_out[95:88]; assign shift_out[103:96] = sbox_out[7:0]; assign shift_out[111:104] = sbox_out[47:40]; assign shift_out[119:112] = sbox_out[87:80]; assign shift_out[127:120] = sbox_out[127:120]; assign dout = shift_out ^ round_key;endmodule

5. sbox模块

sbox模块实现AES的字节替换表,使用查找表方式实现非线性变换。模块包含256个8位预计算值,通过输入字节直接寻址获得输出。

module sbox(input [7:0] s_in,output [7:0] s_out);reg [7:0] sbox[0:255];initial beginsbox[000]=8\'h63; sbox[001]=8\'h7c; sbox[002]=8\'h77; sbox[003]=8\'h7b; sbox[004]=8\'hf2; sbox[005]=8\'h6b; sbox[006]=8\'h6f; sbox[007]=8\'hc5;sbox[008]=8\'h30; sbox[009]=8\'h01; sbox[010]=8\'h67; sbox[011]=8\'h2b; sbox[012]=8\'hfe; sbox[013]=8\'hd7; sbox[014]=8\'hab; sbox[015]=8\'h76;sbox[016]=8\'hca; sbox[017]=8\'h82; sbox[018]=8\'hc9; sbox[019]=8\'h7d; sbox[020]=8\'hfa; sbox[021]=8\'h59; sbox[022]=8\'h47; sbox[023]=8\'hf0;sbox[024]=8\'had; sbox[025]=8\'hd4; sbox[026]=8\'ha2; sbox[027]=8\'haf; sbox[028]=8\'h9c; sbox[029]=8\'ha4; sbox[030]=8\'h72; sbox[031]=8\'hc0;sbox[032]=8\'hb7; sbox[033]=8\'hfd; sbox[034]=8\'h93; sbox[035]=8\'h26; sbox[036]=8\'h36; sbox[037]=8\'h3f; sbox[038]=8\'hf7; sbox[039]=8\'hcc;sbox[040]=8\'h34; sbox[041]=8\'ha5; sbox[042]=8\'he5; sbox[043]=8\'hf1; sbox[044]=8\'h71; sbox[045]=8\'hd8; sbox[046]=8\'h31; sbox[047]=8\'h15;sbox[048]=8\'h04; sbox[049]=8\'hc7; sbox[050]=8\'h23; sbox[051]=8\'hc3; sbox[052]=8\'h18; sbox[053]=8\'h96; sbox[054]=8\'h05; sbox[055]=8\'h9a;sbox[056]=8\'h07; sbox[057]=8\'h12; sbox[058]=8\'h80; sbox[059]=8\'he2; sbox[060]=8\'heb; sbox[061]=8\'h27; sbox[062]=8\'hb2; sbox[063]=8\'h75;sbox[064]=8\'h09; sbox[065]=8\'h83; sbox[066]=8\'h2c; sbox[067]=8\'h1a; sbox[068]=8\'h1b; sbox[069]=8\'h6e; sbox[070]=8\'h5a; sbox[071]=8\'ha0;sbox[072]=8\'h52; sbox[073]=8\'h3b; sbox[074]=8\'hd6; sbox[075]=8\'hb3; sbox[076]=8\'h29; sbox[077]=8\'he3; sbox[078]=8\'h2f; sbox[079]=8\'h84;sbox[080]=8\'h53; sbox[081]=8\'hd1; sbox[082]=8\'h00; sbox[083]=8\'hed; sbox[084]=8\'h20; sbox[085]=8\'hfc; sbox[086]=8\'hb1; sbox[087]=8\'h5b;sbox[088]=8\'h6a; sbox[089]=8\'hcb; sbox[090]=8\'hbe; sbox[091]=8\'h39; sbox[092]=8\'h4a; sbox[093]=8\'h4c; sbox[094]=8\'h58; sbox[095]=8\'hcf;sbox[096]=8\'hd0; sbox[097]=8\'hef; sbox[098]=8\'haa; sbox[099]=8\'hfb; sbox[100]=8\'h43; sbox[101]=8\'h4d; sbox[102]=8\'h33; sbox[103]=8\'h85;sbox[104]=8\'h45; sbox[105]=8\'hf9; sbox[106]=8\'h02; sbox[107]=8\'h7f; sbox[108]=8\'h50; sbox[109]=8\'h3c; sbox[110]=8\'h9f; sbox[111]=8\'ha8;sbox[112]=8\'h51; sbox[113]=8\'ha3; sbox[114]=8\'h40; sbox[115]=8\'h8f; sbox[116]=8\'h92; sbox[117]=8\'h9d; sbox[118]=8\'h38; sbox[119]=8\'hf5;sbox[120]=8\'hbc; sbox[121]=8\'hb6; sbox[122]=8\'hda; sbox[123]=8\'h21; sbox[124]=8\'h10; sbox[125]=8\'hff; sbox[126]=8\'hf3; sbox[127]=8\'hd2;sbox[128]=8\'hcd; sbox[129]=8\'h0c; sbox[130]=8\'h13; sbox[131]=8\'hec; sbox[132]=8\'h5f; sbox[133]=8\'h97; sbox[134]=8\'h44; sbox[135]=8\'h17;sbox[136]=8\'hc4; sbox[137]=8\'ha7; sbox[138]=8\'h7e; sbox[139]=8\'h3d; sbox[140]=8\'h64; sbox[141]=8\'h5d; sbox[142]=8\'h19; sbox[143]=8\'h73;sbox[144]=8\'h60; sbox[145]=8\'h81; sbox[146]=8\'h4f; sbox[147]=8\'hdc; sbox[148]=8\'h22; sbox[149]=8\'h2a; sbox[150]=8\'h90; sbox[151]=8\'h88;sbox[152]=8\'h46; sbox[153]=8\'hee; sbox[154]=8\'hb8; sbox[155]=8\'h14; sbox[156]=8\'hde; sbox[157]=8\'h5e; sbox[158]=8\'h0b; sbox[159]=8\'hdb;sbox[160]=8\'he0; sbox[161]=8\'h32; sbox[162]=8\'h3a; sbox[163]=8\'h0a; sbox[164]=8\'h49; sbox[165]=8\'h06; sbox[166]=8\'h24; sbox[167]=8\'h5c;sbox[168]=8\'hc2; sbox[169]=8\'hd3; sbox[170]=8\'hac; sbox[171]=8\'h62; sbox[172]=8\'h91; sbox[173]=8\'h95; sbox[174]=8\'he4; sbox[175]=8\'h79;sbox[176]=8\'he7; sbox[177]=8\'hc8; sbox[178]=8\'h37; sbox[179]=8\'h6d; sbox[180]=8\'h8d; sbox[181]=8\'hd5; sbox[182]=8\'h4e; sbox[183]=8\'ha9;sbox[184]=8\'h6c; sbox[185]=8\'h56; sbox[186]=8\'hf4; sbox[187]=8\'hea; sbox[188]=8\'h65; sbox[189]=8\'h7a; sbox[190]=8\'hae; sbox[191]=8\'h08;sbox[192]=8\'hba; sbox[193]=8\'h78; sbox[194]=8\'h25; sbox[195]=8\'h2e; sbox[196]=8\'h1c; sbox[197]=8\'ha6; sbox[198]=8\'hb4; sbox[199]=8\'hc6;sbox[200]=8\'he8; sbox[201]=8\'hdd; sbox[202]=8\'h74; sbox[203]=8\'h1f; sbox[204]=8\'h4b; sbox[205]=8\'hbd; sbox[206]=8\'h8b; sbox[207]=8\'h8a;sbox[208]=8\'h70; sbox[209]=8\'h3e; sbox[210]=8\'hb5; sbox[211]=8\'h66; sbox[212]=8\'h48; sbox[213]=8\'h03; sbox[214]=8\'hf6; sbox[215]=8\'h0e;sbox[216]=8\'h61; sbox[217]=8\'h35; sbox[218]=8\'h57; sbox[219]=8\'hb9; sbox[220]=8\'h86; sbox[221]=8\'hc1; sbox[222]=8\'h1d; sbox[223]=8\'h9e;sbox[224]=8\'he1; sbox[225]=8\'hf8; sbox[226]=8\'h98; sbox[227]=8\'h11; sbox[228]=8\'h69; sbox[229]=8\'hd9; sbox[230]=8\'h8e; sbox[231]=8\'h94;sbox[232]=8\'h9b; sbox[233]=8\'h1e; sbox[234]=8\'h87; sbox[235]=8\'he9; sbox[236]=8\'hce; sbox[237]=8\'h55; sbox[238]=8\'h28; sbox[239]=8\'hdf;sbox[240]=8\'h8c; sbox[241]=8\'ha1; sbox[242]=8\'h89; sbox[243]=8\'h0d; sbox[244]=8\'hbf; sbox[245]=8\'he6; sbox[246]=8\'h42; sbox[247]=8\'h68;sbox[248]=8\'h41; sbox[249]=8\'h99; sbox[250]=8\'h2d; sbox[251]=8\'h0f; sbox[252]=8\'hb0; sbox[253]=8\'h54; sbox[254]=8\'hbb; sbox[255]=8\'h16;end assign s_out=sbox[s_in]; endmodule

三、实验结果

使用iverilog进行快速功能验证,测试了10组明文/密文对,testbench和测试结果如下。所有测试用例均通过,实际输出与预期密文完全一致。测试平台自动比较结果并显示通过/失败信息,验证了设计的正确性。VCD波形文件被成功生成,便于后续分析。

`timescale 1ns/1psmodule aes_top_tb; reg clk=0; reg rst_n=0; reg [127:0] mkey=0; reg load_mkey=0; reg [127:0] plaintext=0; reg din_valid=0; wire [127:0] ciphertext; wire dout_valid; wire busy; aes_top uut ( .clk(clk), .rst_n(rst_n), .mkey(mkey), .load_mkey(load_mkey), .plaintext(plaintext), .din_valid(din_valid), .ciphertext(ciphertext), .dout_valid(dout_valid), .busy(busy) ); always #5 clk = ~clk; reg [127:0] test_plaintexts [0:9]; reg [127:0] expected_ciphertexts [0:9]; initial begin test_plaintexts[0]=128\'h00112233445566778899aabbccddeeff; test_plaintexts[1]=128\'h74c78ff3d66dbf57133ad70f3783632e; test_plaintexts[2]=128\'h274c7ca8660c45692ae89ad0ccb181ba; test_plaintexts[3]=128\'h6d996b1ee433d25ec82ae8e525853ef7; test_plaintexts[4]=128\'h53330c09f3b978bfb6f124ef34329292; test_plaintexts[5]=128\'h720f5ec1eafcb180549b5dd35aaa4311; test_plaintexts[6]=128\'hf7cfe13517d5a56ee8390ab607bb1025; test_plaintexts[7]=128\'h7074fa1315798698fee73b1beb30ab55; test_plaintexts[8]=128\'h5e6030ea185d0ea90e1a81a84b2f5651; test_plaintexts[9]=128\'h944375ea4102920901f920a09a86efa7; expected_ciphertexts[0]=128\'h69c4e0d86a7b0430d8cdb78070b4c55a; expected_ciphertexts[1]=128\'heb7db34352d001fe483bddb27e9349a1; expected_ciphertexts[2]=128\'h67d455bea9e118bd8425eaf27bc08933; expected_ciphertexts[3]=128\'h5fe2c1898df6a83b9b061c589357f587; expected_ciphertexts[4]=128\'h965c2dba77ff86a316199702c7c36728; expected_ciphertexts[5]=128\'h5edcf52367a8f289ff6fc2a41d2752a9; expected_ciphertexts[6]=128\'h22f0eaf54a178cf157514dcf83673862; expected_ciphertexts[7]=128\'h6a1ce927be8ea92bcf185f4370c29087; expected_ciphertexts[8]=128\'h2f1043780796ac3b4332e5e09460f327; expected_ciphertexts[9]=128\'h4a5a4421892df67cd9b8af80c0b8f3b6; end integer i = 0; initial begin #15 rst_n = 1; mkey = 128\'h000102030405060708090a0b0c0d0e0f; load_mkey = 1; @(negedge clk); load_mkey = 0; wait(busy == 0); @(negedge clk); #20 plaintext=test_plaintexts[0]; din_valid = 1; #10 din_valid = 0; #20 plaintext = test_plaintexts[1]; din_valid = 1; #10 plaintext = test_plaintexts[2]; #10 plaintext = test_plaintexts[3]; #10 plaintext = test_plaintexts[4]; #10 din_valid = 0; #30 plaintext = test_plaintexts[5]; din_valid = 1; #10 plaintext = test_plaintexts[6]; #10 plaintext = test_plaintexts[7]; #10 plaintext = test_plaintexts[8]; #10 plaintext = test_plaintexts[9]; #10 din_valid = 0; wait(busy == 0); #100 $finish; end always @(posedge clk) begin if (dout_valid) begin if (ciphertext === expected_ciphertexts[i]) begin $display(\"Test %0d: Passed, Expected %h, Actual %h\", i, expected_ciphertexts[i], ciphertext); end else begin $display(\"Test %0d: Failed, Expected %h, Actual %h\", i, expected_ciphertexts[i], ciphertext); end i = i + 1; end end initial begin $dumpfile(\"aes_top.vcd\"); $dumpvars(0, aes_top_tb); endendmodule

在gtkwave和Modelsim中观察仿真波形,可以清晰看到流水线的工作过程。当din_valid有效时,明文进入流水线,经过11个周期后dout_valid变高,输出有效密文。busy信号准确反映了系统状态,密钥扩展和加密过程没有重叠时的控制信号行为符合预期。

用Vivado(XC7A35T-1CSG324C)进行综合,结果如下:

四、总结

AES算法是一种广泛使用的对称加密标准,其Verilog流水线实现通过将加密过程分解为多级处理,显著提高了数据吞吐量。该设计采用128位密钥,包含密钥扩展和加密两大模块,通过流水线结构实现每个时钟周期处理一个数据块。密钥扩展模块预先计算所有轮密钥,加密模块则分为初始轮加、9轮标准加密和最终轮加密,形成11级流水线。实验验证表明,该设计功能正确,所有测试用例均通过验证。每周期128位的吞吐量使其适合高速加密场景,而模块化设计便于在不同平台移植和优化,为安全通信提供了高效的硬件解决方案。

体育用品