Я хочу поделиться Verilog код чисто комбинационной Hasher. Насколько мне известно, все доступные шахтеры FPGA требуется более одного тактового цикла для обработки одного значения одноразового номера (например, 6 тактов с шахтером kramble в для de0-нано борту). Этот код, в отличии от этого, требуется только один цикл для вычисления два SHA-256 хэша.
Пожалуйста, обратите внимание, что код был протестирован только моделированием, так как нет аппаратных средств здесь, чтобы запустить его. Для Cyclone IV E, реализация синтезирует в около 55000 LEs, который будет вписываться в Terasic DE2-115, например.
Icarus Verilog следует назвать следующие:
Код:
iverilog -Wall -DSIM -o расческа comb.v
И, наконец, здесь идет сам код:
Код:
`Определить INDEX (а, я) а [32 * (I) +: 32]
`Определить ROR32 (х, п) {х [(N) - 1: 0], х [31: (п)]}
модуль круглые (данные, слово, хэш);
вход [255: 0] данных;
вход [31: 0] слово;
Выход [255: 0] хэш;
Провод [31: 0] а, б, в, г, д, е, ж, з;
Провод [31: 0] s1, ч, t1, s0, Maj, t2;
назначить = `INDEX (данные, 0);
назначить Ь = `INDEX (данные, 1);
назначать с = `INDEX (данные, 2);
присвоить D = `INDEX (данные, 3);
назначать е = `INDEX (данные, 4);
назначить F = `INDEX (данные, 5);
назначить г = `INDEX (данные, 6);
назначить час = `INDEX (данные, 7);
назначить s1 = `ROR32 (е, 6) ^` ROR32 (е, 11) ^ `ROR32 (е, 25);
назначить CH = г ^ (е & (Е ^ г));
назначить t1 = H + s1 + ч + слово;
назначить s0 = `ROR32 (а, 2) ^` ROR32 (а, 13) ^ `ROR32 (а, 22);
назначить Maj = (а & б) | (с & (А | б));
назначить t2 = s0 + Maj;
назначить хэш = {G, F, E, D + t1, C, B, A, t1 + t2};
endmodule
Модуль цепи (первонач, данные, хэш);
вход [255: 0] INIT;
вход [511: 0] данных;
Выход [255: 0] хэш;
проволочный [31: 0] Слово [0:63];
localparam Конст = {
32'h428a2f98, 32'h71374491, 32'hb5c0fbcf, 32'he9b5dba5,
32'h3956c25b, 32'h59f111f1, 32'h923f82a4, 32'hab1c5ed5,
32'hd807aa98, 32'h12835b01, 32'h243185be, 32'h550c7dc3,
32'h72be5d74, 32'h80deb1fe, 32'h9bdc06a7, 32'hc19bf174,
32'he49b69c1, 32'hefbe4786, 32'h0fc19dc6, 32'h240ca1cc,
32'h2de92c6f, 32'h4a7484aa, 32'h5cb0a9dc, 32'h76f988da,
32'h983e5152, 32'ha831c66d, 32'hb00327c8, 32'hbf597fc7,
32'hc6e00bf3, 32'hd5a79147, 32'h06ca6351, 32'h14292967,
32'h27b70a85, 32'h2e1b2138, 32'h4d2c6dfc, 32'h53380d13,
32'h650a7354, 32'h766a0abb, 32'h81c2c92e, 32'h92722c85,
32'ha2bfe8a1, 32'ha81a664b, 32'hc24b8b70, 32'hc76c51a3,
32'hd192e819, 32'hd6990624, 32'hf40e3585, 32'h106aa070,
32'h19a4c116, 32'h1e376c08, 32'h2748774c, 32'h34b0bcb5,
32'h391c0cb3, 32'h4ed8aa4a, 32'h5b9cca4f, 32'h682e6ff3,
32'h748f82ee, 32'h78a5636f, 32'h84c87814, 32'h8cc70208,
32'h90befffa, 32'ha4506ceb, 32'hbef9a3f7, 32'hc67178f2
};
genvar я;
генерировать
для (я = 0; я < 16; I = I + 1) начинают: во-первых
назначить слова [I] = `INDEX (данные, я);
конец
для (I = 16; я < 64; I = I + 1) начинают: смесь
Провод [31: 0] s0, s1;
присвоить S0 = `ROR32 (слова [я - 15], 7) ^
`ROR32 (слова [я - 15], 18) ^
(Слова [я - 15] >> 3);
присвоить s1 = `ROR32 (слова [я - 2], 17) ^
`ROR32 (слова [я - 2], 19) ^
(Слова [я - 2] >> 10);
назначить слова [I] = слов [I - 16] + слова [я - 7] +
s0 + s1;
конец
для (я = 0; я < 64; I = I + 1) начинают: массив
Провод [31: 0] = ш `INDEX (Конст, 63 - я) + слова [I];
Провод [255: 0] д, ч;
Если я)
назначить д = массив [я - 1] .h;
еще
присвоить D = INIT;
круглый шаг (д, ш, ч);
конец
для (я = 0; я < 8; I = I + 1) начинают: сумматор
назначить `INDEX (хэш, I) =` INDEX (массив [63] .h, я) +
`ИНДЕКС (первонач, я);
конец
endgenerate
endmodule
Модуль шахтер (CLK, данные, середина, результат, найденный);
вход CLK;
вход [255: 0] в середине;
вход [127: 0] данных;
Выход [31: 0] результат;
Выход найден;
рег [31: 0] = Nonce 32'b0;
Провод [255: 0] hash1, хэш;
цепь sha1 (середина, {
32'h00000280, 32'h00000000, 32'h00000000, 32'h00000000,
32'h00000000, 32'h00000000, 32'h00000000, 32'h00000000,
32'h00000000, 32'h00000000, 32'h00000000, 32'h80000000,
результат, данные [95: 0]
}, Hash1);
цепь SHA2 ({
32'h5be0cd19, 32'h1f83d9ab, 32'h9b05688c, 32'h510e527f,
32'ha54ff53a, 32'h3c6ef372, 32'hbb67ae85, 32'h6a09e667
}, {
32'h00000100, 32'h00000000, 32'h00000000, 32'h00000000,
32'h00000000, 32'h00000000, 32'h00000000, 32'h80000000,
hash1
}, Хэш);
присвоить результат = временное значение + данные [127: 96];
присвоить найденное = (32'b0 == `ИНДЕКС (хэш, 7));
всегда @ (posedge CLK)
данное время <= Nonce + 1;
endmodule
`IFDEF SIM
модуль доказательства;
рег CLK = 1'b0;
Провод [31: 0] результат;
Проволока найдено;
минер сердечник (CLK, {
32'h381353f8, 32'h378a0e1c, 32'hfd270c51, 32'ha7f5f990
}, {
32'h00f10dad, 32'hacc0caa8, 32'h7482c0f3, 32'ha66f356d,
32'hdb1ff3ca, 32'hfb545b91, 32'h1efebbc8, 32'h24e39e50
}, Результат, найденный);
всегда начинается
если (результат > 32'h381353fa)
$ Отделка;
# 1 CLK <= ~ CLK;
# 1 CLK <= ~ CLK;
$ Дисплей ("% Х% х% х", Результат, найдено, core.hash);
конец
endmodule
`ENDIF
`Определить ROR32 (х, п) {х [(N) - 1: 0], х [31: (п)]}
модуль круглые (данные, слово, хэш);
вход [255: 0] данных;
вход [31: 0] слово;
Выход [255: 0] хэш;
Провод [31: 0] а, б, в, г, д, е, ж, з;
Провод [31: 0] s1, ч, t1, s0, Maj, t2;
назначить = `INDEX (данные, 0);
назначить Ь = `INDEX (данные, 1);
назначать с = `INDEX (данные, 2);
присвоить D = `INDEX (данные, 3);
назначать е = `INDEX (данные, 4);
назначить F = `INDEX (данные, 5);
назначить г = `INDEX (данные, 6);
назначить час = `INDEX (данные, 7);
назначить s1 = `ROR32 (е, 6) ^` ROR32 (е, 11) ^ `ROR32 (е, 25);
назначить CH = г ^ (е & (Е ^ г));
назначить t1 = H + s1 + ч + слово;
назначить s0 = `ROR32 (а, 2) ^` ROR32 (а, 13) ^ `ROR32 (а, 22);
назначить Maj = (а & б) | (с & (А | б));
назначить t2 = s0 + Maj;
назначить хэш = {G, F, E, D + t1, C, B, A, t1 + t2};
endmodule
Модуль цепи (первонач, данные, хэш);
вход [255: 0] INIT;
вход [511: 0] данных;
Выход [255: 0] хэш;
проволочный [31: 0] Слово [0:63];
localparam Конст = {
32'h428a2f98, 32'h71374491, 32'hb5c0fbcf, 32'he9b5dba5,
32'h3956c25b, 32'h59f111f1, 32'h923f82a4, 32'hab1c5ed5,
32'hd807aa98, 32'h12835b01, 32'h243185be, 32'h550c7dc3,
32'h72be5d74, 32'h80deb1fe, 32'h9bdc06a7, 32'hc19bf174,
32'he49b69c1, 32'hefbe4786, 32'h0fc19dc6, 32'h240ca1cc,
32'h2de92c6f, 32'h4a7484aa, 32'h5cb0a9dc, 32'h76f988da,
32'h983e5152, 32'ha831c66d, 32'hb00327c8, 32'hbf597fc7,
32'hc6e00bf3, 32'hd5a79147, 32'h06ca6351, 32'h14292967,
32'h27b70a85, 32'h2e1b2138, 32'h4d2c6dfc, 32'h53380d13,
32'h650a7354, 32'h766a0abb, 32'h81c2c92e, 32'h92722c85,
32'ha2bfe8a1, 32'ha81a664b, 32'hc24b8b70, 32'hc76c51a3,
32'hd192e819, 32'hd6990624, 32'hf40e3585, 32'h106aa070,
32'h19a4c116, 32'h1e376c08, 32'h2748774c, 32'h34b0bcb5,
32'h391c0cb3, 32'h4ed8aa4a, 32'h5b9cca4f, 32'h682e6ff3,
32'h748f82ee, 32'h78a5636f, 32'h84c87814, 32'h8cc70208,
32'h90befffa, 32'ha4506ceb, 32'hbef9a3f7, 32'hc67178f2
};
genvar я;
генерировать
для (я = 0; я < 16; I = I + 1) начинают: во-первых
назначить слова [I] = `INDEX (данные, я);
конец
для (I = 16; я < 64; I = I + 1) начинают: смесь
Провод [31: 0] s0, s1;
присвоить S0 = `ROR32 (слова [я - 15], 7) ^
`ROR32 (слова [я - 15], 18) ^
(Слова [я - 15] >> 3);
присвоить s1 = `ROR32 (слова [я - 2], 17) ^
`ROR32 (слова [я - 2], 19) ^
(Слова [я - 2] >> 10);
назначить слова [I] = слов [I - 16] + слова [я - 7] +
s0 + s1;
конец
для (я = 0; я < 64; I = I + 1) начинают: массив
Провод [31: 0] = ш `INDEX (Конст, 63 - я) + слова [I];
Провод [255: 0] д, ч;
Если я)
назначить д = массив [я - 1] .h;
еще
присвоить D = INIT;
круглый шаг (д, ш, ч);
конец
для (я = 0; я < 8; I = I + 1) начинают: сумматор
назначить `INDEX (хэш, I) =` INDEX (массив [63] .h, я) +
`ИНДЕКС (первонач, я);
конец
endgenerate
endmodule
Модуль шахтер (CLK, данные, середина, результат, найденный);
вход CLK;
вход [255: 0] в середине;
вход [127: 0] данных;
Выход [31: 0] результат;
Выход найден;
рег [31: 0] = Nonce 32'b0;
Провод [255: 0] hash1, хэш;
цепь sha1 (середина, {
32'h00000280, 32'h00000000, 32'h00000000, 32'h00000000,
32'h00000000, 32'h00000000, 32'h00000000, 32'h00000000,
32'h00000000, 32'h00000000, 32'h00000000, 32'h80000000,
результат, данные [95: 0]
}, Hash1);
цепь SHA2 ({
32'h5be0cd19, 32'h1f83d9ab, 32'h9b05688c, 32'h510e527f,
32'ha54ff53a, 32'h3c6ef372, 32'hbb67ae85, 32'h6a09e667
}, {
32'h00000100, 32'h00000000, 32'h00000000, 32'h00000000,
32'h00000000, 32'h00000000, 32'h00000000, 32'h80000000,
hash1
}, Хэш);
присвоить результат = временное значение + данные [127: 96];
присвоить найденное = (32'b0 == `ИНДЕКС (хэш, 7));
всегда @ (posedge CLK)
данное время <= Nonce + 1;
endmodule
`IFDEF SIM
модуль доказательства;
рег CLK = 1'b0;
Провод [31: 0] результат;
Проволока найдено;
минер сердечник (CLK, {
32'h381353f8, 32'h378a0e1c, 32'hfd270c51, 32'ha7f5f990
}, {
32'h00f10dad, 32'hacc0caa8, 32'h7482c0f3, 32'ha66f356d,
32'hdb1ff3ca, 32'hfb545b91, 32'h1efebbc8, 32'h24e39e50
}, Результат, найденный);
всегда начинается
если (результат > 32'h381353fa)
$ Отделка;
# 1 CLK <= ~ CLK;
# 1 CLK <= ~ CLK;
$ Дисплей ("% Х% х% х", Результат, найдено, core.hash);
конец
endmodule
`ENDIF