Skip to content

Instantly share code, notes, and snippets.

@codedot
Last active December 19, 2015 04:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codedot/5899384 to your computer and use it in GitHub Desktop.
Save codedot/5899384 to your computer and use it in GitHub Desktop.
Bitcoin miner based on combinational logic for SHA-256
`define INDEX(a, i) a[32 * (i)+:32]
`define ROR32(x, n) {x[(n) - 1:0], x[31:(n)]}
module sched(w0, w1, w9, w14, w16);
input [31:0] w0, w1, w9, w14;
output [31:0] w16;
wire [31:0] s0, s1;
assign s0 = `ROR32(w1, 7) ^ `ROR32(w1, 18) ^ (w1 >> 3);
assign s1 = `ROR32(w14, 17) ^ `ROR32(w14, 19) ^ (w14 >> 10);
assign w16 = w0 + s0 + w9 + s1;
endmodule
module round(in, word, out);
input [255:0] in;
input [31:0] word;
output [255:0] out;
wire [31:0] a, b, c, d, e, f, g, h;
wire [31:0] s1, ch, t1, s0, maj, t2;
assign {h, g, f, e, d, c, b, a} = in;
assign s1 = `ROR32(e, 6) ^ `ROR32(e, 11) ^ `ROR32(e, 25);
assign ch = g ^ (e & (f ^ g));
assign t1 = h + s1 + ch + word;
assign s0 = `ROR32(a, 2) ^ `ROR32(a, 13) ^ `ROR32(a, 22);
assign maj = (a & b) | (c & (a | b));
assign t2 = s0 + maj;
assign out = {g, f, e, d + t1, c, b, a, t1 + t2};
endmodule
module synch(clk, prev, konst, next);
input clk;
input [767:0] prev;
input [31:0] konst;
output reg [767:0] next;
wire [255:0] result;
wire [31:0] w0, w1, w9, w14, w16;
assign w0 = `INDEX(prev, 0);
assign w1 = `INDEX(prev, 1);
assign w9 = `INDEX(prev, 9);
assign w14 = `INDEX(prev, 14);
sched link(w0, w1, w9, w14, w16);
round step(prev[767:512], konst + w0, result);
always @(posedge clk)
next <= {result, w16, prev[511:32]};
endmodule
module chain(clk, init, data, hash);
input clk;
input [255:0] init;
input [511:0] data;
output [255:0] hash;
wire [2047:0] konst;
assign konst = {
32'hc67178f2, 32'hbef9a3f7, 32'ha4506ceb, 32'h90befffa,
32'h8cc70208, 32'h84c87814, 32'h78a5636f, 32'h748f82ee,
32'h682e6ff3, 32'h5b9cca4f, 32'h4ed8aa4a, 32'h391c0cb3,
32'h34b0bcb5, 32'h2748774c, 32'h1e376c08, 32'h19a4c116,
32'h106aa070, 32'hf40e3585, 32'hd6990624, 32'hd192e819,
32'hc76c51a3, 32'hc24b8b70, 32'ha81a664b, 32'ha2bfe8a1,
32'h92722c85, 32'h81c2c92e, 32'h766a0abb, 32'h650a7354,
32'h53380d13, 32'h4d2c6dfc, 32'h2e1b2138, 32'h27b70a85,
32'h14292967, 32'h06ca6351, 32'hd5a79147, 32'hc6e00bf3,
32'hbf597fc7, 32'hb00327c8, 32'ha831c66d, 32'h983e5152,
32'h76f988da, 32'h5cb0a9dc, 32'h4a7484aa, 32'h2de92c6f,
32'h240ca1cc, 32'h0fc19dc6, 32'hefbe4786, 32'he49b69c1,
32'hc19bf174, 32'h9bdc06a7, 32'h80deb1fe, 32'h72be5d74,
32'h550c7dc3, 32'h243185be, 32'h12835b01, 32'hd807aa98,
32'hab1c5ed5, 32'h923f82a4, 32'h59f111f1, 32'h3956c25b,
32'he9b5dba5, 32'hb5c0fbcf, 32'h71374491, 32'h428a2f98
};
genvar i;
generate
for (i = 0; i < 64; i = i + 1) begin: array
wire [767:0] prev, next;
if (i)
assign prev = array[i - 1].next;
else
assign prev = {init, data};
synch node(clk, prev, `INDEX(konst, i), next);
end
for (i = 0; i < 8; i = i + 1) begin: adder
assign `INDEX(hash, i) = `INDEX(init, i) +
`INDEX(array[63].next, i + 16);
end
endgenerate
endmodule
module miner(clk, data, mid, result, found);
input clk;
input [255:0] mid;
input [127:0] data;
output [31:0] result;
output found;
reg [31:0] nonce = 32'b0;
wire [255:0] hash1, hash;
chain sha1(clk, mid, {
32'h00000280, 32'h00000000, 32'h00000000, 32'h00000000,
32'h00000000, 32'h00000000, 32'h00000000, 32'h00000000,
32'h00000000, 32'h00000000, 32'h00000000, 32'h80000000,
result, data[95:0]
}, hash1);
chain sha2(clk, {
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
}, hash);
assign result = nonce + data[127:96];
assign found = (32'b0 == `INDEX(hash, 7));
always @(posedge clk)
nonce <= nonce + 1;
endmodule
`ifdef SIM
module proof;
reg clk = 1'b0;
wire [31:0] result;
wire found;
miner core(clk, {
32'h381353f9, 32'h378a0e1c, 32'hfd270c51, 32'ha7f5f990
}, {
32'h00f10dad, 32'hacc0caa8, 32'h7482c0f3, 32'ha66f356d,
32'hdb1ff3ca, 32'hfb545b91, 32'h1efebbc8, 32'h24e39e50
}, result, found);
always begin
if (result >= 32'h381353fb + 128)
$finish;
#1 clk <= ~clk;
#1 clk <= ~clk;
if (result >= 32'h381353f9 + 128)
$display("%x %x %x", result - 128, found, core.hash);
end
endmodule
`endif
all: comb
./comb
clean:
-rm -f comb
.SUFFIXES: .v
.v:
iverilog -Wall -DSIM -o $@ $<
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment