Search code examples
md5vhdlfpgapipelining

3-stage MD5 pipeline in VHDL


I am trying to implement a 3-stage MD5 pipeline according to this link. In particular the algoritms on page 31. There is also another document which describes data forwarding. The MD5 algoritm is described in RFC1321. This is done in an FPGA (Terasic DE2-115). There is no schematics in this project, only VHDL code

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity md5core is
    port (
        CLOCK_50        : in std_logic;
        SW              : in std_logic_vector(17 downto 17)
    );
end entity md5core;

architecture md5core_rtl of md5core is
type r_array is array(0 to 64) of std_logic_vector(7 downto 0);
constant R        : r_array := ( x"07", x"0c", x"11", x"16", x"07", x"0c", x"11", x"16", x"07", x"0c", x"11", x"16", x"07", x"0c", x"11", 
                                 x"16", x"05", x"09", x"0e", x"14", x"05", x"09", x"0e", x"14", x"05", x"09", x"0e", x"14", x"05", x"09",
                                 x"0e", x"14", x"04", x"0b", x"10", x"17", x"04", x"0b", x"10", x"17", x"04", x"0b", x"10", x"17", x"04",
                                 x"0b", x"10", x"17", x"06", x"0a", x"0f", x"15", x"06", x"0a", x"0f", x"15", x"06", x"0a", x"0f", x"15",
                                 x"06", x"0a", x"0f", x"15", others => x"00");

type k_array is array(0 to 66) of std_logic_vector(31 downto 0);
constant K        : k_array := (x"d76aa478", x"e8c7b756", x"242070db", x"c1bdceee",
                                x"f57c0faf", x"4787c62a", x"a8304613", x"fd469501",
                                x"698098d8", x"8b44f7af", x"ffff5bb1", x"895cd7be",
                                x"6b901122", x"fd987193", x"a679438e", x"49b40821", 
                                x"f61e2562", x"c040b340", x"265e5a51", x"e9b6c7aa",
                                x"d62f105d", x"02441453", x"d8a1e681", x"e7d3fbc8",
                                x"21e1cde6", x"c33707d6", x"f4d50d87", x"455a14ed",
                                x"a9e3e905", x"fcefa3f8", x"676f02d9", x"8d2a4c8a",
                                x"fffa3942", x"8771f681", x"6d9d6122", x"fde5380c",
                                x"a4beea44", x"4bdecfa9", x"f6bb4b60", x"bebfbc70",
                                x"289b7ec6", x"eaa127fa", x"d4ef3085", x"04881d05",
                                x"d9d4d039", x"e6db99e5", x"1fa27cf8", x"c4ac5665",
                                x"f4292244", x"432aff97", x"ab9423a7", x"fc93a039",
                                x"655b59c3", x"8f0ccc92", x"ffeff47d", x"85845dd1",
                                x"6fa87e4f", x"fe2ce6e0", x"a3014314", x"4e0811a1",
                                x"f7537e82", x"bd3af235", x"2ad7d2bb", x"eb86d391", others => x"00000000");

type g_array is array(0 to 64) of integer range 0 to 15;
constant g_arr      : g_array := (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
                                          1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,
                                          5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,
                                          0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, 0);                                               

type w_array is array(0 to 15) of std_logic_vector(31 downto 0);
signal W            : w_array;

constant AA        : std_logic_vector(31 downto 0) := x"67452301";
constant BB        : std_logic_vector(31 downto 0) := x"EFCDAB89";
constant CC        : std_logic_vector(31 downto 0) := x"98BADCFE";
constant DD        : std_logic_vector(31 downto 0) := x"10325476";

signal res_A    : std_logic_vector(31 downto 0) := x"00000000";
signal res_B    : std_logic_vector(31 downto 0) := x"00000000";
signal res_C    : std_logic_vector(31 downto 0) := x"00000000";
signal res_D    : std_logic_vector(31 downto 0) := x"00000000";

type in_str_t is array(0 to 5) of std_logic_vector(7 downto 0);
constant in_str    : in_str_t := (x"68", x"65", x"6c", x"6c", x"6f", x"6f");

type pad_str_t    is array(0 to 63) of std_logic_vector(7 downto 0);
signal pad_str    : pad_str_t;

type state_t is (start, padding, init_w, state_1, state_2, state_3, state_4, done);
signal state    : state_t;

signal a, b, c, d, f    : std_logic_vector(31 downto 0) := x"00000000";
signal i                : integer range 0 to 64 := 0;
signal g                        : integer range 0 to 15 := 0;
--signal tmp_b              : std_logic_vector(31 downto 0);

signal akw                  : std_logic_vector(31 downto 0);
signal ak                   : std_logic_vector(31 downto 0);
signal b_tmp                : std_logic_vector(31 downto 0);
begin

    --tmp_b <= std_logic_vector(unsigned(b) + rotate_left(unsigned(a) + unsigned(f) + unsigned(K(i)) + unsigned(W(g)), to_integer(unsigned(R(i)))));

    pipe_p : process(CLOCK_50, SW, a, b, c, d, i)
    begin
        if SW(17) = '0' then
--          ak <= std_logic_vector(unsigned(K(2)) + unsigned(BB));
--          akw <= std_logic_vector(unsigned(W(0)) + 1 + unsigned(K(2)) + unsigned(BB));
            b_tmp <= BB;
        elsif rising_edge(CLOCK_50) and state = state_1 then
            if i = 0 then
                ak <= std_logic_vector(unsigned(K(0)) + unsigned(a));
            elsif i = 1 then
                ak <= std_logic_vector(unsigned(K(1)) + unsigned(a));
                akw <= std_logic_vector(unsigned(W(0)) + unsigned(ak));
            elsif i = 2 then
                ak <= std_logic_vector(unsigned(K(2)) + unsigned(a));
                akw <= std_logic_vector(unsigned(W(1)) + unsigned(ak));
                b_tmp <= std_logic_vector(unsigned(b) + (rotate_left(unsigned(akw) + unsigned(f), to_integer(unsigned(R(0))))));
            else
                ak <= std_logic_vector(unsigned(K(i)) + unsigned(a));
                akw <= std_logic_vector(unsigned(W(g_arr(i-1))) + unsigned(ak));
                b_tmp <= std_logic_vector(unsigned(b) + (rotate_left(unsigned(akw) + unsigned(f), to_integer(unsigned(R(i-2))))));
            end if;
        end if;
    end process pipe_p;


    md5_f_p : process(state, a, b, c, d, i)
    begin 
        case state is
            when state_1 =>
                if i = 0 or i > 4 then
                    f <= (b and c) or ((not b) and d);
                    g <= g_arr(i);
                end if;

            when state_2 =>
            f <= (d and b) or ((not d) and c);
                g <= g_arr(i);

            when state_3 =>
                f <= b xor c xor d;
            g <= g_arr(i);

            when state_4 =>
                f <= c xor (b or (not d));
            g <= g_arr(i);

            when others =>
                f <= x"00000000";
                g <= 0;             

        end case;
    end process md5_f_p;

     md5_p : process(CLOCK_50, SW, a, b, c, d, f, g)
     begin
        if SW(17) = '0' then
            state <= start;
                i <= 0;
                a <= AA;
            b <= BB;
            c <= CC;
            d <= DD;                
            W <= (others => x"00000000");
                pad_str <= (others => x"00");
                --tmp_b := BB;
        elsif rising_edge(CLOCK_50) then
            case state is            
                when start =>

                    pad_str(0) <= in_str(0);
                    pad_str(1) <= in_str(1);
                    pad_str(2) <= in_str(2);
                    pad_str(3) <= in_str(3);
                    pad_str(4) <= in_str(4);
                    pad_str(5) <= in_str(5);
                    state <= padding;

                when padding =>
                    pad_str(6) <= "10000000";
                    pad_str(56) <= std_logic_vector(to_unsigned(in_str'length*8, 8));
                          state <= init_w;

                when init_w =>                
                    W(0) <= pad_str(3) & pad_str(2) & pad_str(1) & pad_str(0);
                    W(1) <= pad_str(7) & pad_str(6) & pad_str(5) & pad_str(4);
                    W(14) <= pad_str(59) & pad_str(58) & pad_str(57) & pad_str(56);
                          state <= state_1;

                when state_1 =>
                          if i = 16 then
                              state <= state_2;
                          else 
                        if i > 2 then
                                    --tmp_b := b;
                                    a <= d;
                                    c <= b;
                                    d <= c;
                                    b <= b_tmp;

--                                  d <= c;
--                                  b <= b_tmp;
--                                  c <= b;
--                                  a <= d;
                                end if;
                                i <= i + 1;
                    end if;

                when state_2 =>
                    if i = 32 then
                        state <= state_3;
                          else                  
                        d <= c;
                        b <= b_tmp;
                                c <= b;
                        a <= d;
                        i <= i + 1;
                    end if;

                when state_3 =>
                    if i = 48 then
                                state <= state_4;
                          else
                        d <= c;
                        b <= b_tmp;
                                c <= b;
                        a <= d;
                        i <= i + 1;
                    end if;

                when state_4 =>
                    if i = 64 then
                                res_A <= std_logic_vector(unsigned(AA) + unsigned(a));
                                res_B <= std_logic_vector(unsigned(BB) + unsigned(b));
                                res_C <= std_logic_vector(unsigned(CC) + unsigned(c));
                                res_D <= std_logic_vector(unsigned(DD) + unsigned(d));
                                state <= done;
                    else
                        d <= c;
                        c <= b;
                                b <= b_tmp;
                        a <= d;
                        i <= i + 1;
                    end if;

                when done =>
                    state <= done;

                when others =>
                    state <= done;

            end case;
        end if;
    end process md5_p;
end architecture md5core_rtl;

Using this code, I get correct values for b in the first stage of round 0, but thereafter nothing seems to fit. As seen in this simulation, first stage in round 0 is correct, but thereafter not. This is when using a in this expression:

ak <= std_logic_vector(unsigned(K(0)) + unsigned(a)); -- using a

simulation

But... If I understand the second document correctly I should be using c instead of a (data forwarding), but then the first stage in round 0 doesn't work either. I.e when I do this, the first stage in round 0 gets the wrong numbers too.

ak <= std_logic_vector(unsigned(K(0)) + unsigned(c)); -- changed to c

For the particular string in the code (helloo) the following values are correct (all stages).

i:0 => a:271733878, b:3679623978, c:4023233417, d:2562383102, f:2562383102, g:0
i:1 => a:2562383102, b:268703616, c:3679623978, d:4023233417, f:3421032412, g:1
i:2 => a:4023233417, b:566857930, c:268703616, d:3679623978, f:4291410697, g:2
i:3 => a:3679623978, b:2813098031, c:566857930, d:268703616, f:3658619808, g:3
i:4 => a:268703616, b:3540887984, c:2813098031, d:566857930, f:831002506, g:4
i:5 => a:566857930, b:1416558949, c:3540887984, d:2813098031, f:2748069994, g:5
i:6 => a:2813098031, b:1417573490, c:1416558949, d:3540887984, f:4086081834, g:6
i:7 => a:3540887984, b:412978483, c:1417573490, d:1416558949, f:3614439904, g:7
i:8 => a:1416558949, b:2667121787, c:412978483, d:1417573490, f:1417573494, g:8
i:9 => a:1417573490, b:3587014656, c:2667121787, d:412978483, f:1486847027, g:9
i:10 => a:412978483, b:2424005293, c:3587014656, d:2667121787, f:2631470387, g:10
i:11 => a:2667121787, b:3779826569, c:2424005293, d:3587014656, f:2663976018, g:11
i:12 => a:3587014656, b:2371593944, c:3779826569, d:2424005293, f:2496594569, g:12
i:13 => a:2424005293, b:2829036837, c:2371593944, d:3779826569, f:2439758509, g:13
i:14 => a:3779826569, b:1652927941, c:2829036837, d:2371593944, f:3378230920, g:14
i:15 => a:2371593944, b:343664023, c:1652927941, d:2829036837, f:2917117725, g:15
i:16 => a:2829036837, b:3610776431, c:343664023, d:1652927941, f:1109108165, g:1
i:17 => a:1652927941, b:2356907245, c:3610776431, d:343664023, f:1450852695, g:6
i:18 => a:343664023, b:1950114052, c:2356907245, d:3610776431, f:3346765549, g:11
i:19 => a:3610776431, b:1998115502, c:1950114052, d:2356907245, f:1551601028, g:0
i:20 => a:2356907245, b:2811855282, c:1998115502, d:1950114052, f:1948049836, g:5
i:21 => a:1950114052, b:1476613917, c:2811855282, d:1998115502, f:655922090, g:10
i:22 => a:1998115502, b:1051434612, c:1476613917, d:2811855282, f:3498136348, g:15
i:23 => a:2811855282, b:2313778686, c:1051434612, d:1476613917, f:2123093565, g:4
i:24 => a:1476613917, b:2391742621, c:2313778686, d:1051434612, f:782884220, g:9
i:25 => a:1051434612, b:2587925491, c:2391742621, d:2313778686, f:2412476830, g:14
i:26 => a:2313778686, b:1270631524, c:2587925491, d:2391742621, f:2386958835, g:3
i:27 => a:2391742621, b:2967137637, c:1270631524, d:2587925491, f:449612646, g:8
i:28 => a:2587925491, b:4275359302, c:2967137637, d:1270631524, f:3523005797, g:13
i:29 => a:1270631524, b:221196138, c:4275359302, d:2967137637, f:4208389445, g:2
i:30 => a:2967137637, b:1826025400, c:221196138, d:4275359302, f:1309552482, g:7
i:31 => a:4275359302, b:4266766346, c:1826025400, d:221196138, f:1845489448, g:12
i:32 => a:221196138, b:3855169043, c:4266766346, d:1826025400, f:2678616280, g:5
i:33 => a:1826025400, b:1648727666, c:3855169043, d:4266766346, f:2001627553, g:8
i:34 => a:4266766346, b:3280661187, c:1648727666, d:3855169043, f:2044530795, g:11
i:35 => a:3855169043, b:933955932, c:3280661187, d:1648727666, f:1141263010, g:14
i:36 => a:1648727666, b:1316709518, c:933955932, d:3280661187, f:2523166189, g:1
i:37 => a:3280661187, b:1172621265, c:1316709518, d:933955932, f:3126494993, g:4
i:38 => a:933955932, b:638303819, c:1172621265, d:1316709518, f:1010084355, g:7
i:39 => a:1316709518, b:2518531516, c:638303819, d:1172621265, f:764681492, g:10
i:40 => a:1172621265, b:1723348322, c:2518531516, d:638303819, f:4126327846, g:13
i:41 => a:638303819, b:1796634879, c:1723348322, d:2518531516, f:3601741461, g:0
i:42 => a:2518531516, b:1242042285, c:1796634879, d:1723348322, f:2612260897, g:3
i:43 => a:1723348322, b:3271112123, c:1242042285, d:1796634879, f:1202078256, g:6
i:44 => a:1796634879, b:171818493, c:3271112123, d:1242042285, f:3823583977, g:9
i:45 => a:1242042285, b:4279516322, c:171818493, d:3271112123, f:2194442219, g:12
i:46 => a:3271112123, b:1084087837, c:4279516322, d:171818493, f:936424676, g:15
i:47 => a:171818493, b:4055665426, c:1084087837, d:4279516322, f:3048496962, g:2
i:48 => a:4279516322, b:4279453145, c:4055665426, d:1084087837, f:2975995202, g:0
i:49 => a:1084087837, b:1002426141, c:4279453145, d:4055665426, f:248508137, g:7
i:50 => a:4055665426, b:2580293036, c:1002426141, d:4279453145, f:3236739620, g:14
i:51 => a:4279453145, b:429799967, c:2580293036, d:1002426141, f:2723377331, g:5
i:52 => a:1002426141, b:969799177, c:429799967, d:2580293036, f:1142038355, g:12
i:53 => a:2580293036, b:4081959629, c:969799177, d:429799967, f:1717683268, g:3
i:54 => a:429799967, b:424965883, c:4081959629, d:969799177, f:3466605028, g:10
i:55 => a:969799177, b:2878206675, c:424965883, d:4081959629, f:742112562, g:1
i:56 => a:4081959629, b:3289205483, c:2878206675, d:424965883, f:3068889352, g:8
i:57 => a:424965883, b:932769765, c:3289205483, d:2878206675, f:1294088508, g:15
i:58 => a:2878206675, b:3877873675, c:932769765, d:3289205483, f:3019351302, g:6
i:59 => a:3289205483, b:3573278773, c:3877873675, d:932769765, f:3362476794, g:13
i:60 => a:932769765, b:2755809458, c:3573278773, d:3877873675, f:1004294196, g:4
i:61 => a:3877873675, b:2328479269, c:2755809458, d:3573278773, f:1747304387, g:11
i:62 => a:3573278773, b:198924010, c:2328479269, d:2755809458, f:261064541, g:2
i:63 => a:2755809458, b:3186462216, c:198924010, d:2328479269, f:3509991882, g:9

By the way, AKM in the document is akw in the code.

Any tips or suggestions on bringing me in the right direction would be very appreciated. Code would be ideal. If something is unclear, I'll edit the question and try to rectify that.


Solution

  • the problem is, that you have a pipeline of two in your "b-path" (--> 1st stage is b_tmp, 2nd stage is b) while the allocation pipeline has one stage (e.g. a<=d) only. I did some changes to the code and marked them with "--***". with this code, you get the first results right...

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    
    entity md5core is
        port (
            CLOCK_50        : in std_logic;
            SW              : in std_logic_vector(17 downto 17)
        );
    end entity md5core;
    
    architecture md5core_rtl of md5core is
    type r_array is array(0 to 64) of std_logic_vector(7 downto 0);
    constant R        : r_array := ( x"07", x"0c", x"11", x"16", x"07", x"0c", x"11", x"16", x"07", x"0c", x"11", x"16", x"07", x"0c", x"11", 
                                     x"16", x"05", x"09", x"0e", x"14", x"05", x"09", x"0e", x"14", x"05", x"09", x"0e", x"14", x"05", x"09",
                                     x"0e", x"14", x"04", x"0b", x"10", x"17", x"04", x"0b", x"10", x"17", x"04", x"0b", x"10", x"17", x"04",
                                     x"0b", x"10", x"17", x"06", x"0a", x"0f", x"15", x"06", x"0a", x"0f", x"15", x"06", x"0a", x"0f", x"15",
                                     x"06", x"0a", x"0f", x"15", others => x"00");
    
    type k_array is array(0 to 66) of std_logic_vector(31 downto 0);
    constant K        : k_array := (x"d76aa478", x"e8c7b756", x"242070db", x"c1bdceee",
                                    x"f57c0faf", x"4787c62a", x"a8304613", x"fd469501",
                                    x"698098d8", x"8b44f7af", x"ffff5bb1", x"895cd7be",
                                    x"6b901122", x"fd987193", x"a679438e", x"49b40821", 
                                    x"f61e2562", x"c040b340", x"265e5a51", x"e9b6c7aa",
                                    x"d62f105d", x"02441453", x"d8a1e681", x"e7d3fbc8",
                                    x"21e1cde6", x"c33707d6", x"f4d50d87", x"455a14ed",
                                    x"a9e3e905", x"fcefa3f8", x"676f02d9", x"8d2a4c8a",
                                    x"fffa3942", x"8771f681", x"6d9d6122", x"fde5380c",
                                    x"a4beea44", x"4bdecfa9", x"f6bb4b60", x"bebfbc70",
                                    x"289b7ec6", x"eaa127fa", x"d4ef3085", x"04881d05",
                                    x"d9d4d039", x"e6db99e5", x"1fa27cf8", x"c4ac5665",
                                    x"f4292244", x"432aff97", x"ab9423a7", x"fc93a039",
                                    x"655b59c3", x"8f0ccc92", x"ffeff47d", x"85845dd1",
                                    x"6fa87e4f", x"fe2ce6e0", x"a3014314", x"4e0811a1",
                                    x"f7537e82", x"bd3af235", x"2ad7d2bb", x"eb86d391", others => x"00000000");
    
    type g_array is array(0 to 64) of integer range 0 to 15;
    constant g_arr      : g_array := (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
                                              1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,
                                              5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,
                                              0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, 0);                                               
    
    type w_array is array(0 to 15) of std_logic_vector(31 downto 0);
    signal W            : w_array;
    
    constant AA        : std_logic_vector(31 downto 0) := x"67452301";
    constant BB        : std_logic_vector(31 downto 0) := x"EFCDAB89";
    constant CC        : std_logic_vector(31 downto 0) := x"98BADCFE";
    constant DD        : std_logic_vector(31 downto 0) := x"10325476";
    
    signal res_A    : std_logic_vector(31 downto 0) := x"00000000";
    signal res_B    : std_logic_vector(31 downto 0) := x"00000000";
    signal res_C    : std_logic_vector(31 downto 0) := x"00000000";
    signal res_D    : std_logic_vector(31 downto 0) := x"00000000";
    
    type in_str_t is array(0 to 5) of std_logic_vector(7 downto 0);
    constant in_str    : in_str_t := (x"68", x"65", x"6c", x"6c", x"6f", x"6f");
    
    type pad_str_t    is array(0 to 63) of std_logic_vector(7 downto 0);
    signal pad_str    : pad_str_t;
    
    type state_t is (start, padding, init_w, state_1, state_2, state_3, state_4, done);
    signal state    : state_t;
    
    signal a, b, c, d, f    : std_logic_vector(31 downto 0) := x"00000000";
    signal i                : integer range 0 to 64 := 0;
    signal g                        : integer range 0 to 15 := 0;
    --signal tmp_b              : std_logic_vector(31 downto 0);
    
    signal akw                  : std_logic_vector(31 downto 0);
    signal ak                   : std_logic_vector(31 downto 0);
    signal b_tmp                : std_logic_vector(31 downto 0);
    
    begin
    
        --tmp_b <= std_logic_vector(unsigned(b) + rotate_left(unsigned(a) + unsigned(f) + unsigned(K(i)) + unsigned(W(g)), to_integer(unsigned(R(i)))));
    
        pipe_p : process(CLOCK_50, SW)--*** removed: , a, b, c, d, i)
        begin
            if SW(17) = '0' then
    --          ak <= std_logic_vector(unsigned(K(2)) + unsigned(BB));
    --          akw <= std_logic_vector(unsigned(W(0)) + 1 + unsigned(K(2)) + unsigned(BB));
                b <= BB;--*** changed, was: b_tmp
            elsif rising_edge(CLOCK_50) and state = state_1 then
                if i = 0 then
                    ak <= std_logic_vector(unsigned(K(0)) + unsigned(a));
                elsif i = 1 then
                    ak <= std_logic_vector(unsigned(K(1)) + unsigned(d));--*** changed, was: unsigned(a));
                    akw <= std_logic_vector(unsigned(W(0)) + unsigned(ak));
                elsif i = 2 then
                    ak <= std_logic_vector(unsigned(K(2)) + unsigned(c));--*** changed, was: unsigned(a));
                    akw <= std_logic_vector(unsigned(W(1)) + unsigned(ak));
                    b <= std_logic_vector(unsigned(b) + (rotate_left(unsigned(akw) + unsigned(f), to_integer(unsigned(R(0))))));--*** changed, was: b_tmp
                else
                    ak <= std_logic_vector(unsigned(K(i)) + unsigned(c));--*** changed, was:  unsigned(a));
                    akw <= std_logic_vector(unsigned(W(g_arr(i-1))) + unsigned(ak));
                    b <= std_logic_vector(unsigned(b) + (rotate_left(unsigned(akw) + unsigned(f), to_integer(unsigned(R(i-2))))));--*** changed, was: b_tmp
                end if;
            end if;
        end process pipe_p;
    
    
        md5_f_p : process(state, a, b, c, d, i)
        begin 
            case state is
                when state_1 =>
                    -- if i = 0 or i > 4 then----*** removed
                        f <= (b and c) or ((not b) and d);
                        g <= g_arr(i);
                    -- end if;----*** removed
    
                when state_2 =>
                f <= (d and b) or ((not d) and c);
                    g <= g_arr(i);
    
                when state_3 =>
                    f <= b xor c xor d;
                g <= g_arr(i);
    
                when state_4 =>
                    f <= c xor (b or (not d));
                g <= g_arr(i);
    
                when others =>
                    f <= x"00000000";
                    g <= 0;             
    
            end case;
        end process md5_f_p;
    
         md5_p : process(CLOCK_50, SW)----*** removed: , a, b, c, d, f, g)
         begin
            if SW(17) = '0' then
                state <= start;
                    i <= 0;
                    a <= AA;
                -- b <= BB; ----*** removed
                c <= CC;
                d <= DD;                
                W <= (others => x"00000000");
                    pad_str <= (others => x"00");
                    --tmp_b := BB;
            elsif rising_edge(CLOCK_50) then
                case state is            
                    when start =>
    
                        pad_str(0) <= in_str(0);
                        pad_str(1) <= in_str(1);
                        pad_str(2) <= in_str(2);
                        pad_str(3) <= in_str(3);
                        pad_str(4) <= in_str(4);
                        pad_str(5) <= in_str(5);
                        state <= padding;
    
                    when padding =>
                        pad_str(6) <= "10000000";
                        pad_str(56) <= std_logic_vector(to_unsigned(in_str'length*8, 8));
                              state <= init_w;
    
                    when init_w =>                
                        W(0) <= pad_str(3) & pad_str(2) & pad_str(1) & pad_str(0);
                        W(1) <= pad_str(7) & pad_str(6) & pad_str(5) & pad_str(4);
                        W(14) <= pad_str(59) & pad_str(58) & pad_str(57) & pad_str(56);
                              state <= state_1;
    
                    when state_1 =>
                              if i = 16 then
                                  state <= state_2;
                              else 
                            if i > 1 then----*** changed, was: --if i > 2 then
                                        --tmp_b := b;
                                        a <= d;
                                        c <= b;
                                        d <= c;
                                        -- b <= b_tmp; --*** removed
    
    --                                  d <= c;
    --                                  b <= b_tmp;
    --                                  c <= b;
    --                                  a <= d;
                                    end if;
                                    i <= i + 1;
                        end if;
    
                    when state_2 =>
                        if i = 32 then
                            state <= state_3;
                              else                  
                            d <= c;
                            -- b <= b_tmp;--*** removed
                                    c <= b;
                            a <= d;
                            i <= i + 1;
                        end if;
    
                    when state_3 =>
                        if i = 48 then
                                    state <= state_4;
                              else
                            d <= c;
                            -- b <= b_tmp;----*** removed
                                    c <= b;
                            a <= d;
                            i <= i + 1;
                        end if;
    
                    when state_4 =>
                        if i = 64 then
                                    res_A <= std_logic_vector(unsigned(AA) + unsigned(a));
                                    res_B <= std_logic_vector(unsigned(BB) + unsigned(b));
                                    res_C <= std_logic_vector(unsigned(CC) + unsigned(c));
                                    res_D <= std_logic_vector(unsigned(DD) + unsigned(d));
                                    state <= done;
                        else
                            d <= c;
                            c <= b;
                                    -- b <= b_tmp;----*** removed
                            a <= d;
                            i <= i + 1;
                        end if;
    
                    when done =>
                        state <= done;
    
                    when others =>
                        state <= done;
    
                end case;
            end if;
        end process md5_p;
    end architecture md5core_rtl;
    

    enter image description here

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    
    entity md5core is
        port (
            CLOCK_50        : in std_logic;
            SW              : in std_logic_vector(17 downto 17)
        );
    end entity md5core;
    
    architecture md5core_rtl of md5core is
    type r_array is array(0 to 64) of std_logic_vector(7 downto 0);
    constant R        : r_array := ( x"07", x"0c", x"11", x"16", x"07", x"0c", x"11", x"16", x"07", x"0c", x"11", x"16", x"07", x"0c", x"11", 
                                     x"16", x"05", x"09", x"0e", x"14", x"05", x"09", x"0e", x"14", x"05", x"09", x"0e", x"14", x"05", x"09",
                                     x"0e", x"14", x"04", x"0b", x"10", x"17", x"04", x"0b", x"10", x"17", x"04", x"0b", x"10", x"17", x"04",
                                     x"0b", x"10", x"17", x"06", x"0a", x"0f", x"15", x"06", x"0a", x"0f", x"15", x"06", x"0a", x"0f", x"15",
                                     x"06", x"0a", x"0f", x"15", others => x"00");
    
    type k_array is array(0 to 66) of std_logic_vector(31 downto 0);
    constant K        : k_array := (x"d76aa478", x"e8c7b756", x"242070db", x"c1bdceee",
                                    x"f57c0faf", x"4787c62a", x"a8304613", x"fd469501",
                                    x"698098d8", x"8b44f7af", x"ffff5bb1", x"895cd7be",
                                    x"6b901122", x"fd987193", x"a679438e", x"49b40821", 
                                    x"f61e2562", x"c040b340", x"265e5a51", x"e9b6c7aa",
                                    x"d62f105d", x"02441453", x"d8a1e681", x"e7d3fbc8",
                                    x"21e1cde6", x"c33707d6", x"f4d50d87", x"455a14ed",
                                    x"a9e3e905", x"fcefa3f8", x"676f02d9", x"8d2a4c8a",
                                    x"fffa3942", x"8771f681", x"6d9d6122", x"fde5380c",
                                    x"a4beea44", x"4bdecfa9", x"f6bb4b60", x"bebfbc70",
                                    x"289b7ec6", x"eaa127fa", x"d4ef3085", x"04881d05",
                                    x"d9d4d039", x"e6db99e5", x"1fa27cf8", x"c4ac5665",
                                    x"f4292244", x"432aff97", x"ab9423a7", x"fc93a039",
                                    x"655b59c3", x"8f0ccc92", x"ffeff47d", x"85845dd1",
                                    x"6fa87e4f", x"fe2ce6e0", x"a3014314", x"4e0811a1",
                                    x"f7537e82", x"bd3af235", x"2ad7d2bb", x"eb86d391", others => x"00000000");
    
    type g_array is array(0 to 64) of integer range 0 to 15;
    constant g_arr      : g_array := (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
                                              1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,
                                              5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,
                                              0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, 0);                                               
    
    type w_array is array(0 to 15) of std_logic_vector(31 downto 0);
    signal W            : w_array;
    
    constant AA        : std_logic_vector(31 downto 0) := x"67452301";
    constant BB        : std_logic_vector(31 downto 0) := x"EFCDAB89";
    constant CC        : std_logic_vector(31 downto 0) := x"98BADCFE";
    constant DD        : std_logic_vector(31 downto 0) := x"10325476";
    
    signal res_A    : std_logic_vector(31 downto 0) := x"00000000";
    signal res_B    : std_logic_vector(31 downto 0) := x"00000000";
    signal res_C    : std_logic_vector(31 downto 0) := x"00000000";
    signal res_D    : std_logic_vector(31 downto 0) := x"00000000";
    
    type in_str_t is array(0 to 5) of std_logic_vector(7 downto 0);
    constant in_str    : in_str_t := (x"68", x"65", x"6c", x"6c", x"6f", x"6f");
    
    type pad_str_t    is array(0 to 63) of std_logic_vector(7 downto 0);
    signal pad_str    : pad_str_t;
    
    type state_t is (start, padding, init_w, state_1, state_2, state_3, state_4, done);
    signal state    : state_t;
    
    signal a, b, c, d, f    : std_logic_vector(31 downto 0) := x"00000000";
    signal i                : integer range 0 to 65 := 0;--**** changed, was: to 64
    signal g                        : integer range 0 to 15 := 0;
    --signal tmp_b              : std_logic_vector(31 downto 0);
    
    signal akw                  : std_logic_vector(31 downto 0);
    signal ak                   : std_logic_vector(31 downto 0);
    signal b_tmp                : std_logic_vector(31 downto 0);
    
    begin
    
        --tmp_b <= std_logic_vector(unsigned(b) + rotate_left(unsigned(a) + unsigned(f) + unsigned(K(i)) + unsigned(W(g)), to_integer(unsigned(R(i)))));
    
        pipe_p : process(CLOCK_50, SW)--*** removed: , a, b, c, d, i)
        begin
            if SW(17) = '0' then
    --          ak <= std_logic_vector(unsigned(K(2)) + unsigned(BB));
    --          akw <= std_logic_vector(unsigned(W(0)) + 1 + unsigned(K(2)) + unsigned(BB));
                b <= BB;--*** changed, was: b_tmp
            elsif rising_edge(CLOCK_50) then --**** removed: and state = state_1 then
                    --**** added start
                    if state = done then
                        b<=b;
                        ak<=ak;
                        akw<=akw;
                    --**** added stop
                elsif i = 0 then
                    ak <= std_logic_vector(unsigned(K(0)) + unsigned(a));
                elsif i = 1 then
                    ak <= std_logic_vector(unsigned(K(1)) + unsigned(d));--*** changed, was: unsigned(a));
                    akw <= std_logic_vector(unsigned(W(0)) + unsigned(ak));
                elsif i = 2 then
                    ak <= std_logic_vector(unsigned(K(2)) + unsigned(c));--*** changed, was: unsigned(a));
                    akw <= std_logic_vector(unsigned(W(1)) + unsigned(ak));
                    b <= std_logic_vector(unsigned(b) + (rotate_left(unsigned(akw) + unsigned(f), to_integer(unsigned(R(0))))));--*** changed, was: b_tmp
                else
                    ak <= std_logic_vector(unsigned(K(i)) + unsigned(c));--*** changed, was:  unsigned(a));
                    akw <= std_logic_vector(unsigned(W(g_arr(i-1))) + unsigned(ak));
                    b <= std_logic_vector(unsigned(b) + (rotate_left(unsigned(akw) + unsigned(f), to_integer(unsigned(R(i-2))))));--*** changed, was: b_tmp
                end if;
            end if;
        end process pipe_p;
    
    
        md5_f_p : process(state, a, b, c, d, i)
        begin 
            case state is
                when state_1 =>
                    -- if i = 0 or i > 4 then----*** removed
                        f <= (b and c) or ((not b) and d);
    --                    g <= g_arr(i);--**** removed
                    -- end if;----*** removed
    
                when state_2 =>
                f <= (d and b) or ((not d) and c);
    --                g <= g_arr(i);--**** removed
    
                when state_3 =>
                    f <= b xor c xor d;
    --            g <= g_arr(i);--**** removed
    
                when state_4 =>
                    f <= c xor (b or (not d));
    --            g <= g_arr(i);--**** removed
    
                when others =>
                    f <= x"00000000";
    --                g <= 0;       --**** removed      
    
            end case;
        end process md5_f_p;
    
         md5_p : process(CLOCK_50, SW)----*** removed: , a, b, c, d, f, g)
         begin
            if SW(17) = '0' then
                state <= start;
                    i <= 0;
                    a <= AA;
                -- b <= BB; ----*** removed
                c <= CC;
                d <= DD;                
                W <= (others => x"00000000");
                    pad_str <= (others => x"00");
                    --tmp_b := BB;
            elsif rising_edge(CLOCK_50) then
                case state is            
                    when start =>
    
                        pad_str(0) <= in_str(0);
                        pad_str(1) <= in_str(1);
                        pad_str(2) <= in_str(2);
                        pad_str(3) <= in_str(3);
                        pad_str(4) <= in_str(4);
                        pad_str(5) <= in_str(5);
                        state <= padding;
    
                    when padding =>
                        pad_str(6) <= "10000000";
                        pad_str(56) <= std_logic_vector(to_unsigned(in_str'length*8, 8));
                              state <= init_w;
    
                    when init_w =>                
                        W(0) <= pad_str(3) & pad_str(2) & pad_str(1) & pad_str(0);
                        W(1) <= pad_str(7) & pad_str(6) & pad_str(5) & pad_str(4);
                        W(14) <= pad_str(59) & pad_str(58) & pad_str(57) & pad_str(56);
                              state <= state_1;
    
                    when state_1 =>
                              if i = 17 then--**** changed, was: 16
                                  state <= state_2;
                                        end if; --****added
    --                          else --**** removed
                            if i > 1 then----*** changed, was: --if i > 2 then
                                        --tmp_b := b;
                                        a <= d;
                                        c <= b;
                                        d <= c;
                                        -- b <= b_tmp; --*** removed
    
    --                                  d <= c;
    --                                  b <= b_tmp;
    --                                  c <= b;
    --                                  a <= d;
                                    end if;
                                    i <= i + 1;
    --                    end if;--**** removed
    
                    when state_2 =>
                        if i = 33 then--**** changed, was: 32
                            state <= state_3;
                                end if; --****added
    --                    else --**** removed                 
                            d <= c;
                            -- b <= b_tmp;--*** removed
                            c <= b;
                            a <= d;
                            i <= i + 1;
    --                    end if;--**** removed  
    
                    when state_3 =>
                        if i = 49 then--**** changed, was: 48
                                    state <= state_4;
                                end if; --****added
    --                          else--**** removed  
                            d <= c;
                            -- b <= b_tmp;----*** removed
                            c <= b;
                            a <= d;
                            i <= i + 1;
    --                    end if;--**** removed  
    
                    when state_4 =>
                        if i = 65 then--**** changed, was: 64
    --                                res_A <= std_logic_vector(unsigned(AA) + unsigned(a));--**** removed  
    --                                res_B <= std_logic_vector(unsigned(BB) + unsigned(b));--**** removed  
    --                                res_C <= std_logic_vector(unsigned(CC) + unsigned(c));--**** removed  
    --                                res_D <= std_logic_vector(unsigned(DD) + unsigned(d));--**** removed  
                                      state <= done;
                                end if; --****added
    --                    else--**** removed  
                            d <= c;
                            c <= b;
                            -- b <= b_tmp;----*** removed
                            a <= d;
                            i <= i + 1;
    --                    end if;--**** removed  
    
                    when done =>
                              res_A <= std_logic_vector(unsigned(AA) + unsigned(a));--****added
                              res_B <= std_logic_vector(unsigned(BB) + unsigned(b));--****added
                              res_C <= std_logic_vector(unsigned(CC) + unsigned(c));--****added
                              res_D <= std_logic_vector(unsigned(DD) + unsigned(d));    --****added              
                        state <= done;
    
                    when others =>
                        state <= done;
    
                end case;
            end if;
        end process md5_p;
    end architecture md5core_rtl;