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

Subversion Repositories apbtoaes128

[/] [apbtoaes128/] [trunk/] [rtl/] [datapath.v] - Blame information for rev 11

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

Line No. Rev Author Line
1 2 redbear
//////////////////////////////////////////////////////////////////
2
////
3
////
4
////    AES CORE BLOCK
5
////
6
////
7
////
8 7 redbear
//// This file is part of the APB to I2C project
9 2 redbear
////
10 7 redbear
//// http://www.opencores.org/cores/apbi2c/
11 2 redbear
////
12
////
13
////
14
//// Description
15
////
16
//// Implementation of APB IP core according to
17
////
18
//// aes128_spec IP core specification document.
19
////
20
////
21
////
22
//// To Do: Things are right here but always all block can suffer changes
23
////
24
////
25
////
26
////
27
////
28
//// Author(s): - Felipe Fernandes Da Costa, fefe2560@gmail.com
29
////              Julio Cesar 
30
////
31
///////////////////////////////////////////////////////////////// 
32
////
33
////
34
//// Copyright (C) 2009 Authors and OPENCORES.ORG
35
////
36
////
37
////
38
//// This source file may be used and distributed without
39
////
40
//// restriction provided that this copyright statement is not
41
////
42
//// removed from the file and that any derivative work contains
43
//// the original copyright notice and the associated disclaimer.
44
////
45
////
46
//// This source file is free software; you can redistribute it
47
////
48
//// and/or modify it under the terms of the GNU Lesser General
49
////
50
//// Public License as published by the Free Software Foundation;
51
//// either version 2.1 of the License, or (at your option) any
52
////
53
//// later version.
54
////
55
////
56
////
57
//// This source is distributed in the hope that it will be
58
////
59
//// useful, but WITHOUT ANY WARRANTY; without even the implied
60
////
61
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
62
////
63
//// PURPOSE. See the GNU Lesser General Public License for more
64
//// details.
65
////
66
////
67
////
68
//// You should have received a copy of the GNU Lesser General
69
////
70
//// Public License along with this source; if not, download it
71
////
72
//// from http://www.opencores.org/lgpl.shtml
73
////
74
////
75
///////////////////////////////////////////////////////////////////
76
module datapath
77
(
78
        // OUTPUTS
79
        output [31:0] col_bus,
80
        output [31:0] key_bus,
81
        output [31:0] iv_bus,
82
        output end_aes,
83
        // INPUTS
84
        input [31:0] bus_in,
85
        input [ 1:0] data_type,
86
        input [ 1:0] rk_sel,
87
        input [ 1:0] key_out_sel,
88
        input [ 3:0] round,
89
        input [ 2:0] sbox_sel,
90
        input [ 3:0] iv_en,
91
        input [ 3:0] iv_sel_rd,
92
        input [ 3:0] col_en_host,
93
        input [ 3:0] col_en_cnt_unit,
94
        input [ 3:0] key_host_en,
95
        input [ 3:0] key_en,
96
        input [ 1:0] key_sel_rd,
97
        input [ 1:0] col_sel,
98
        input [ 1:0] col_sel_host,
99
        input end_comp,
100
        input key_sel,
101
        input key_init,
102
        input bypass_rk,
103
        input bypass_key_en,
104
        input first_block,
105
        input last_round,
106
        input iv_cnt_en,
107
        input iv_cnt_sel,
108
        input enc_dec,
109
        input mode_ctr,
110
        input mode_cbc,
111
        input key_gen,
112
        input key_derivation_en,
113
        input rst_n,
114
        input clk
115
);
116
 
117
//`include "include/control_unit_params.vh"
118
//=============================================================================
119
// SBOX SEL
120
//=============================================================================
121
localparam COL_0 = 3'b000;
122
localparam COL_1 = 3'b001;
123
localparam COL_2 = 3'b010;
124
localparam COL_3 = 3'b011;
125
localparam G_FUNCTION = 3'b100;
126
 
127
//=============================================================================
128
// RK_SEL
129
//=============================================================================
130
localparam COL        = 2'b00;
131
localparam MIXCOL_IN  = 2'b01;
132
localparam MIXCOL_OUT = 2'b10;
133
 
134
//=============================================================================
135
// KEY_OUT_SEL
136
//=============================================================================
137
localparam KEY_0 = 2'b00;
138
localparam KEY_1 = 2'b01;
139
localparam KEY_2 = 2'b10;
140
localparam KEY_3 = 2'b11;
141
 
142
//=============================================================================
143
// COL_SEL
144
//=============================================================================
145
localparam SHIFT_ROWS = 2'b00;
146
localparam ADD_RK_OUT = 2'b01;
147
localparam INPUT      = 2'b10;
148
 
149
//=============================================================================
150
// KEY_SEL
151
//=============================================================================
152
localparam KEY_HOST = 1'b0;
153
localparam KEY_OUT  = 1'b1;
154
 
155
//=============================================================================
156
// KEY_EN
157
//=============================================================================
158
localparam KEY_DIS  = 4'b0000;
159
localparam EN_KEY_0 = 4'b0001;
160
localparam EN_KEY_1 = 4'b0010;
161
localparam EN_KEY_2 = 4'b0100;
162
localparam EN_KEY_3 = 4'b1000;
163
localparam KEY_ALL  = 4'b1111;
164
 
165
//=============================================================================
166
// COL_EN
167
//=============================================================================
168
localparam COL_DIS  = 4'b0000;
169
localparam EN_COL_0 = 4'b0001;
170
localparam EN_COL_1 = 4'b0010;
171
localparam EN_COL_2 = 4'b0100;
172
localparam EN_COL_3 = 4'b1000;
173
localparam COL_ALL  = 4'b1111;
174
 
175
//=============================================================================
176
// IV_CNT_SEL
177
//=============================================================================
178
localparam IV_CNT = 1'b1;
179
localparam IV_BUS = 1'b0;
180
 
181
//=============================================================================
182
// ENABLES
183
//=============================================================================
184
localparam ENABLE = 1'b1;
185
localparam DISABLE = 1'b0;
186
 
187
reg [31 : 0] col     [0:3];
188
reg [31 : 0] key     [0:3];
189
reg [31 : 0] key_host[0:3];
190
reg [31 : 0] bkp     [0:3];
191
reg [31 : 0] bkp_1   [0:3];
192
reg [31 : 0] iv      [0:3];
193
 
194
reg  [127 : 0] col_in;
195
reg  [ 31 : 0] data_in;
196
reg  [ 31 : 0] add_rd_key_in;
197
reg  [ 31 : 0] sbox_input;
198
reg  [ 31 : 0] key_mux_out;
199
reg  [ 31 : 0] iv_mux_out;
200
reg  [ 31 : 0] bkp_mux_out;
201
 
202
wire [127 : 0] key_in, key_out;
203
wire [127 : 0] sr_input;
204
wire [127 : 0] sr_enc, sr_dec;
205
wire [ 31 : 0] add_rk_out;
206
wire [ 31 : 0] sbox_out_enc;
207
wire [ 31 : 0] sbox_out_dec;
208
wire [ 31 : 0] g_in;
209
wire [ 31 : 0] mix_out_enc;
210
wire [ 31 : 0] mix_out_dec;
211
wire [ 31 : 0] add_rd;
212
wire [ 31 : 0] bus_swap;
213
wire [ 31 : 0] iv_bkp_mux;
214
wire [ 31 : 0] xor_input_bkp_iv;
215
wire [ 31 : 0] sr_input_0;
216
wire [ 31 : 0] sr_input_3;
217
wire [  3 : 0] key_en_sel;
218
wire [  3 : 0] bkp_en;
219
wire [  3 : 0] col_en;
220
wire [  1 : 0] key_mux_sel;
221
wire [  1 : 0] rk_sel_mux;
222
wire [  1 : 0] col_sel_w_bypass;
223
wire [  3 : 0] col_en_w_bypass;
224
wire rk_out_sel;
225
wire add_rk_sel;
226
wire key_sel_mux;
227
wire key1_mux_cnt;
228
wire enc_dec_sbox;
229
 
230
reg [31 : 0] sbox_pp2;
231
reg [ 3 : 0] col_en_cnt_unit_pp1;
232
reg [ 3 : 0] col_en_cnt_unit_pp2;
233
reg [ 3 : 0] key_en_pp1;
234
reg [ 3 : 0] round_pp1;
235
reg [ 1 : 0] col_sel_pp1;
236
reg [ 1 : 0] col_sel_pp2;
237
reg [ 1 : 0] key_out_sel_pp1;
238
reg [ 1 : 0] key_out_sel_pp2;
239
reg [ 1 : 0] rk_sel_pp1;
240
reg [ 1 : 0] rk_sel_pp2;
241
reg key_sel_pp1;
242
reg rk_out_sel_pp1, rk_out_sel_pp2;
243
reg last_round_pp1, last_round_pp2;
244 9 redbear
//reg end_aes_pp2,end_aes_pp1;//end_aes_pp2;
245 2 redbear
 
246
assign key_bus = key_mux_out;
247
assign iv_bus = iv_mux_out;
248
 
249
// Input Swap Unit
250
data_swap SWAP_IN
251
(
252
        .data_swap( bus_swap  ),
253
        .data_in  ( bus_in    ),
254
        .swap_type( data_type )
255
);
256
 
257
// Output Swap Unit
258
data_swap SWAP_OUT
259
(
260
        .data_swap( col_bus    ),
261
        .data_in  ( sbox_input ),
262
        .swap_type( data_type  )
263
);
264
 
265
// IV and BKP Muxs
266
always @(*)
267
        begin: IV_BKP_MUX
268
                integer i;
269
                iv_mux_out  = {32{1'b0}};
270
                bkp_mux_out = {32{1'b0}};
271
                for(i = 0; i < 4; i = i + 1)
272
                        begin
273
                                if(col_en[i] | iv_sel_rd[i])
274
                                        begin
275
                                                iv_mux_out  = iv[i];
276
                                                bkp_mux_out = bkp[i];
277
                                        end
278
                        end
279
        end
280
 
281
assign iv_bkp_mux = (first_block && !mode_ctr) ? iv_mux_out : bkp_mux_out;
282
 
283
assign xor_input_bkp_iv = ((enc_dec && !mode_ctr) ? bus_swap : add_rk_out) ^ iv_bkp_mux;
284
 
285
always @(*)
286
        begin
287
                data_in = {32{1'b0}};
288
                case(1'b1)
289
                        mode_cbc:
290
                                data_in = (enc_dec || last_round) ? xor_input_bkp_iv : bus_swap;
291
                        mode_ctr:
292
                                data_in = (last_round) ? xor_input_bkp_iv : iv_mux_out;
293
                        default:
294
                                data_in = bus_swap;
295
                endcase
296
        end
297
 
298
assign bkp_en = ( {4{ mode_cbc && last_round && enc_dec}} & col_en_cnt_unit_pp2) |
299
                ( {4{(mode_cbc && !enc_dec) || mode_ctr}} & col_en_host     );
300
 
301
 
302
// IV and BKP Registers
303
generate
304
        genvar l;
305 7 redbear
 
306
        for(l = 0; l < 4;l=l+1)
307
        begin
308 2 redbear
                always @(posedge clk, negedge rst_n)
309 7 redbear
                begin
310 2 redbear
                                if(!rst_n)
311 7 redbear
                                begin
312 2 redbear
                                                iv[l]    <= {32{1'b0}};
313
                                                bkp[l]   <= {32{1'b0}};
314
                                                bkp_1[l] <= {32{1'b0}};
315 7 redbear
                                end
316 2 redbear
                                else
317 7 redbear
                                begin
318 2 redbear
                                                if(l == 3)
319 7 redbear
                                                begin
320 2 redbear
                                                                if(iv_en[l] || iv_cnt_en)
321 9 redbear
                                                                begin
322
                                                                        /*
323
                                                                        if(mode_ctr)
324
                                                                                iv[l] <= (iv_cnt_sel) ? iv[l] + 1'b1 : bus_in;
325
 
326
                                                                        else
327
                                                                                iv[l] <= (iv_cnt_sel) ? iv[l] : bus_in;
328
                                                                        */
329
 
330 8 redbear
                                                                        iv[l] <= (iv_cnt_sel) ? iv[l] : bus_in;
331 9 redbear
                                                                end
332 7 redbear
                                                end
333 2 redbear
                                                else
334 7 redbear
                                                begin
335 2 redbear
                                                                if(iv_en[l])
336
                                                                        iv[l] <= bus_in;
337 7 redbear
                                                end
338 2 redbear
 
339
                                        if(bkp_en[l])
340 7 redbear
                                                //bkp[l] <= (mode_ctr) ? bus_swap : ((mode_cbc && enc_dec) ? col_in : bkp_1[l]);
341 8 redbear
                                        bkp[l] <= (mode_ctr) ? bus_swap : ((mode_cbc && enc_dec)? col_in[32*(l + 1) - 1 : 32*l] : bkp_1[l]);
342 2 redbear
 
343
                                        if(bkp_en[l])
344 7 redbear
                                                bkp_1[l] <= col_in[32*(l + 1) - 1 : 32*l];
345
                                end
346 2 redbear
                        end
347 7 redbear
 
348
                end
349 2 redbear
endgenerate
350
 
351
assign col_sel_w_bypass = (bypass_rk) ? col_sel : col_sel_pp2;
352
 
353
// Columns Input Multiplexors
354
always @(*)
355
        begin
356
                col_in = {128{1'b0}};
357
                case(col_sel_w_bypass)
358
                        SHIFT_ROWS:
359
                                col_in = (enc_dec) ? sr_enc : sr_dec;
360
                        ADD_RK_OUT:
361
                                col_in = {4{add_rk_out}};
362
                        INPUT:
363
                                col_in = {4{data_in}};
364
                endcase
365
        end
366
 
367
assign col_en_w_bypass = (bypass_rk) ? col_en_cnt_unit : col_en_cnt_unit_pp2;
368
assign col_en = col_en_host | col_en_w_bypass;
369
 
370
// Columns Definition
371
generate
372
        genvar i;
373
        for(i = 0; i < 4; i = i + 1)
374
                always @(posedge clk, negedge rst_n)
375
                        begin
376
                                if(!rst_n)
377
                                        col[3 - i] <= {32{1'b0}};
378
                                else
379
                                if(col_en[3 - i])
380
                                        col[3 - i] <= col_in[32*(i + 1) - 1 : 32*i];
381
                        end
382
endgenerate
383
 
384
// Shift Rows Operation
385
assign sr_input_3 = (enc_dec) ? add_rk_out : col[3];
386
assign sr_input_0 = (enc_dec) ? col[0] : add_rk_out;
387
assign sr_input = {sr_input_0, col[1], col[2], sr_input_3};
388
 
389
shift_rows SHIFT_ROW
390
(
391
        .data_out_enc  ( sr_enc   ),
392
        .data_out_dec  ( sr_dec   ),
393
  .data_in       ( sr_input )
394
);
395
 
396
//SBOX Input Multiplexor
397
always @(*)
398
        begin
399
                sbox_input = {32{1'b0}};
400
                case(sbox_sel | col_sel_host)
401
                        COL_0:
402
                                sbox_input = col[0];
403
                        COL_1:
404
                                sbox_input = col[1];
405
                        COL_2:
406
                                sbox_input = col[2];
407
                        COL_3:
408
                                sbox_input = col[3];
409
                        G_FUNCTION:
410
                                sbox_input = g_in;
411
                endcase
412
        end
413
 
414
// 32 bits SBOX
415
assign enc_dec_sbox = enc_dec | key_gen;
416
 sBox SBOX
417
  (
418
    .sbox_out_enc ( sbox_out_enc ),
419
                .sbox_out_dec ( sbox_out_dec ),
420
    .sbox_in      ( sbox_input   ),
421
    .enc_dec      ( enc_dec_sbox ),
422
                .clk          ( clk          )
423
  );
424
 
425
// Second stage of pipeline
426
always @(posedge clk)
427
        begin
428
                sbox_pp2 <= (enc_dec || mode_ctr) ? sbox_out_enc : sbox_out_dec ^ key_mux_out;
429
        end
430
 
431
assign key_en_sel  = (bypass_key_en) ? key_en : key_en_pp1;
432
assign key_sel_mux = (bypass_key_en) ? key_sel : key_sel_pp1;
433
 
434
// Key registers
435
generate
436
        genvar j;
437
        for(j = 0; j < 4; j = j + 1)
438
                always @(posedge clk, negedge rst_n)
439
                        begin
440
                                if(!rst_n)
441
                                        begin
442
                                                key_host[3 - j] <= {32{1'b0}};
443
                                                key[3 - j] <= {32{1'b0}};
444
                                        end
445
                                else
446
                                        begin
447
                                                if(key_host_en[3 - j] || key_derivation_en)
448
                                                        key_host[3 - j] <= (key_derivation_en) ? key[3 - j] : bus_in;
449
 
450
                                                if(key_en_sel[3 - j] || key_init || key_host_en[3 - j])
451
                                                        key[3 - j] <= (key_sel_mux) ? key_out[32*(j + 1) - 1 : 32*j] : ( (key_host_en[3 - j]) ? bus_in : key_host[3 - j] );
452
                                        end
453
                        end
454
endgenerate
455
 
456
assign key_in = {key[0], key[1], key[2], key[3]};
457
 
458
assign key1_mux_cnt = bypass_key_en & enc_dec;
459
 
460
key_expander KEY_EXPANDER
461
(
462
        .key_out   ( key_out       ),
463
        .g_in              ( g_in          ),
464
        .g_out     ( sbox_out_enc  ),
465
        .key_in    ( key_in        ),
466
        .round     ( round_pp1     ),
467
        .add_w_out ( key1_mux_cnt  ),
468
        .enc_dec   ( enc_dec | key_gen)
469
);
470
 
471
assign key_mux_sel = (bypass_key_en) ? key_out_sel : ( (enc_dec | mode_ctr) ? key_out_sel_pp2 : key_out_sel_pp1 );
472
 
473
// Key Expander Mux
474
always @(*)
475
        begin
476
                key_mux_out = {32{1'b0}};
477
                case(key_mux_sel | key_sel_rd)
478
                        KEY_0:
479
                                key_mux_out = key[0];
480
                        KEY_1:
481
                                key_mux_out = key[1];
482
                        KEY_2:
483
                                key_mux_out = key[2];
484
                        KEY_3:
485
                                key_mux_out = key[3];
486
                endcase
487
        end
488
 
489
  mix_columns MIX_COL
490
  (
491
    .mix_out_enc ( mix_out_enc  ),
492
                .mix_out_dec ( mix_out_dec  ),
493
    .mix_in      ( sbox_pp2     )
494
  );
495
 
496
assign rk_sel_mux = (bypass_rk) ? rk_sel : rk_sel_pp2;
497
 
498
always @(*)
499
        begin
500
                add_rd_key_in = {32{1'b0}};
501
                case(rk_sel_mux)
502
                        COL:
503
                                add_rd_key_in = sbox_input;
504
                        MIXCOL_IN:
505
                                add_rd_key_in = sbox_pp2;
506
                        MIXCOL_OUT:
507
                                add_rd_key_in = mix_out_enc;
508
                endcase
509
        end
510
 
511
// Add Round Key
512
assign add_rd = add_rd_key_in ^ key_mux_out;
513
 
514
assign rk_out_sel = (enc_dec | mode_ctr | bypass_rk);
515
 
516
assign add_rk_sel = (bypass_rk) ? rk_out_sel : rk_out_sel_pp2;
517
 
518
assign add_rk_out = (add_rk_sel) ? add_rd : (last_round_pp2 ? sbox_pp2 : mix_out_dec);
519
 
520 9 redbear
assign end_aes = end_comp;
521 2 redbear
 
522
// Pipeline Registers for Control Signals
523
always @(posedge clk, negedge rst_n)
524
        begin
525
                if(!rst_n)
526
                        begin
527 7 redbear
                                //end_aes_pp1 <= DISABLE;
528
                                //end_aes_pp2 <= DISABLE;
529 2 redbear
 
530
                                col_sel_pp1 <= INPUT;
531
                                col_sel_pp2 <= INPUT;
532
 
533
                                col_en_cnt_unit_pp1 <= COL_DIS;
534
                                col_en_cnt_unit_pp2 <= COL_DIS;
535
 
536
                                key_sel_pp1 <= KEY_HOST;
537
                                key_en_pp1  <= KEY_DIS;
538
 
539
                                round_pp1 <= 4'b0000;
540
 
541
                                key_out_sel_pp1 <= KEY_0;
542
                                key_out_sel_pp2 <= KEY_0;
543
 
544
                                rk_sel_pp1 <= COL;
545
                                rk_sel_pp2 <= COL;
546
 
547
                                rk_out_sel_pp1 <= 1'b1;
548
                                rk_out_sel_pp2 <= 1'b1;
549
 
550
                                last_round_pp1 <= 1'b1;
551
                                last_round_pp2 <= 1'b0;
552
                        end
553
                else
554
                        begin
555
                                col_sel_pp1 <= col_sel;
556
                                col_sel_pp2 <= col_sel_pp1;
557
 
558
                                if(!bypass_rk)
559
                                        begin
560
                                                col_en_cnt_unit_pp1 <= col_en_cnt_unit;
561
                                                col_en_cnt_unit_pp2 <= col_en_cnt_unit_pp1;
562
                                        end
563
 
564
                                key_sel_pp1 <= key_sel;
565
 
566
                                if(!bypass_key_en)
567
                                        key_en_pp1 <= key_en;
568
 
569
                                round_pp1 <= round;
570
 
571
                                key_out_sel_pp1 <= key_out_sel;
572
                                key_out_sel_pp2 <= key_out_sel_pp1;
573
 
574
                                rk_sel_pp1 <= rk_sel;
575
                                rk_sel_pp2 <= rk_sel_pp1;
576
 
577
                                rk_out_sel_pp1 <= rk_out_sel;
578
                                rk_out_sel_pp2 <= rk_out_sel_pp1;
579
 
580
                                last_round_pp1 <= last_round;
581
                                last_round_pp2 <= last_round_pp1;
582
 
583 7 redbear
                                //end_aes_pp1 <= end_comp;
584 9 redbear
                                //end_aes_pp2 <= end_aes_pp1;
585 2 redbear
                        end
586
        end
587
endmodule

powered by: WebSVN 2.1.0

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