Verilog code for order check

This commit is contained in:
bsdevlin 2019-02-26 16:58:19 -05:00
parent 73c20415f8
commit a10bb8df71
1 changed files with 92 additions and 0 deletions

View File

@ -0,0 +1,92 @@
/*
This verifies that a Zcash equihash solution has the correct ordering.
Take input stream of indices which make up a solution, and checks
left-most leaf nodes at each level are in increasing order.
Code is split up into 3 main always blocks, one for loading RAM, one for parsing
output and loading the Blake2b block, and the final for running checks.
Copyright (C) 2019 Benjamin Devlin and Zcash Foundation
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
module zcash_verif_equihash_order
import zcash_verif_pkg::*;
(
input i_clk, i_rst,
if_axi_stream.sink i_axi,
output logic o_order_wrong,
output logic o_val
);
logic [$clog2(SOL_LIST_LEN)-1:0] sol_cnt;
logic [K-1:0] order_check;
logic [K-1:0] index_val;
logic [K-1:0][SOL_BITS-1:0] index_l;
logic done;
// Control for writing memory with indcies as they come in
always_ff @ (posedge i_clk) begin
if (i_rst) begin
i_axi.rdy <= 0;
o_order_wrong <= 0;
o_val <= 0;
sol_cnt <= 0;
done <= 0;
index_l <= 0;
index_val <= 0;
order_check <= 0;
end else begin
i_axi.rdy <= 1;
o_val <= 0;
if (i_axi.val && i_axi.rdy) begin
sol_cnt <= sol_cnt + 1;
// We check if we need to either latch the current value into some level,
// or need to do a comparison
for (int i = 0; i < K; i++) begin
if (sol_cnt % (1 << i) == 0) begin
if (index_val[i] == 0) begin
index_l[i] <= i_axi.dat;
index_val[i] <= 1;
end else begin
// If this is greater than or equal then we fail the order check
if (i_axi.dat <= index_l[i])
order_check[i] <= order_check[i] || 1;
index_val[i] <= 0;
end
end
end
done <= i_axi.eop;
end
if (done) begin
done <= 0;
order_check <= 0;
index_val <= 0;
o_order_wrong <= |order_check;
o_val <= 1;
sol_cnt <= 0;
end
end
end
endmodule