diff --git a/bittware_xupvvh/synth/bittware_xupvvh_top.xdc b/bittware_xupvvh/synth/bittware_xupvvh_top.xdc
index bade581..46432e5 100644
--- a/bittware_xupvvh/synth/bittware_xupvvh_top.xdc
+++ b/bittware_xupvvh/synth/bittware_xupvvh_top.xdc
@@ -190,253 +190,22 @@ set_bus_skew -from [get_pins -filter { NAME =~ "*ram*C" } -of_objects [get_cell
set_max_delay -datapath_only -from [get_pins -filter { NAME =~ "*ram*C" } -of_objects [get_cells -hierarchical -filter {NAME =~ zcash_fpga_top/equihash_verif_top/dup_check_fifo_out/* }]] -to [get_pins -filter { NAME =~ "*o_dat_b*D" } -of_objects [get_cells -hierarchical -filter {NAME =~ zcash_fpga_top/equihash_verif_top/dup_check_fifo_out/* }]] 1.667
-create_debug_core u_ila_0 ila
-set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0]
-set_property ALL_PROBE_SAME_MU_CNT 1 [get_debug_cores u_ila_0]
-set_property C_ADV_TRIGGER false [get_debug_cores u_ila_0]
-set_property C_DATA_DEPTH 1024 [get_debug_cores u_ila_0]
-set_property C_EN_STRG_QUAL false [get_debug_cores u_ila_0]
-set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0]
-set_property C_TRIGIN_EN false [get_debug_cores u_ila_0]
-set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0]
-set_property port_width 1 [get_debug_ports u_ila_0/clk]
-connect_debug_port u_ila_0/clk [get_nets [list clk_300]]
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0]
-set_property port_width 2 [get_debug_ports u_ila_0/probe0]
-connect_debug_port u_ila_0/probe0 [get_nets [list {uart_wrapper/uart_axi_rresp[0]} {uart_wrapper/uart_axi_rresp[1]}]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe1]
-set_property port_width 8 [get_debug_ports u_ila_0/probe1]
-connect_debug_port u_ila_0/probe1 [get_nets [list {uart_wrapper/rxuart_debug_if/dat[0]} {uart_wrapper/rxuart_debug_if/dat[1]} {uart_wrapper/rxuart_debug_if/dat[2]} {uart_wrapper/rxuart_debug_if/dat[3]} {uart_wrapper/rxuart_debug_if/dat[4]} {uart_wrapper/rxuart_debug_if/dat[5]} {uart_wrapper/rxuart_debug_if/dat[6]} {uart_wrapper/rxuart_debug_if/dat[7]}]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe2]
-set_property port_width 8 [get_debug_ports u_ila_0/probe2]
-connect_debug_port u_ila_0/probe2 [get_nets [list {uart_wrapper/txuart_debug_if/dat[0]} {uart_wrapper/txuart_debug_if/dat[1]} {uart_wrapper/txuart_debug_if/dat[2]} {uart_wrapper/txuart_debug_if/dat[3]} {uart_wrapper/txuart_debug_if/dat[4]} {uart_wrapper/txuart_debug_if/dat[5]} {uart_wrapper/txuart_debug_if/dat[6]} {uart_wrapper/txuart_debug_if/dat[7]}]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe3]
-set_property port_width 2 [get_debug_ports u_ila_0/probe3]
-connect_debug_port u_ila_0/probe3 [get_nets [list {uart_wrapper/uart_axi_awaddr[2]} {uart_wrapper/uart_axi_awaddr[3]}]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe4]
-set_property port_width 8 [get_debug_ports u_ila_0/probe4]
-connect_debug_port u_ila_0/probe4 [get_nets [list {uart_wrapper/tx_byt_len[8]} {uart_wrapper/tx_byt_len[9]} {uart_wrapper/tx_byt_len[10]} {uart_wrapper/tx_byt_len[11]} {uart_wrapper/tx_byt_len[12]} {uart_wrapper/tx_byt_len[13]} {uart_wrapper/tx_byt_len[14]} {uart_wrapper/tx_byt_len[15]}]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe5]
-set_property port_width 32 [get_debug_ports u_ila_0/probe5]
-connect_debug_port u_ila_0/probe5 [get_nets [list {uart_wrapper/uart_axi_rdata[0]} {uart_wrapper/uart_axi_rdata[1]} {uart_wrapper/uart_axi_rdata[2]} {uart_wrapper/uart_axi_rdata[3]} {uart_wrapper/uart_axi_rdata[4]} {uart_wrapper/uart_axi_rdata[5]} {uart_wrapper/uart_axi_rdata[6]} {uart_wrapper/uart_axi_rdata[7]} {uart_wrapper/uart_axi_rdata[8]} {uart_wrapper/uart_axi_rdata[9]} {uart_wrapper/uart_axi_rdata[10]} {uart_wrapper/uart_axi_rdata[11]} {uart_wrapper/uart_axi_rdata[12]} {uart_wrapper/uart_axi_rdata[13]} {uart_wrapper/uart_axi_rdata[14]} {uart_wrapper/uart_axi_rdata[15]} {uart_wrapper/uart_axi_rdata[16]} {uart_wrapper/uart_axi_rdata[17]} {uart_wrapper/uart_axi_rdata[18]} {uart_wrapper/uart_axi_rdata[19]} {uart_wrapper/uart_axi_rdata[20]} {uart_wrapper/uart_axi_rdata[21]} {uart_wrapper/uart_axi_rdata[22]} {uart_wrapper/uart_axi_rdata[23]} {uart_wrapper/uart_axi_rdata[24]} {uart_wrapper/uart_axi_rdata[25]} {uart_wrapper/uart_axi_rdata[26]} {uart_wrapper/uart_axi_rdata[27]} {uart_wrapper/uart_axi_rdata[28]} {uart_wrapper/uart_axi_rdata[29]} {uart_wrapper/uart_axi_rdata[30]} {uart_wrapper/uart_axi_rdata[31]}]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6]
-set_property port_width 1 [get_debug_ports u_ila_0/probe6]
-connect_debug_port u_ila_0/probe6 [get_nets [list uart_wrapper/txuart_debug_if/ctl]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7]
-set_property port_width 1 [get_debug_ports u_ila_0/probe7]
-connect_debug_port u_ila_0/probe7 [get_nets [list uart_wrapper/rxuart_debug_if/ctl]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe8]
-set_property port_width 1 [get_debug_ports u_ila_0/probe8]
-connect_debug_port u_ila_0/probe8 [get_nets [list uart_wrapper/txuart_debug_if/eop]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe9]
-set_property port_width 1 [get_debug_ports u_ila_0/probe9]
-connect_debug_port u_ila_0/probe9 [get_nets [list uart_wrapper/rxuart_debug_if/eop]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe10]
-set_property port_width 1 [get_debug_ports u_ila_0/probe10]
-connect_debug_port u_ila_0/probe10 [get_nets [list uart_wrapper/rxuart_debug_if/err]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe11]
-set_property port_width 1 [get_debug_ports u_ila_0/probe11]
-connect_debug_port u_ila_0/probe11 [get_nets [list uart_wrapper/txuart_debug_if/err]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe12]
-set_property port_width 1 [get_debug_ports u_ila_0/probe12]
-connect_debug_port u_ila_0/probe12 [get_nets [list uart_wrapper/txuart_debug_if/mod]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe13]
-set_property port_width 1 [get_debug_ports u_ila_0/probe13]
-connect_debug_port u_ila_0/probe13 [get_nets [list uart_wrapper/rxuart_debug_if/mod]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe14]
-set_property port_width 1 [get_debug_ports u_ila_0/probe14]
-connect_debug_port u_ila_0/probe14 [get_nets [list uart_wrapper/txuart_debug_if/rdy]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe15]
-set_property port_width 1 [get_debug_ports u_ila_0/probe15]
-connect_debug_port u_ila_0/probe15 [get_nets [list uart_wrapper/rxuart_debug_if/rdy]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe16]
-set_property port_width 1 [get_debug_ports u_ila_0/probe16]
-connect_debug_port u_ila_0/probe16 [get_nets [list uart_wrapper/rxuart_debug_if/sop]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe17]
-set_property port_width 1 [get_debug_ports u_ila_0/probe17]
-connect_debug_port u_ila_0/probe17 [get_nets [list uart_wrapper/txuart_debug_if/sop]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe18]
-set_property port_width 1 [get_debug_ports u_ila_0/probe18]
-connect_debug_port u_ila_0/probe18 [get_nets [list uart_wrapper/uart_axi_arready]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe19]
-set_property port_width 1 [get_debug_ports u_ila_0/probe19]
-connect_debug_port u_ila_0/probe19 [get_nets [list uart_wrapper/uart_axi_awready]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe20]
-set_property port_width 1 [get_debug_ports u_ila_0/probe20]
-connect_debug_port u_ila_0/probe20 [get_nets [list uart_wrapper/uart_axi_rvalid]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe21]
-set_property port_width 1 [get_debug_ports u_ila_0/probe21]
-connect_debug_port u_ila_0/probe21 [get_nets [list uart_wrapper/rxuart_debug_if/val]]
-create_debug_port u_ila_0 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe22]
-set_property port_width 1 [get_debug_ports u_ila_0/probe22]
-connect_debug_port u_ila_0/probe22 [get_nets [list uart_wrapper/txuart_debug_if/val]]
-create_debug_core u_ila_1 ila
-set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_1]
-set_property ALL_PROBE_SAME_MU_CNT 1 [get_debug_cores u_ila_1]
-set_property C_ADV_TRIGGER false [get_debug_cores u_ila_1]
-set_property C_DATA_DEPTH 1024 [get_debug_cores u_ila_1]
-set_property C_EN_STRG_QUAL false [get_debug_cores u_ila_1]
-set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_1]
-set_property C_TRIGIN_EN false [get_debug_cores u_ila_1]
-set_property C_TRIGOUT_EN false [get_debug_cores u_ila_1]
-set_property port_width 1 [get_debug_ports u_ila_1/clk]
-connect_debug_port u_ila_1/clk [get_nets [list clk_wiz_mmcm/inst/clk_200]]
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe0]
-set_property port_width 3 [get_debug_ports u_ila_1/probe0]
connect_debug_port u_ila_1/probe0 [get_nets [list {zcash_fpga_top/secp256k1_top/debug_if_rx/mod[0]} {zcash_fpga_top/secp256k1_top/debug_if_rx/mod[1]} {zcash_fpga_top/secp256k1_top/debug_if_rx/mod[2]}]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe1]
-set_property port_width 64 [get_debug_ports u_ila_1/probe1]
connect_debug_port u_ila_1/probe1 [get_nets [list {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[0]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[1]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[2]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[3]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[4]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[5]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[6]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[7]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[8]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[9]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[10]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[11]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[12]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[13]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[14]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[15]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[16]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[17]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[18]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[19]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[20]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[21]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[22]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[23]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[24]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[25]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[26]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[27]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[28]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[29]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[30]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[31]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[32]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[33]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[34]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[35]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[36]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[37]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[38]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[39]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[40]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[41]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[42]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[43]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[44]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[45]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[46]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[47]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[48]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[49]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[50]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[51]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[52]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[53]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[54]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[55]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[56]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[57]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[58]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[59]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[60]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[61]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[62]} {zcash_fpga_top/secp256k1_top/debug_if_tx/dat[63]}]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe2]
-set_property port_width 3 [get_debug_ports u_ila_1/probe2]
connect_debug_port u_ila_1/probe2 [get_nets [list {zcash_fpga_top/secp256k1_top/debug_if_tx/mod[0]} {zcash_fpga_top/secp256k1_top/debug_if_tx/mod[1]} {zcash_fpga_top/secp256k1_top/debug_if_tx/mod[2]}]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe3]
-set_property port_width 64 [get_debug_ports u_ila_1/probe3]
connect_debug_port u_ila_1/probe3 [get_nets [list {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[0]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[1]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[2]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[3]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[4]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[5]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[6]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[7]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[8]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[9]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[10]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[11]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[12]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[13]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[14]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[15]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[16]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[17]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[18]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[19]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[20]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[21]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[22]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[23]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[24]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[25]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[26]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[27]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[28]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[29]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[30]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[31]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[32]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[33]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[34]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[35]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[36]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[37]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[38]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[39]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[40]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[41]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[42]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[43]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[44]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[45]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[46]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[47]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[48]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[49]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[50]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[51]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[52]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[53]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[54]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[55]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[56]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[57]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[58]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[59]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[60]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[61]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[62]} {zcash_fpga_top/secp256k1_top/debug_if_rx/dat[63]}]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe4]
-set_property port_width 64 [get_debug_ports u_ila_1/probe4]
-connect_debug_port u_ila_1/probe4 [get_nets [list {zcash_fpga_top/control_top/debug_if_tx/dat[0]} {zcash_fpga_top/control_top/debug_if_tx/dat[1]} {zcash_fpga_top/control_top/debug_if_tx/dat[2]} {zcash_fpga_top/control_top/debug_if_tx/dat[3]} {zcash_fpga_top/control_top/debug_if_tx/dat[4]} {zcash_fpga_top/control_top/debug_if_tx/dat[5]} {zcash_fpga_top/control_top/debug_if_tx/dat[6]} {zcash_fpga_top/control_top/debug_if_tx/dat[7]} {zcash_fpga_top/control_top/debug_if_tx/dat[8]} {zcash_fpga_top/control_top/debug_if_tx/dat[9]} {zcash_fpga_top/control_top/debug_if_tx/dat[10]} {zcash_fpga_top/control_top/debug_if_tx/dat[11]} {zcash_fpga_top/control_top/debug_if_tx/dat[12]} {zcash_fpga_top/control_top/debug_if_tx/dat[13]} {zcash_fpga_top/control_top/debug_if_tx/dat[14]} {zcash_fpga_top/control_top/debug_if_tx/dat[15]} {zcash_fpga_top/control_top/debug_if_tx/dat[16]} {zcash_fpga_top/control_top/debug_if_tx/dat[17]} {zcash_fpga_top/control_top/debug_if_tx/dat[18]} {zcash_fpga_top/control_top/debug_if_tx/dat[19]} {zcash_fpga_top/control_top/debug_if_tx/dat[20]} {zcash_fpga_top/control_top/debug_if_tx/dat[21]} {zcash_fpga_top/control_top/debug_if_tx/dat[22]} {zcash_fpga_top/control_top/debug_if_tx/dat[23]} {zcash_fpga_top/control_top/debug_if_tx/dat[24]} {zcash_fpga_top/control_top/debug_if_tx/dat[25]} {zcash_fpga_top/control_top/debug_if_tx/dat[26]} {zcash_fpga_top/control_top/debug_if_tx/dat[27]} {zcash_fpga_top/control_top/debug_if_tx/dat[28]} {zcash_fpga_top/control_top/debug_if_tx/dat[29]} {zcash_fpga_top/control_top/debug_if_tx/dat[30]} {zcash_fpga_top/control_top/debug_if_tx/dat[31]} {zcash_fpga_top/control_top/debug_if_tx/dat[32]} {zcash_fpga_top/control_top/debug_if_tx/dat[33]} {zcash_fpga_top/control_top/debug_if_tx/dat[34]} {zcash_fpga_top/control_top/debug_if_tx/dat[35]} {zcash_fpga_top/control_top/debug_if_tx/dat[36]} {zcash_fpga_top/control_top/debug_if_tx/dat[37]} {zcash_fpga_top/control_top/debug_if_tx/dat[38]} {zcash_fpga_top/control_top/debug_if_tx/dat[39]} {zcash_fpga_top/control_top/debug_if_tx/dat[40]} {zcash_fpga_top/control_top/debug_if_tx/dat[41]} {zcash_fpga_top/control_top/debug_if_tx/dat[42]} {zcash_fpga_top/control_top/debug_if_tx/dat[43]} {zcash_fpga_top/control_top/debug_if_tx/dat[44]} {zcash_fpga_top/control_top/debug_if_tx/dat[45]} {zcash_fpga_top/control_top/debug_if_tx/dat[46]} {zcash_fpga_top/control_top/debug_if_tx/dat[47]} {zcash_fpga_top/control_top/debug_if_tx/dat[48]} {zcash_fpga_top/control_top/debug_if_tx/dat[49]} {zcash_fpga_top/control_top/debug_if_tx/dat[50]} {zcash_fpga_top/control_top/debug_if_tx/dat[51]} {zcash_fpga_top/control_top/debug_if_tx/dat[52]} {zcash_fpga_top/control_top/debug_if_tx/dat[53]} {zcash_fpga_top/control_top/debug_if_tx/dat[54]} {zcash_fpga_top/control_top/debug_if_tx/dat[55]} {zcash_fpga_top/control_top/debug_if_tx/dat[56]} {zcash_fpga_top/control_top/debug_if_tx/dat[57]} {zcash_fpga_top/control_top/debug_if_tx/dat[58]} {zcash_fpga_top/control_top/debug_if_tx/dat[59]} {zcash_fpga_top/control_top/debug_if_tx/dat[60]} {zcash_fpga_top/control_top/debug_if_tx/dat[61]} {zcash_fpga_top/control_top/debug_if_tx/dat[62]} {zcash_fpga_top/control_top/debug_if_tx/dat[63]}]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe5]
-set_property port_width 3 [get_debug_ports u_ila_1/probe5]
-connect_debug_port u_ila_1/probe5 [get_nets [list {zcash_fpga_top/control_top/debug_if_tx/mod[0]} {zcash_fpga_top/control_top/debug_if_tx/mod[1]} {zcash_fpga_top/control_top/debug_if_tx/mod[2]}]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe6]
-set_property port_width 3 [get_debug_ports u_ila_1/probe6]
-connect_debug_port u_ila_1/probe6 [get_nets [list {zcash_fpga_top/control_top/debug_if_rx/mod[0]} {zcash_fpga_top/control_top/debug_if_rx/mod[1]} {zcash_fpga_top/control_top/debug_if_rx/mod[2]}]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe7]
-set_property port_width 64 [get_debug_ports u_ila_1/probe7]
-connect_debug_port u_ila_1/probe7 [get_nets [list {zcash_fpga_top/control_top/debug_if_rx/dat[0]} {zcash_fpga_top/control_top/debug_if_rx/dat[1]} {zcash_fpga_top/control_top/debug_if_rx/dat[2]} {zcash_fpga_top/control_top/debug_if_rx/dat[3]} {zcash_fpga_top/control_top/debug_if_rx/dat[4]} {zcash_fpga_top/control_top/debug_if_rx/dat[5]} {zcash_fpga_top/control_top/debug_if_rx/dat[6]} {zcash_fpga_top/control_top/debug_if_rx/dat[7]} {zcash_fpga_top/control_top/debug_if_rx/dat[8]} {zcash_fpga_top/control_top/debug_if_rx/dat[9]} {zcash_fpga_top/control_top/debug_if_rx/dat[10]} {zcash_fpga_top/control_top/debug_if_rx/dat[11]} {zcash_fpga_top/control_top/debug_if_rx/dat[12]} {zcash_fpga_top/control_top/debug_if_rx/dat[13]} {zcash_fpga_top/control_top/debug_if_rx/dat[14]} {zcash_fpga_top/control_top/debug_if_rx/dat[15]} {zcash_fpga_top/control_top/debug_if_rx/dat[16]} {zcash_fpga_top/control_top/debug_if_rx/dat[17]} {zcash_fpga_top/control_top/debug_if_rx/dat[18]} {zcash_fpga_top/control_top/debug_if_rx/dat[19]} {zcash_fpga_top/control_top/debug_if_rx/dat[20]} {zcash_fpga_top/control_top/debug_if_rx/dat[21]} {zcash_fpga_top/control_top/debug_if_rx/dat[22]} {zcash_fpga_top/control_top/debug_if_rx/dat[23]} {zcash_fpga_top/control_top/debug_if_rx/dat[24]} {zcash_fpga_top/control_top/debug_if_rx/dat[25]} {zcash_fpga_top/control_top/debug_if_rx/dat[26]} {zcash_fpga_top/control_top/debug_if_rx/dat[27]} {zcash_fpga_top/control_top/debug_if_rx/dat[28]} {zcash_fpga_top/control_top/debug_if_rx/dat[29]} {zcash_fpga_top/control_top/debug_if_rx/dat[30]} {zcash_fpga_top/control_top/debug_if_rx/dat[31]} {zcash_fpga_top/control_top/debug_if_rx/dat[32]} {zcash_fpga_top/control_top/debug_if_rx/dat[33]} {zcash_fpga_top/control_top/debug_if_rx/dat[34]} {zcash_fpga_top/control_top/debug_if_rx/dat[35]} {zcash_fpga_top/control_top/debug_if_rx/dat[36]} {zcash_fpga_top/control_top/debug_if_rx/dat[37]} {zcash_fpga_top/control_top/debug_if_rx/dat[38]} {zcash_fpga_top/control_top/debug_if_rx/dat[39]} {zcash_fpga_top/control_top/debug_if_rx/dat[40]} {zcash_fpga_top/control_top/debug_if_rx/dat[41]} {zcash_fpga_top/control_top/debug_if_rx/dat[42]} {zcash_fpga_top/control_top/debug_if_rx/dat[43]} {zcash_fpga_top/control_top/debug_if_rx/dat[44]} {zcash_fpga_top/control_top/debug_if_rx/dat[45]} {zcash_fpga_top/control_top/debug_if_rx/dat[46]} {zcash_fpga_top/control_top/debug_if_rx/dat[47]} {zcash_fpga_top/control_top/debug_if_rx/dat[48]} {zcash_fpga_top/control_top/debug_if_rx/dat[49]} {zcash_fpga_top/control_top/debug_if_rx/dat[50]} {zcash_fpga_top/control_top/debug_if_rx/dat[51]} {zcash_fpga_top/control_top/debug_if_rx/dat[52]} {zcash_fpga_top/control_top/debug_if_rx/dat[53]} {zcash_fpga_top/control_top/debug_if_rx/dat[54]} {zcash_fpga_top/control_top/debug_if_rx/dat[55]} {zcash_fpga_top/control_top/debug_if_rx/dat[56]} {zcash_fpga_top/control_top/debug_if_rx/dat[57]} {zcash_fpga_top/control_top/debug_if_rx/dat[58]} {zcash_fpga_top/control_top/debug_if_rx/dat[59]} {zcash_fpga_top/control_top/debug_if_rx/dat[60]} {zcash_fpga_top/control_top/debug_if_rx/dat[61]} {zcash_fpga_top/control_top/debug_if_rx/dat[62]} {zcash_fpga_top/control_top/debug_if_rx/dat[63]}]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe8]
-set_property port_width 32 [get_debug_ports u_ila_1/probe8]
-connect_debug_port u_ila_1/probe8 [get_nets [list {zcash_fpga_top/secp256k1_top/secp256k1_state[0]} {zcash_fpga_top/secp256k1_top/secp256k1_state[1]} {zcash_fpga_top/secp256k1_top/secp256k1_state[2]} {zcash_fpga_top/secp256k1_top/secp256k1_state[3]} {zcash_fpga_top/secp256k1_top/secp256k1_state[4]} {zcash_fpga_top/secp256k1_top/secp256k1_state[5]} {zcash_fpga_top/secp256k1_top/secp256k1_state[6]} {zcash_fpga_top/secp256k1_top/secp256k1_state[7]} {zcash_fpga_top/secp256k1_top/secp256k1_state[8]} {zcash_fpga_top/secp256k1_top/secp256k1_state[9]} {zcash_fpga_top/secp256k1_top/secp256k1_state[10]} {zcash_fpga_top/secp256k1_top/secp256k1_state[11]} {zcash_fpga_top/secp256k1_top/secp256k1_state[12]} {zcash_fpga_top/secp256k1_top/secp256k1_state[13]} {zcash_fpga_top/secp256k1_top/secp256k1_state[14]} {zcash_fpga_top/secp256k1_top/secp256k1_state[15]} {zcash_fpga_top/secp256k1_top/secp256k1_state[16]} {zcash_fpga_top/secp256k1_top/secp256k1_state[17]} {zcash_fpga_top/secp256k1_top/secp256k1_state[18]} {zcash_fpga_top/secp256k1_top/secp256k1_state[19]} {zcash_fpga_top/secp256k1_top/secp256k1_state[20]} {zcash_fpga_top/secp256k1_top/secp256k1_state[21]} {zcash_fpga_top/secp256k1_top/secp256k1_state[22]} {zcash_fpga_top/secp256k1_top/secp256k1_state[23]} {zcash_fpga_top/secp256k1_top/secp256k1_state[24]} {zcash_fpga_top/secp256k1_top/secp256k1_state[25]} {zcash_fpga_top/secp256k1_top/secp256k1_state[26]} {zcash_fpga_top/secp256k1_top/secp256k1_state[27]} {zcash_fpga_top/secp256k1_top/secp256k1_state[28]} {zcash_fpga_top/secp256k1_top/secp256k1_state[29]} {zcash_fpga_top/secp256k1_top/secp256k1_state[30]} {zcash_fpga_top/secp256k1_top/secp256k1_state[31]}]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe9]
-set_property port_width 1 [get_debug_ports u_ila_1/probe9]
-connect_debug_port u_ila_1/probe9 [get_nets [list zcash_fpga_top/control_top/debug_if_rx/ctl]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe10]
-set_property port_width 1 [get_debug_ports u_ila_1/probe10]
-connect_debug_port u_ila_1/probe10 [get_nets [list zcash_fpga_top/control_top/debug_if_tx/ctl]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe11]
-set_property port_width 1 [get_debug_ports u_ila_1/probe11]
connect_debug_port u_ila_1/probe11 [get_nets [list zcash_fpga_top/secp256k1_top/debug_if_rx/ctl]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe12]
-set_property port_width 1 [get_debug_ports u_ila_1/probe12]
connect_debug_port u_ila_1/probe12 [get_nets [list zcash_fpga_top/secp256k1_top/debug_if_tx/ctl]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe13]
-set_property port_width 1 [get_debug_ports u_ila_1/probe13]
connect_debug_port u_ila_1/probe13 [get_nets [list zcash_fpga_top/secp256k1_top/debug_if_rx/eop]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe14]
-set_property port_width 1 [get_debug_ports u_ila_1/probe14]
-connect_debug_port u_ila_1/probe14 [get_nets [list zcash_fpga_top/control_top/debug_if_tx/eop]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe15]
-set_property port_width 1 [get_debug_ports u_ila_1/probe15]
connect_debug_port u_ila_1/probe15 [get_nets [list zcash_fpga_top/secp256k1_top/debug_if_tx/eop]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe16]
-set_property port_width 1 [get_debug_ports u_ila_1/probe16]
-connect_debug_port u_ila_1/probe16 [get_nets [list zcash_fpga_top/control_top/debug_if_rx/eop]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe17]
-set_property port_width 1 [get_debug_ports u_ila_1/probe17]
-connect_debug_port u_ila_1/probe17 [get_nets [list zcash_fpga_top/control_top/debug_if_tx/err]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe18]
-set_property port_width 1 [get_debug_ports u_ila_1/probe18]
connect_debug_port u_ila_1/probe18 [get_nets [list zcash_fpga_top/secp256k1_top/debug_if_rx/err]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe19]
-set_property port_width 1 [get_debug_ports u_ila_1/probe19]
connect_debug_port u_ila_1/probe19 [get_nets [list zcash_fpga_top/secp256k1_top/debug_if_tx/err]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe20]
-set_property port_width 1 [get_debug_ports u_ila_1/probe20]
-connect_debug_port u_ila_1/probe20 [get_nets [list zcash_fpga_top/control_top/debug_if_rx/err]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe21]
-set_property port_width 1 [get_debug_ports u_ila_1/probe21]
-connect_debug_port u_ila_1/probe21 [get_nets [list zcash_fpga_top/control_top/debug_if_tx/rdy]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe22]
-set_property port_width 1 [get_debug_ports u_ila_1/probe22]
-connect_debug_port u_ila_1/probe22 [get_nets [list zcash_fpga_top/control_top/debug_if_rx/rdy]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe23]
-set_property port_width 1 [get_debug_ports u_ila_1/probe23]
connect_debug_port u_ila_1/probe23 [get_nets [list zcash_fpga_top/secp256k1_top/debug_if_rx/rdy]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe24]
-set_property port_width 1 [get_debug_ports u_ila_1/probe24]
connect_debug_port u_ila_1/probe24 [get_nets [list zcash_fpga_top/secp256k1_top/debug_if_tx/rdy]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe25]
-set_property port_width 1 [get_debug_ports u_ila_1/probe25]
connect_debug_port u_ila_1/probe25 [get_nets [list zcash_fpga_top/secp256k1_top/debug_if_rx/sop]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe26]
-set_property port_width 1 [get_debug_ports u_ila_1/probe26]
-connect_debug_port u_ila_1/probe26 [get_nets [list zcash_fpga_top/control_top/debug_if_tx/sop]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe27]
-set_property port_width 1 [get_debug_ports u_ila_1/probe27]
connect_debug_port u_ila_1/probe27 [get_nets [list zcash_fpga_top/secp256k1_top/debug_if_tx/sop]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe28]
-set_property port_width 1 [get_debug_ports u_ila_1/probe28]
-connect_debug_port u_ila_1/probe28 [get_nets [list zcash_fpga_top/control_top/debug_if_rx/sop]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe29]
-set_property port_width 1 [get_debug_ports u_ila_1/probe29]
-connect_debug_port u_ila_1/probe29 [get_nets [list zcash_fpga_top/control_top/debug_if_rx/val]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe30]
-set_property port_width 1 [get_debug_ports u_ila_1/probe30]
connect_debug_port u_ila_1/probe30 [get_nets [list zcash_fpga_top/secp256k1_top/debug_if_tx/val]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe31]
-set_property port_width 1 [get_debug_ports u_ila_1/probe31]
connect_debug_port u_ila_1/probe31 [get_nets [list zcash_fpga_top/secp256k1_top/debug_if_rx/val]]
-create_debug_port u_ila_1 probe
-set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_1/probe32]
-set_property port_width 1 [get_debug_ports u_ila_1/probe32]
-connect_debug_port u_ila_1/probe32 [get_nets [list zcash_fpga_top/control_top/debug_if_tx/val]]
set_false_path -from [get_pins {zcash_fpga_top/core_rst1_sync/dat_reg[0][0]/C}] -to [get_pins {zcash_fpga_top/core_rst1_sync/dat_reg[2][0]_srl2/D}]
set_false_path -from [get_pins {zcash_fpga_top/if_rst_sync/dat_reg[0][0]/C}] -to [get_pins {zcash_fpga_top/if_rst_sync/dat_reg[2][0]_srl2/D}]
-set_property C_CLK_INPUT_FREQ_HZ 300000000 [get_debug_cores dbg_hub]
-set_property C_ENABLE_CLK_DIVIDER false [get_debug_cores dbg_hub]
-set_property C_USER_SCAN_CHAIN 1 [get_debug_cores dbg_hub]
-connect_debug_port dbg_hub/clk [get_nets clk_200]
+
diff --git a/ip_cores/common/src/rtl/common_if.sv b/ip_cores/common/src/rtl/common_if.sv
index 25ae853..18528f9 100644
--- a/ip_cores/common/src/rtl/common_if.sv
+++ b/ip_cores/common/src/rtl/common_if.sv
@@ -129,13 +129,14 @@ interface if_axi_stream # (
task automatic get_stream(ref logic [common_pkg::MAX_SIM_BYTS*8-1:0] data, ref integer signed len, input integer unsigned bp = 50);
logic sop_l = 0;
logic done = 0;
- rdy = ($random % 100) >= bp;
+ logic rdy_l;
+ rdy = ($urandom % 100) >= bp;
len = 0;
data = 0;
- @(negedge i_clk);
+ rdy_l = rdy;
+ @(posedge i_clk);
while (1) begin
- @(posedge i_clk);
if (val && rdy) begin
sop_l = sop_l || sop;
if (!sop_l) begin
@@ -149,14 +150,14 @@ interface if_axi_stream # (
break;
end
end
- if (~done) begin
- @(negedge i_clk);
+ if (~done) begin
rdy = ($random % 100) >= bp;
+ @(posedge i_clk);
end
end
//@(negedge i_clk);
- rdy = 0;
+ rdy = rdy_l;
endtask
endinterface
diff --git a/zcash_fpga/src/rtl/secp256k1/secp256k1_mod.sv b/zcash_fpga/src/rtl/secp256k1/secp256k1_mod.sv
index a6904c7..c9c6f51 100644
--- a/zcash_fpga/src/rtl/secp256k1/secp256k1_mod.sv
+++ b/zcash_fpga/src/rtl/secp256k1/secp256k1_mod.sv
@@ -90,7 +90,7 @@ always_ff @ (posedge i_clk) begin
val <= val << 1;
ctl <= {ctl, i_ctl};
err <= err << 1;
- val[0] <= i_val;
+ val[0] <= i_val && o_rdy;
err[0] <= i_err;
o_dat <= res1 >= p_eq ? res1 - p_eq : res1;
diff --git a/zcash_fpga/src/rtl/secp256k1/secp256k1_mult_mod.sv b/zcash_fpga/src/rtl/secp256k1/secp256k1_mult_mod.sv
index 7d62371..d4a1bdc 100644
--- a/zcash_fpga/src/rtl/secp256k1/secp256k1_mult_mod.sv
+++ b/zcash_fpga/src/rtl/secp256k1/secp256k1_mult_mod.sv
@@ -1,16 +1,16 @@
/*
This performs a 256 bit multiplication followed by optional modulus
operation. Modulus is either n or p depending on ctl.
-
- Using Karatsuba-Ofman multiplication, where the factor of splitting
+
+ Using Karatsuba-Ofman multiplication, where the factor of splitting
is parameterized.
-
+
Each level in Karatsuba-Ofman multiplication adds 3 clock cycle.
The modulus reduction takes 3 clock cycles.
-
+
The barret reduction requires a 257 bit multiplication, so we multiplex
the multiplier.
-
+
Copyright (C) 2019 Benjamin Devlin and Zcash Foundation
This program is free software: you can redistribute it and/or modify
@@ -36,7 +36,7 @@ module secp256k1_mult_mod #(
input [255:0] i_dat_b,
input [CTL_BITS-1:0] i_ctl,
input i_val,
- input i_cmd, // 0 = mod p, 1 = mod n
+ input [1:0] i_cmd, // 0 = mod p, 1 = mod n, 2 = 256 bit shift mod p (needed for endomorphism)
input i_err,
output logic o_rdy,
// output
@@ -46,13 +46,13 @@ module secp256k1_mult_mod #(
output logic o_val,
output logic o_err
);
-
+
import secp256k1_pkg::*;
import common_pkg::*;
localparam KARATSUBA_LEVEL = 2;
-if_axi_stream #(.DAT_BITS(512+2), .CTL_BITS(CTL_BITS+1)) int_if(i_clk);
+if_axi_stream #(.DAT_BITS(512+2), .CTL_BITS(CTL_BITS+2)) int_if(i_clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(CTL_BITS)) out_mod_p_if(i_clk);
if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(CTL_BITS)) out_mod_n_if(i_clk);
@@ -64,16 +64,10 @@ logic [KARATSUBA_LEVEL-1:0] err;
logic [256+8-1:0] dat_a, dat_b;
logic o_rdy_int, i_val_int;
-/*
-always_ff @ (posedge i_clk) begin
- in_brt_mult_if.val <= out_brt_mult_if.val;
- in_brt_mult_if.dat <= out_brt_mult_if.dat[0 +: 257] * out_brt_mult_if.dat[257 +: 257];
-end*/
-
karatsuba_ofman_mult # (
.BITS ( 256 + 8 ),
.LEVEL ( KARATSUBA_LEVEL ),
- .CTL_BITS ( CTL_BITS + 1 )
+ .CTL_BITS ( CTL_BITS + 2 )
)
karatsuba_ofman_mult (
.i_clk ( i_clk ),
@@ -88,7 +82,7 @@ karatsuba_ofman_mult (
.i_rdy ( int_if.rdy ),
.o_ctl ( int_if.ctl )
);
-
+
always_ff @ (posedge i_clk) begin
if (i_rst) begin
err <= 0;
@@ -114,15 +108,18 @@ always_ff @ (posedge i_clk) begin
wait_barret_r <= 0;
end else begin
// We have to wait for pipeline to clear on output of multiplier
- wait_barret_r <= {wait_barret_r, wait_barret};
- if (i_val && o_rdy && i_cmd == 1'd1) begin
+ if (int_if.rdy) begin
+ wait_barret_r <= {wait_barret_r, wait_barret};
+ end
+
+ if (i_val && o_rdy && i_cmd == 2'd1) begin
wait_barret <= 1;
end
if (out_mod_n_if.val && out_mod_n_if.rdy) begin
wait_barret <= 0;
wait_barret_r <= 0;
end
-
+
end
end
@@ -131,9 +128,9 @@ always_comb begin
out_mod_p_if.rdy = i_rdy;
out_mod_n_if.rdy = i_rdy;
out_mod_n_if.err = 0;
-
+
o_rdy = o_rdy_int && ~wait_barret;
-
+
in_brt_mult_if.sop = 0;
in_brt_mult_if.eop = 0;
in_brt_mult_if.err = 0;
@@ -141,7 +138,7 @@ always_comb begin
in_brt_mult_if.ctl = 0;
in_brt_mult_if.val = int_if.val;
in_brt_mult_if.dat = int_if.dat;
-
+
// Prevent new input
if (wait_barret) begin
out_brt_mult_if.rdy = o_rdy_int;
@@ -155,7 +152,7 @@ always_comb begin
i_val_int = i_val;
in_brt_mult_if.val = 0;
end
-
+
// Take over multiplier output after pipeline is clear
if (wait_barret_r[KARATSUBA_LEVEL*3-1]) begin
in_brt_mult_if.val = int_if.val;
@@ -163,14 +160,14 @@ always_comb begin
end else begin
in_brt_mult_if.val = 0;
out_brt_mult_if.rdy = 0;
- int_if.rdy = int_if.ctl[CTL_BITS] == 0 ? int_if_rdy_p : int_if_rdy_n;
+ int_if.rdy = (int_if.ctl[CTL_BITS +: 2] == 2'd0 || int_if.ctl[CTL_BITS +: 2] == 2'd2) ? int_if_rdy_p : int_if_rdy_n;
end
-
+
o_dat = out_mod_p_if.val ? out_mod_p_if.dat : out_mod_n_if.dat;
o_ctl = out_mod_p_if.val ? out_mod_p_if.ctl : out_mod_n_if.ctl;
o_err = out_mod_p_if.val ? out_mod_p_if.err : out_mod_n_if.err;
o_val = out_mod_p_if.val ? out_mod_p_if.val : out_mod_n_if.val;
-
+
end
secp256k1_mod #(
@@ -180,8 +177,8 @@ secp256k1_mod #(
secp256k1_mod (
.i_clk( i_clk ),
.i_rst( i_rst ),
- .i_dat( int_if.dat ),
- .i_val( int_if.val && int_if.ctl[CTL_BITS] == 0 && ~wait_barret_r[KARATSUBA_LEVEL*3-1]),
+ .i_dat( int_if.ctl[CTL_BITS +: 2] == 2'd0 ? int_if.dat : {256'd0, int_if.dat[256 +: 256]} ),
+ .i_val( int_if.val && (int_if.ctl[CTL_BITS +: 2] == 2'd0 || int_if.ctl[CTL_BITS +: 2] == 2'd2) && ~wait_barret_r[KARATSUBA_LEVEL*3-1]),
.i_ctl( int_if.ctl[CTL_BITS-1:0] ),
.i_err( int_if.err ),
.o_rdy( int_if_rdy_p ),
@@ -198,12 +195,12 @@ barret_mod #(
.CTL_BITS ( CTL_BITS ),
.P ( secp256k1_pkg::n ),
.MULTIPLIER( "EXTERNAL" )
-)
+)
barret_mod (
.i_clk ( i_clk ),
.i_rst ( i_rst ),
.i_dat ( int_if.dat ),
- .i_val ( int_if.val && int_if.ctl[CTL_BITS] == 1 && ~wait_barret_r[KARATSUBA_LEVEL*3-1]),
+ .i_val ( int_if.val && int_if.ctl[CTL_BITS +: 2] == 2'd1 && ~wait_barret_r[KARATSUBA_LEVEL*3-1]),
.i_ctl ( int_if.ctl[CTL_BITS-1:0] ),
.o_rdy ( int_if_rdy_n ),
.o_ctl ( out_mod_n_if.ctl ),
diff --git a/zcash_fpga/src/rtl/secp256k1/secp256k1_pkg.sv b/zcash_fpga/src/rtl/secp256k1/secp256k1_pkg.sv
index 5619ca1..881ff77 100644
--- a/zcash_fpga/src/rtl/secp256k1/secp256k1_pkg.sv
+++ b/zcash_fpga/src/rtl/secp256k1/secp256k1_pkg.sv
@@ -1,6 +1,6 @@
/*
Package for the secp256k1 core
-
+
Copyright (C) 2019 Benjamin Devlin and Zcash Foundation
This program is free software: you can redistribute it and/or modify
@@ -18,7 +18,7 @@
*/
package secp256k1_pkg;
-
+
parameter [255:0] p = 256'hFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFC2F;
parameter [255:0] a = 256'h0;
parameter [255:0] b = 256'h7;
@@ -26,9 +26,19 @@ package secp256k1_pkg;
parameter [255:0] Gy = 256'h483ADA77_26A3C465_5DA4FBFC_0E1108A8_FD17B448_A6855419_9C47D08F_FB10D4B8;
parameter [255:0] n = 256'hFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_BAAEDCE6_AF48A03B_BFD25E8C_D0364141;
parameter [255:0] h = 256'h1;
-
+
+ // These are used for endomorphisms
+ parameter [255:0] lam = 256'd37718080363155996902926221483475020450927657555482586988616620542887997980018;
+ parameter [255:0] beta = 256'd55594575648329892869085402983802832744385952214688224221778511981742606582254;
+ parameter [255:0] a1 = 256'd64502973549206556628585045361533709077;
+ parameter [255:0] a2 = 256'd367917413016453100223835821029139468248;
+ parameter [255:0] b2 = 256'd64502973549206556628585045361533709077;
+ parameter [255:0] b1_neg = 256'd303414439467246543595250775667605759171;
+ parameter [255:0] c1_pre = 256'd64502973549206556628585045361533709077; // Precalculated c1 without k (scaled 256 bits)
+ parameter [255:0] c2_pre = 256'd303414439467246543595250775667605759172; // Precalculated c2 without k (scaled 256 bits)
+
parameter [255:0] p_eq = (1 << 256) - (1 << 32) - (1 << 9) - (1 << 8) - (1 << 7) - (1 << 6) - (1 << 4) - 1;
-
+
// Use register map for debug, holds information on current operation
parameter REGISTER_SIZE = 64;
// The mapping to index
@@ -44,34 +54,32 @@ package secp256k1_pkg;
parameter SIG_VER_U2 = 36; // 256 bits
parameter SIG_VER_X = 40; // Result of (u1.P + u2.Q) 256 * 3 bits as is in jb coords.
parameter SIG_VER_X_AFF = 52; // 256 bits, SIG_VER_X result's X in affine coords.
-
+
// Expected to be in Jacobian coordinates
typedef struct packed {
logic [255:0] x, y, z;
} jb_point_t;
-
- jb_point_t G_p = {x: secp256k1_pkg::Gx, y: secp256k1_pkg::Gy, z:1};
-
+
typedef struct packed {
logic [3:0] padding;
logic FAILED_SIG_VER;
logic X_INFINITY_POINT;
logic OUT_OF_RANGE_S;
logic OUT_OF_RANGE_R;
- } secp256k1_ver_t;
-
+ } secp256k1_ver_t;
+
function is_zero(jb_point_t p);
is_zero = (p.x == 0 && p.y == 0 && p.z == 1);
return is_zero;
endfunction
-
+
// Function to double point in Jacobian coordinates (for comparison in testbench)
// Here a is 0, and we also mod p the result
function jb_point_t dbl_jb_point(jb_point_t p);
logic signed [512:0] I_X, I_Y, I_Z, A, B, C, D, X, Y, Z;
-
+
if (p.z == 0) return p;
-
+
I_X = p.x;
I_Y = p.y;
I_Z = p.z;
@@ -81,68 +89,70 @@ package secp256k1_pkg;
D = (((3*I_X)% p_eq)*I_X) % p_eq;
X = (D*D)% p_eq;
X = X + ((2*B) % p_eq > X ? p_eq : 0) - (2*B) % p_eq;
-
- Y = (D*((B + (X > B ? p_eq : 0)-X) % p_eq)) % p_eq;
+
+ Y = (D*((B + (X > B ? p_eq : 0)-X) % p_eq)) % p_eq;
Y = Y + (C > Y ? p_eq : 0) - C;
Z = (((2*I_Y)% p_eq)*I_Z) % p_eq;
-
- dbl_jb_point = {x:X, y:Y, z:Z};
+
+ dbl_jb_point.x = X;
+ dbl_jb_point.y = Y;
+ dbl_jb_point.z = Z;
return dbl_jb_point;
endfunction
-
+
function jb_point_t add_jb_point(jb_point_t p1, p2);
logic signed [512:0] A, U1, U2, S1, S2, H, H3, R;
-
+
if (p1.z == 0) return p2;
if (p2.z == 0) return p1;
-
+
if (p1.y == p2.y && p1.x == p2.x)
return (dbl_jb_point(p1));
-
+
U1 = p1.x*p2.z % p_eq;
U1 = U1*p2.z % p_eq;
-
+
U2 = p2.x*p1.z % p_eq;
U2 = U2 *p1.z % p_eq;
S1 = p1.y *p2.z % p_eq;
S1 = (S1*p2.z % p_eq) *p2.z % p_eq;
S2 = p2.y * p1.z % p_eq;
S2 = (S2*p1.z % p_eq) *p1.z % p_eq;
-
- H = U2 + (U1 > U2 ? p_eq : 0) -U1;
+
+ H = U2 + (U1 > U2 ? p_eq : 0) -U1;
R = S2 + (S1 > S2 ? p_eq : 0) -S1;
//$display("R = %x", R);
//$display("H = %x", H);
//$display("H^2 = %x", (H * H %p_eq ));
H3 = ((H * H %p_eq ) * H ) % p_eq;
A = (((2*U1 % p_eq) *H % p_eq) * H % p_eq);
-
+
add_jb_point.z = ((H * p1.z % p_eq) * p2.z) % p_eq;
add_jb_point.x = R*R % p_eq;
-
+
//$display("R^2 = %x", add_jb_point.x);
//$display("H^3 = %x", H3);
-
+
add_jb_point.x = add_jb_point.x + (H3 > add_jb_point.x ? p_eq : 0) - H3;
add_jb_point.x = add_jb_point.x + (A > add_jb_point.x ? p_eq : 0) - A;
-
+
A = (U1*H % p_eq) * H % p_eq;
A = A + (add_jb_point.x > A ? p_eq : 0) - add_jb_point.x;
A = A*R % p_eq;
add_jb_point.y = S1*H3 % p_eq;
-
+
add_jb_point.y = A + (add_jb_point.y > A ? p_eq : 0) - add_jb_point.y;
-
+
endfunction
-
+
function on_curve(jb_point_t p);
return (p.y*p.y - p.x*p.x*p.x - secp256k1_pkg::a*p.x*p.z*p.z*p.z*p.z - secp256k1_pkg::b*p.z*p.z*p.z*p.z*p.z*p.z);
endfunction
-
+
function print_jb_point(jb_point_t p);
$display("x:%h", p.x);
$display("y:%h", p.y);
$display("z:%h", p.z);
endfunction
-
+
endpackage
\ No newline at end of file
diff --git a/zcash_fpga/src/rtl/secp256k1/secp256k1_point_add.sv b/zcash_fpga/src/rtl/secp256k1/secp256k1_point_add.sv
index 0635d00..30e8a10 100644
--- a/zcash_fpga/src/rtl/secp256k1/secp256k1_point_add.sv
+++ b/zcash_fpga/src/rtl/secp256k1/secp256k1_point_add.sv
@@ -125,6 +125,8 @@ always_ff @ (posedge i_clk) begin
A <= 0;
C <= 0;
end else begin
+
+ o_mult_if.ctl[7:6] <= 0; // All operations are mod p
if (o_mult_if.rdy) o_mult_if.val <= 0;
if (o_mod_if.rdy) o_mod_if.val <= 0;
@@ -180,8 +182,8 @@ always_ff @ (posedge i_clk) begin
// Check any results from multiplier
if (i_mult_if.val && i_mult_if.rdy) begin
- eq_val[i_mult_if.ctl] <= 1;
- case(i_mult_if.ctl) inside
+ eq_val[i_mult_if.ctl[5:0]] <= 1;
+ case(i_mult_if.ctl[5:0]) inside
0: A <= i_mult_if.dat;
1: i_p1_l.x <= i_mult_if.dat;
2: C <= i_mult_if.dat;
@@ -323,7 +325,7 @@ task multiply(input int unsigned ctl, input logic [255:0] a, b);
o_mult_if.val <= 1;
o_mult_if.dat[0 +: 256] <= a;
o_mult_if.dat[256 +: 256] <= b;
- o_mult_if.ctl <= ctl;
+ o_mult_if.ctl[5:0] <= ctl;
eq_wait[ctl] <= 1;
end
endtask
diff --git a/zcash_fpga/src/rtl/secp256k1/secp256k1_point_dbl.sv b/zcash_fpga/src/rtl/secp256k1/secp256k1_point_dbl.sv
index 8a1fcd1..03688eb 100644
--- a/zcash_fpga/src/rtl/secp256k1/secp256k1_point_dbl.sv
+++ b/zcash_fpga/src/rtl/secp256k1/secp256k1_point_dbl.sv
@@ -102,6 +102,8 @@ always_ff @ (posedge i_clk) begin
D <= 0;
E <= 0;
end else begin
+
+ o_mult_if.ctl[7:6] <= 0; // All operations are mod p
if (o_mult_if.rdy) o_mult_if.val <= 0;
if (o_mod_if.rdy) o_mod_if.val <= 0;
@@ -150,8 +152,8 @@ always_ff @ (posedge i_clk) begin
// Check any results from multiplier
if (i_mult_if.val && i_mult_if.rdy) begin
- eq_val[i_mult_if.ctl] <= 1;
- case(i_mult_if.ctl) inside
+ eq_val[i_mult_if.ctl[5:0]] <= 1;
+ case(i_mult_if.ctl[5:0]) inside
0: A <= i_mult_if.dat;
1: B <= i_mult_if.dat;
3: C <= i_mult_if.dat;
@@ -259,7 +261,7 @@ task multiply(input int unsigned ctl, input logic [255:0] a, b);
o_mult_if.val <= 1;
o_mult_if.dat[0 +: 256] <= a;
o_mult_if.dat[256 +: 256] <= b;
- o_mult_if.ctl <= ctl;
+ o_mult_if.ctl[5:0] <= ctl;
eq_wait[ctl] <= 1;
end
endtask
diff --git a/zcash_fpga/src/rtl/secp256k1/secp256k1_point_mult.sv b/zcash_fpga/src/rtl/secp256k1/secp256k1_point_mult.sv
index 75f81ac..7de08fc 100644
--- a/zcash_fpga/src/rtl/secp256k1/secp256k1_point_mult.sv
+++ b/zcash_fpga/src/rtl/secp256k1/secp256k1_point_mult.sv
@@ -1,7 +1,7 @@
/*
This performs point multiplication. We use the standard double
and add algorithm.
-
+
Copyright (C) 2019 Benjamin Devlin and Zcash Foundation
This program is free software: you can redistribute it and/or modify
@@ -40,17 +40,17 @@ module secp256k1_point_mult
// Interface to only mod reduction block (if RESOURCE_SHARE == "YES")
if_axi_stream.source o_mod_if,
if_axi_stream.sink i_mod_if,
-
+
// We provide another input so that the final point addition can be done
input jb_point_t i_p2,
input i_p2_val
);
// [0] is connection from/to dbl block, [1] is add block, [2] is arbitrated value
-if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(8)) mult_in_if [2:0] (i_clk);
-if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(8)) mult_out_if [2:0] (i_clk);
-if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(8)) mod_in_if [2:0] (i_clk);
-if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(8)) mod_out_if [2:0] (i_clk);
+if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mult_in_if [2:0] (i_clk);
+if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mult_out_if [2:0] (i_clk);
+if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mod_in_if [2:0] (i_clk);
+if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mod_out_if [2:0] (i_clk);
logic [255:0] k_l;
jb_point_t p_n, p_q, p_dbl, p_add;
@@ -106,7 +106,7 @@ always_ff @ (posedge i_clk) begin
p_add_in_val <= 1;
end
end
-
+
end
{DOUBLE_ADD}: begin
p_dbl_in_val <= (p_dbl_in_val && p_dbl_in_rdy) ? 0 : p_dbl_in_val;
@@ -123,7 +123,7 @@ always_ff @ (posedge i_clk) begin
p_add_done <= 1;
p_q <= p_add;
end
-
+
// Update variables and issue new commands
if (p_add_done && p_dbl_done) begin
p_add_done <= 0;
@@ -140,27 +140,27 @@ always_ff @ (posedge i_clk) begin
end else begin
p_add_done <= 1;
end
-
+
// Don't need to double on the final bit
if ((k_l >> 1) != 0)
p_dbl_in_val <= 1;
else
p_dbl_done <= 1;
-
+
if (k_l == 0) begin
state <= FINISHED;
o_p <= p_add;
o_val <= 1;
p_dbl_in_val <= 0;
p_add_in_val <= 0;
- end
+ end
end
end
{ADD_ONLY}: begin
p_dbl_in_val <= (p_dbl_in_val && p_dbl_in_rdy) ? 0 : p_dbl_in_val;
p_add_in_val <= (p_add_in_val && p_add_in_rdy) ? 0 : p_add_in_val;
-
+
if (p_dbl_out_val && p_dbl_out_rdy) begin
state <= FINISHED;
o_p <= p_dbl;
@@ -170,23 +170,23 @@ always_ff @ (posedge i_clk) begin
state <= FINISHED;
o_p <= p_add;
o_val <= 1;
- end
+ end
end
{FINISHED}: begin
if (i_rdy && o_val) begin
o_val <= 0;
state <= IDLE;
end
- end
+ end
endcase
-
+
if (p_dbl_out_err || p_add_out_err) begin
o_err <= 1;
o_val <= 1;
state <= FINISHED;
- end
-
- end
+ end
+
+ end
end
secp256k1_point_dbl secp256k1_point_dbl(
@@ -229,48 +229,48 @@ secp256k1_point_add secp256k1_point_add(
);
// We add arbitrators to these to share with the point add module
-localparam ARB_BIT = 5;
+localparam ARB_BIT = 8;
packet_arb # (
.DAT_BYTS ( 512/8 ),
- .CTL_BITS ( 8 ),
+ .CTL_BITS ( 16 ),
.NUM_IN ( 2 ),
.OVR_WRT_BIT ( ARB_BIT ),
.PIPELINE ( 0 )
-)
+)
packet_arb_mult (
- .i_clk ( i_clk ),
+ .i_clk ( i_clk ),
.i_rst ( i_rst ),
- .i_axi ( mult_in_if[1:0] ),
+ .i_axi ( mult_in_if[1:0] ),
.o_axi ( mult_in_if[2] )
);
packet_arb # (
.DAT_BYTS ( 512/8 ),
- .CTL_BITS ( 8 ),
+ .CTL_BITS ( 16 ),
.NUM_IN ( 2 ),
.OVR_WRT_BIT ( ARB_BIT ),
.PIPELINE ( 0 )
-)
+)
packet_arb_mod (
- .i_clk ( i_clk ),
+ .i_clk ( i_clk ),
.i_rst ( i_rst ),
- .i_axi ( mod_in_if[1:0] ),
+ .i_axi ( mod_in_if[1:0] ),
.o_axi ( mod_in_if[2] )
);
-always_comb begin
+always_comb begin
mod_out_if[0].copy_if_comb(mod_out_if[2].to_struct());
mod_out_if[1].copy_if_comb(mod_out_if[2].to_struct());
-
+
mod_out_if[0].ctl = mod_out_if[2].ctl;
mod_out_if[1].ctl = mod_out_if[2].ctl;
mod_out_if[0].ctl[ARB_BIT] = 0;
mod_out_if[1].ctl[ARB_BIT] = 0;
-
+
mod_out_if[1].val = mod_out_if[2].val && mod_out_if[2].ctl[ARB_BIT] == 1;
mod_out_if[0].val = mod_out_if[2].val && mod_out_if[2].ctl[ARB_BIT] == 0;
mod_out_if[2].rdy = mod_out_if[2].ctl[ARB_BIT] == 0 ? mod_out_if[0].rdy : mod_out_if[1].rdy;
-
+
mod_out_if[2].sop = 1;
mod_out_if[2].eop = 1;
mod_out_if[2].mod = 0;
@@ -279,22 +279,22 @@ end
always_comb begin
mult_out_if[0].copy_if_comb(mult_out_if[2].to_struct());
mult_out_if[1].copy_if_comb(mult_out_if[2].to_struct());
-
+
mult_out_if[0].ctl = mult_out_if[2].ctl;
mult_out_if[1].ctl = mult_out_if[2].ctl;
mult_out_if[0].ctl[ARB_BIT] = 0;
mult_out_if[1].ctl[ARB_BIT] = 0;
-
+
mult_out_if[1].val = mult_out_if[2].val && mult_out_if[2].ctl[ARB_BIT] == 1;
mult_out_if[0].val = mult_out_if[2].val && mult_out_if[2].ctl[ARB_BIT] == 0;
mult_out_if[2].rdy = mult_out_if[2].ctl[ARB_BIT] == 0 ? mult_out_if[0].rdy : mult_out_if[1].rdy;
-
+
mult_out_if[2].sop = 1;
mult_out_if[2].eop = 1;
mult_out_if[2].mod = 0;
end
-generate
+generate
if (RESOURCE_SHARE == "YES") begin: RESOURCE_GEN
always_comb begin
o_mult_if.val = mult_in_if[2].val;
@@ -305,7 +305,7 @@ generate
o_mult_if.sop = 1;
o_mult_if.eop = 1;
mult_in_if[2].rdy = o_mult_if.rdy;
-
+
o_mod_if.val = mod_in_if[2].val;
o_mod_if.dat = mod_in_if[2].dat;
o_mod_if.ctl = mod_in_if[2].ctl;
@@ -314,12 +314,12 @@ generate
o_mod_if.sop = 1;
o_mod_if.eop = 1;
mod_in_if[2].rdy = o_mod_if.rdy;
-
+
i_mult_if.rdy = mult_out_if[2].rdy;
mult_out_if[2].val = i_mult_if.val;
mult_out_if[2].dat = i_mult_if.dat;
mult_out_if[2].ctl = i_mult_if.ctl;
-
+
i_mod_if.rdy = mod_out_if[2].rdy;
mod_out_if[2].val = i_mod_if.val;
mod_out_if[2].dat = i_mod_if.dat;
@@ -333,7 +333,7 @@ generate
i_mod_if.rdy = 0;
end
secp256k1_mult_mod #(
- .CTL_BITS ( 8 )
+ .CTL_BITS ( 16 )
)
secp256k1_mult_mod (
.i_clk ( i_clk ),
@@ -349,12 +349,12 @@ generate
.i_rdy ( mult_out_if[2].rdy ),
.o_val ( mult_out_if[2].val ),
.o_ctl ( mult_out_if[2].ctl ),
- .o_err ( mult_out_if[2].err )
+ .o_err ( mult_out_if[2].err )
);
-
+
secp256k1_mod #(
.USE_MULT ( 0 ),
- .CTL_BITS ( 8 )
+ .CTL_BITS ( 16 )
)
secp256k1_mod (
.i_clk( i_clk ),
diff --git a/zcash_fpga/src/rtl/secp256k1/secp256k1_point_mult_endo.sv b/zcash_fpga/src/rtl/secp256k1/secp256k1_point_mult_endo.sv
new file mode 100644
index 0000000..9caec18
--- /dev/null
+++ b/zcash_fpga/src/rtl/secp256k1/secp256k1_point_mult_endo.sv
@@ -0,0 +1,371 @@
+/*
+ This performs point multiplication, but first decomposes the scalar
+ value using endomorphsis. Then we use the standard double
+ and add algorithm in parallel on the two products.
+
+ 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 .
+*/
+
+module secp256k1_point_mult_endo
+ import secp256k1_pkg::*;
+(
+ input i_clk, i_rst,
+ // Input point and value to multiply
+ input jb_point_t i_p,
+ input logic [255:0] i_k,
+ input logic i_val,
+ output logic o_rdy,
+ // Output point
+ output jb_point_t o_p,
+ input logic i_rdy,
+ output logic o_val,
+ output logic o_err,
+ // Interface to 256bit multiplier
+ if_axi_stream.source o_mult_if,
+ if_axi_stream.sink i_mult_if,
+ // Interface to only mod reduction block
+ if_axi_stream.source o_mod_if,
+ if_axi_stream.sink i_mod_if,
+
+ // We provide another input so that the final point addition can be done
+ // This is connected to k2 block's addition input
+ input jb_point_t i_p2,
+ input i_p2_val
+);
+
+// [0] is connection from/to k1 block, [1] is k2 block, [2] is multiplier used by decomposing block, [3] is arbitrated value
+if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mult_in_if [3:0] (i_clk);
+if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mult_out_if [3:0] (i_clk);
+if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mod_in_if [2:0] (i_clk);
+if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mod_out_if [2:0] (i_clk);
+
+logic [255:0] k_l, k1, k2;
+logic signed [255:0] k1_decom, k2_decom;
+jb_point_t p2_k1, p2_k2, p_k1, p_k2, p_o1, p_o2, p_o_decom;
+logic i_val1, o_rdy1, i_rdy1, o_val1, o_err1, i_val2, o_rdy2, i_rdy2, o_val2, o_err2;
+logic p2_k1_val, p2_k2_val;
+enum {IDLE, ADD_ONLY, DECOMPOSE_K, POINT_MULT, COMBINE_K_PROD, FINISHED} state;
+logic i_val_decom, o_rdy_decom, i_rdy_decom, o_val_decom, o_err_decom;
+
+always_ff @ (posedge i_clk) begin
+ if (i_rst) begin
+ o_val <= 0;
+ o_err <= 0;
+ o_rdy <= 0;
+ k_l <= 0;
+ k1 <= 0;
+ k2 <= 0;
+ state <= IDLE;
+ o_p <= 0;
+ i_val1 <= 0;
+ i_rdy1 <= 0;
+ i_val2 <= 0;
+ i_rdy2 <= 0;
+ p2_k1 <= 0;
+ p2_k2 <= 0;
+ p_k1 <= 0;
+ p_k2 <= 0;
+ i_val_decom <= 0;
+ i_rdy_decom <= 0;
+ p2_k1_val <= 0;
+ p2_k2_val <= 0;
+ end else begin
+
+ if (i_val_decom && o_rdy_decom) i_val_decom <= 0;
+ if (i_val1 && o_rdy1) i_val1 <= 0;
+ if (i_val2 && o_rdy2) i_val2 <= 0;
+ if (p2_k1_val && o_rdy1) p2_k1_val <= 0;
+
+ i_rdy_decom <= 0;
+ i_rdy1 <= 0;
+ i_rdy2 <= 0;
+
+ case (state)
+ {IDLE}: begin
+ i_rdy_decom <= 1;
+ i_rdy1 <= 1;
+ i_rdy2 <= 1;
+
+ o_val <= 0;
+ o_err <= 0;
+ o_rdy <= 1;
+ k_l <= i_k;
+ k1 <= 0;
+ k2 <= 0;
+ o_p <= 0;
+
+ p2_k1 <= 0;
+ p2_k2 <= 0;
+ p_k1 <= i_p;
+ p_k2 <= 0;
+ p2_k1_val <= 0;
+ p2_k2_val <= 0;
+
+ if (o_rdy && i_val) begin
+ o_rdy <= 0;
+ i_val_decom <= 1;
+ state <= DECOMPOSE_K;
+ end
+ if (o_rdy && i_p2_val) begin
+ i_val_decom <= 0;
+ o_rdy <= 0;
+ p_k2 <= i_p;
+ p2_k2 <= i_p2;
+ p2_k2_val <= 1;
+ state <= ADD_ONLY;
+ end
+
+ end
+ {ADD_ONLY}: begin
+ if (o_val && i_rdy) begin
+ state <= IDLE;
+ i_rdy2 <= 1;
+ end
+ i_rdy2 <= 0;
+ o_p <= p_o2;
+ o_val <= o_val2;
+ end
+ {DECOMPOSE_K}: begin
+ if (o_val_decom) begin
+ p_k2 <= p_o_decom;
+ i_val2 <= 1;
+ i_val1 <= 1;
+ // Only want absolute values here
+ // We don't assert ready on the decom block as we need to check the sign later
+ k1 <= k1_decom[255] ? -k1_decom : k1_decom;
+ k2 <= k2_decom[255] ? -k2_decom : k2_decom;
+ state <= POINT_MULT;
+ end
+ end
+ {POINT_MULT}: begin
+ // Combine the final products
+ // If k1 or k2 were negative we need to invert the point here before we add
+ if (o_val1 && o_val2) begin
+ i_rdy1 <= 1;
+ i_rdy2 <= 1;
+ p2_k1 <= p_o1;
+ p_k1 <= p_o2;
+ p2_k1_val <= 1;
+ state <= COMBINE_K_PROD;
+ i_rdy_decom <= 1;
+ if (k2_decom[255]) begin
+ p_k1.y <= secp256k1_pkg::p_eq - p_o2.y;
+ end
+ if (k1_decom[255]) begin
+ p2_k1.y <= secp256k1_pkg::p_eq - p_o1.y;
+ end
+ end
+
+ end
+ {COMBINE_K_PROD}: begin
+ if (o_val1 && ~p2_k1_val) begin
+ o_val <= 1;
+ o_p <= p_o1;
+ state <= FINISHED;
+ end
+ end
+ {FINISHED}: begin
+ if (i_rdy && o_val) begin
+ o_val <= 0;
+ i_rdy_decom <= 1;
+ i_rdy1 <= 1;
+ i_rdy2 <= 1;
+ state <= IDLE;
+ end
+ end
+ endcase
+
+ if (o_err_decom || o_err1 || o_err2) begin
+ o_err <= 1;
+ o_val <= 1;
+ state <= FINISHED;
+ end
+
+ end
+end
+
+secp256k1_point_mult_endo_decom secp256k1_point_mult_endo_decom (
+ .i_clk ( i_clk ),
+ .i_rst ( i_rst ),
+ .i_p ( p_k1 ),
+ .i_k ( k_l ),
+ .i_val ( i_val_decom ),
+ .o_rdy ( o_rdy_decom ),
+ .o_p ( p_o_decom ),
+ .i_rdy ( i_rdy_decom ),
+ .o_val ( o_val_decom ),
+ .o_err ( o_err_decom ),
+ .o_k1 ( k1_decom ),
+ .o_k2 ( k2_decom ),
+ .o_mult_if ( mult_in_if[2] ),
+ .i_mult_if ( mult_out_if[2] )
+);
+
+
+secp256k1_point_mult #(
+ .RESOURCE_SHARE ( "YES" )
+)
+secp256k1_point_mult_k1 (
+ .i_clk ( i_clk ),
+ .i_rst ( i_rst ),
+ .i_p ( p_k1 ),
+ .i_k ( k1 ),
+ .i_val ( i_val1 ),
+ .o_rdy ( o_rdy1 ),
+ .o_p ( p_o1 ),
+ .i_rdy ( i_rdy1 ),
+ .o_val ( o_val1 ),
+ .o_err ( o_err1 ),
+ .o_mult_if ( mult_in_if[0] ),
+ .i_mult_if ( mult_out_if[0] ),
+ .o_mod_if ( mod_in_if[0] ),
+ .i_mod_if ( mod_out_if[0] ),
+ .i_p2 ( p2_k1 ),
+ .i_p2_val ( p2_k1_val )
+);
+
+secp256k1_point_mult #(
+ .RESOURCE_SHARE ( "YES" )
+)
+secp256k1_point_mult_k2 (
+ .i_clk ( i_clk ),
+ .i_rst ( i_rst ),
+ .i_p ( p_k2 ),
+ .i_k ( k2 ),
+ .i_val ( i_val2 ),
+ .o_rdy ( o_rdy2 ),
+ .o_p ( p_o2 ),
+ .i_rdy ( i_rdy2 ),
+ .o_val ( o_val2 ),
+ .o_err ( o_err2 ),
+ .o_mult_if ( mult_in_if[1] ),
+ .i_mult_if ( mult_out_if[1] ),
+ .o_mod_if ( mod_in_if[1] ),
+ .i_mod_if ( mod_out_if[1] ),
+ .i_p2 ( p2_k2 ),
+ .i_p2_val ( p2_k2_val )
+);
+
+// We add arbitrators to these to share with the point add module
+localparam ARB_BIT = 10;
+packet_arb # (
+ .DAT_BYTS ( 512/8 ),
+ .CTL_BITS ( 16 ),
+ .NUM_IN ( 3 ),
+ .OVR_WRT_BIT ( ARB_BIT ),
+ .PIPELINE ( 0 )
+)
+packet_arb_mult (
+ .i_clk ( i_clk ),
+ .i_rst ( i_rst ),
+ .i_axi ( mult_in_if[2:0] ),
+ .o_axi ( mult_in_if[3] )
+);
+
+packet_arb # (
+ .DAT_BYTS ( 512/8 ),
+ .CTL_BITS ( 16 ),
+ .NUM_IN ( 2 ),
+ .OVR_WRT_BIT ( ARB_BIT ),
+ .PIPELINE ( 0 )
+)
+packet_arb_mod (
+ .i_clk ( i_clk ),
+ .i_rst ( i_rst ),
+ .i_axi ( mod_in_if[1:0] ),
+ .o_axi ( mod_in_if[2] )
+);
+
+always_comb begin
+ mod_out_if[0].copy_if_comb(mod_out_if[2].to_struct());
+ mod_out_if[1].copy_if_comb(mod_out_if[2].to_struct());
+
+ mod_out_if[0].ctl = mod_out_if[2].ctl;
+ mod_out_if[1].ctl = mod_out_if[2].ctl;
+ mod_out_if[0].ctl[ARB_BIT] = 0;
+ mod_out_if[1].ctl[ARB_BIT] = 0;
+
+ mod_out_if[1].val = mod_out_if[2].val && mod_out_if[2].ctl[ARB_BIT] == 1;
+ mod_out_if[0].val = mod_out_if[2].val && mod_out_if[2].ctl[ARB_BIT] == 0;
+ mod_out_if[2].rdy = mod_out_if[2].ctl[ARB_BIT] == 0 ? mod_out_if[0].rdy : mod_out_if[1].rdy;
+
+ mod_out_if[2].sop = 1;
+ mod_out_if[2].eop = 1;
+ mod_out_if[2].mod = 0;
+end
+
+always_comb begin
+ mult_out_if[0].copy_if_comb(mult_out_if[3].to_struct());
+ mult_out_if[1].copy_if_comb(mult_out_if[3].to_struct());
+ mult_out_if[2].copy_if_comb(mult_out_if[3].to_struct());
+
+ mult_out_if[0].ctl = mult_out_if[3].ctl;
+ mult_out_if[1].ctl = mult_out_if[3].ctl;
+ mult_out_if[2].ctl = mult_out_if[3].ctl;
+ mult_out_if[0].ctl[ARB_BIT +: 2] = 0;
+ mult_out_if[1].ctl[ARB_BIT +: 2] = 0;
+ mult_out_if[2].ctl[ARB_BIT +: 2] = 0;
+
+ mult_out_if[0].val = mult_out_if[3].val && mult_out_if[3].ctl[ARB_BIT +: 2] == 0;
+ mult_out_if[1].val = mult_out_if[3].val && mult_out_if[3].ctl[ARB_BIT +: 2] == 1;
+ mult_out_if[2].val = mult_out_if[3].val && mult_out_if[3].ctl[ARB_BIT +: 2] == 2;
+
+ if (mult_out_if[3].ctl[ARB_BIT +: 2] == 0)
+ mult_out_if[3].rdy = mult_out_if[0].rdy;
+ else if (mult_out_if[3].ctl[ARB_BIT +: 2] == 1)
+ mult_out_if[3].rdy = mult_out_if[1].rdy;
+ else
+ mult_out_if[3].rdy = mult_out_if[2].rdy;
+
+ mult_out_if[3].sop = 1;
+ mult_out_if[3].eop = 1;
+ mult_out_if[3].mod = 0;
+ mult_out_if[3].err = 0;
+end
+
+// We always use the external multiplier
+always_comb begin
+ o_mult_if.val = mult_in_if[3].val;
+ o_mult_if.dat = mult_in_if[3].dat;
+ o_mult_if.ctl = mult_in_if[3].ctl;
+ o_mult_if.err = 0;
+ o_mult_if.mod = 0;
+ o_mult_if.sop = 1;
+ o_mult_if.eop = 1;
+ mult_in_if[3].rdy = o_mult_if.rdy;
+
+ o_mod_if.val = mod_in_if[2].val;
+ o_mod_if.dat = mod_in_if[2].dat;
+ o_mod_if.ctl = mod_in_if[2].ctl;
+ o_mod_if.err = 0;
+ o_mod_if.mod = 0;
+ o_mod_if.sop = 1;
+ o_mod_if.eop = 1;
+ mod_in_if[2].rdy = o_mod_if.rdy;
+
+ i_mult_if.rdy = mult_out_if[3].rdy;
+ mult_out_if[3].val = i_mult_if.val;
+ mult_out_if[3].dat = i_mult_if.dat;
+ mult_out_if[3].ctl = i_mult_if.ctl;
+
+ i_mod_if.rdy = mod_out_if[2].rdy;
+ mod_out_if[2].val = i_mod_if.val;
+ mod_out_if[2].dat = i_mod_if.dat;
+ mod_out_if[2].ctl = i_mod_if.ctl;
+end
+
+
+endmodule
\ No newline at end of file
diff --git a/zcash_fpga/src/rtl/secp256k1/secp256k1_point_mult_endo_decom.sv b/zcash_fpga/src/rtl/secp256k1/secp256k1_point_mult_endo_decom.sv
new file mode 100644
index 0000000..740181d
--- /dev/null
+++ b/zcash_fpga/src/rtl/secp256k1/secp256k1_point_mult_endo_decom.sv
@@ -0,0 +1,206 @@
+/*
+ This decomposes the scalar value required for endomorphsis.
+ Requires external multiplier.
+
+ 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 .
+*/
+
+module secp256k1_point_mult_endo_decom
+ import secp256k1_pkg::*;
+#(
+ parameter MULT_CTL_BIT = 6 // Bit used to control multiplier shift
+)(
+ input i_clk, i_rst,
+ // Input point and value to decompose
+ input jb_point_t i_p,
+ input logic [255:0] i_k,
+ input logic i_val,
+ output logic o_rdy,
+ // Output point (beta multiplied)
+ output jb_point_t o_p,
+ input logic i_rdy,
+ output logic o_val,
+ output logic o_err,
+ // Output values of k decomposed (can be negative)
+ output logic signed [255:0] o_k1,
+ output logic signed [255:0] o_k2,
+ // Interface to 256bit multiplier
+ if_axi_stream.source o_mult_if,
+ if_axi_stream.sink i_mult_if
+);
+
+/* Equations we calculate for the decomposisiton:
+ 0. o_p = {(beta*i_p.x) mod p, i_p.y, i_p.z}
+ 1. c1 = (c1_pre*k) (scale mod p)
+ 2. c2 = (c2_pre*k) (scale mod p)
+ 3. c1_a1 = (c1*a1) mod p [eq1]
+ 4. c2_a2 = (c2*a2) mod p [eq2]
+ 5. c1_b1 = (c1*b1_neg) mod p [eq1]
+ 6. c2_b2 = (c2*b2) mod p [eq2]
+ 7. k1 = k - (c1_a1) [eq3, eq4]
+ 8. k1 = k1 - (c2_a2) [eq7]
+ 9. k2 = c1_b1 - c2_b2 [eq5, eq6]
+ */
+
+logic [9:0] eq_val, eq_wait;
+logic [255:0] c1, c2, c1_a1, c2_a2, c2_b2;
+enum {IDLE, START, FINISHED} state;
+
+always_ff @ (posedge i_clk) begin
+ if (i_rst) begin
+ o_val <= 0;
+ o_err <= 0;
+ o_rdy <= 0;
+ o_k1 <= 0;
+ o_k2 <= 0;
+ state <= IDLE;
+ o_p <= 0;
+ o_mult_if.reset_source();
+ i_mult_if.rdy <= 0;
+ c1 <= 0;
+ c2 <= 0;
+ c1_a1 <= 0;
+ c2_a2 <= 0;
+ c2_b2 <= 0;
+ eq_val <= 0;
+ eq_wait <= 0;
+ end else begin
+
+ if (o_mult_if.rdy) o_mult_if.val <= 0;
+ o_mult_if.sop <= 1;
+ o_mult_if.eop <= 1;
+
+ case(state)
+ {IDLE}: begin
+ o_val <= 0;
+ o_err <= 0;
+ o_rdy <= 1;
+ o_k1 <= i_k;
+ o_k2 <= 0;
+ o_p <= i_p;
+ c1 <= 0;
+ c2 <= 0;
+ c1_a1 <= 0;
+ c2_a2 <= 0;
+ c2_b2 <= 0;
+ eq_val <= 0;
+ eq_wait <= 0;
+ if (i_val && o_rdy) begin
+ state <= START;
+ o_rdy <= 0;
+ end
+ end
+ // Just a big if tree where we issue equations if the required inputs
+ // are valid
+ {START}: begin
+
+ i_mult_if.rdy <= 1;
+
+
+
+ // Check any results from multiplier
+ if (i_mult_if.val && i_mult_if.rdy) begin
+ eq_val[i_mult_if.ctl[5:0]] <= 1;
+ case(i_mult_if.ctl[5:0]) inside
+ 0: o_p.x <= i_mult_if.dat;
+ 1: c1 <= i_mult_if.dat;
+ 2: c2 <= i_mult_if.dat;
+ 3: c1_a1 <= i_mult_if.dat;
+ 4: c2_a2 <= i_mult_if.dat;
+ 5: o_k2 <= i_mult_if.dat;
+ 6: c2_b2 <= i_mult_if.dat;
+ default: o_err <= 1;
+ endcase
+ end
+
+ // Issue new multiplies
+ if (~eq_wait[0]) begin // 0. o_p = {(beta*i_p.x) mod p, i_p.y, i_p.z}
+ multiply(0, secp256k1_pkg::beta, o_p.x, 2'd0);
+ end else
+ if (~eq_wait[1]) begin // 1. c1 = (c1_pre*k) (scale mod p)
+ multiply(1, o_k1, secp256k1_pkg::c1_pre, 2'd2);
+ end else
+ if (~eq_wait[2]) begin // 2. c2 = (c2_pre*k) (scale mod p)
+ multiply(2, o_k1, secp256k1_pkg::c2_pre, 2'd2);
+ end else
+ if (~eq_wait[3] && eq_val[1]) begin // 3. c1_a1 = (c1*a1) mod p [eq1]
+ multiply(3, c1, secp256k1_pkg::a1, 2'd0);
+ end else
+ if (~eq_wait[4] && eq_val[2]) begin // 4. c2_a2 = (c2*a2) mod p [eq2]
+ multiply(4, c2, secp256k1_pkg::a2, 2'd0);
+ end else
+ if (~eq_wait[5] && eq_val[1]) begin // 5. c1_b1 = (c1*b1_neg) mod p [eq1]
+ multiply(5, c1, secp256k1_pkg::b1_neg, 2'd0);
+ end else
+ if (~eq_wait[6] && eq_val[2]) begin // 6. c2_b2 = (c2*b2) mod p [eq2]
+ multiply(6, c2, secp256k1_pkg::b2, 2'd0);
+ end
+
+ // Subtractions we do in-module
+ if (eq_val[3] && eq_val[4] && ~eq_wait[7]) begin // 7. k1 = k - (c1_a1) [eq3, eq4]
+ o_k1 <= o_k1 - $signed(c1_a1);
+ eq_val[7] <= 1;
+ eq_wait[7] <= 1;
+ end
+ if (eq_val[7] && ~eq_wait[8]) begin // 8. k1 = k1 - (c2_a2) [eq7]
+ o_k1 <= o_k1 - $signed(c2_a2);
+ eq_val[8] <= 1;
+ eq_wait[8] <= 1;
+ end
+ if (eq_val[5] && eq_val[6] && ~eq_wait[9]) begin // 9. k2 = c1_b1 - c2_b2 [eq5, eq6]
+ o_k2 <= o_k2 - $signed(c2_b2);
+ eq_val[9] <= 1;
+ eq_wait[9] <= 1;
+ end
+
+ if (&eq_val) begin
+ state <= FINISHED;
+ o_val <= 1;
+ end
+ end
+ {FINISHED}: begin
+ if (o_val && i_rdy) begin
+ state <= IDLE;
+ o_val <= 0;
+ o_rdy <= 1;
+ end
+ end
+ endcase
+
+ if (o_err) begin
+ o_val <= 1;
+ if (o_val && i_rdy) begin
+ o_err <= 0;
+ state <= IDLE;
+ end
+ end
+
+ end
+end
+
+// Task for using multiplies
+task multiply(input int unsigned ctl, input logic [255:0] a, b, input logic [1:0] cmd);
+ if (~o_mult_if.val || (o_mult_if.val && o_mult_if.rdy)) begin
+ o_mult_if.val <= 1;
+ o_mult_if.dat[0 +: 256] <= a;
+ o_mult_if.dat[256 +: 256] <= b;
+ o_mult_if.ctl[5:0] <= ctl;
+ o_mult_if.ctl[7:6] <= cmd;
+ eq_wait[ctl] <= 1;
+ end
+endtask
+
+endmodule
\ No newline at end of file
diff --git a/zcash_fpga/src/rtl/secp256k1/secp256k1_top.sv b/zcash_fpga/src/rtl/secp256k1/secp256k1_top.sv
index 435fb88..95882c7 100644
--- a/zcash_fpga/src/rtl/secp256k1/secp256k1_top.sv
+++ b/zcash_fpga/src/rtl/secp256k1/secp256k1_top.sv
@@ -25,10 +25,10 @@ if_axi_stream #(.DAT_BYTS(256/8)) bin_inv_in_if(i_clk);
if_axi_stream #(.DAT_BYTS(256/8)) bin_inv_out_if(i_clk);
// [0] is connection from/to point_mult0 block, [1] is add point_mult1 block, 2 is this state machine, [3] is arbitrated value
-if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(8)) mult_in_if [3:0] (i_clk);
-if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(8)) mult_out_if [3:0] (i_clk);
-if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(8)) mod_in_if [2:0] (i_clk);
-if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(8)) mod_out_if [2:0] (i_clk);
+if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mult_in_if [3:0] (i_clk);
+if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mult_out_if [3:0] (i_clk);
+if_axi_stream #(.DAT_BYTS(256*2/8), .CTL_BITS(16)) mod_in_if [2:0] (i_clk);
+if_axi_stream #(.DAT_BYTS(256/8), .CTL_BITS(16)) mod_out_if [2:0] (i_clk);
jb_point_t pt_mult0_in_p, pt_mult0_out_p, pt_mult1_in_p, pt_mult1_out_p, pt_X0, pt_X1, pt_X, pt_mult0_in_p2;
logic [255:0] pt_mult0_in_k, pt_mult1_in_k;
@@ -43,8 +43,6 @@ typedef enum {IDLE,
VERIFY_SECP256K1_SIG_PARSE,
CALC_S_INV,
CALC_U1_U2,
- CALC_ENDOMORPH_K,
-
CALC_X,
CALC_X_AFFINE,
CHECK_IN_JB,
@@ -224,7 +222,7 @@ always_ff @ (posedge i_clk) begin
bin_inv_out_if.rdy <= 0;
bin_inv_in_if.dat <= bin_inv_out_if.dat;
// Start calculating U2
- mult_in_if[2].ctl <= 1; // mod n
+ mult_in_if[2].ctl[7:6] <= 1; // mod n
mult_in_if[2].dat[256 +: 256] <= bin_inv_out_if.dat;
mult_in_if[2].val <= 1;
secp256k1_state <= CALC_U1_U2;
@@ -302,12 +300,12 @@ always_ff @ (posedge i_clk) begin
secp256k1_state <= CALC_X_AFFINE;
mult_in_if[2].val <= 1;
mult_in_if[2].dat <= {pt_mult0_out_p.z, pt_mult0_out_p.z};
- mult_in_if[2].ctl <= 0; // mod p
+ mult_in_if[2].ctl[7:6] <= 0; // mod p
end else begin
secp256k1_state <= CHECK_IN_JB;
mult_in_if[2].val <= 1;
mult_in_if[2].dat <= {pt_mult0_out_p.z, pt_mult0_out_p.z};
- mult_in_if[2].ctl <= 0; // mod p
+ mult_in_if[2].ctl[7:6] <= 0; // mod p
end
// Here we either do a final inverstion to get the original .x value or we can do special checks
end
@@ -326,7 +324,7 @@ always_ff @ (posedge i_clk) begin
if (bin_inv_out_if.val && bin_inv_out_if.rdy) begin
mult_in_if[2].val <= 1;
mult_in_if[2].dat <= {bin_inv_out_if.dat, pt_mult0_in_p2.x};
- mult_in_if[2].ctl <= 0; // mod p
+ mult_in_if[2].ctl[7:6] <= 0; // mod p
cnt <= 1;
end
end
@@ -335,7 +333,7 @@ always_ff @ (posedge i_clk) begin
if (mult_out_if[2].rdy && mult_out_if[2].val) begin
mult_in_if[2].val <= 1;
mult_in_if[2].dat <= {256'd1, mult_out_if[2].dat};
- mult_in_if[2].ctl <= 1; // mod n
+ mult_in_if[2].ctl[7:6] <= 1; // mod n
cnt <= 2;
end
end
@@ -362,7 +360,7 @@ always_ff @ (posedge i_clk) begin
pt_mult0_in_p2.z <= mult_out_if[2].dat;
mult_in_if[2].val <= 1;
mult_in_if[2].dat <= {r, mult_out_if[2].dat};
- mult_in_if[2].ctl <= 0; // mod p
+ mult_in_if[2].ctl[7:6] <= 0; // mod p
cnt <= 1;
end
end
@@ -377,7 +375,7 @@ always_ff @ (posedge i_clk) begin
end else begin
// Need to do one more check
mult_in_if[2].dat <= {r, pt_mult0_in_p2.z};
- mult_in_if[2].ctl <= 0; // mod p
+ mult_in_if[2].ctl[7:6] <= 0; // mod p
mult_in_if[2].val <= 1;
cnt <= 2;
end
@@ -473,11 +471,12 @@ bin_inv (
localparam RESOURCE_SHARE = "YES";
-localparam ARB_BIT = 6;
+localparam ARB_BIT = 12;
+localparam MULT_CTL_BIT = 6; // 2 bits
// Shared multiplier with cmd to control modulo p or modulo n
secp256k1_mult_mod #(
- .CTL_BITS ( 8 )
+ .CTL_BITS ( 16 )
)
secp256k1_mult_mod (
.i_clk ( i_clk ),
@@ -487,7 +486,7 @@ secp256k1_mult_mod (
.i_val ( mult_in_if[3].val ),
.i_err ( mult_in_if[3].err ),
.i_ctl ( mult_in_if[3].ctl ),
- .i_cmd ( mult_in_if[3].ctl[ARB_BIT +: 2] == 2 ? mult_in_if[3].ctl[0] : 1'd0 ),
+ .i_cmd ( mult_in_if[3].ctl[MULT_CTL_BIT +: 2] ),
.o_rdy ( mult_in_if[3].rdy ),
.o_dat ( mult_out_if[3].dat ),
.i_rdy ( mult_out_if[3].rdy ),
@@ -497,8 +496,8 @@ secp256k1_mult_mod (
);
secp256k1_mod #(
- .USE_MULT ( 0 ),
- .CTL_BITS ( 8 )
+ .USE_MULT ( 0 ),
+ .CTL_BITS ( 16 )
)
secp256k1_mod (
.i_clk( i_clk ),
@@ -517,7 +516,7 @@ secp256k1_mod (
packet_arb # (
.DAT_BYTS ( 512/8 ),
- .CTL_BITS ( 8 ),
+ .CTL_BITS ( 16 ),
.NUM_IN ( 3 ),
.OVR_WRT_BIT ( ARB_BIT ),
.PIPELINE ( 0 )
@@ -531,7 +530,7 @@ packet_arb_mult (
packet_arb # (
.DAT_BYTS ( 512/8 ),
- .CTL_BITS ( 8 ),
+ .CTL_BITS ( 16 ),
.NUM_IN ( 2 ),
.OVR_WRT_BIT ( ARB_BIT ),
.PIPELINE ( 0 )