Updates to top control, secp256k1 core.
This commit is contained in:
parent
051f3e68b5
commit
571bfb2dc0
|
@ -0,0 +1,315 @@
|
||||||
|
//**************************************************************************
|
||||||
|
//************* BittWare Incorporated *************
|
||||||
|
//************* 45 S. Main Street, Concord, NH 03301 *************
|
||||||
|
//**************************************************************************
|
||||||
|
// LEGAL NOTICE:
|
||||||
|
// Copyright (c) 2018 BittWare, Inc.
|
||||||
|
// The user is hereby granted a non-exclusive license to use and or
|
||||||
|
// modify this code provided that it runs on BittWare hardware.
|
||||||
|
// Usage of this code on non-BittWare hardware without the express
|
||||||
|
// written permission of BittWare is strictly prohibited.
|
||||||
|
//
|
||||||
|
// E-mail: support@bittware.com Tel: 603-226-0404
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//# Created by: Jeff Sanders
|
||||||
|
//# Date: 20 Jun 2018
|
||||||
|
///
|
||||||
|
//**************************************************************************
|
||||||
|
// pcie_base: Default PCIe-based design incorporating the following functionality:
|
||||||
|
// - PCIe Gen3x16 interface w/integrated PCIe-to-AXI4 conversion (within IPI subsystem)
|
||||||
|
// - SPI controller (within IPI subsystem)
|
||||||
|
// - I2C controller (within IPI subsystem)
|
||||||
|
// - 16550-compatible UART (within IPI subsystem)
|
||||||
|
// - STARTUPE3 primitive configured to allow writes to QSPI flash
|
||||||
|
//
|
||||||
|
// PCIe address map: (BAR0, 32-bit)
|
||||||
|
// 0x0000: CSR (0x0=Version(rd);LED[2:0](wr), 0x4=UAR timestamp(rd), 0x8=CSR(rd/wr))
|
||||||
|
// 0x1100: SPI core
|
||||||
|
// 0x2200: I2C Core
|
||||||
|
// 0x3300: UART Core
|
||||||
|
// 0x4000: 4KB scratchpad BRAM
|
||||||
|
//
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
`timescale 1ps/1ps
|
||||||
|
|
||||||
|
`define DEV_SEL_HI_BIT 11
|
||||||
|
`define DEV_SEL_LO_BIT 8
|
||||||
|
`define VERSION_REG 32'h00600000
|
||||||
|
|
||||||
|
module bittware_xupvvh_top (
|
||||||
|
led_pins,
|
||||||
|
pcie_7x_mgt_rxn,
|
||||||
|
pcie_7x_mgt_rxp,
|
||||||
|
pcie_7x_mgt_txn,
|
||||||
|
pcie_7x_mgt_txp,
|
||||||
|
prog_b5_p,
|
||||||
|
prog_b5_n,
|
||||||
|
avr_rxd,
|
||||||
|
avr_txd,
|
||||||
|
usb_rxd,
|
||||||
|
usb_txd,
|
||||||
|
i2c_sda,
|
||||||
|
i2c_scl,
|
||||||
|
FPGA_I2C_MASTER_L,
|
||||||
|
QSFP_CTL_EN,
|
||||||
|
SAS_CTL_EN,
|
||||||
|
sys_clkp,
|
||||||
|
sys_clkn,
|
||||||
|
sys_reset_l);
|
||||||
|
|
||||||
|
//####### Misc. Board-specific #######
|
||||||
|
output [3:0]led_pins; // On-board LEDs 0-3
|
||||||
|
output FPGA_I2C_MASTER_L; // Drive high to allow BMC to control QSFPs
|
||||||
|
output QSFP_CTL_EN; // Drive high for normal operation
|
||||||
|
output SAS_CTL_EN; // Drive high for normal operation
|
||||||
|
//####### PCIe Interface #######
|
||||||
|
input [15:0]pcie_7x_mgt_rxn;
|
||||||
|
input [15:0]pcie_7x_mgt_rxp;
|
||||||
|
output [15:0]pcie_7x_mgt_txn;
|
||||||
|
output [15:0]pcie_7x_mgt_txp;
|
||||||
|
//####### I2C and UART I/F's #######
|
||||||
|
input avr_txd; // Tx UART data from the AVR
|
||||||
|
output avr_rxd; // Rx UART data to the AVR
|
||||||
|
inout i2c_sda; // I2C biderectional data
|
||||||
|
inout i2c_scl; // I2C clock
|
||||||
|
input usb_uart_txd; // Tx UART data from the USB
|
||||||
|
output logic usb_uart_rxd; // Rx UART data to the USB
|
||||||
|
//####### Clocks & Reset #######
|
||||||
|
input sys_clkp; // PCIe reference clock
|
||||||
|
input sys_clkn;
|
||||||
|
input prog_b5_p;
|
||||||
|
input prog_b5_n;
|
||||||
|
input sys_reset_l; // PCIe PERSTN
|
||||||
|
|
||||||
|
|
||||||
|
wire [3:0] spi_in;
|
||||||
|
wire [3:0] spi_out;
|
||||||
|
wire [3:0] spi_tri;
|
||||||
|
wire spi_sel;
|
||||||
|
wire spi_clk_o;
|
||||||
|
wire spi_clk_t;
|
||||||
|
reg spi_cs_l;
|
||||||
|
reg [31:0] clk_cnt;
|
||||||
|
reg [3:0] led_q;
|
||||||
|
wire [3:0] memtest_ok;
|
||||||
|
reg led_test_reg;
|
||||||
|
reg [3:0] qsfp_rst_reg;
|
||||||
|
reg [3:0] qsfp_lp_reg;
|
||||||
|
reg [3:0] qsfp_sel_oh;
|
||||||
|
reg [3:0] qsfp_i2c_ctri_vec;
|
||||||
|
reg [3:0] qsfp_i2c_dtri_vec;
|
||||||
|
reg [3:0] qsfp_i2c_cin_vec;
|
||||||
|
reg [3:0] qsfp_i2c_din_vec;
|
||||||
|
wire [31:0] CSR_awaddr;
|
||||||
|
wire [31:0] CSR_wdata;
|
||||||
|
wire [31:0] CSR_araddr;
|
||||||
|
reg [31:0] CSR_rdata;
|
||||||
|
reg CSR_rvalid;
|
||||||
|
reg CSR_awready;
|
||||||
|
reg CSR_arready;
|
||||||
|
reg CSR_wready;
|
||||||
|
reg CSR_bvalid;
|
||||||
|
wire CSR_wdecode;
|
||||||
|
wire CSR_rdecode;
|
||||||
|
wire csr_ren;
|
||||||
|
wire csr_wen;
|
||||||
|
wire sys_clk;
|
||||||
|
wire sys_clk_gt;
|
||||||
|
wire [31:0] UAR_DATA;
|
||||||
|
|
||||||
|
|
||||||
|
IBUFDS_GTE4 refclk_ibuf (.O(sys_clk_gt), .ODIV2(sys_clk), .I(sys_clkp), .CEB(1'b0), .IB(sys_clkn));
|
||||||
|
|
||||||
|
// STARTUPE3 block: Allows FPGA logic connections to dedicated config. pins
|
||||||
|
// From the UltraScale Configuration Guide:
|
||||||
|
// FCSBO: FPGA logic signal to external FCS_B configuration pin. FCSBO allows user
|
||||||
|
// control of FCS_B pin for Flash access.
|
||||||
|
// USRCCLKO (User CCLK input). USRCCLKO is an input from the FPGA logic. USERCCLKO drives a custom,
|
||||||
|
// FPGA-generated clock frequency onto the external FPGA CCLK pin. This is useful for
|
||||||
|
// post-configuration access of external SPI flash devices.
|
||||||
|
|
||||||
|
// STARTUPE3: STARTUP Block
|
||||||
|
// UltraScale
|
||||||
|
// Xilinx HDL Libraries Guide, version 2014.4
|
||||||
|
STARTUPE3 #(
|
||||||
|
.PROG_USR("FALSE") // Activate program event security feature. Requires encrypted bitstreams.
|
||||||
|
)
|
||||||
|
STARTUPE3_inst (
|
||||||
|
.CFGCLK(), // 1-bit output: Configuration main clock output
|
||||||
|
.CFGMCLK(), // 1-bit output: Configuration internal oscillator clock output
|
||||||
|
.DI(spi_in), // 4-bit output: Allow receiving on the D input pin
|
||||||
|
.EOS(), // 1-bit output: Active-High output signal indicating the End Of Startup
|
||||||
|
.PREQ(), // 1-bit output: PROGRAM request to fabric output
|
||||||
|
.DO({3'b000,spi_mosi}),// 4-bit input: Allows control of the D pin output
|
||||||
|
.DTS(4'b1110), // 4-bit input: Allows tristate of the D pin
|
||||||
|
.FCSBO(spi_cs_l), // 1-bit input: Contols the FCS_B pin for flash access
|
||||||
|
.FCSBTS(1'b0), // 1-bit input: Tristate the FCS_B pin
|
||||||
|
.GSR(), // 1-bit input: Global Set/Reset input (GSR cannot be used for the port)
|
||||||
|
.GTS(1'b0), // 1-bit input: Global 3-state input (GTS cannot be used for the port name)
|
||||||
|
.KEYCLEARB(), // 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM)
|
||||||
|
.PACK(), // 1-bit input: PROGRAM acknowledge input
|
||||||
|
.USRCCLKO(spi_sck_o), // 1-bit input: User CCLK input
|
||||||
|
.USRCCLKTS(1'b0), // 1-bit input: User CCLK 3-state enable input
|
||||||
|
.USRDONEO(1'b1), // 1-bit input: User DONE pin output control
|
||||||
|
.USRDONETS(1'b1) // 1-bit input: User DONE 3-state enable output
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// PCIe IPI subsystem instantiation
|
||||||
|
//
|
||||||
|
pcie2axilite_sub pcie2axilite_sub_i(
|
||||||
|
.sys_clk(sys_clk),
|
||||||
|
.sys_clk_gt(sys_clk_gt),
|
||||||
|
.clk_100_clk_p(prog_b5_p),
|
||||||
|
.clk_100_clk_n(prog_b5_n),
|
||||||
|
.sys_reset_l(sys_reset_l),
|
||||||
|
.pcie_7x_mgt_rxn(pcie_7x_mgt_rxn),
|
||||||
|
.pcie_7x_mgt_rxp(pcie_7x_mgt_rxp),
|
||||||
|
.pcie_7x_mgt_txn(pcie_7x_mgt_txn),
|
||||||
|
.pcie_7x_mgt_txp(pcie_7x_mgt_txp),
|
||||||
|
.axi_aclk(axi_clk),
|
||||||
|
.user_link_up(rst_l),
|
||||||
|
.m00_axi_0_araddr(CSR_araddr),
|
||||||
|
.m00_axi_0_arprot(CSR_arprot),
|
||||||
|
.m00_axi_0_arready(CSR_arready),
|
||||||
|
.m00_axi_0_arvalid(CSR_arvalid),
|
||||||
|
.m00_axi_0_awaddr(CSR_awaddr),
|
||||||
|
.m00_axi_0_awprot(CSR_awprot),
|
||||||
|
.m00_axi_0_awready(CSR_awready),
|
||||||
|
.m00_axi_0_awvalid(CSR_awvalid),
|
||||||
|
.m00_axi_0_bready(CSR_bready),
|
||||||
|
.m00_axi_0_bresp(1'b0),
|
||||||
|
.m00_axi_0_bvalid(CSR_bvalid),
|
||||||
|
.m00_axi_0_rdata(CSR_rdata),
|
||||||
|
.m00_axi_0_rready(CSR_rready),
|
||||||
|
.m00_axi_0_rresp(1'b0),
|
||||||
|
.m00_axi_0_rvalid(CSR_rvalid),
|
||||||
|
.m00_axi_0_wdata(CSR_wdata),
|
||||||
|
.m00_axi_0_wready(CSR_wready),
|
||||||
|
.m00_axi_0_wstrb(CSR_wstrb),
|
||||||
|
.m00_axi_0_wvalid(CSR_wvalid),
|
||||||
|
.uart_0_baudoutn(),
|
||||||
|
.uart_0_ctsn(1'b0),
|
||||||
|
.uart_0_dcdn(1'b0),
|
||||||
|
.uart_0_ddis(),
|
||||||
|
.uart_0_dsrn(1'b0),
|
||||||
|
.uart_0_dtrn(),
|
||||||
|
.uart_0_out1n(),
|
||||||
|
.uart_0_out2n(),
|
||||||
|
.uart_0_ri(1'b0),
|
||||||
|
.uart_0_rtsn(),
|
||||||
|
.uart_0_rxd(avr_txd),
|
||||||
|
.uart_0_rxrdyn(),
|
||||||
|
.uart_0_txd(avr_rxd),
|
||||||
|
.uart_0_txrdyn(),
|
||||||
|
.iic_0_scl_i(i2c_cin),
|
||||||
|
.iic_0_scl_o(i2c_cout),
|
||||||
|
.iic_0_scl_t(i2c_ctri),
|
||||||
|
.iic_0_sda_i(i2c_din),
|
||||||
|
.iic_0_sda_o(i2c_dout),
|
||||||
|
.iic_0_sda_t(i2c_dtri),
|
||||||
|
.spi_0_io0_o(spi_io0_o),
|
||||||
|
.spi_0_io1_i(spi_io1_i),
|
||||||
|
.spi_0_sck_o(spi_sck_o),
|
||||||
|
.spi_0_ss_o(spi_ss_o_0),
|
||||||
|
.spi_0_ss_t(spi_ss_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign spi_mosi = spi_io0_o;
|
||||||
|
assign spi_io1_i = spi_miso;
|
||||||
|
|
||||||
|
always@(posedge axi_clk) begin
|
||||||
|
if (spi_ss_t == 0)
|
||||||
|
spi_cs_l <= spi_ss_o_0;
|
||||||
|
else
|
||||||
|
spi_cs_l <= 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Buffers for I2C Tri-State I/O
|
||||||
|
//***************************************************************************
|
||||||
|
IOBUF IOBUF_i2c_clk_inst (
|
||||||
|
.O(i2c_cin),
|
||||||
|
.I(i2c_cout),
|
||||||
|
.IO(i2c_scl),
|
||||||
|
.T(i2c_ctri)
|
||||||
|
);
|
||||||
|
|
||||||
|
IOBUF IOBUF_i2c_data_inst (
|
||||||
|
.O(i2c_din),
|
||||||
|
.I(i2c_dout),
|
||||||
|
.IO(i2c_sda),
|
||||||
|
.T(i2c_dtri)
|
||||||
|
);
|
||||||
|
|
||||||
|
USR_ACCESSE2 USR_ACCESSE2_inst (
|
||||||
|
.CFGCLK(), // 1-bit output: Configuration Clock
|
||||||
|
.DATA(UAR_DATA), // 32-bit output: Configuration Data reflecting the contents of the AXSS register
|
||||||
|
.DATAVALID() // 1-bit output: Active High Data Valid
|
||||||
|
);
|
||||||
|
|
||||||
|
// decode CSR Transaction
|
||||||
|
assign CSR_wdecode = (CSR_awaddr[`DEV_SEL_HI_BIT:`DEV_SEL_LO_BIT] == 0) | (CSR_awaddr[`DEV_SEL_HI_BIT:`DEV_SEL_LO_BIT] > 3); // Decode 0x0 and out-of-range to CSR
|
||||||
|
assign CSR_rdecode = (CSR_araddr[`DEV_SEL_HI_BIT:`DEV_SEL_LO_BIT] == 0) | (CSR_araddr[`DEV_SEL_HI_BIT:`DEV_SEL_LO_BIT] > 3); // Decode 0x0 and out-of-range to CSR
|
||||||
|
assign csr_wen = CSR_awready & CSR_wdecode;
|
||||||
|
assign csr_ren = CSR_arready & CSR_rdecode;
|
||||||
|
|
||||||
|
always@(posedge axi_clk or negedge(rst_l)) begin
|
||||||
|
if (rst_l == 1'b0) begin
|
||||||
|
CSR_awready <= 1'b0;
|
||||||
|
CSR_arready <= 1'b0;
|
||||||
|
clk_cnt <= 0;
|
||||||
|
led_q <= 0;
|
||||||
|
led_test_reg <= 1'b0;
|
||||||
|
qsfp_rst_reg <= 'h0;
|
||||||
|
qsfp_lp_reg <= 'h0;
|
||||||
|
qsfp_sel_oh <= 4'h0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
clk_cnt <= clk_cnt + 1;
|
||||||
|
led_q[3] <= clk_cnt[25];
|
||||||
|
CSR_awready <= CSR_awvalid;
|
||||||
|
CSR_arready <= CSR_arvalid;
|
||||||
|
if (csr_wen & CSR_wvalid) begin
|
||||||
|
CSR_wready <= CSR_wvalid & ~(CSR_awvalid);
|
||||||
|
if (CSR_awaddr[`DEV_SEL_LO_BIT-1]) begin
|
||||||
|
qsfp_rst_reg <= CSR_wdata[19:16]; // AXI Write to addr 0x80 Config Reg, R/W
|
||||||
|
qsfp_lp_reg <= CSR_wdata[15:12];
|
||||||
|
qsfp_sel_oh <= CSR_wdata[11:8];
|
||||||
|
led_test_reg <= CSR_wdata[7];
|
||||||
|
led_q[2:0] <= CSR_wdata[6:4];
|
||||||
|
end
|
||||||
|
CSR_bvalid <= 1;
|
||||||
|
end
|
||||||
|
else if (csr_ren & CSR_rready) begin
|
||||||
|
CSR_rvalid <= CSR_rready & ~(CSR_arvalid);
|
||||||
|
// AXI Read: 0x80 reads config reg, 0x0 reads VERSION REG, 0x4 reads UAR. 0x0 and 0x4 are READ ONLY
|
||||||
|
CSR_rdata <= CSR_araddr[`DEV_SEL_LO_BIT-1] ? {12'h0,
|
||||||
|
qsfp_rst_reg,
|
||||||
|
qsfp_lp_reg,
|
||||||
|
qsfp_sel_oh,
|
||||||
|
led_test_reg,
|
||||||
|
led_q[2:0],
|
||||||
|
4'b0000} : CSR_araddr[3] ? 32'h0 : (CSR_araddr[2] ? UAR_DATA : `VERSION_REG);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
CSR_rvalid <= 0;
|
||||||
|
CSR_wready <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign spi_miso = spi_in[1];
|
||||||
|
|
||||||
|
assign led_pins = ~led_q;
|
||||||
|
assign FPGA_I2C_MASTER_L = 1'b1; // Change to 1'b0 to allow FPGA control of QSFP I2C bus
|
||||||
|
assign QSFP_CTL_EN = 1'b1;
|
||||||
|
assign SAS_CTL_EN = 1'b1;
|
||||||
|
|
||||||
|
// User logic
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Find all the cdc_fifos and synchronizers set constraints for the cross clock domains.
|
||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
set synchronizer_instance [get_cells -hierarchical -filter { ORIG_REF_NAME =~ "synchronizer" || REF_NAME =~ "synchronizer" } ]
|
||||||
|
foreach child $synchronizer_instance {
|
||||||
|
|
||||||
|
set name [get_property NAME $child]
|
||||||
|
|
||||||
|
set cells [get_cells -hierarchical -filter "NAME =~ $name/* "]
|
||||||
|
set clock [get_clocks -of_objects [get_pins -filter { NAME =~ "*dat_reg[1]*C" } -of_objects $cells]]
|
||||||
|
set clock_period [get_property PERIOD $clock]
|
||||||
|
|
||||||
|
set_bus_skew -from [get_pins -filter { NAME =~ "*dat_reg[0]*C" } -of_objects $cells] -to [get_pins -filter { NAME =~ "*dat_reg[1]*D" } -of_objects $cells] [expr $clock_period/2]
|
||||||
|
set_max_delay -from [get_pins -filter { NAME =~ "*dat_reg[0]*C" } -of_objects $cells] -to [get_pins -filter { NAME =~ "*dat_reg[1]*D" } -of_objects $cells] -datapath_only [expr $clock_period/2]
|
||||||
|
|
||||||
|
}
|
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface if_axi_stream # (
|
interface if_axi_stream # (
|
||||||
parameter DAT_BYTS = 64,
|
parameter DAT_BYTS = 8,
|
||||||
parameter DAT_BITS = DAT_BYTS*8,
|
parameter DAT_BITS = DAT_BYTS*8,
|
||||||
parameter CTL_BYTS = 1,
|
parameter CTL_BYTS = 1,
|
||||||
parameter CTL_BITS = CTL_BYTS*8,
|
parameter CTL_BITS = CTL_BYTS*8,
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
set cdc_fifo_instance [get_cells -hierarchical -filter { ORIG_REF_NAME =~ "cdc_fifo" || REF_NAME =~ "cdc_fifo" } ]
|
set cdc_fifo_instance [get_cells -hierarchical -filter { ORIG_REF_NAME =~ "cdc_fifo" || REF_NAME =~ "cdc_fifo" } ]
|
||||||
foreach child $cdc_fifo_instance {
|
foreach child $cdc_fifo_instance {
|
||||||
|
|
||||||
set using_bram [get_property USE_BRAM [get_cells $child]]
|
|
||||||
set name [get_property NAME $child]
|
set name [get_property NAME $child]
|
||||||
|
|
||||||
set wr_ptr_cells [get_cells -hierarchical -filter "NAME =~ $name/synchronizer_wr_ptr/* "]
|
set wr_ptr_cells [get_cells -hierarchical -filter "NAME =~ $name/synchronizer_wr_ptr/* "]
|
||||||
|
|
|
@ -26,7 +26,7 @@ module control_top
|
||||||
parameter [63:0] BUILD_HOST = "test",
|
parameter [63:0] BUILD_HOST = "test",
|
||||||
parameter [63:0] BUILD_DATE = "20180311"
|
parameter [63:0] BUILD_DATE = "20180311"
|
||||||
)(
|
)(
|
||||||
input i_clk_core, i_rst_core,
|
input i_clk_core, i_rst_core, i_rst_core_perm, // _perm reset is not effected by o_usr_rst
|
||||||
input i_clk_if, i_rst_if,
|
input i_clk_if, i_rst_if,
|
||||||
// User is able to reset custom logic on FPGA
|
// User is able to reset custom logic on FPGA
|
||||||
output logic o_usr_rst,
|
output logic o_usr_rst,
|
||||||
|
@ -43,6 +43,8 @@ module control_top
|
||||||
localparam IN_DAT_BITS = IN_DAT_BYTS*8;
|
localparam IN_DAT_BITS = IN_DAT_BYTS*8;
|
||||||
localparam CORE_DAT_BITS = CORE_DAT_BYTS*8;
|
localparam CORE_DAT_BITS = CORE_DAT_BYTS*8;
|
||||||
|
|
||||||
|
localparam MAX_BYT_MSG = 256; // Max bytes in a reply message
|
||||||
|
|
||||||
// When a command comes in it is put through a clock crossing, and then stored in a command
|
// When a command comes in it is put through a clock crossing, and then stored in a command
|
||||||
// FIFO to be processed. There are two FIFOS - one for processing status / reset commands (msg_type == 0),
|
// FIFO to be processed. There are two FIFOS - one for processing status / reset commands (msg_type == 0),
|
||||||
// and one for everything else. This is so we can process these messages even if we are
|
// and one for everything else. This is so we can process these messages even if we are
|
||||||
|
@ -59,24 +61,31 @@ if_axi_stream #(.DAT_BYTS(CORE_DAT_BYTS), .CTL_BYTS(1)) rx_typ1_if (i_clk_core);
|
||||||
if_axi_stream #(.DAT_BYTS(CORE_DAT_BYTS), .CTL_BYTS(1)) tx_arb_in_if [2] (i_clk_core);
|
if_axi_stream #(.DAT_BYTS(CORE_DAT_BYTS), .CTL_BYTS(1)) tx_arb_in_if [2] (i_clk_core);
|
||||||
if_axi_stream #(.DAT_BYTS(CORE_DAT_BYTS), .CTL_BYTS(1)) tx_int_if (i_clk_core);
|
if_axi_stream #(.DAT_BYTS(CORE_DAT_BYTS), .CTL_BYTS(1)) tx_int_if (i_clk_core);
|
||||||
|
|
||||||
enum {TYP0_IDLE = 0,
|
typedef enum {TYP0_IDLE = 0,
|
||||||
TYP0_SEND_STATUS = 1,
|
TYP0_SEND_STATUS = 1,
|
||||||
TYP0_RESET_FPGA = 2,
|
TYP0_RESET_FPGA = 2,
|
||||||
TYP0_IGNORE = 3} typ0_msg_state;
|
TYP0_SEND_IGNORE = 3,
|
||||||
|
TYP0_IGNORE = 4} typ0_msg_state_t;
|
||||||
|
|
||||||
|
typ0_msg_state_t typ0_msg_state;
|
||||||
|
|
||||||
enum {TYP1_IDLE = 0,
|
enum {TYP1_IDLE = 0,
|
||||||
TYP1_VERIFY_EQUIHASH = 1,
|
TYP1_VERIFY_EQUIHASH = 1,
|
||||||
TYP1_IGNORE = 2} typ1_msg_state;
|
TYP1_IGNORE = 2} typ1_msg_state;
|
||||||
|
|
||||||
header_t header, header0, header1, header0_l, header1_l;
|
header_t header, header0, header1, header0_l, header1_l;
|
||||||
fpga_status_rpl_t fpga_status_rpl;
|
//fpga_status_rpl_t fpga_status_rpl;
|
||||||
fpga_reset_rpl_t fpga_reset_rpl;
|
//fpga_reset_rpl_t fpga_reset_rpl;
|
||||||
|
//fpga_ignore_rpl_t fpga0_ignore_rpl;
|
||||||
verify_equihash_rpl_t verify_equihash_rpl;
|
verify_equihash_rpl_t verify_equihash_rpl;
|
||||||
|
|
||||||
logic [7:0] typ0_wrd_cnt, typ1_wrd_cnt, reset_cnt;
|
logic [7:0] reset_cnt;
|
||||||
|
logic [$clog2(MAX_BYT_MSG) -1:0] typ0_wrd_cnt, typ1_wrd_cnt;
|
||||||
|
logic [MAX_BYT_MSG*8 -1:0] typ0_msg;
|
||||||
logic [63:0] equihash_index;
|
logic [63:0] equihash_index;
|
||||||
logic equihash_index_val, rx_typ1_if_rdy, verify_equihash_rpl_val;
|
logic equihash_index_val, rx_typ1_if_rdy, verify_equihash_rpl_val;
|
||||||
logic sop_l;
|
logic sop_l;
|
||||||
|
logic eop_typ0_l;
|
||||||
|
|
||||||
fpga_state_t fpga_state;
|
fpga_state_t fpga_state;
|
||||||
always_comb begin
|
always_comb begin
|
||||||
|
@ -90,45 +99,54 @@ end
|
||||||
|
|
||||||
// Logic for processing msg_type == 0 messages
|
// Logic for processing msg_type == 0 messages
|
||||||
always_ff @ (posedge i_clk_core) begin
|
always_ff @ (posedge i_clk_core) begin
|
||||||
if (i_rst_core) begin
|
if (i_rst_core_perm ) begin
|
||||||
rx_typ0_if.rdy <= 0;
|
rx_typ0_if.rdy <= 0;
|
||||||
typ0_msg_state <= TYP0_IDLE;
|
typ0_msg_state <= TYP0_IDLE;
|
||||||
header0_l <= 0;
|
header0_l <= 0;
|
||||||
tx_arb_in_if[0].reset_source();
|
tx_arb_in_if[0].reset_source();
|
||||||
fpga_status_rpl <= 0;
|
// fpga_status_rpl <= 0;
|
||||||
fpga_reset_rpl <= 0;
|
// fpga_reset_rpl <= 0;
|
||||||
|
/// fpga0_ignore_rpl <= 0;
|
||||||
typ0_wrd_cnt <= 0;
|
typ0_wrd_cnt <= 0;
|
||||||
o_usr_rst <= 0;
|
o_usr_rst <= 0;
|
||||||
reset_cnt <= 0;
|
reset_cnt <= 0;
|
||||||
|
eop_typ0_l <= 0;
|
||||||
|
typ0_msg <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
rx_typ0_if.rdy <= 1;
|
rx_typ0_if.rdy <= 1;
|
||||||
case (typ0_msg_state)
|
case (typ0_msg_state)
|
||||||
|
|
||||||
TYP0_IDLE: begin
|
TYP0_IDLE: begin
|
||||||
fpga_status_rpl <= get_fpga_status_rpl(BUILD_HOST, BUILD_DATE, fpga_state);
|
//fpga_status_rpl <= get_fpga_status_rpl(BUILD_HOST, BUILD_DATE, fpga_state);
|
||||||
fpga_reset_rpl <= get_fpga_reset_rpl();
|
//fpga_reset_rpl <= get_fpga_reset_rpl();
|
||||||
|
//fpga0_ignore_rpl <= get_fpga_ignore_rpl(header0);
|
||||||
|
|
||||||
if (rx_typ0_if.val && rx_typ0_if.rdy) begin
|
if (rx_typ0_if.val && rx_typ0_if.rdy) begin
|
||||||
header0_l <= header0;
|
header0_l <= header0;
|
||||||
rx_typ0_if.rdy <= 0;
|
rx_typ0_if.rdy <= 0;
|
||||||
case(header0.cmd)
|
case(header0.cmd)
|
||||||
RESET_FPGA: begin
|
RESET_FPGA: begin
|
||||||
|
typ0_msg <= get_fpga_reset_rpl();
|
||||||
typ0_wrd_cnt <= $bits(fpga_reset_rpl_t)/8;
|
typ0_wrd_cnt <= $bits(fpga_reset_rpl_t)/8;
|
||||||
typ0_msg_state <= TYP0_RESET_FPGA;
|
typ0_msg_state <= TYP0_RESET_FPGA;
|
||||||
o_usr_rst <= 1;
|
o_usr_rst <= 1;
|
||||||
reset_cnt <= -1;
|
reset_cnt <= -1;
|
||||||
end
|
end
|
||||||
FPGA_STATUS: begin
|
FPGA_STATUS: begin
|
||||||
|
typ0_msg <= get_fpga_status_rpl(BUILD_HOST, BUILD_DATE, fpga_state);
|
||||||
typ0_wrd_cnt <= $bits(fpga_status_rpl_t)/8;
|
typ0_wrd_cnt <= $bits(fpga_status_rpl_t)/8;
|
||||||
typ0_msg_state <= TYP0_SEND_STATUS;
|
typ0_msg_state <= TYP0_SEND_STATUS;
|
||||||
end
|
end
|
||||||
default:
|
default: begin
|
||||||
if (~rx_typ0_if.eop)
|
typ0_msg <= get_fpga_ignore_rpl(header0);
|
||||||
typ0_msg_state <= TYP0_IGNORE;
|
eop_typ0_l <= rx_typ0_if.eop;
|
||||||
|
typ0_msg_state <= TYP0_SEND_IGNORE;
|
||||||
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
TYP0_SEND_STATUS: begin
|
TYP0_SEND_STATUS: begin
|
||||||
|
/*
|
||||||
rx_typ0_if.rdy <= 0;
|
rx_typ0_if.rdy <= 0;
|
||||||
if (~tx_arb_in_if[0].val || (tx_arb_in_if[0].rdy && tx_arb_in_if[0].val)) begin
|
if (~tx_arb_in_if[0].val || (tx_arb_in_if[0].rdy && tx_arb_in_if[0].val)) begin
|
||||||
tx_arb_in_if[0].dat <= fpga_status_rpl;
|
tx_arb_in_if[0].dat <= fpga_status_rpl;
|
||||||
|
@ -143,6 +161,8 @@ always_ff @ (posedge i_clk_core) begin
|
||||||
typ0_msg_state <= TYP0_IDLE;
|
typ0_msg_state <= TYP0_IDLE;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
*/
|
||||||
|
send_typ0_message($bits(fpga_status_rpl_t)/8, typ0_msg, typ0_wrd_cnt);
|
||||||
end
|
end
|
||||||
TYP0_RESET_FPGA: begin
|
TYP0_RESET_FPGA: begin
|
||||||
rx_typ0_if.rdy <= 0;
|
rx_typ0_if.rdy <= 0;
|
||||||
|
@ -152,6 +172,8 @@ always_ff @ (posedge i_clk_core) begin
|
||||||
reset_cnt <= reset_cnt - 1;
|
reset_cnt <= reset_cnt - 1;
|
||||||
|
|
||||||
if (~o_usr_rst) begin
|
if (~o_usr_rst) begin
|
||||||
|
send_typ0_message($bits(fpga_reset_rpl_t)/8, typ0_msg, typ0_wrd_cnt);
|
||||||
|
/*
|
||||||
if (~tx_arb_in_if[0].val || (tx_arb_in_if[0].rdy && tx_arb_in_if[0].val)) begin
|
if (~tx_arb_in_if[0].val || (tx_arb_in_if[0].rdy && tx_arb_in_if[0].val)) begin
|
||||||
tx_arb_in_if[0].dat <= fpga_reset_rpl;
|
tx_arb_in_if[0].dat <= fpga_reset_rpl;
|
||||||
tx_arb_in_if[0].val <= 1;
|
tx_arb_in_if[0].val <= 1;
|
||||||
|
@ -164,9 +186,26 @@ always_ff @ (posedge i_clk_core) begin
|
||||||
tx_arb_in_if[0].val <= 0;
|
tx_arb_in_if[0].val <= 0;
|
||||||
typ0_msg_state <= TYP0_IDLE;
|
typ0_msg_state <= TYP0_IDLE;
|
||||||
end
|
end
|
||||||
|
end*/
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
TYP0_SEND_IGNORE: begin
|
||||||
|
send_typ0_message($bits(fpga0_ignore_rpl_t)/8, typ0_msg, typ0_wrd_cnt, eop_typ0_l ? TYP0_IDLE :TYP0_IGNORE);
|
||||||
|
/*
|
||||||
|
rx_typ0_if.rdy <= 0;
|
||||||
|
if (~tx_arb_in_if[0].val || (tx_arb_in_if[0].rdy && tx_arb_in_if[0].val)) begin
|
||||||
|
tx_arb_in_if[0].dat <= fpga_ignore_rpl;
|
||||||
|
tx_arb_in_if[0].val <= 1;
|
||||||
|
tx_arb_in_if[0].sop <= typ0_wrd_cnt == $bits(fpga0_ignore_rpl_t)/8;
|
||||||
|
tx_arb_in_if[0].eop <= typ0_wrd_cnt <= CORE_DAT_BYTS;
|
||||||
|
tx_arb_in_if[0].mod <= typ0_wrd_cnt < CORE_DAT_BYTS ? typ0_wrd_cnt : 0;
|
||||||
|
typ0_wrd_cnt <= (typ0_wrd_cnt > CORE_DAT_BYTS) ? (typ0_wrd_cnt - CORE_DAT_BYTS) : 0;
|
||||||
|
fpga_ignore_rpl <= fpga_ignore_rpl >> CORE_DAT_BITS;
|
||||||
|
if (typ0_wrd_cnt == 0) begin
|
||||||
|
tx_arb_in_if[0].val <= 0;
|
||||||
|
typ0_msg_state <= eop_typ0_l ? TYP0_IDLE :TYP0_IGNORE;
|
||||||
|
end
|
||||||
|
end*/
|
||||||
end
|
end
|
||||||
TYP0_IGNORE: begin
|
TYP0_IGNORE: begin
|
||||||
rx_typ0_if.rdy <= 1;
|
rx_typ0_if.rdy <= 1;
|
||||||
|
@ -177,6 +216,24 @@ always_ff @ (posedge i_clk_core) begin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// Task to help build reply messages. Assume no message will be more than MAX_BYT_MSG bytes
|
||||||
|
task automatic send_typ0_message(input logic [$clog2(MAX_BYT_MSG)-1:0] msg_size, ref logic [MAX_BYT_MSG*8-1:0] msg, ref logic [$clog2(MAX_BYT_MSG)-1:0] byt_cnt, input typ0_msg_state_t nxt_state = TYP0_IDLE);
|
||||||
|
rx_typ0_if.rdy <= 0;
|
||||||
|
if (~tx_arb_in_if[0].val || (tx_arb_in_if[0].rdy && tx_arb_in_if[0].val)) begin
|
||||||
|
tx_arb_in_if[0].dat <= msg;
|
||||||
|
tx_arb_in_if[0].val <= 1;
|
||||||
|
tx_arb_in_if[0].sop <= byt_cnt == msg_size;
|
||||||
|
tx_arb_in_if[0].eop <= byt_cnt <= CORE_DAT_BYTS;
|
||||||
|
tx_arb_in_if[0].mod <= byt_cnt < CORE_DAT_BYTS ? byt_cnt : 0;
|
||||||
|
byt_cnt <= (byt_cnt > CORE_DAT_BYTS) ? (byt_cnt - CORE_DAT_BYTS) : 0;
|
||||||
|
msg <= msg >> CORE_DAT_BITS;
|
||||||
|
if (byt_cnt == 0) begin
|
||||||
|
tx_arb_in_if[0].val <= 0;
|
||||||
|
typ0_msg_state <= nxt_state;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case(typ1_msg_state)
|
case(typ1_msg_state)
|
||||||
TYP1_IDLE: rx_typ1_if.rdy = rx_typ1_if_rdy;
|
TYP1_IDLE: rx_typ1_if.rdy = rx_typ1_if_rdy;
|
||||||
|
@ -199,6 +256,7 @@ always_ff @ (posedge i_clk_core) begin
|
||||||
equihash_index_val <= 0;
|
equihash_index_val <= 0;
|
||||||
sop_l <= 0;
|
sop_l <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
|
// TODO add IGNORE type here
|
||||||
case (typ1_msg_state)
|
case (typ1_msg_state)
|
||||||
TYP1_IDLE: begin
|
TYP1_IDLE: begin
|
||||||
rx_typ1_if_rdy <= 1;
|
rx_typ1_if_rdy <= 1;
|
||||||
|
@ -303,7 +361,7 @@ always_comb begin
|
||||||
end
|
end
|
||||||
|
|
||||||
always_ff @ (posedge i_clk_core) begin
|
always_ff @ (posedge i_clk_core) begin
|
||||||
if (i_rst_core || o_usr_rst) begin
|
if (i_rst_core ) begin
|
||||||
msg_type_l <= 0;
|
msg_type_l <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
if (rx_int_if.val && rx_int_if.rdy) begin
|
if (rx_int_if.val && rx_int_if.rdy) begin
|
||||||
|
@ -321,7 +379,7 @@ axi_stream_fifo #(
|
||||||
)
|
)
|
||||||
cmd_fifo0 (
|
cmd_fifo0 (
|
||||||
.i_clk ( i_clk_core ),
|
.i_clk ( i_clk_core ),
|
||||||
.i_rst ( i_rst_core || o_usr_rst ),
|
.i_rst ( i_rst_core ),
|
||||||
.i_axi ( rx_int0_if ),
|
.i_axi ( rx_int0_if ),
|
||||||
.o_axi ( rx_typ0_if )
|
.o_axi ( rx_typ0_if )
|
||||||
);
|
);
|
||||||
|
@ -332,7 +390,7 @@ axi_stream_fifo #(
|
||||||
)
|
)
|
||||||
cmd_fifo1 (
|
cmd_fifo1 (
|
||||||
.i_clk ( i_clk_core ),
|
.i_clk ( i_clk_core ),
|
||||||
.i_rst ( i_rst_core || o_usr_rst ),
|
.i_rst ( i_rst_core ),
|
||||||
.i_axi ( rx_int1_if ),
|
.i_axi ( rx_int1_if ),
|
||||||
.o_axi ( rx_typ1_if )
|
.o_axi ( rx_typ1_if )
|
||||||
);
|
);
|
||||||
|
@ -346,9 +404,9 @@ width_change_cdc_fifo #(
|
||||||
)
|
)
|
||||||
cdc_fifo_rx (
|
cdc_fifo_rx (
|
||||||
.i_clk_a ( i_clk_if ),
|
.i_clk_a ( i_clk_if ),
|
||||||
.i_rst_a ( i_rst_if || o_usr_rst ),
|
.i_rst_a ( i_rst_if ),
|
||||||
.i_clk_b ( i_clk_core ),
|
.i_clk_b ( i_clk_core ),
|
||||||
.i_rst_b ( i_rst_core || o_usr_rst ),
|
.i_rst_b ( i_rst_core ),
|
||||||
.i_axi_a ( rx_if ),
|
.i_axi_a ( rx_if ),
|
||||||
.o_axi_b ( rx_int_if )
|
.o_axi_b ( rx_int_if )
|
||||||
);
|
);
|
||||||
|
@ -361,7 +419,7 @@ packet_arb # (
|
||||||
)
|
)
|
||||||
packet_arb_tx (
|
packet_arb_tx (
|
||||||
.i_clk ( i_clk_core ),
|
.i_clk ( i_clk_core ),
|
||||||
.i_rst ( i_rst_core || o_usr_rst ),
|
.i_rst ( i_rst_core ),
|
||||||
|
|
||||||
.i_axi ( tx_arb_in_if ),
|
.i_axi ( tx_arb_in_if ),
|
||||||
.o_axi ( tx_int_if )
|
.o_axi ( tx_int_if )
|
||||||
|
@ -377,9 +435,9 @@ width_change_cdc_fifo #(
|
||||||
)
|
)
|
||||||
cdc_fifo_tx (
|
cdc_fifo_tx (
|
||||||
.i_clk_a ( i_clk_core ),
|
.i_clk_a ( i_clk_core ),
|
||||||
.i_rst_a ( i_rst_core || o_usr_rst ),
|
.i_rst_a ( i_rst_core ),
|
||||||
.i_clk_b ( i_clk_if ),
|
.i_clk_b ( i_clk_if ),
|
||||||
.i_rst_b ( i_rst_if || o_usr_rst ),
|
.i_rst_b ( i_rst_if ),
|
||||||
.i_axi_a ( tx_int_if ),
|
.i_axi_a ( tx_int_if ),
|
||||||
.o_axi_b ( tx_if )
|
.o_axi_b ( tx_if )
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
This performs modular reduction using Algorithm 2.4 from
|
||||||
|
D. Hankerson, A. Menezes, S. Vanstone, “Guide to Elliptic Curve Cryptography”
|
||||||
|
but with data width 256, for the prime field used in secp256k1
|
||||||
|
|
||||||
|
p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
|
||||||
|
|
||||||
|
Implemented with 2 stages of 8x 256b adds and one final optional
|
||||||
|
subtract in the case we are >= p.
|
||||||
|
|
||||||
|
returns o_dat = i_dat % p, where i_dat < p^2
|
||||||
|
|
||||||
|
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 secp256k1_mod (
|
||||||
|
input i_clk, i_rst,
|
||||||
|
// Input value
|
||||||
|
input [256*2-1:0] i_dat,
|
||||||
|
input i_val,
|
||||||
|
output logic o_rdy,
|
||||||
|
// output
|
||||||
|
output logic [255:0] o_dat,
|
||||||
|
input i_rdy,
|
||||||
|
output logic o_val
|
||||||
|
);
|
||||||
|
|
||||||
|
import secp256k1_pkg::*;
|
||||||
|
|
||||||
|
logic [256*2-1:0] b, a, a_;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
a_ = (a << 32) + (a << 9) + (a << 8) + (a << 7) + (a << 6) + (a << 4) + a + b;
|
||||||
|
end
|
||||||
|
|
||||||
|
enum {IDLE, S1, S2} state;
|
||||||
|
|
||||||
|
always_ff @ (posedge i_clk) begin
|
||||||
|
if (i_rst) begin
|
||||||
|
a <= 0;
|
||||||
|
b <= 0;
|
||||||
|
state <= IDLE;
|
||||||
|
o_val <= 0;
|
||||||
|
o_rdy <= 0;
|
||||||
|
end else begin
|
||||||
|
o_rdy <= 0;
|
||||||
|
o_dat <= a_ >= p_eq ? (a_ - p_eq) : a_;
|
||||||
|
case(state)
|
||||||
|
IDLE: begin
|
||||||
|
o_rdy <= 1;
|
||||||
|
o_val <= 0;
|
||||||
|
if (i_val && o_rdy) begin
|
||||||
|
a <= i_dat[511:256];
|
||||||
|
b <= i_dat[255:0];
|
||||||
|
o_rdy <= 0;
|
||||||
|
state <= S1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
S1: begin
|
||||||
|
a <= a_[511:256];
|
||||||
|
b <= a_[255:0];
|
||||||
|
state <= S2;
|
||||||
|
end
|
||||||
|
S2: begin
|
||||||
|
o_val <= 1;
|
||||||
|
if (o_val && i_rdy) begin
|
||||||
|
state <=IDLE;
|
||||||
|
o_rdy <= 1;
|
||||||
|
o_val <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package secp256k1_pkg;
|
||||||
|
|
||||||
|
// TODO might have to flip these
|
||||||
|
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;
|
||||||
|
parameter [255:0] Gx = 256'h79BE667E_F9DCBBAC_55A06295_CE870B07_029BFCDB_2DCE28D9_59F2815B_16F81798;
|
||||||
|
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;
|
||||||
|
|
||||||
|
parameter [255:0] p_eq = (1 << 256) - (1 << 32) - (1 << 9) - (1 << 8) - (1 << 7) - (1 << 6) - (1 << 4) - 1;
|
||||||
|
|
||||||
|
endpackage
|
|
@ -0,0 +1,10 @@
|
||||||
|
module secp256k1_top ();
|
||||||
|
|
||||||
|
|
||||||
|
// inversion
|
||||||
|
|
||||||
|
// multiplication
|
||||||
|
|
||||||
|
// addition
|
||||||
|
|
||||||
|
endmodule
|
|
@ -21,9 +21,13 @@ package zcash_fpga_pkg;
|
||||||
|
|
||||||
import equihash_pkg::equihash_bm_t;
|
import equihash_pkg::equihash_bm_t;
|
||||||
import equihash_pkg::cblockheader_sol_t;
|
import equihash_pkg::cblockheader_sol_t;
|
||||||
|
import equihash_pkg::N;
|
||||||
|
import equihash_pkg::K;
|
||||||
|
|
||||||
parameter FPGA_VERSION = 32'h0;
|
parameter FPGA_VERSION = 32'h0;
|
||||||
localparam [63:0] FPGA_CMD_CAP = 64'h0;
|
localparam [63:0] FPGA_CMD_CAP = {{62'd0},
|
||||||
|
(equihash_pkg::N == 144 && equihash_pkg::K == 5), // N = 144, K = 5 for VERIFY_EQUIHASH command
|
||||||
|
(equihash_pkg::N == 200 && equihash_pkg::K == 9)}; // N = 200, K = 9 for VERIFY_EQUIHASH command
|
||||||
|
|
||||||
// These are all the command types the FPGA supports
|
// These are all the command types the FPGA supports
|
||||||
// Reply messages from the FPGA to host all have the last
|
// Reply messages from the FPGA to host all have the last
|
||||||
|
@ -36,6 +40,7 @@ package zcash_fpga_pkg;
|
||||||
// Replies from the FPGA
|
// Replies from the FPGA
|
||||||
RESET_FPGA_RPL = 'h80_00_00_00,
|
RESET_FPGA_RPL = 'h80_00_00_00,
|
||||||
FPGA_STATUS_RPL = 'h80_00_00_01,
|
FPGA_STATUS_RPL = 'h80_00_00_01,
|
||||||
|
FPGA_IGNORE_RPL = 'h80_00_00_02,
|
||||||
VERIFY_EQUIHASH_RPL = 'h80_00_01_00
|
VERIFY_EQUIHASH_RPL = 'h80_00_01_00
|
||||||
} command_t;
|
} command_t;
|
||||||
|
|
||||||
|
@ -50,6 +55,11 @@ package zcash_fpga_pkg;
|
||||||
header_t hdr;
|
header_t hdr;
|
||||||
} fpga_reset_rpl_t;
|
} fpga_reset_rpl_t;
|
||||||
|
|
||||||
|
typedef struct packed {
|
||||||
|
header_t hdr;
|
||||||
|
logic [63:0] ignore_hdr;
|
||||||
|
} fpga_ignore_rpl_t;
|
||||||
|
|
||||||
// These are registers we use for debug
|
// These are registers we use for debug
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
logic [3:0] padding;
|
logic [3:0] padding;
|
||||||
|
@ -83,6 +93,10 @@ package zcash_fpga_pkg;
|
||||||
get_fpga_reset_rpl.hdr = '{cmd:RESET_FPGA_RPL, len:$bits(fpga_reset_rpl_t)/8};
|
get_fpga_reset_rpl.hdr = '{cmd:RESET_FPGA_RPL, len:$bits(fpga_reset_rpl_t)/8};
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function fpga_ignore_rpl_t get_fpga_ignore_rpl(header_t hdr);
|
||||||
|
get_fpga_ignore_rpl.hdr = '{cmd:FPGA_IGNORE_RPL, len:$bits(fpga_ignore_rpl_t)/8};
|
||||||
|
endfunction
|
||||||
|
|
||||||
function fpga_status_rpl_t get_fpga_status_rpl(input [63:0] build_host, build_date, fpga_state_t fpga_state);
|
function fpga_status_rpl_t get_fpga_status_rpl(input [63:0] build_host, build_date, fpga_state_t fpga_state);
|
||||||
get_fpga_status_rpl.cmd_cap = FPGA_CMD_CAP;
|
get_fpga_status_rpl.cmd_cap = FPGA_CMD_CAP;
|
||||||
get_fpga_status_rpl.hdr = '{cmd:FPGA_STATUS_RPL, len:$bits(fpga_status_rpl_t)/8};
|
get_fpga_status_rpl.hdr = '{cmd:FPGA_STATUS_RPL, len:$bits(fpga_status_rpl_t)/8};
|
||||||
|
|
|
@ -27,37 +27,65 @@ module zcash_fpga_top
|
||||||
parameter CORE_DAT_BYTS = 8 // Only tested at 8 byte data width
|
parameter CORE_DAT_BYTS = 8 // Only tested at 8 byte data width
|
||||||
)(
|
)(
|
||||||
// Clocks and resets
|
// Clocks and resets
|
||||||
input i_clk_200, i_rst_200,
|
input i_clk_core0, i_rst_core0, // Core 0 is the main clock
|
||||||
input i_clk_300, i_rst_300,
|
input i_clk_core1, i_rst_core1, // Core 1 is used on logic with faster clock
|
||||||
input i_clk_if, i_rst_if,
|
input i_clk_if, i_rst_if, // Command interface clock (e.g. UART / PCIe)
|
||||||
|
|
||||||
// Interface input and output
|
// Command interface input and output
|
||||||
// UART
|
|
||||||
if_axi_stream.sink rx_if,
|
if_axi_stream.sink rx_if,
|
||||||
if_axi_stream.source tx_if
|
if_axi_stream.source tx_if
|
||||||
);
|
);
|
||||||
|
|
||||||
logic usr_rst, core_clk, core_rst;
|
logic rst_core0, rst_core1, rst_if, usr_rst, usr_rst_r;
|
||||||
if_axi_stream #(.DAT_BYTS(CORE_DAT_BYTS)) equihash_axi(core_clk);
|
|
||||||
|
logic rst_200, rst_300;
|
||||||
|
|
||||||
|
if_axi_stream #(.DAT_BYTS(CORE_DAT_BYTS)) equihash_axi(i_clk_core0);
|
||||||
|
|
||||||
equihash_bm_t equihash_mask;
|
equihash_bm_t equihash_mask;
|
||||||
logic equihash_mask_val;
|
logic equihash_mask_val;
|
||||||
|
|
||||||
always_comb begin
|
always_ff @ (posedge i_clk_core0) begin
|
||||||
core_clk = i_clk_200;
|
usr_rst_r <= usr_rst;
|
||||||
core_rst = i_rst_200;
|
rst_core0 <= i_rst_core0 || usr_rst_r;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// Synchronize resets
|
||||||
|
(* DONT_TOUCH = "yes" *)
|
||||||
|
synchronizer #(
|
||||||
|
.DAT_BITS ( 1 ),
|
||||||
|
.NUM_CLKS ( 3 )
|
||||||
|
)
|
||||||
|
core_rst1_sync (
|
||||||
|
.i_clk_a ( i_clk_core0 ),
|
||||||
|
.i_clk_b ( i_clk_core1 ),
|
||||||
|
.i_dat_a ( usr_rst_r || i_rst_core1 ),
|
||||||
|
.o_dat_b ( rst_core1 )
|
||||||
|
);
|
||||||
|
|
||||||
|
(* DONT_TOUCH = "yes" *)
|
||||||
|
synchronizer #(
|
||||||
|
.DAT_BITS ( 1 ),
|
||||||
|
.NUM_CLKS ( 3 )
|
||||||
|
)
|
||||||
|
if_rst_sync (
|
||||||
|
.i_clk_a ( i_clk_core0 ),
|
||||||
|
.i_clk_b ( i_clk_if ),
|
||||||
|
.i_dat_a ( usr_rst_r || i_rst_if ),
|
||||||
|
.o_dat_b ( rst_if )
|
||||||
|
);
|
||||||
|
|
||||||
// This block takes in the interface signals and interfaces with other blocks
|
// This block takes in the interface signals and interfaces with other blocks
|
||||||
control_top #(
|
control_top #(
|
||||||
.CORE_DAT_BYTS ( CORE_DAT_BYTS ),
|
.CORE_DAT_BYTS ( CORE_DAT_BYTS ),
|
||||||
.IN_DAT_BYTS ( IF_DAT_BYTS )
|
.IN_DAT_BYTS ( IF_DAT_BYTS )
|
||||||
)
|
)
|
||||||
control_top (
|
control_top (
|
||||||
.i_clk_core ( core_clk ),
|
.i_clk_core ( i_clk_core0 ),
|
||||||
.i_rst_core ( core_rst ),
|
.i_rst_core ( rst_core0 ),
|
||||||
|
.i_rst_core_perm ( i_rst_core0 ),
|
||||||
.i_clk_if ( i_clk_if ),
|
.i_clk_if ( i_clk_if ),
|
||||||
.i_rst_if ( i_rst_if ),
|
.i_rst_if ( rst_if ),
|
||||||
.o_usr_rst ( usr_rst ),
|
.o_usr_rst ( usr_rst ),
|
||||||
.rx_if ( rx_if ),
|
.rx_if ( rx_if ),
|
||||||
.tx_if ( tx_if ),
|
.tx_if ( tx_if ),
|
||||||
|
@ -72,12 +100,10 @@ equihash_verif_top #(
|
||||||
.DAT_BYTS( CORE_DAT_BYTS )
|
.DAT_BYTS( CORE_DAT_BYTS )
|
||||||
)
|
)
|
||||||
equihash_verif_top (
|
equihash_verif_top (
|
||||||
.i_clk ( core_clk ),
|
.i_clk ( i_clk_core0 ),
|
||||||
.i_rst ( core_rst || usr_rst ),
|
.i_rst ( core_rst ),
|
||||||
|
.i_clk_300 ( i_clk_core1 ), // Faster clock
|
||||||
.i_clk_300 ( i_clk_300 ),
|
.i_rst_300 ( rst_core1 ),
|
||||||
.i_rst_300 ( i_rst_300 || usr_rst ), // Faster clock
|
|
||||||
|
|
||||||
.i_axi ( equihash_axi ),
|
.i_axi ( equihash_axi ),
|
||||||
.o_mask ( equihash_mask ),
|
.o_mask ( equihash_mask ),
|
||||||
.o_mask_val ( equihash_mask_val )
|
.o_mask_val ( equihash_mask_val )
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
`timescale 1ps/1ps
|
||||||
|
|
||||||
|
module secp256k1_mod_tb ();
|
||||||
|
import common_pkg::*;
|
||||||
|
import secp256k1_pkg::*;
|
||||||
|
|
||||||
|
localparam CLK_PERIOD = 100;
|
||||||
|
|
||||||
|
logic clk, rst;
|
||||||
|
|
||||||
|
if_axi_stream #(.DAT_BYTS(512/8)) in_if(clk);
|
||||||
|
if_axi_stream #(.DAT_BYTS(256/8)) out_if(clk);
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
rst = 0;
|
||||||
|
repeat(2) #(20*CLK_PERIOD) rst = ~rst;
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
clk = 0;
|
||||||
|
forever #CLK_PERIOD clk = ~clk;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
out_if.sop = 1;
|
||||||
|
out_if.eop = 1;
|
||||||
|
out_if.err = 0;
|
||||||
|
out_if.ctl = 0;
|
||||||
|
out_if.mod = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
secp256k1_mod secp256k1_mod
|
||||||
|
(
|
||||||
|
.i_clk( clk ),
|
||||||
|
.i_rst( rst ),
|
||||||
|
.i_dat( in_if.dat ),
|
||||||
|
.i_val( in_if.val ),
|
||||||
|
.o_rdy( in_if.rdy ),
|
||||||
|
.o_dat( out_if.dat ),
|
||||||
|
.i_rdy( out_if.rdy ),
|
||||||
|
.o_val( out_if.val )
|
||||||
|
);
|
||||||
|
|
||||||
|
task test0();
|
||||||
|
begin
|
||||||
|
integer signed get_len;
|
||||||
|
logic [common_pkg::MAX_SIM_BYTS*8-1:0] expected, in_dat, get_dat;
|
||||||
|
$display("Running test0...");
|
||||||
|
in_dat = 1 << 433;
|
||||||
|
expected = 256'd822752465816620949324161418291805943222876982255305228346720256;
|
||||||
|
fork
|
||||||
|
in_if.put_stream(in_dat, 512/8);
|
||||||
|
out_if.get_stream(get_dat, get_len);
|
||||||
|
join
|
||||||
|
|
||||||
|
common_pkg::compare_and_print(get_dat, expected);
|
||||||
|
$display("test0 PASSED");
|
||||||
|
end
|
||||||
|
endtask;
|
||||||
|
|
||||||
|
task test_loop();
|
||||||
|
begin
|
||||||
|
integer signed get_len, i, max;
|
||||||
|
logic [common_pkg::MAX_SIM_BYTS*8-1:0] expected, in_dat, get_dat;
|
||||||
|
$display("Running test_loop...");
|
||||||
|
in_dat = 1 << 433;
|
||||||
|
expected = 256'd822752465816620949324161418291805943222876982255305228346720256;
|
||||||
|
i = 0;
|
||||||
|
max = 10000;
|
||||||
|
repeat (max) begin
|
||||||
|
|
||||||
|
in_dat = in_dat*2;
|
||||||
|
expected = expected*2;
|
||||||
|
while (expected >= p_eq)
|
||||||
|
expected = expected - p_eq;
|
||||||
|
|
||||||
|
fork
|
||||||
|
in_if.put_stream(in_dat, 512/8);
|
||||||
|
out_if.get_stream(get_dat, get_len);
|
||||||
|
join
|
||||||
|
|
||||||
|
common_pkg::compare_and_print(get_dat, expected);
|
||||||
|
$display("test_loop PASSED loop %d/%d", i, max);
|
||||||
|
i = i + 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
$display("test_loop PASSED");
|
||||||
|
end
|
||||||
|
endtask;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
out_if.rdy = 0;
|
||||||
|
in_if.val = 0;
|
||||||
|
#(40*CLK_PERIOD);
|
||||||
|
test0();
|
||||||
|
test_loop();
|
||||||
|
#1us $finish();
|
||||||
|
end
|
||||||
|
endmodule
|
|
@ -195,6 +195,7 @@ initial begin
|
||||||
#20us; // Let internal memories reset
|
#20us; // Let internal memories reset
|
||||||
|
|
||||||
test_block_346_equihash();
|
test_block_346_equihash();
|
||||||
|
test_ignored_message();
|
||||||
|
|
||||||
#1us $finish();
|
#1us $finish();
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
create_clock -period 5.000 -name i_clk_200 -waveform {0.000 2.500} [get_ports -filter { NAME =~ "*i_clk_200*" && DIRECTION == "IN" }]
|
create_clock -period 3.000 -name i_clk_core1 -waveform {0.000 1.500} [get_ports -filter { NAME =~ "i_clk_core1" && DIRECTION == "IN" }]
|
||||||
create_clock -period 3.333 -name i_clk_300 -waveform {0.000 1.666} [get_ports -filter { NAME =~ "i_clk_300" && DIRECTION == "IN" }]
|
create_clock -period 5.000 -name i_clk_core0 -waveform {0.000 2.500} [get_ports -filter { NAME =~ "i_clk_core0" && DIRECTION == "IN" }]
|
||||||
create_clock -period 10.000 -name i_clk_if -waveform {0.000 5.000} [get_ports -filter { NAME =~ "i_clk_if" && DIRECTION == "IN" }]
|
create_clock -period 10.000 -name i_clk_if -waveform {0.000 5.000} [get_ports -filter { NAME =~ "i_clk_if" && DIRECTION == "IN" }]
|
||||||
|
|
||||||
|
#Just for when we are synth a test block
|
||||||
|
create_clock -period 5.000 -name i_clk -waveform {0.000 2.500} [get_ports -filter { NAME =~ "i_clk" && DIRECTION == "IN" }]
|
||||||
|
|
||||||
set_bus_skew -from [get_pins -filter { NAME =~ "*dat_reg[0]*C" } -of_objects [get_cells -hierarchical -filter {NAME =~ control_top/cdc_fifo_rx/cdc_fifo/synchronizer_wr_ptr/* }]] -to [get_pins -filter { NAME =~ "*dat_reg[1]*D" } -of_objects [get_cells -hierarchical -filter {NAME =~ control_top/cdc_fifo_rx/cdc_fifo/synchronizer_wr_ptr/* }]] 2.500
|
set_bus_skew -from [get_pins -filter { NAME =~ "*dat_reg[0]*C" } -of_objects [get_cells -hierarchical -filter {NAME =~ control_top/cdc_fifo_rx/cdc_fifo/synchronizer_wr_ptr/* }]] -to [get_pins -filter { NAME =~ "*dat_reg[1]*D" } -of_objects [get_cells -hierarchical -filter {NAME =~ control_top/cdc_fifo_rx/cdc_fifo/synchronizer_wr_ptr/* }]] 2.500
|
||||||
set_max_delay -datapath_only -from [get_pins -filter { NAME =~ "*dat_reg[0]*C" } -of_objects [get_cells -hierarchical -filter {NAME =~ control_top/cdc_fifo_rx/cdc_fifo/synchronizer_wr_ptr/* }]] -to [get_pins -filter { NAME =~ "*dat_reg[1]*D" } -of_objects [get_cells -hierarchical -filter {NAME =~ control_top/cdc_fifo_rx/cdc_fifo/synchronizer_wr_ptr/* }]] 2.500
|
set_max_delay -datapath_only -from [get_pins -filter { NAME =~ "*dat_reg[0]*C" } -of_objects [get_cells -hierarchical -filter {NAME =~ control_top/cdc_fifo_rx/cdc_fifo/synchronizer_wr_ptr/* }]] -to [get_pins -filter { NAME =~ "*dat_reg[1]*D" } -of_objects [get_cells -hierarchical -filter {NAME =~ control_top/cdc_fifo_rx/cdc_fifo/synchronizer_wr_ptr/* }]] 2.500
|
||||||
set_bus_skew -from [get_pins -filter { NAME =~ "*dat_reg[0]*C" } -of_objects [get_cells -hierarchical -filter {NAME =~ control_top/cdc_fifo_rx/cdc_fifo/synchronizer_rd_ptr/* }]] -to [get_pins -filter { NAME =~ "*dat_reg[1]*D" } -of_objects [get_cells -hierarchical -filter {NAME =~ control_top/cdc_fifo_rx/cdc_fifo/synchronizer_rd_ptr/* }]] 5.000
|
set_bus_skew -from [get_pins -filter { NAME =~ "*dat_reg[0]*C" } -of_objects [get_cells -hierarchical -filter {NAME =~ control_top/cdc_fifo_rx/cdc_fifo/synchronizer_rd_ptr/* }]] -to [get_pins -filter { NAME =~ "*dat_reg[1]*D" } -of_objects [get_cells -hierarchical -filter {NAME =~ control_top/cdc_fifo_rx/cdc_fifo/synchronizer_rd_ptr/* }]] 5.000
|
||||||
|
@ -48,5 +51,9 @@ set_bus_skew -from [get_pins -filter { NAME =~ "*dat_reg[0]*C" } -of_objects [g
|
||||||
set_max_delay -datapath_only -from [get_pins -filter { NAME =~ "*dat_reg[0]*C" } -of_objects [get_cells -hierarchical -filter {NAME =~ equihash_verif_top/dup_check_fifo_out/synchronizer_rd_ptr/* }]] -to [get_pins -filter { NAME =~ "*dat_reg[1]*D" } -of_objects [get_cells -hierarchical -filter {NAME =~ equihash_verif_top/dup_check_fifo_out/synchronizer_rd_ptr/* }]] 1.667
|
set_max_delay -datapath_only -from [get_pins -filter { NAME =~ "*dat_reg[0]*C" } -of_objects [get_cells -hierarchical -filter {NAME =~ equihash_verif_top/dup_check_fifo_out/synchronizer_rd_ptr/* }]] -to [get_pins -filter { NAME =~ "*dat_reg[1]*D" } -of_objects [get_cells -hierarchical -filter {NAME =~ equihash_verif_top/dup_check_fifo_out/synchronizer_rd_ptr/* }]] 1.667
|
||||||
set_bus_skew -from [get_pins -filter { NAME =~ "*ram*C" } -of_objects [get_cells -hierarchical -filter {NAME =~ equihash_verif_top/dup_check_fifo_out/* }]] -to [get_pins -filter { NAME =~ "*o_dat_b*D" } -of_objects [get_cells -hierarchical -filter {NAME =~ equihash_verif_top/dup_check_fifo_out/* }]] 1.667
|
set_bus_skew -from [get_pins -filter { NAME =~ "*ram*C" } -of_objects [get_cells -hierarchical -filter {NAME =~ equihash_verif_top/dup_check_fifo_out/* }]] -to [get_pins -filter { NAME =~ "*o_dat_b*D" } -of_objects [get_cells -hierarchical -filter {NAME =~ equihash_verif_top/dup_check_fifo_out/* }]] 1.667
|
||||||
set_max_delay -datapath_only -from [get_pins -filter { NAME =~ "*ram*C" } -of_objects [get_cells -hierarchical -filter {NAME =~ equihash_verif_top/dup_check_fifo_out/* }]] -to [get_pins -filter { NAME =~ "*o_dat_b*D" } -of_objects [get_cells -hierarchical -filter {NAME =~ equihash_verif_top/dup_check_fifo_out/* }]] 1.667
|
set_max_delay -datapath_only -from [get_pins -filter { NAME =~ "*ram*C" } -of_objects [get_cells -hierarchical -filter {NAME =~ equihash_verif_top/dup_check_fifo_out/* }]] -to [get_pins -filter { NAME =~ "*o_dat_b*D" } -of_objects [get_cells -hierarchical -filter {NAME =~ equihash_verif_top/dup_check_fifo_out/* }]] 1.667
|
||||||
set_multicycle_path -hold -from [get_pins control_top/o_usr_rst_reg/C] 5
|
|
||||||
set_multicycle_path -setup -from [get_pins control_top/o_usr_rst_reg/C] 5
|
|
||||||
|
|
||||||
|
set_false_path -from [get_pins {core_rst1_sync/dat_reg[0][0]/C}] -to [get_pins {core_rst1_sync/dat_reg[2][0]_srl2/D}]
|
||||||
|
set_false_path -from [get_pins {if_rst_sync/dat_reg[0][0]/C}] -to [get_pins {if_rst_sync/dat_reg[2][0]_srl2/D}]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue