Verilog code for order check
This commit is contained in:
parent
73c20415f8
commit
a10bb8df71
|
@ -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
|
Loading…
Reference in New Issue