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 7

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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