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 3

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

powered by: WebSVN 2.1.0

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