OpenCores
URL https://opencores.org/ocsvn/aes_highthroughput_lowarea/aes_highthroughput_lowarea/trunk

Subversion Repositories aes_highthroughput_lowarea

[/] [aes_highthroughput_lowarea/] [trunk/] [verilog/] [rtl/] [aes.v] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 motilito
//---------------------------------------------------------------------------------------
2
// 
3
//      AES core top module 
4
// 
5
//      Description: 
6
//              AES core top module with direct interface to key and data buses. 
7
// 
8
//      To Do: 
9
//              - done 
10
//
11
//      Author(s):
12
//              - Luo Dongjun,   dongjun_luo@hotmail.com 
13
//
14
//---------------------------------------------------------------------------------------
15 7 motilito
 
16
// uncomment the following define to enable use of distributed RAM implementation 
17
// for XILINX FPGAs instead of block memory.
18 8 motilito
// NOTE: when commenting the following define, core size is slightly smaller but maximum 
19
// achievable clock frequency is also slightly lower. 
20 7 motilito
`define XILINX          1
21
 
22 5 motilito
module aes (
23 8 motilito
        clk, reset,
24
        i_start, i_enable,
25
        i_ende, i_key,
26
        i_key_mode, i_data,
27
        i_data_valid, o_ready,
28
        o_data, o_data_valid,
29
        o_key_ready
30 5 motilito
);
31
 
32 8 motilito
//---------------------------------------------------------------------------------------
33
// module interfaces 
34
input                   clk;            // core global clock 
35
input                   reset;          // core global async reset control 
36
input                   i_start;        // key expansion start pulse 
37
input                   i_enable;       // enable encryption / decryption core operation 
38
input   [1:0]    i_key_mode; // key length: 0 => 128; 1 => 192; 2 => 256
39
input   [255:0]  i_key;          // if key size is 128/192, upper bits are the inputs 
40
input   [127:0]  i_data;         // plain/cipher text data input 
41
input                   i_data_valid;   // data input valid 
42
input                   i_ende;         // core mode of operation: 0 => encryption; 1 => decryption
43
output                  o_ready;        // indicates core is ready for new input data at the next clock cycle 
44
output  [127:0]  o_data;         // data output 
45
output                  o_data_valid;   // data output valid 
46
output                  o_key_ready;    // key expansion procedure done 
47
 
48
//---------------------------------------------------------------------------------------
49
// module registers and signals 
50 5 motilito
genvar i;
51
wire           final_round;
52
reg   [3:0]    max_round;
53
wire  [127:0]  en_sb_data,de_sb_data,sr_data,mc_data,imc_data,ark_data;
54
reg   [127:0]  sb_data,o_data,i_data_L;
55
reg            i_data_valid_L;
56
reg            round_valid;
57
reg   [2:0]    sb_valid;
58
reg            o_data_valid;
59
reg   [3:0]    round_cnt,sb_round_cnt1,sb_round_cnt2,sb_round_cnt3;
60
wire  [127:0]  round_key;
61
wire  [63:0]   rd_data0,rd_data1;
62
wire           wr;
63
wire  [4:0]    wr_addr;
64
wire  [63:0]   wr_data;
65
wire  [127:0]  imc_round_key,en_ark_data,de_ark_data,ark_data_final,ark_data_init;
66 8 motilito
 
67
//---------------------------------------------------------------------------------------
68
// module implementation 
69 5 motilito
assign final_round = sb_round_cnt3[3:0] == max_round[3:0];
70
//assign o_ready = ~sb_valid[1]; // if ready is asserted, user can input data for the same cycle
71
assign o_ready = ~sb_valid[0]; // if ready is asserted, user can input data for the next cycle
72
 
73
// round count is Nr - 1
74
always @ (*)
75
begin
76
   case (i_key_mode)
77
      2'b00: max_round[3:0] = 4'd10;
78
      2'b01: max_round[3:0] = 4'd12;
79
      default: max_round[3:0] = 4'd14;
80
   endcase
81
end
82
 
83 8 motilito
//---------------------------------------------------------------------------------------
84 5 motilito
// Sub Bytes
85
//
86
//
87
generate
88
for (i=0;i<16;i=i+1)
89
begin : sbox_block
90
   sbox u_sbox (
91
      .clk(clk),
92 7 motilito
      .reset(reset),
93 5 motilito
      .enable(i_enable),
94
      .ende(i_ende),
95
      .din(o_data[i*8+7:i*8]),
96
      .en_dout(en_sb_data[i*8+7:i*8]),
97
      .de_dout(de_sb_data[i*8+7:i*8])
98
   );
99
end
100
endgenerate
101
 
102
always @ (posedge clk or posedge reset)
103
begin
104
   if (reset)
105
      sb_data[127:0] <= 128'b0;
106
   else if (i_enable)
107
      sb_data[127:0] <= i_ende ? de_sb_data[127:0] : en_sb_data[127:0];
108
end
109
 
110 8 motilito
//---------------------------------------------------------------------------------------
111 5 motilito
// Shift Rows
112
//
113
//
114
wire [127:0] shrows, ishrows;
115
 
116
shift_rows u_shrows (.si(sb_data[127:0]), .so(shrows));
117
inv_shift_rows u_ishrows (.si(sb_data[127:0]), .so(ishrows));
118
 
119
assign sr_data[127:0] = i_ende ? ishrows : shrows;
120
 
121 8 motilito
//---------------------------------------------------------------------------------------
122 5 motilito
// Mix Columns
123
//
124
//
125
mix_columns mxc_u (.in(sr_data), .out(mc_data));
126
 
127
always @ (posedge clk or posedge reset)
128
begin
129
   if (reset)
130
   begin
131
      i_data_valid_L  <= 1'b0;
132
      i_data_L[127:0] <= 128'b0;
133
   end
134
   else
135
   begin
136
      i_data_valid_L  <= i_data_valid;
137
      i_data_L[127:0] <=i_data[127:0];
138
   end
139
end
140
 
141 8 motilito
//---------------------------------------------------------------------------------------
142 5 motilito
// Inverse Mix Columns
143
//
144
//
145
inv_mix_columns imxc_u (.in(sr_data), .out(imc_data));
146
 
147 8 motilito
//---------------------------------------------------------------------------------------
148 5 motilito
// add round key for decryption
149
//
150
inv_mix_columns imxk_u (.in(round_key), .out(imc_round_key));
151
 
152
assign ark_data_final[127:0] = sr_data[127:0] ^ round_key[127:0];
153
assign ark_data_init[127:0] = i_data_L[127:0] ^ round_key[127:0];
154
assign en_ark_data[127:0] = mc_data[127:0] ^ round_key[127:0];
155
assign de_ark_data[127:0] = imc_data[127:0] ^ imc_round_key[127:0];
156
assign ark_data[127:0] = i_data_valid_L ? ark_data_init[127:0] :
157
                           (final_round ? ark_data_final[127:0] :
158
                                (i_ende ? de_ark_data[127:0] : en_ark_data[127:0]));
159
 
160 8 motilito
//---------------------------------------------------------------------------------------
161 5 motilito
// Data outputs after each round
162
//
163
always @ (posedge clk or posedge reset)
164
begin
165
   if (reset)
166
      o_data[127:0] <= 128'b0;
167
   else if (i_enable && (i_data_valid_L || sb_valid[2]))
168
      o_data[127:0] <= ark_data[127:0];
169
end
170
 
171 8 motilito
//---------------------------------------------------------------------------------------
172 5 motilito
// in sbox, we have 3 stages (sb_valid),
173
// before the end of each round, we have another stage (round_valid)
174
//
175
always @ (posedge clk or posedge reset)
176
begin
177
   if (reset)
178
   begin
179
      round_valid  <= 1'b0;
180
      sb_valid[2:0] <= 3'b0;
181
      o_data_valid  <= 1'b0;
182
   end
183
   else if (i_enable)
184
   begin
185
      o_data_valid  <= sb_valid[2] && final_round;
186
      round_valid   <= (sb_valid[2] && !final_round) || i_data_valid_L;
187
      sb_valid[2:0] <= {sb_valid[1:0],round_valid};
188
   end
189
end
190
 
191
always @ (posedge clk or posedge reset)
192
begin
193
   if (reset)                      round_cnt[3:0] <= 4'd0;
194
   else if (i_data_valid_L) round_cnt[3:0] <= 4'd1;
195
   else if (i_enable && sb_valid[2])  round_cnt[3:0] <= sb_round_cnt3[3:0] + 1'b1;
196
end
197
 
198
always @ (posedge clk or posedge reset)
199
begin
200
   if (reset)
201
   begin
202
      sb_round_cnt1[3:0] <= 4'd0;
203
      sb_round_cnt2[3:0] <= 4'd0;
204
      sb_round_cnt3[3:0] <= 4'd0;
205
   end
206
   else if (i_enable)
207
   begin
208
      if (round_valid) sb_round_cnt1[3:0] <= round_cnt[3:0];
209
      if (sb_valid[0]) sb_round_cnt2[3:0] <= sb_round_cnt1[3:0];
210
      if (sb_valid[1]) sb_round_cnt3[3:0] <= sb_round_cnt2[3:0];
211
   end
212
end
213
 
214 8 motilito
//---------------------------------------------------------------------------------------
215 5 motilito
// round key generation: the expansion keys are stored in 4 16*32 rams or 
216
// 2 16*64 rams or 1 16*128 rams
217
//
218
//assign rd_addr[3:0] = i_ende ? (max_round[3:0] - sb_round_cnt2[3:0]) : sb_round_cnt2[3:0];
219
 
220
assign round_key[127:0] = {rd_data0[63:0],rd_data1[63:0]};
221
 
222
`ifdef XILINX
223
reg [3:0] rd_addr;
224
 
225
always @ (posedge clk or posedge reset)
226
begin
227
        if (reset)
228
                rd_addr <= 4'b0;
229
        else if (sb_valid[1] | i_data_valid)
230
        begin
231
                if (i_ende)
232
                begin
233
                        if (i_data_valid)
234
                                rd_addr <= max_round[3:0];
235
                        else
236
                                rd_addr <= max_round[3:0] - sb_round_cnt2[3:0];
237
                end
238
                else
239
                begin
240
                        if (i_data_valid)
241
                                rd_addr <= 4'b0;
242
                        else
243
                                rd_addr <= sb_round_cnt2[3:0];
244
                end
245
        end
246
end
247
 
248
xram_16x64 u_ram_0
249
(
250
        .clk(clk),
251
        .wr(wr & ~wr_addr[0]),
252
        .wr_addr(wr_addr[4:1]),
253
        .wr_data(wr_data[63:0]),
254
        .rd_addr(rd_addr[3:0]),
255
        .rd_data(rd_data0[63:0])
256
);
257
xram_16x64 u_ram_1
258
(
259
        .clk(clk),
260
        .wr(wr & wr_addr[0]),
261
        .wr_addr(wr_addr[4:1]),
262
        .wr_data(wr_data[63:0]),
263
        .rd_addr(rd_addr[3:0]),
264
        .rd_data(rd_data1[63:0])
265
);
266
`else
267
wire [3:0] rd_addr;
268
 
269
assign rd_addr[3:0] = i_ende ? (i_data_valid ? max_round[3:0] : (max_round[3:0] - sb_round_cnt2[3:0])) :
270
                               (i_data_valid ? 4'b0 : sb_round_cnt2[3:0]);
271
 
272
ram_16x64 u_ram_0
273
(
274
        .clk(clk),
275
        .wr(wr & ~wr_addr[0]),
276
        .wr_addr(wr_addr[4:1]),
277
        .wr_data(wr_data[63:0]),
278
        .rd_addr(rd_addr[3:0]),
279
        .rd_data(rd_data0[63:0]),
280
        .rd(sb_valid[1] | i_data_valid)
281
);
282
ram_16x64 u_ram_1
283
(
284
        .clk(clk),
285
        .wr(wr & wr_addr[0]),
286
        .wr_addr(wr_addr[4:1]),
287
        .wr_data(wr_data[63:0]),
288
        .rd_addr(rd_addr[3:0]),
289
        .rd_data(rd_data1[63:0]),
290
        .rd(sb_valid[1] | i_data_valid)
291
);
292
`endif
293 8 motilito
//---------------------------------------------------------------------------------------
294 5 motilito
// Key Expansion module
295
//
296
//
297
key_exp u_key_exp (
298
   .clk(clk),
299 7 motilito
   .reset(reset),
300 5 motilito
   .key_in(i_key[255:0]),
301
   .key_mode(i_key_mode[1:0]),
302
   .key_start(i_start),
303
   .wr(wr),
304
   .wr_addr(wr_addr[4:0]),
305
   .wr_data(wr_data[63:0]),
306
   .key_ready(o_key_ready)
307
);
308
 
309
endmodule
310 8 motilito
//---------------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.