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

Subversion Repositories rsa_512

[/] [rsa_512/] [trunk/] [rtl/] [rsa_top.vhd] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 jcastillo
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:    16:01:04 12/13/2009 
6
-- Design Name: 
7
-- Module Name:    rsa_top - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description: 
12
--
13
-- Dependencies: 
14
--
15
-- Revision: 
16
-- Revision 0.01 - File Created
17
-- Additional Comments: 
18
--
19
----------------------------------------------------------------------------------
20
library IEEE;
21
use IEEE.STD_LOGIC_1164.all;
22
use IEEE.STD_LOGIC_ARITH.all;
23
use IEEE.STD_LOGIC_UNSIGNED.all;
24
-- synthesis translate_off
25
library UNISIM;
26
use UNISIM.VCOMPONENTS.all;
27
-- synthesis translate_on
28
 
29
---- Uncomment the following library declaration if instantiating
30
---- any Xilinx primitives in this code.
31
--library UNISIM;
32
--use UNISIM.VComponents.all;
33
 
34
entity rsa_top is
35
  port(
36
    clk       : in  std_logic;
37
    reset     : in  std_logic;
38
    valid_in  : in  std_logic;
39 9 jcastillo
    start_in  : in  std_logic;
40 3 jcastillo
    x         : in  std_logic_vector(15 downto 0);  -- estos 3 son x^y mod m
41
    y         : in  std_logic_vector(15 downto 0);
42
    m         : in  std_logic_vector(15 downto 0);
43
    r_c       : in  std_logic_vector(15 downto 0);  --constante de montgomery r^2 mod m
44
    s         : out std_logic_vector( 15 downto 0);
45
    valid_out : out std_logic;
46
    bit_size  : in  std_logic_vector(15 downto 0)  --tamano bit del exponente y (log2(y))
47
    );
48
end rsa_top;
49
 
50
architecture Behavioral of rsa_top is
51
 
52 9 jcastillo
  component n_c_core
53
    port (clk   : in  std_logic;
54
          m_lsw : in  std_logic_vector(15 downto 0);
55
          ce    : in  std_logic;
56
          n_c   : out std_logic_vector(15 downto 0);
57
          done  : out std_logic
58
          );
59
  end component;
60 3 jcastillo
 
61
--Multiplicador de Montgomery que sera instanciado 2 veces
62 9 jcastillo
  component montgomery_mult
63
    port(
64
      clk       : in  std_logic;
65
      reset     : in  std_logic;
66
      valid_in  : in  std_logic;
67
      a         : in  std_logic_vector(15 downto 0);
68
      b         : in  std_logic_vector(15 downto 0);
69
      n         : in  std_logic_vector(15 downto 0);
70
      s_prev    : in  std_logic_vector(15 downto 0);
71
      n_c       : in  std_logic_vector(15 downto 0);
72
      s         : out std_logic_vector( 15 downto 0);
73
      valid_out : out std_logic         -- es le valid out TODO : cambiar nombre
74
      );
75 3 jcastillo
  end component;
76
 
77
--Memoria para guardar el exponente y el modulo
78
  component Mem_b
79
    port (
80
      clka  : in  std_logic;
81
      wea   : in  std_logic_vector(0 downto 0);
82
      addra : in  std_logic_vector(5 downto 0);
83
      dina  : in  std_logic_vector(15 downto 0);
84
      douta : out std_logic_vector(15 downto 0));
85
  end component;
86
 
87
 
88
--fifos para los resultados de las mult parciales
89
  component res_out_fifo
90
    port (
91
      clk   : in  std_logic;
92
      rst   : in  std_logic;
93
      din   : in  std_logic_vector(31 downto 0);
94
      wr_en : in  std_logic;
95
      rd_en : in  std_logic;
96
      dout  : out std_logic_vector(31 downto 0);
97
      full  : out std_logic;
98
      empty : out std_logic);
99
  end component;
100
 
101
 
102
  signal valid_in_mon_1, valid_in_mon_2, valid_out_mon_1, valid_out_mon_2, fifo_1_rd, fifo_1_wr : std_logic;
103
 
104
  signal a_mon_1, b_mon_1, n_mon_1, s_p_mon_1, s_out_mon_1, a_mon_2, b_mon_2, n_mon_2, s_p_mon_2, s_out_mon_2, fifo_1_in, fifo_2_in, fifo_1_out, exp_out, n_out : std_logic_vector(15 downto 0);
105
 
106
  signal fifo_out, fifo_in : std_logic_vector(31 downto 0);
107
 
108
  signal addr_exp, addr_n, next_addr_exp, next_addr_n : std_logic_vector(5 downto 0);
109
 
110
  type state_type is (wait_start, prepare_data, wait_constants, writting_cts_fifo, processing_data_0, processing_data_1, wait_results, transition, prepare_next, writting_results, final_mult, show_final, prepare_final, wait_final);
111
  signal state, next_state                                            : state_type;
112
  signal w_numb, next_w_numb                                          : std_logic_vector(7 downto 0);
113
--Señales registradas
114
  signal n_c_reg, next_n_c_reg                                        : std_logic_vector(15 downto 0);
115
  --Cuenta los datos que se van metiendo al multiplicador para generar el padding por si solo.
116
  signal count_input, next_count_input, bit_counter, next_bit_counter : std_logic_vector(15 downto 0);
117
 
118
  signal bsize_reg, next_bsize_reg : std_logic_vector (15 downto 0);
119
  signal write_b_n                 : std_logic_vector(0 downto 0);
120
 
121 9 jcastillo
  signal n_c_o    : std_logic_vector(15 downto 0);
122
  signal n_c      : std_logic_vector(15 downto 0);
123
  signal n_c_load : std_logic;
124
 
125 3 jcastillo
begin
126
 
127 9 jcastillo
  n_c1 : n_c_core
128
    port map (
129
      clk   => clk,
130
      m_lsw => m,
131
      ce    => start_in,
132
      n_c   => n_c_o,
133
      done  => n_c_load
134
      );
135 3 jcastillo
 
136 9 jcastillo
 
137 3 jcastillo
  mon_1 : montgomery_mult port map(
138
    clk       => clk,
139
    reset     => reset,
140
    valid_in  => valid_in_mon_1,
141
    a         => a_mon_1,
142
    b         => b_mon_1,
143
    n         => n_mon_1,
144
    s_prev    => s_p_mon_1,
145
    n_c       => n_c_reg,
146
    s         => s_out_mon_1,
147
    valid_out => valid_out_mon_1
148
    );
149
 
150
  mon_2 : montgomery_mult port map(
151
    clk       => clk,
152
    reset     => reset,
153
    valid_in  => valid_in_mon_2,
154
    a         => a_mon_2,
155
    b         => b_mon_2,
156
    n         => n_mon_2,
157
    s_prev    => s_p_mon_2,
158
    n_c       => n_c_reg,
159
    s         => s_out_mon_2,
160
    valid_out => valid_out_mon_2
161
    );
162
 
163
 
164
  fifo_mon_out : res_out_fifo
165
    port map (
166
      clk   => clk,
167
      rst   => reset,
168
      din   => fifo_in,
169
      wr_en => fifo_1_wr,
170
      rd_en => fifo_1_rd,
171
      dout  => fifo_out
172
      );
173
 
174
  exp : Mem_b port map (
175
    clka  => clk,
176
    wea   => write_b_n,
177
    addra => addr_exp,
178
    dina  => y,
179
    douta => exp_out);
180
 
181
  n_mod : Mem_b port map (
182
    clka  => clk,
183
    wea   => write_b_n,
184
    addra => addr_n,
185
    dina  => m,
186
    douta => n_out);
187
 
188
 
189
 
190
  process(clk, reset)
191
  begin
192
 
193
    if(clk = '1' and clk'event) then
194
 
195
      if(reset = '1')then
196
        state       <= wait_start;
197
        n_c_reg     <= (others => '0');
198
        w_numb      <= (others => '0');
199
        count_input <= (others => '0');
200
        addr_exp    <= (others => '0');
201
        addr_n      <= (others => '0');
202
        bit_counter <= (others => '0');
203
        bsize_reg   <= (others => '0');
204 9 jcastillo
        n_c         <= (others => '0');
205
 
206 3 jcastillo
      else
207 9 jcastillo
        if(n_c_load = '1') then
208
          n_c       <= n_c_o;
209
        end if;
210 3 jcastillo
        state       <= next_state;
211
        n_c_reg     <= next_n_c_reg;
212
        w_numb      <= next_w_numb;
213
        count_input <= next_count_input;
214
        addr_exp    <= next_addr_exp;
215
        addr_n      <= next_addr_n;
216
        bit_counter <= next_bit_counter;
217
        bsize_reg   <= next_bsize_reg;
218
      end if;
219
    end if;
220
  end process;
221
 
222
  process(state, bsize_reg, n_c_reg, valid_in, x, n_c, r_c, m, y, w_numb, count_input, addr_exp, addr_n, s_out_mon_1, s_out_mon_2, bit_size, valid_out_mon_1, bit_counter, exp_out, fifo_out, n_out)
223
 
224
    variable mask : std_logic_vector(3 downto 0);
225
 
226
  begin
227
 
228
    --Registers update
229
    next_state       <= state;
230
    next_n_c_reg     <= n_c_reg;
231
    next_w_numb      <= w_numb;
232
    next_count_input <= count_input;
233
    next_bsize_reg   <= bsize_reg;
234
    --Entradas de los montgomerys.
235
    valid_in_mon_1   <= '0';
236
    valid_in_mon_2   <= '0';
237
    a_mon_1          <= (others => '0');
238
    b_mon_1          <= (others => '0');
239
    n_mon_1          <= (others => '0');
240
    a_mon_2          <= (others => '0');
241
    b_mon_2          <= (others => '0');
242
    n_mon_2          <= (others => '0');
243
    s_p_mon_1        <= (others => '0');
244
    s_p_mon_2        <= (others => '0');
245
    --Control de las fifos
246
    fifo_1_rd        <= '0';
247
    fifo_in          <= (others => '0');
248
    fifo_1_wr        <= '0';
249
    --Control de memorias de exp y modulo
250
    write_b_n        <= b"0";
251
    next_addr_exp    <= addr_exp;
252
    next_addr_n      <= addr_n;
253
    next_bit_counter <= bit_counter;
254
    --Outputs
255
    valid_out        <= '0';
256
    s                <= (others => '0');
257
    case state is
258
 
259
      when wait_start =>
260
 
261
        valid_in_mon_1 <= valid_in;
262
        valid_in_mon_2 <= valid_in;
263
        if(valid_in = '1') then
264
          a_mon_1      <= x;
265
          b_mon_1      <= r_c;
266
          n_mon_1      <= m;
267
 
268
          a_mon_2          <= x"0001";
269
          b_mon_2          <= r_c;
270
          n_mon_2          <= m;
271
          next_w_numb      <= x"23";    --Se extiende en 3 para poder usar las multiplicaciones modulares
272
          next_n_c_reg     <= n_c;
273
          next_state       <= prepare_data;
274
          next_count_input <= x"0001";
275
 
276
          write_b_n      <= b"1";       --Notificamos que hay que guardar el exponente y modulo
277
          next_addr_exp  <= "000001";
278
          next_addr_n    <= "000001";
279
          next_bsize_reg <= bit_size-1;
280
        end if;
281
 
282
      when prepare_data =>
283
        next_count_input <= count_input+1;
284
        valid_in_mon_1   <= '1';
285
        valid_in_mon_2   <= '1';
286
        --Esto es solo mientras los datos en la entrada son validos, cuando no lo son
287
        --se meten 0s para la extension de 3 palabras en los montgomerys
288
        if(valid_in = '1') then
289
          a_mon_1        <= x;
290
          b_mon_1        <= r_c;
291
          n_mon_1        <= m;
292
          b_mon_2        <= r_c;
293
          n_mon_2        <= m;
294
 
295
          write_b_n     <= b"1";
296
          next_addr_exp <= addr_exp+1;
297
          next_addr_n   <= addr_n+1;
298
        end if;
299
        if(count_input = w_numb) then
300
          next_state    <= wait_constants;
301
          next_addr_n   <= (others => '0');
302
 
303
          next_addr_exp                                                    <= bsize_reg(9 downto 4);
304
                                        --Decodificador para establecer la mascara
305
          mask := bsize_reg(3 downto 0);
306
          case (mask) is
307
            when "0000"                                => next_bit_counter <= "0000000000000001";
308
            when "0001"                                => next_bit_counter <= "0000000000000010";
309
            when "0010"                                => next_bit_counter <= "0000000000000100";
310
            when "0011"                                => next_bit_counter <= "0000000000001000";
311
            when "0100"                                => next_bit_counter <= "0000000000010000";
312
            when "0101"                                => next_bit_counter <= "0000000000100000";
313
            when "0110"                                => next_bit_counter <= "0000000001000000";
314
            when "0111"                                => next_bit_counter <= "0000000010000000";
315
            when "1000"                                => next_bit_counter <= "0000000100000000";
316
            when "1001"                                => next_bit_counter <= "0000001000000000";
317
            when "1010"                                => next_bit_counter <= "0000010000000000";
318
            when "1011"                                => next_bit_counter <= "0000100000000000";
319
            when "1100"                                => next_bit_counter <= "0001000000000000";
320
            when "1101"                                => next_bit_counter <= "0010000000000000";
321
            when "1110"                                => next_bit_counter <= "0100000000000000";
322
            when "1111"                                => next_bit_counter <= "1000000000000000";
323
            when others                                =>
324
          end case;
325
          next_count_input                                                 <= (others => '0');
326
        end if;
327
 
328
        --Esperamos los valores validos de la salida de los montgomery                  
329
      when wait_constants =>
330
 
331
        --Comienzo a escribir en la fifo de datos
332
        if(valid_out_mon_1 = '1') then
333
          fifo_1_wr        <= '1';
334
          fifo_in          <= s_out_mon_1 & s_out_mon_2;
335
          next_count_input <= count_input+1;
336
          next_state       <= writting_cts_fifo;
337
        end if;
338
 
339
        --Escribimos las dos constantes iniciales en las fifos
340
      when writting_cts_fifo =>
341
        fifo_1_wr        <= valid_out_mon_1;
342
        next_count_input <= count_input+1;
343
        if(count_input < x"20") then
344
          fifo_in        <= s_out_mon_1 & s_out_mon_2;
345
        end if;
346
 
347
        --Pedimos el siguiente input para la multiplicacion
348
        if(valid_out_mon_1 = '0') then
349
          next_count_input <= (others => '0');
350
          next_state       <= transition;
351
        end if;
352
 
353
      when transition =>
354
 
355
        next_count_input <= count_input+1;
356
 
357
        if(count_input > 2) then
358
          next_count_input <= (others => '0');
359
                                        --fifo_1_rd <= '1';
360
                                        --next_addr_n <= addr_n+1;
361
          if((bit_counter and exp_out) = x"0000") then
362
            next_state     <= processing_data_0;
363
          else
364
            next_state     <= processing_data_1;
365
          end if;
366
 
367
        end if;
368
 
369
        --se van ejecutando las multiplicaciones sucesivas
370
      when processing_data_1 =>
371
 
372
 
373
        if(count_input > x"0000")then
374
          valid_in_mon_1 <= '1';
375
          valid_in_mon_2 <= '1';
376
        end if;
377
 
378
 
379
        fifo_1_rd <= '1';
380
 
381
        a_mon_1 <= fifo_out(31 downto 16);
382
        b_mon_1 <= fifo_out(15 downto 0);
383
        n_mon_1 <= n_out;
384
 
385
        a_mon_2 <= fifo_out(31 downto 16);
386
        b_mon_2 <= fifo_out(31 downto 16);
387
        n_mon_2 <= n_out;
388
 
389
        next_addr_n      <= addr_n+1;
390
        next_count_input <= count_input +1;
391
 
392
        --Cuando llego al final cambio de estado a esperar resultados
393
        if(count_input = w_numb) then
394
          next_state <= wait_results;
395
        end if;
396
 
397
      when processing_data_0 =>
398
 
399
        if(count_input > x"0000")then
400
          valid_in_mon_1 <= '1';
401
          valid_in_mon_2 <= '1';
402
        end if;
403
 
404
        fifo_1_rd <= '1';
405
 
406
        a_mon_1 <= fifo_out(15 downto 0);
407
        b_mon_1 <= fifo_out(15 downto 0);
408
        n_mon_1 <= n_out;
409
 
410
        a_mon_2 <= fifo_out(31 downto 16);
411
        b_mon_2 <= fifo_out(15 downto 0);
412
        n_mon_2 <= n_out;
413
 
414
        next_addr_n      <= addr_n+1;
415
        next_count_input <= count_input +1;
416
 
417
        --Cuando llego al final cambio de estado a esperar resultados
418
        if(count_input = w_numb) then
419
          next_state       <= wait_results;
420
          next_count_input <= (others => '0');
421
        end if;
422
 
423
      when wait_results =>
424
 
425
        --Comienzo a escribir en la fifo de datos
426
        if(valid_out_mon_1 = '1') then
427
          fifo_1_wr        <= '1';
428
          fifo_in          <= s_out_mon_2 & s_out_mon_1;
429
          next_count_input <= x"0001";
430
          next_state       <= writting_results;
431
        end if;
432
 
433
      when writting_results =>
434
 
435
        next_addr_n      <= (others => '0');
436
        fifo_1_wr        <= valid_out_mon_1;
437
        next_count_input <= count_input+1;
438
        if(count_input < x"20") then
439
          fifo_in        <= s_out_mon_2 & s_out_mon_1;
440
        end if;
441
 
442
        --Pedimos el siguiente input para la multiplicacion
443
        if(valid_out_mon_1 = '0') then
444
          next_count_input   <= (others => '0');
445
          next_state         <= prepare_next;
446
                                        --Calculo del siguiente bit del exponente
447
                                        --Shifto uno la mascara
448
          next_bit_counter   <= '0'&bit_counter(15 downto 1);
449
          if(bit_counter = x"0001")
450
          then
451
            next_addr_exp    <= addr_exp -1;
452
            next_bit_counter <= "1000000000000000";
453
          end if;
454
          if((bit_counter = x"0001") and addr_exp = "000000000")
455
          then
456 9 jcastillo
            next_state       <= final_mult;
457 3 jcastillo
            next_count_input <= (others => '0');
458 9 jcastillo
            next_addr_exp    <= (others => '0');
459 3 jcastillo
          end if;
460
        end if;
461 9 jcastillo
 
462
      when prepare_next             =>
463
        next_state       <= transition;
464 3 jcastillo
        next_count_input <= (others => '0');
465 9 jcastillo
        fifo_1_rd        <= '0';
466
 
467 3 jcastillo
      when final_mult =>
468
        next_count_input <= count_input+1;
469 9 jcastillo
 
470 3 jcastillo
        if(count_input > 2) then
471
          next_count_input <= (others => '0');
472 9 jcastillo
          next_state       <= prepare_final;
473 3 jcastillo
        end if;
474 9 jcastillo
 
475 3 jcastillo
      when prepare_final =>
476 9 jcastillo
 
477 3 jcastillo
        if(count_input > x"0000")then
478
          valid_in_mon_1 <= '1';
479
        end if;
480 9 jcastillo
 
481 3 jcastillo
        fifo_1_rd <= '1';
482 9 jcastillo
 
483
        a_mon_1   <= fifo_out(15 downto 0);
484 3 jcastillo
        if(count_input = x"0001") then
485
          b_mon_1 <= x"0001";
486
        end if;
487 9 jcastillo
        n_mon_1   <= n_out;
488
 
489
        next_addr_n      <= addr_n+1;
490 3 jcastillo
        next_count_input <= count_input +1;
491 9 jcastillo
 
492 3 jcastillo
        --Cuando llego al final cambio de estado a esperar resultados
493
        if(count_input = w_numb) then
494 9 jcastillo
          next_state       <= wait_final;
495
          next_count_input <= (others => '0');
496 3 jcastillo
        end if;
497 9 jcastillo
 
498 3 jcastillo
      when wait_final =>
499 9 jcastillo
 
500 3 jcastillo
        if(valid_out_mon_1 = '1') then
501 9 jcastillo
          valid_out        <= '1';
502
          s                <= s_out_mon_1;
503
          next_state       <= show_final;
504 3 jcastillo
          next_count_input <= count_input +1;
505
        end if;
506 9 jcastillo
 
507 3 jcastillo
      when show_final =>
508 9 jcastillo
        valid_out        <= '1';
509
        s                <= s_out_mon_1;
510 3 jcastillo
        next_count_input <= count_input +1;
511
        --Cuando llego al final cambio de estado a esperar resultados
512
        if(count_input = x"20") then
513 9 jcastillo
          valid_out      <= '0';
514
          next_state     <= wait_start;
515 3 jcastillo
        end if;
516 9 jcastillo
 
517 3 jcastillo
    end case;
518 9 jcastillo
 
519 3 jcastillo
  end process;
520
 
521
end Behavioral;
522
 

powered by: WebSVN 2.1.0

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