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 5

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

powered by: WebSVN 2.1.0

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