3-stage MD5 pipeline in VHDL - md5

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
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.

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;
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;

Related

How to iterate an array in Go, starting from the index middle and then continue from index 0?

My goal is to iterate an array from the middle, and then continue from index 0.
full code
The current solution is to duplicate the body block
for _, daysInMonth := range daysInMonths[a.Month()-1:] {
daysDiff -= float64(daysInMonth)
if daysDiff < 0 {
daysDiff += float64(daysInMonth)
break
}
monthsDiff += 1
}
for _, daysInMonth := range daysInMonths {
daysDiff -= float64(daysInMonth)
if daysDiff < 0 {
daysDiff += float64(daysInMonth)
break
}
monthsDiff += 1
}
It should work if you set monthDiff back to zero once your month reaches twelve.
monthsDiff = 0
// i.e. a.Month() is 10
// then subtract daysDiff with days of Month 10, 11, 12, 1, 2, and so on.
for _, daysInMonth := range daysInMonths[a.Month()-1:] {
daysDiff -= float64(daysInMonth)
if daysDiff < 0 {
daysDiff += float64(daysInMonth)
break
}
if monthDiff == 12 {
monthsDiff = 0
} else {
monthsDiff += 1
}
}

Asynchronous load data in counter bug

I build a counter with asynchronous load in VHDL. When i press the button(which should load data in counter) it will not increment the data but it will go like that: if the counter displays 10 -> 1, 11->2, etc..
It works fine when i press the button repeatedly but if i left the button a while the next time when i press it will not work fine.
My counter:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity countfeed is
Port ( Clock : in STD_LOGIC;
Num_out : out STD_LOGIC_VECTOR (15 downto 0);
ECU : in STD_LOGIC;
ALoad: in STD_LOGIC;
data : in STD_LOGIC_VECTOR(15 downto 0);
ECD : in STD_LOGIC);
end countfeed;
architecture Behavioral of countfeed is
signal count : STD_LOGIC_VECTOR(15 downto 0) := X"0000";
begin
Num_out <= count;
process(Clock,ALoad)
begin
if(ALoad = '1') then
count <= data;
elsif(rising_edge(Clock)) then
if(ECU = '1') then
if(count(3 downto 0) = X"9") then
count(3 downto 0) <= X"0";
count(7 downto 4) <= count(7 downto 4) + 1;
else
count(3 downto 0) <= count(3 downto 0) + 1;
end if;
if(count(7 downto 0) = X"59") then
count(7 downto 0) <= X"00";
count(11 downto 8) <= count(11 downto 8) + 1;
end if;
if(count(11 downto 0) = X"959") then
count(11 downto 0) <= X"000";
count(15 downto 12) <= count(15 downto 12) + 1;
end if;
if(count(15 downto 0) = X"9959") then
count(15 downto 0) <= X"0000";
end if;
elsif(ECD = '1') then
if(count(3 downto 0) = X"0") then
if(count(15 downto 4) /= X"0") then
count(3 downto 0) <= X"9";
count(7 downto 4) <= count(7 downto 4) - 1;
if(count(7 downto 4) = X"0") then
if(count(15 downto 8) /= X"0") then
count(7 downto 4) <= X"5";
count(11 downto 8) <= count(11 downto 8) - 1;
if(count(11 downto 8) = X"0") then
if(count(15 downto 12) /= X"0") then
count(11 downto 8) <= X"9";
count(15 downto 12) <= count(15 downto 12) - 1;
end if;
end if;
end if;
end if;
end if;
else
count(3 downto 0) <= count(3 downto 0) - 1;
end if;
end if;
end if;
end process;
end Behavioral;
My data processing(where bS is the button, disp_n the output of the counter, data is the data to load:
process(bS)
begin
if(rising_edge(bS)) then
data(15 downto 8) <= disp_n(15 downto 8);
if(disp_n(7 downto 0) = X"59") then
data(7 downto 0) <= X"00";
elsif(disp_n(3 downto 0) = X"9") then
data(3 downto 0) <= X"0";
data(7 downto 4) <= disp_n(7 downto 4) + 1;
else
data(3 downto 0) <= disp_n(3 downto 0) + 1;
end if;
end if;
end process;
Load:
ALoad <= bS;
toplevel:
architecture Behavioral of toplevel is
Component ClockDivider is...
Component BCD is...
Component DebouncerC is...
Component edge_det is...
Component countfeed is
Port ( Clock : in STD_LOGIC;
Num_out : out STD_LOGIC_VECTOR (15 downto 0);
ECU : in STD_LOGIC;
ALoad: in STD_LOGIC;
data: in STD_LOGIC_VECTOR(15 downto 0);
ECD: in STD_LOGIC);
end Component;
signal bSS,bS,bM : STD_LOGIC; --Debounced buttons
signal clk1s : STD_LOGIC; -- 1 Hz Clock
signal ECU,ECD : STD_LOGIC; -- Enable Count Up/Down
signal Reset : STD_LOGIC; -- Reset
signal disp_n: STD_LOGIC_VECTOR(15 downto 0);
signal ALoad: STD_LOGIC;
signal data: STD_LOGIC_VECTOR(15 downto 0);
signal btS,btM: STD_LOGIC;
signal dataS: STD_LOGIC_VECTOR(15 downto 0);
begin
--Execution Unit--
E0: ClockDivider port map( Clock => Clock, ClockDiv => clk1s);
E1: BCD port map( Number => disp_n, Clock => Clock, Anod => Anod, Segment => seg);
E2: DebouncerC port map( Clock => Clock, Button_in => StartStop, Button_out => bSS);
E3: DebouncerC port map( Clock => Clock, Button_in => Seconds, Button_out => bS);
E4: DebouncerC port map( Clock => Clock, Button_in => Minutes, Button_out => bM);
E5: Reset <= bS and bM;
E6: countfeed port map(Clock => clk1s, Num_out => disp_n,ECU => ECU,
ECD => ECD,ALoad => ALoad, data => data);
E7: edge_det port map (Clock => Clock, Signal_in => bS, Signal_out => btS);
E8: edge_det port map (Clock => Clock, Signal_in => bM, Signal_out => btM);
ALoad <= btS or btM;
process(bS)
begin
if(rising_edge(bS)) then
data(15 downto 8) <= disp_n(15 downto 8);
if(disp_n(7 downto 0) = X"59") then
data(7 downto 0) <= X"00";
elsif(disp_n(3 downto 0) = X"9") then
data(3 downto 0) <= X"0";
data(7 downto 4) <= disp_n(7 downto 4) + 1;
else
data(3 downto 0) <= disp_n(3 downto 0) + 1;
end if;
end if;
end process;
process(bSS)
begin
if(rising_edge(bSS)) then
ECU <= not ECU;
end if;
end process;
end Behavioral;

multidimensional arrays in VHDL

I want to do multiplication of 2 matrix,and I am trying to make an array of std_logic_vectors in VHDL.
package matrice is
type t11 is array (32 downto 0,0 downto 19) of unsigned(7 downto 0);<
type t1 is array (0 downto 19) of t11;
type t2 is array (0 downto 194) of unsigned(7 downto 0);
entity matrice_test is
Port (clk : in STD_LOGIC;a : in t1;b : in t2;multi :out t2);
end matrice_test;
architecture Behavioral of matrice_test is
type t11 is array (M_MAX-1 downto 0,0 downto O_MAX-1) of unsigned(N-1 downto 0);
type t1 is array (0 downto O_MAX-1) of t11;
type t2 is array (0 downto N_MAX-1) of unsigned(N-1 downto 0);
The error that I am getting:
indexed name prefix type t11 expects 2 dimensions
I can't reproduce your error (how about submitting an MCVE), but this
type t11 is array (323 downto 0,0 downto 19) of unsigned(7 downto 0);
should be this
type t11 is array (323 downto 0,0 to 19) of unsigned(7 downto 0);
-- ^
-- |

5 seconds Timer in VHDL

I am using 50MHz clock in fpga and trying make 5 seconds timer. below cnt_t reach to 5 x 50MHz (x"0EE6B280" --> 250,000,000) then make time_tick_32 to 1 and make cnt_t <= x"00000000";. The code below did not work never time_tick_32 gets 1.
signal cnt_t : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00000000";
signal time_tick : STD_LOGIC:= '0' ;
signal time_tick_32 : STD_LOGIC_VECTOR(31 DOWNTO 0):= x"00000000";
process (clk_50) IS
begin
if falling_edge(clk_50) then
cnt_t <= cnt_t + '1';
end if;
if (cnt_t = x"0EE6B280") then --if 5 seconds
time_tick <= '1';
cnt_t <= x"00000000";
time_tick_32(0)<=time_tick;
else
time_tick <= '0';
time_tick_32(0)<=time_tick;
end if;
end process;
Try:
signal cnt_t : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00000000";
signal time_tick : STD_LOGIC:= '0' ;
signal time_tick_32 : STD_LOGIC_VECTOR(31 DOWNTO 0):= x"00000000";
-- I assume you begin your architecture somewhere
-- Can make the following a concurrent statement
-- (unless it is some kind of shift reg assigned in a diff process...
-- then you will get multiple driver issues)
time_tick_32(0) <= time_tick;
process (clk_50) IS
begin
if rising_edge(clk_50) then -- Changed to rising_edge;
-- Any particular reason you are using falling_edge?
if (cnt_t = x"0EE6B280") then --if 5 seconds
time_tick <= '1';
cnt_t <= x"00000000";
else
time_tick <= '0';
cnt_t <= cnt_t + '1';
end if;
end if;
end process;

All values changes in array using vhdl

I'm trying to make brick break in VHDL.
Everything went well but I have a weird problem.
In a piece of my code you see below I change the value to '0' at index (y,x) in my array when the ball reaches the edges of a brick. The problem is that all the values in my array change to 0, even when the ball is not moving (When the program start up, the ball is not moving).
process(Ball_x1,Ball_x2,Ball_y1,Ball_y2) begin
x1 <= 280 + (x * 55); --edges of my brick
x2 <= 280 + ((x + 1) * 55);
y1 <= 108 + (y * 13);
y2 <= 108 + ((y + 1) * 13);
waardeArray := level1(y,x);
if (vcnt >= y1) and (vcnt <= y2) then
if (Ball_x1 >= x1) and (Ball_x1 <= x2) then -- edges of my ball
if waardeArray = '1' then
level1(y,x) := '0';
end if;
end if;
end if;
end process;
The declaration of my array is
type levels is array ( 0 to 3, 0 to 5 ) of bit;
shared variable level1 : levels := (
('1','0','0','0','0','1'),
('0','1','0','0','1','0'),
('0','0','1','1','0','0'),
('0','0','1','1','0','0')
);
Next variable is used to store the value of the array at place (y,x)
shared variable waardeArray: bit;
It's the intention to use Ball_x2 etc too but I just tried with 1 edge of my ball to test the code.
Update
process(Ball_x1,Ball_x2,Ball_y1,Ball_y2) begin
x1 <= 280 + (x * 55); -- edges of my brick
x2 <= 280 + ((x + 1) * 55);
y1 <= 108 + (y * 13);
y2 <= 108 + ((y + 1) * 13);
if (vcnt >= y1) and (vcnt <= y2) then --vcnt is from another component where I send my data to my screen
if (Ball_x1 >= x1) and (Ball_x1 <= x2) then -- left edge of my ball
if level1(y)(x) = '1' then
level1(y)(x) <= '1'; --I do this to test if the elements with value 1 stay 1 and the 0 stay 0 ata initialization, but every element in my array change to 1.
else
level1(y)(x) <= level1(y)(x);
end if;
end if;
end if;
end process;
Declarations
signal x: integer range 0 to 6 := 0; --Six is used for something else.
signal y: integer range 0 to 3 := 0;
signal x1: integer range 279 to 616;
signal x2: integer range 279 to 616;
signal y1: integer range 107 to 228;
signal y2: integer range 107 to 228;
signal color: std_logic_vector (7 downto 0) := "00000111";
type levels is array ( 0 to 3) of std_logic_vector (5 downto 0);
signal level1 : levels := ("101101",
"010010",
"001100",
"001100");
This is my intention
Don't use shared variables. If you need to communicate a value between processes, use a signal. You can't be sure of the order at which updates compared to reads occur using shared variables. Well, you can, but you have to use protected types.
Also, in your process, you are looking at the values of x, y and vcnt. But those signals (I hope they are signals not shared variables :) are not in the sensitivity list of the process, so when they change, your process will not be triggered.

Resources