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

Subversion Repositories apbtoaes128

[/] [apbtoaes128/] [trunk/] [rtl/] [host_interface.v] - Blame information for rev 2

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
//// This file is part of the APB to I2C project
9
////
10
//// http://www.opencores.org/cores/apbi2c/
11
////
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 host_interface
77
(
78
        // OUTPUTS
79
        output [3:0] key_en,
80
        output [1:0] col_addr,
81
        output [1:0] chmod,
82
        output [1:0] mode,
83
        output [1:0] data_type,
84
        output col_wr_en,
85
        output col_rd_en,
86
        output [1:0] key_sel,
87
        output [3:0] iv_en,
88
        output [3:0] iv_sel,
89
        output int_ccf,
90
        output int_err,
91
        output disable_core,
92
        output reg first_block,
93
        output dma_req_wr,
94
        output dma_req_rd,
95
        output reg start_core,
96
        output [31:0] PRDATA,
97
        //INPUTS
98
        input [3:0] PADDR,
99
        input [31:0] PWDATA,
100
        input PWRITE,
101
        input PENABLE,
102
        input PSEL,
103
        input PCLK,
104
        input PRESETn,
105
        input [31:0] key_bus,
106
        input [31:0] col_bus,
107
        input [31:0] iv_bus,
108
        input ccf_set
109
);
110
 
111
//`include "include/host_interface.vh"
112
 
113
//=====================================================================================
114
// Memory Mapped Registers Address
115
//=====================================================================================
116
localparam AES_CR    = 4'd00;
117
localparam AES_SR    = 4'd01;
118
localparam AES_DINR  = 4'd02;
119
localparam AES_DOUTR = 4'd03;
120
localparam AES_KEYR0 = 4'd04;
121
localparam AES_KEYR1 = 4'd05;
122
localparam AES_KEYR2 = 4'd06;
123
localparam AES_KEYR3 = 4'd07;
124
localparam AES_IVR0  = 4'd08;
125
localparam AES_IVR1  = 4'd09;
126
localparam AES_IVR2  = 4'd10;
127
localparam AES_IVR3  = 4'd11;
128
 
129
//=============================================================================
130
// Operation Modes
131
//=============================================================================
132
localparam ENCRYPTION     = 2'b00;
133
localparam KEY_DERIVATION = 2'b01;
134
localparam DECRYPTION     = 2'b10;
135
localparam DECRYP_W_DERIV = 2'b11;
136
 
137
//=============================================================================
138
// AES Modes
139
//=============================================================================
140
localparam ECB = 2'b00;
141
localparam CBC = 2'b01;
142
localparam CTR = 2'b10;
143
 
144
//=============================================================================
145
// Resets Values
146
//=============================================================================
147
localparam AES_CR_RESET = 13'd0;
148
localparam AES_SR_RESET =  3'd0;
149
 
150
//=============================================================================
151
// Enable Value (Active High)
152
//=============================================================================
153
localparam ENABLE  = 1'b1;
154
localparam DISABLE = 1'b0;
155
 
156
//=============================================================================
157
// FSM STATES
158
//=============================================================================
159
localparam IDLE   = 3'd0;
160
localparam INPUT  = 3'd1;
161
localparam START  = 3'd2;
162
localparam WAIT   = 3'd3;
163
localparam OUTPUT = 3'd4;
164
 
165
reg [31:0] bus_out;
166
reg [31:0] bus_out_mux;
167
reg cnt_en;
168
reg enable_clear;
169
reg access_permission;
170
reg first_block_set;
171
reg first_block_clear;
172
wire [1:0] mode_in;
173
wire [1:0] chmod_in;
174
wire write_en;
175
wire read_en;
176
wire dma_out_en;
177
wire dma_in_en;
178
wire err_ie;
179
wire ccf_ie;
180
wire errc;
181
wire ccfc;
182
wire aes_cr_wr_en;
183
wire wr_err_en;
184
wire rd_err_en;
185
wire write_completed;
186
wire read_completed;
187
wire key_deriv;
188
 
189
 
190
reg [10:0] aes_cr;
191
reg wr_err;
192
reg rd_err;
193
reg ccf;
194
reg [2:0] state, next_state;
195
reg [1:0] cnt;
196
reg dma_req;
197
 
198
// Write and read enable signals
199
assign write_en = PSEL & PENABLE & PWRITE;
200
assign read_en  = PSEL & ~PWRITE;
201
 
202
// Configuration Register Logic
203
assign dma_out_en = aes_cr[10];
204
assign dma_in_en  = aes_cr[9];
205
assign err_ie     = aes_cr[8];
206
assign ccf_ie     = aes_cr[7];
207
assign errc       = PWDATA[8];
208
assign ccfc       = PWDATA[7];
209
assign chmod      = aes_cr[6:5];
210
assign mode       = aes_cr[4:3];
211
assign data_type  = aes_cr[2:1];
212
assign enable     = aes_cr[0];
213
 
214
assign aes_cr_wr_en = (PADDR == AES_CR) & write_en;
215
assign mode_in  = PWDATA[4:3];
216
assign chmod_in = PWDATA[6:5];
217
 
218
always @(posedge PCLK, negedge PRESETn)
219
        begin
220
                if(!PRESETn)
221
                        aes_cr <= AES_CR_RESET;
222
                else
223
                        begin
224
                                if(enable_clear)
225
                                        aes_cr[0] <= 1'b0;
226
                                else
227
                                        if(aes_cr_wr_en)
228
                                                aes_cr[0] <= PWDATA[0];
229
 
230
                                if(aes_cr_wr_en && access_permission)
231
                                        begin
232
                                                aes_cr[2:1] <= PWDATA[2:1];
233
                                                if(mode_in == DECRYP_W_DERIV && chmod_in == CTR)
234
                                                        aes_cr[4:3] <= DECRYPTION;
235
                                                else
236
                                                        aes_cr[4:3] <= mode_in;
237
                                                aes_cr[ 6:5] <= PWDATA[6:5];
238
                                                aes_cr[10:7] <= PWDATA[12:9];
239
                                        end
240
                        end
241
        end
242
 
243
// Status Register Logic
244
assign aes_sr_wr_en = (PADDR == AES_SR) & write_en & access_permission;
245
 
246
always @(posedge PCLK, negedge PRESETn)
247
        begin
248
                if(!PRESETn)
249
                        {wr_err, rd_err, ccf} <= AES_SR_RESET;
250
                else
251
                        begin
252
                                // Write Error Flag
253
                                if(wr_err_en)
254
                                        wr_err <= 1'b1;
255
                                else
256
                                        if(errc && aes_cr_wr_en && access_permission)
257
                                                wr_err <= 1'b0;
258
 
259
                                //Read Error Flag
260
                                if(rd_err_en)
261
                                        rd_err <= 1'b1;
262
                                else
263
                                        if(errc && aes_cr_wr_en && access_permission)
264
                                                rd_err <= 1'b0;
265
 
266
                                // Computation Complete Flag
267
                                if(ccf_set)
268
                                        ccf <= 1'b1;
269
                                else
270
                                        if(ccfc && aes_cr_wr_en)// && access_permission)
271
                                                ccf <= 1'b0;
272
                        end
273
        end
274
// Interruption on erros Signals
275
assign int_ccf = ccf_ie & ccf_set;
276
assign int_err = (wr_err_en | rd_err_en) & err_ie;
277
 
278
// Key Signals Decoding
279
assign key_en = (4'b1000 >> PADDR[1:0]) & {4{(~PADDR[3] & PADDR[2] & access_permission & write_en)}};
280
assign key_sel = ~PADDR[1:0] & {2{(PADDR[2] & access_permission)}};
281
 
282
// IV Signals Decoding
283
assign iv_sel = (4'b1000 >> PADDR[1:0]) & {4{(PADDR[3] & ~PADDR[2] & access_permission)}};
284
assign iv_en = iv_sel & {4{write_en}};
285
 
286
// State Register
287
always @(posedge PCLK, negedge PRESETn)
288
        begin
289
                if(!PRESETn)
290
                        state <= IDLE;
291
                else
292
                        if(!enable)
293
                                state <= IDLE;
294
                        else
295
                                state <= next_state;
296
        end
297
 
298
assign write_completed = (cnt == 2'b11);
299
assign read_completed  = (cnt == 2'b11);
300
assign key_deriv = (mode == KEY_DERIVATION);
301
 
302
// Next State Logic
303
always @(*)
304
        begin
305
                next_state = state;
306
                case(state)
307
                IDLE  :
308
                        begin
309
                                if(enable)
310
                                        next_state = (key_deriv) ? START : INPUT;
311
                        end
312
                INPUT :
313
                        next_state = (write_completed && cnt_en) ? START : INPUT;
314
                START :
315
                        next_state = WAIT;
316
                WAIT  :
317
                        begin
318
                                if(ccf_set)
319
                                        next_state = (key_deriv) ? IDLE : OUTPUT;
320
                        end
321
                OUTPUT:
322
                        next_state = (read_completed && cnt_en) ? INPUT : OUTPUT;
323
                endcase
324
        end
325
 
326
// Output Logic
327
assign disable_core = ~enable;
328
 
329
always @(*)
330
        begin
331
                access_permission = DISABLE;
332
                start_core = DISABLE;
333
                cnt_en = DISABLE;
334
                enable_clear = DISABLE;
335
                first_block_set = DISABLE;
336
                first_block_clear = DISABLE;
337
                case(state)
338
                        IDLE:
339
                                begin
340
                                        access_permission = ENABLE;
341
                                        first_block_set = ENABLE;
342
                                        if(enable && !key_deriv)
343
                                                cnt_en = ENABLE;
344
                                end
345
                        INPUT:
346
                                begin
347
                                        if(PADDR == AES_DINR && write_en)
348
                                                cnt_en = ENABLE;
349
                                end
350
                        START:
351
                                begin
352
                                        start_core = ENABLE;
353
                                end
354
                        WAIT:
355
                                begin
356
                                        if(ccf_set)
357
                                                cnt_en = ENABLE;
358
                                        if(ccf_set && key_deriv)
359
                                                enable_clear = ENABLE;
360
                                end
361
                        OUTPUT:
362
                                begin
363
                                        first_block_clear = ENABLE;
364
                                        if(PADDR == AES_DOUTR && read_en && PENABLE )//|| write_completed)
365
                                                cnt_en = ENABLE;
366
                                end
367
                endcase
368
        end
369
 
370
// First Block Signal indicates when IV register is used
371
always @(posedge PCLK, negedge PRESETn)
372
        begin
373
                if(!PRESETn)
374
                        first_block <= 1'b1;
375
                else
376
                        if(first_block_set)
377
                                first_block <= 1'b1;
378
                        else
379
                                if(first_block_clear)
380
                                        first_block <= 1'b0;
381
        end
382
 
383
always @(posedge PCLK, negedge PRESETn)
384
        begin
385
                if(!PRESETn)
386
                        cnt <= 2'b11;
387
                else
388
                        begin
389
                                if(!enable || state == START)
390
                                        cnt <= 2'b11;
391
                                else
392
                                        if(cnt_en)
393
                                                cnt <= cnt + 1'b1;
394
                        end
395
        end
396
 
397
assign col_addr = cnt;
398
assign col_wr_en = (PADDR == AES_DINR  && write_en && state == INPUT);
399
assign col_rd_en = (PADDR == AES_DOUTR && read_en  && state == OUTPUT);
400
assign wr_err_en = (PADDR == AES_DINR  && write_en && (state != INPUT  && state != IDLE));
401
assign rd_err_en = (PADDR == AES_DOUTR && read_en  && (state != OUTPUT && state != IDLE));
402
 
403
// DMA Requests Logic
404
always @(posedge PCLK, negedge PRESETn)
405
        begin
406
                if(!PRESETn)
407
                        dma_req <= 0;
408
                else
409
                        dma_req <= cnt[0];
410
        end
411
 
412
assign dma_req_wr = (dma_req ^ cnt[0]) & dma_in_en  & enable & (state == INPUT  || state == IDLE);
413
assign dma_req_rd = (dma_req ^ cnt[0]) & dma_out_en & enable & (state == OUTPUT);
414
 
415
// APB Read Signal
416
assign PRDATA = bus_out;
417
 
418
// Output Mux
419
always @(*)
420
        begin
421
                bus_out_mux = 32'd0;
422
                case(PADDR)
423
                        AES_CR:
424
                                bus_out_mux = {{19{1'b0}}, aes_cr[10:7], 2'b00, aes_cr[6:0]};
425
                        AES_SR:
426
                                bus_out_mux = {{29{1'b0}}, wr_err, rd_err, ccf};
427
                        AES_DINR, AES_DOUTR:
428
                                bus_out_mux = col_bus;
429
                        AES_KEYR0, AES_KEYR1, AES_KEYR2, AES_KEYR3:
430
                                bus_out_mux = key_bus;
431
                        AES_IVR0, AES_IVR1, AES_IVR2, AES_IVR3:
432
                                if(!enable)
433
                                        bus_out_mux = iv_bus;
434
                endcase
435
        end
436
 
437
// The output Bus is registered
438
always @(posedge PCLK, negedge PRESETn)
439
        begin
440
                if(!PRESETn)
441
                        bus_out <= 32'd0;
442
                else
443
                        if(read_en)
444
                                bus_out <= bus_out_mux;
445
        end
446
 
447
endmodule

powered by: WebSVN 2.1.0

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