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

Subversion Repositories mod_mult_exp

[/] [mod_mult_exp/] [trunk/] [rtl/] [vhdl/] [mod_exp/] [ModExpSM.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 gajos
-----------------------------------------------------------------------
2
----                                                               ----
3
---- Montgomery modular multiplier and exponentiator               ----
4
----                                                               ----
5
---- This file is part of the Montgomery modular multiplier        ----
6
---- and exponentiator project                                     ----
7
---- http://opencores.org/project,mod_mult_exp                     ----
8
----                                                               ----
9
---- Description:                                                  ----
10
----   This is state machine of the Montgomery modular             ----
11
----   exponentiator. It controls all the registers, block memory  ----
12
----   and the exponentiation process.                             ----
13
----                                                               ----
14
---- To Do:                                                        ----
15
----   Description                                                 ----
16
---- Author(s):                                                    ----
17
---- - Krzysztof Gajewski, gajos@opencores.org                     ----
18
----                       k.gajewski@gmail.com                    ----
19
----                                                               ----
20
-----------------------------------------------------------------------
21
----                                                               ----
22
---- Copyright (C) 2014 Authors and OPENCORES.ORG                  ----
23
----                                                               ----
24
---- This source file may be used and distributed without          ----
25
---- restriction provided that this copyright statement is not     ----
26
---- removed from the file and that any derivative work contains   ----
27
---- the original copyright notice and the associated disclaimer.  ----
28
----                                                               ----
29
---- This source file is free software; you can redistribute it    ----
30
---- and-or modify it under the terms of the GNU Lesser General    ----
31
---- Public License as published by the Free Software Foundation;  ----
32
---- either version 2.1 of the License, or (at your option) any    ----
33
---- later version.                                                ----
34
----                                                               ----
35
---- This source is distributed in the hope that it will be        ----
36
---- useful, but WITHOUT ANY WARRANTY; without even the implied    ----
37
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR       ----
38
---- PURPOSE. See the GNU Lesser General Public License for more   ----
39
---- details.                                                      ----
40
----                                                               ----
41
---- You should have received a copy of the GNU Lesser General     ----
42
---- Public License along with this source; if not, download it    ----
43
---- from http://www.opencores.org/lgpl.shtml                      ----
44
----                                                               ----
45
-----------------------------------------------------------------------
46
library IEEE;
47
use work.properties.ALL;
48
use IEEE.STD_LOGIC_1164.ALL;
49
use IEEE.STD_LOGIC_UNSIGNED.ALL;
50
use IEEE.NUMERIC_STD.ALL;
51
 
52
-- Uncomment the following library declaration if using
53
-- arithmetic functions with Signed or Unsigned values
54
--use IEEE.NUMERIC_STD.ALL;
55
 
56
-- Uncomment the following library declaration if instantiating
57
-- any Xilinx primitives in this code.
58
--library UNISIM;
59
--use UNISIM.VComponents.all;
60
 
61
entity ModExpSM is
62
    generic(
63
        word_size   : integer := WORD_LENGTH;
64
        word_binary : integer := WORD_INTEGER
65
    );
66
    port (
67
        data_in_ready  : in  STD_LOGIC;
68
        clk            : in  STD_LOGIC;
69
        exp_ctrl       : in  STD_LOGIC_VECTOR(2 downto 0);
70
        reset          : in  STD_LOGIC;
71
        in_mux_control : out STD_LOGIC_VECTOR(1 downto 0);
72
        -- finalizer end status
73
        ready          : out STD_LOGIC;
74
        -- control for multiplier
75
        modMultStart   : out STD_LOGIC;
76
        modMultReady   : in  STD_LOGIC;
77
        -- control for memory and registers
78
        addr_dataA     : out STD_LOGIC_VECTOR(3 downto 0);
79
        addr_dataB     : out STD_LOGIC_VECTOR(3 downto 0);
80
        regData_EnA    : out STD_LOGIC_vector(0 downto 0);
81
        regData_EnB    : out STD_LOGIC_vector(0 downto 0);
82
        regData_EnC    : out STD_LOGIC;
83
        regData_EnExponent   : out STD_LOGIC;
84
        ExponentData         : in  STD_LOGIC_VECTOR(word_size - 1 downto 0);
85
        memory_reset   : out std_logic
86
         );
87
end ModExpSM;
88
 
89
architecture Behavioral of ModExpSM is
90
 
91
-- Enable signals for registers and block memory
92
signal regDataEnA  : STD_LOGIC_vector(0 downto 0);
93
signal regDataEnB  : STD_LOGIC_vector(0 downto 0);
94
signal regDataEnC  : STD_LOGIC;
95
signal regDataEnD2 : STD_LOGIC;
96
 
97
-- states data 
98
signal state      : exponentiator_states;
99
signal next_state : exponentiator_states;
100
 
101
-- addres data for block memory ''registers''
102
signal addr_reg_A : STD_LOGIC_VECTOR(3 downto 0);
103
signal addr_reg_B : STD_LOGIC_VECTOR(3 downto 0);
104
 
105
-- signal informing about first exponentiation in given word
106
signal first_exp  : STD_LOGIC;
107
 
108
-- signal for counting the iterations during exponentiation
109
signal position_counter : std_logic_vector(word_binary downto 0);
110
 
111
begin
112
    -- signals assigment
113
        regData_EnA <= regDataEnA;
114
        regData_EnB <= regDataEnB;
115
        regData_EnC <= regDataEnC;
116
        regData_EnExponent <= regDataEnD2;
117
        addr_dataA <= addr_reg_A;
118
        addr_dataB <= addr_reg_B;
119
 
120
    -- State machine process
121
    SM : process(data_in_ready, exp_ctrl, modMultReady, state, position_counter)
122
        begin
123
            case state is
124
                when FIRST_RUN =>
125
                    -- Preparing the core before the exponentiation
126
                    in_mux_control <= "10";
127
                    ready          <= '0';
128
                    modMultStart   <= '0';
129
                    regDataEnA <= "0";
130
                    regDataEnB <= "0";
131
                    regDataEnC <= '0';
132
                    regDataEnD2 <= '0';
133
                    addr_reg_A <= addr_unused;
134
                    addr_reg_B <= addr_unused;
135
                    first_exp <= '1';
136
                    next_state <= NOP;
137
                                -- ''No operation'' during waiting  for the command and suitable data
138
                when NOP =>
139
                    in_mux_control <= "11";
140
                    ready          <= '0';
141
                    modMultStart   <= '0';
142
                    first_exp <= '1';
143
                    regDataEnA <= "1";
144
                    regDataEnB <= "1";
145
                    regDataEnC <= '0';
146
                    regDataEnD2 <= '0';
147
                    -- Read base 
148
                    if (exp_ctrl = mn_read_base) and (data_in_ready = '1') then
149
                        addr_reg_A <= addr_base;
150
                        addr_reg_B <= addr_base;
151
                        next_state <= READ_DATA_BASE;
152
                    -- Read modulus
153
                    elsif (exp_ctrl = mn_read_modulus) and (data_in_ready = '1') then
154
                        regDataEnC <= '1';
155
                        addr_reg_A <= addr_modulus;
156
                        addr_reg_B <= addr_modulus;
157
                        next_state <= READ_DATA_MODULUS;
158
                    -- Read exponent
159
                    elsif (exp_ctrl = mn_read_exponent) and (data_in_ready = '1') then
160
                        regDataEnD2 <= '1';
161
                        addr_reg_A <= addr_exponent;
162
                        addr_reg_B <= addr_exponent;
163
                        next_state <= READ_DATA_EXPONENT;
164
                    -- Read residuum
165
                    elsif (exp_ctrl = mn_read_residuum) and (data_in_ready = '1') then
166
                        addr_reg_A <= addr_residuum;
167
                        addr_reg_B <= addr_residuum;
168
                        next_state <= READ_DATA_RESIDUUM;
169
                    -- Read power
170
                    elsif (exp_ctrl = mn_count_power) then
171
                        in_mux_control <= "01";
172
                        addr_reg_A <= addr_one;
173
                        addr_reg_B <= addr_one;
174
                        next_state <= COUNT_POWER;
175
                    -- Prepare the exponentiator for the new data 
176
                    -- i.e. wrong data was readed first. More important 
177
                    -- prepare is after the exponentiation (SHOW_RESULT)
178
                    elsif (exp_ctrl = mn_prepare_for_data) then
179
                        addr_reg_A <= addr_unused;
180
                        addr_reg_B <= addr_unused;
181
                        regDataEnA <= "0";
182
                        regDataEnB <= "0";
183
                        regDataEnC <= '0';
184
                        regDataEnD2 <= '0';
185
                        next_state <= FIRST_RUN;
186
                    -- in case of unpredicted ''command'' appear
187
                    else
188
                        addr_reg_A <= addr_unused;
189
                        addr_reg_B <= addr_unused;
190
                        regDataEnA <= "0";
191
                        regDataEnB <= "0";
192
                        regDataEnC <= '0';
193
                        regDataEnD2 <= '0';
194
                        next_state <= NOP;
195
                    end if;
196
                -- ''READ'' states differs only by the addres under
197
                -- which the data are written.
198
                -- State for reading base of the exponentiation
199
                when READ_DATA_BASE =>
200
                    in_mux_control <= "11";
201
                    ready          <= '0';
202
                    modMultStart   <= '0';
203
                    addr_reg_A <= addr_base;
204
                    addr_reg_B <= addr_base;
205
                    regDataEnA <= "1";
206
                    regDataEnB <= "1";
207
                    regDataEnC <= '0';
208
                    regDataEnD2 <= '0';
209
                    next_state <= NOP;
210
                    first_exp <= '1';
211
                -- State for reading the modulus
212
                when READ_DATA_MODULUS =>
213
                    in_mux_control <= "11";
214
                    ready          <= '0';
215
                    modMultStart   <= '0';
216
                    addr_reg_A <= addr_modulus;
217
                    addr_reg_B <= addr_modulus;
218
                    regDataEnA <= "1";
219
                    regDataEnB <= "1";
220
                    regDataEnC <= '1';
221
                    regDataEnD2 <= '0';
222
                    next_state <= NOP;
223
                    first_exp <= '1';
224
                -- State for reading the exponent
225
                when READ_DATA_EXPONENT =>
226
                    in_mux_control <= "11";
227
                    ready          <= '0';
228
                    modMultStart   <= '0';
229
                    addr_reg_A <= addr_exponent;
230
                    addr_reg_B <= addr_exponent;
231
                    regDataEnA <= "1";
232
                    regDataEnB <= "1";
233
                    regDataEnC <= '0';
234
                    regDataEnD2 <= '1';
235
                    next_state <= NOP;
236
                    first_exp <= '1';
237
                -- State for reading the residuum
238
                when READ_DATA_RESIDUUM =>
239
                    in_mux_control <= "11";
240
                    ready          <= '0';
241
                    modMultStart   <= '0';
242
                    addr_reg_A <= addr_residuum;
243
                    addr_reg_B <= addr_residuum;
244
                    regDataEnA <= "1";
245
                    regDataEnB <= "1";
246
                    regDataEnC <= '0';
247
                    regDataEnD2 <= '0';
248
                    next_state <= NOP;
249
                    first_exp <= '1';
250
                -- State for preparing the system for the exponentiation
251
                -- First pre computed value ''Z'' - prepare data
252
                when COUNT_POWER =>
253
                    in_mux_control <= "10";
254
                    ready          <= '0';
255
                    modMultStart   <= '0';
256
                    regDataEnA <= "0";
257
                    regDataEnB <= "0";
258
                    regDataEnC <= '0';
259
                    regDataEnD2 <= '0';
260
                    addr_reg_A <= addr_one;
261
                    addr_reg_B <= addr_residuum;
262
                    first_exp <= '1';
263
                    next_state <= EXP_Z;
264
                -- ''Z'' multiplying - in case if it is first computation or no
265
                                -- system behaves a little bit different
266
                when EXP_Z =>
267
                    regDataEnC <= '0';
268
                    regDataEnD2 <= '0';
269
                    regDataEnD2 <= '0';
270
                    ready <= '0';
271
                    in_mux_control <= "10";
272
                    modMultStart <= '1';
273
                                        -- If end of multiplying
274
                    if (modMultReady = '1') then
275
                        addr_reg_A <= addr_z;
276
                        addr_reg_B <= addr_z;
277
                        regDataEnA <= "1";
278
                        regDataEnB <= "1";
279
                        if (first_exp = '1') then
280
                            first_exp <= '1';
281
                        else
282
                            first_exp <= '0';
283
                        end if;
284
                        next_state <= SAVE_EXP_Z;
285
                    else
286
                                            -- During first exponentiation it is ''Z precomputing''
287
                        if (first_exp = '1') then
288
                            first_exp <= '1';
289
                            addr_reg_A <= addr_one;
290
                            addr_reg_B <= addr_residuum;
291
                        -- in another case computing related with the algorithm
292
                        else
293
                            first_exp <= '0';
294
                            if (ExponentData(conv_integer(position_counter)) = '1') then
295
                                addr_reg_A <= addr_z;
296
                                addr_reg_B <= addr_p;
297
                            else
298
                                addr_reg_A <= addr_p;
299
                                addr_reg_B <= addr_p;
300
                            end if;
301
                        end if;
302
                        regDataEnA <= "0";
303
                        regDataEnB <= "0";
304
                        next_state <= EXP_Z;
305
                    end if;
306
                -- Svaing the ''Z'' calculation result
307
                when SAVE_EXP_Z =>
308
                    modMultStart <= '0';
309
                    ready <= '0';
310
                    in_mux_control <= "10";
311
                    regDataEnA <= "0";
312
                    regDataEnB <= "0";
313
                    regDataEnC <= '0';
314
                    regDataEnD2 <= '0';
315
                                        -- Preparing for the ''P'' precalculation in case first 
316
                    -- calculation of the exponentiation
317
                    if (first_exp = '1') then
318
                        first_exp <= '1';
319
                        addr_reg_A <= addr_base;
320
                        addr_reg_B <= addr_residuum;
321
                        next_state <= EXP_P;
322
                    -- In another case ''P'' square is performed
323
                    else
324
                        first_exp <= '0';
325
                        addr_reg_A <= addr_p;
326
                        addr_reg_B <= addr_p;
327
                        next_state <= EXP_P;
328
                    end if;
329
                -- ''P'' multiplying - in case if it is first computation or no
330
                                -- system behaves a little bit different
331
                when EXP_P =>
332
                    modMultStart <= '1';
333
                    ready <= '0';
334
                    in_mux_control <= "10";
335
                    regDataEnC <= '0';
336
                    regDataEnD2 <= '0';
337
                                        -- If end of multiplying
338
                    if (modMultReady = '1') then
339
                        addr_reg_A <= addr_p;
340
                        addr_reg_B <= addr_p;
341
                        regDataEnA <= "1";
342
                        regDataEnB <= "1";
343
                        if (first_exp = '1') then
344
                            first_exp <= '1';
345
                        else
346
                            first_exp <= '0';
347
                        end if;
348
                        next_state <= SAVE_EXP_P;
349
                    else
350
                        -- During first exponentiation it is ''P precomputing''
351
                        if (first_exp = '1') then
352
                            first_exp <= '1';
353
                            addr_reg_A <= addr_base;
354
                            addr_reg_B <= addr_residuum;
355
                                                -- in another case computing related with the algorithm
356
                        else
357
                            first_exp <= '0';
358
                            addr_reg_A <= addr_p;
359
                            addr_reg_B <= addr_p;
360
                        end if;
361
                        regDataEnA <= "0";
362
                        regDataEnB <= "0";
363
                        next_state <= EXP_P;
364
                    end if;
365
                -- Svaing the ''P'' calculation result
366
                when SAVE_EXP_P =>
367
                    ready <= '0';
368
                    modMultStart <= '0';
369
                    in_mux_control <= "10";
370
                    regDataEnA <= "0";
371
                    regDataEnB <= "0";
372
                    regDataEnC <= '0';
373
                    regDataEnD2 <= '0';
374
                    addr_reg_A <= addr_p;
375
                    addr_reg_B <= addr_p;
376
                    first_exp <= '0';
377
                    next_state <= EXP_CONTROL;
378
                -- State controlling the exponentiation process
379
                -- related to compute ''Z'' or ''P'' element
380
                when EXP_CONTROL =>
381
                    ready <= '0';
382
                    modMultStart <= '0';
383
                    in_mux_control <= "10";
384
                    regDataEnA <= "0";
385
                    regDataEnB <= "0";
386
                    regDataEnC <= '0';
387
                    regDataEnD2 <= '0';
388
                    -- Checking if it was last exponentiation (if yes
389
                    -- post computing stage is performed)
390
                    -- modify for change key size by properties 
391
                    -- (historical remark)
392
                    if (position_counter(word_binary - 1) = '1') then
393
                        addr_reg_A <= addr_one;
394
                        addr_reg_B <= addr_z;
395
                        next_state <= EXP_END;
396
                    -- in another case algorithm 'stage' checking is made 
397
                    else
398
                        if (ExponentData(conv_integer(position_counter)) = '1') then
399
                            addr_reg_A <= addr_z;
400
                            addr_reg_B <= addr_p;
401
                            next_state <= EXP_Z;
402
                        else
403
                            addr_reg_A <= addr_p;
404
                            addr_reg_B <= addr_p;
405
                            next_state <= EXP_P;
406
                        end if;
407
                    end if;
408
                    first_exp <= '0';
409
                -- Algorithm ''post computing''
410
                when EXP_END =>
411
                    modMultStart <= '1';
412
                    ready <= '0';
413
                    in_mux_control <= "10";
414
                    addr_reg_A <= addr_one;
415
                    addr_reg_B <= addr_z;
416
                    -- if end of ''post computing'' multiplying
417
                    -- save result
418
                    if (modMultReady = '1') then
419
                        addr_reg_A <= addr_power;
420
                        addr_reg_B <= addr_power;
421
                        regDataEnA <= "1";
422
                        regDataEnB <= "1";
423
                        regDataEnC <= '0';
424
                        regDataEnD2 <= '0';
425
                        next_state <= SAVE_EXP_MULT;
426
                    -- in another case ''wait'' for the end
427
                    else
428
                        regDataEnA <= "0";
429
                        regDataEnB <= "0";
430
                        regDataEnC <= '0';
431
                        regDataEnD2 <= '0';
432
                        next_state <= EXP_END;
433
                    end if;
434
                    first_exp <= '0';
435
                -- save step
436
                when SAVE_EXP_MULT =>
437
                    in_mux_control <= "10";
438
                    modMultStart <= '0';
439
                    ready <= '0';
440
                    addr_reg_A <= addr_power;
441
                    addr_reg_B <= addr_power;
442
                    regDataEnA <= "1";
443
                    regDataEnB <= "1";
444
                    regDataEnC <= '0';
445
                    regDataEnD2 <= '0';
446
                    first_exp <= '1';
447
                    next_state <= INFO_RESULT;
448
                -- Stage informing ''the world'' about end of 
449
                                -- exponentiation
450
                when INFO_RESULT =>
451
                    modMultStart <= '0';
452
                    in_mux_control <= "10";
453
                    ready <= '1';
454
                    addr_reg_A <= addr_power;
455
                    addr_reg_B <= addr_power;
456
                    regDataEnA <= "0";
457
                    regDataEnB <= "0";
458
                    regDataEnC <= '0';
459
                    regDataEnD2 <= '0';
460
                    if (exp_ctrl = mn_show_result) then
461
                        next_state <= SHOW_RESULT;
462
                    else
463
                        next_state <= INFO_RESULT;
464
                    end if;
465
                    first_exp <= '1';
466
                -- Show result
467
                when SHOW_RESULT =>
468
                    ready <= '1';
469
                    in_mux_control <= "10";
470
                    modMultStart <= '0';
471
                    addr_reg_A <= addr_power;
472
                    addr_reg_B <= addr_power;
473
                    regDataEnA <= "0";
474
                    regDataEnB <= "0";
475
                    regDataEnC <= '0';
476
                    regDataEnD2 <= '0';
477
                    -- Here we are waiting until ''prepare data'' command
478
                    -- appears
479
                    if (exp_ctrl = mn_prepare_for_data) then
480
                        next_state <= FIRST_RUN;
481
                    else
482
                        next_state <= SHOW_RESULT;
483
                    end if;
484
                    first_exp <= '1';
485
            end case;
486
        end process SM;
487
 
488
    -- Process resetting the block memory and registers before each exponentiation
489
    memory_reset_proc : process(clk, reset, state)
490
        begin
491
            if (reset = '1') then
492
                memory_reset <= '1';
493
            elsif (clk = '1' and clk'Event) then
494
                if (state = FIRST_RUN) then
495
                    memory_reset <= '1';
496
                else
497
                    memory_reset <= '0';
498
                end if;
499
            end if;
500
        end process memory_reset_proc;
501
 
502
    -- State change process
503
    state_modifier : process (clk, reset)
504
        begin
505
            if (reset = '1') then
506
                state <= FIRST_RUN;
507
            elsif (clk = '1' and clk'Event) then
508
                state <= next_state;
509
            end if;
510
        end process state_modifier;
511
 
512
    -- Counter process for the control of the exponentiation number iteration
513
    counter_modifier : process (state, clk, reset)
514
            begin
515
            if (clk = '1' and clk'Event) then
516
                if (reset = '1') then
517
                    position_counter <= (others => '1');
518
                elsif (state = SAVE_EXP_P) then
519
                    position_counter <= position_counter + 1;
520
                elsif (state = EXP_END) then
521
                    position_counter <= (others => '1');
522
                else
523
                    position_counter <= position_counter;
524
                end if;
525
            end if;
526
                end process counter_modifier;
527
 
528
end Behavioral;

powered by: WebSVN 2.1.0

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