diff --git a/aws/cl_zcash/software/runtime/test_zcash.cpp b/aws/cl_zcash/software/runtime/test_zcash.cpp index 84ead07..286dbf0 100644 --- a/aws/cl_zcash/software/runtime/test_zcash.cpp +++ b/aws/cl_zcash/software/runtime/test_zcash.cpp @@ -92,15 +92,14 @@ int main(int argc, char **argv) { } } } - + zcash_fpga& zfpga = zcash_fpga::get_instance(); - zfpga.init_fpga(); // Get FPGA status zcash_fpga::fpga_status_rpl_t status_rpl; rc = zfpga.get_status(status_rpl); fail_on(rc, out, "Unable toget FPGA status!"); - + // Read and write a data slot in BLS12_381 zcash_fpga::bls12_381_slot_t data_slot; rc = zfpga.bls12_381_read_data_slot(0, data_slot); diff --git a/aws/cl_zcash/software/runtime/zcash_fpga.cpp b/aws/cl_zcash/software/runtime/zcash_fpga.cpp index 220a3f9..47076bc 100644 --- a/aws/cl_zcash/software/runtime/zcash_fpga.cpp +++ b/aws/cl_zcash/software/runtime/zcash_fpga.cpp @@ -6,6 +6,23 @@ #include +zcash_fpga::zcash_fpga() { + if (zfpga.init_fpga() != 0) + printf("ERROR: Unable to initialize to FPGA!\n"); +} + +zcash_fpga::~zcash_fpga() { + /* clean up */ + if (m_pci_bar_handle_bar0 >= 0) { + rc = fpga_pci_detach(pci_bar_handle_bar0); + if (rc) printf("ERROR: Failure while detaching bar0 from the fpga.\n"); + } + if (m_pci_bar_handle_bar4 >= 0) { + rc = fpga_pci_detach(pci_bar_handle_bar4); + if (rc) printf("ERROR: Failure while detaching bar4 from the fpga.\n"); + } +} + zcash_fpga& zcash_fpga::get_instance() { static zcash_fpga instance; return instance; @@ -23,22 +40,22 @@ int zcash_fpga::init_fpga(int slot_id) { /* initialize the fpga_pci library so we could have access to FPGA PCIe from this applications */ rc = fpga_pci_init(); - fail_on(rc, out, "Unable to initialize the fpga_pci library"); + fail_on(rc, out, "ERROR: Unable to initialize the fpga_pci library"); rc = check_afi_ready(slot_id); - fail_on(rc, out, "AFI not ready"); + fail_on(rc, out, "ERROR: AFI not ready"); // We need to attach to the FPGA BAR0 (OCL) and BAR4 (PCIS) rc = fpga_pci_attach(slot_id, FPGA_APP_PF, APP_PF_BAR0, 0, &pci_bar_handle_bar0); - fail_on(rc, out, "Unable to attach to the AFI BAR0 on slot id %d", slot_id); + fail_on(rc, out, "ERROR: Unable to attach to the AFI BAR0 on slot id %d", slot_id); rc = fpga_pci_attach(slot_id, FPGA_APP_PF, APP_PF_BAR4, BURST_CAPABLE, &pci_bar_handle_bar4); - fail_on(rc, out, "Unable to attach to the AFI BAR4 on slot id %d", slot_id); + fail_on(rc, out, "ERROR: Unable to attach to the AFI BAR4 on slot id %d", slot_id); // Now setup the streaming interface rc = fpga_pci_peek(pci_bar_handle_bar0, AXI_FIFO_OFFSET, &rdata); //ISR - fail_on(rc, out, "Unable to read from FPGA!"); + fail_on(rc, out, "ERROR: Unable to read from FPGA!"); printf("INFO: Read 0x%x from ISR register.\n", rdata); if (rdata != 0x01D00000) { printf("WARNING: Expected 0x01D00000.\n"); @@ -55,37 +72,72 @@ int zcash_fpga::init_fpga(int slot_id) { } rc = fpga_pci_peek(pci_bar_handle_bar0, AXI_FIFO_OFFSET+0x1CULL, &rdata); //RDFO - fail_on(rc, out, "Unable to read from FPGA!"); + fail_on(rc, out, "ERROR: Unable to read from FPGA!"); printf("INFO: Read 0x%x from RDFO register.\n", rdata); if (rdata != 0x00000000) { printf("WARNING: Expected 0x00000000.\n"); } rc = fpga_pci_poke(pci_bar_handle_bar0, AXI_FIFO_OFFSET+0x4ULL, 0x0C000000); // Clear IER - fail_on(rc, out, "Unable to write to FPGA!"); + fail_on(rc, out, "ERROR: Unable to write to FPGA!"); // Check if we have AXI4 mode enabled or not rc = fpga_pci_peek(pci_bar_handle_bar0, AXI_FIFO_OFFSET+0x44ULL, &rdata); //RDFO - fail_on(rc, out, "Unable to write to FPGA!"); + fail_on(rc, out, "ERROR: Unable to write to FPGA!"); AXI4_enabled = (1 << 31) & rdata; if (AXI4_enabled) printf("INFO: AXI4 mode is set ENABLED\n"); else printf("INFO: AXI4 mode is set DISABLED\n"); - printf("INFO: Finished initializing FPGA.\n"); initialized = true; + // Send a Status message to FPGA to get configuration info + fpga_status_rpl_t fpga_status_rpl; + rc = get_status(fpga_status_rpl_t status_rpl); + fail_on(rc, out, "ERROR: Unable to get FPGA status!"); + + + printf("INFO: FPGA version: 0x%x, built on 0x%xxl\n", status_rpl.version, status_rpl.build_date); + printf("INFO: FPGA capability register: 0x%lx [ENB_VERIFY_EQUIHASH_200_9: %d, ENB_VERIFY_EQUIHASH_144_5 %d, ENB_VERIFY_SECP256K1_SIG %d, ENB_BLS12_381 %d]\n", + status_rpl.cmd_cap, + status_rpl.cmd_cap & (1 << ENB_VERIFY_EQUIHASH_200_9), + status_rpl.cmd_cap & (1 << ENB_VERIFY_EQUIHASH_144_5), + status_rpl.cmd_cap & (1 << ENB_VERIFY_SECP256K1_SIG), + status_rpl.cmd_cap & (1 << ENB_BLS12_381)); + + if (status_rpl.cmd_cap & (1 << ENB_BLS12_381)) { + rc = fpga_pci_peek(pci_bar_handle_bar0, BLS12_381_OFFSET + 0, &rdata); + fail_on(rc, out, "ERROR: Unable to read from FPGA!\n"); + m_bls12_381_inst_axil_offset = rdata; + + rc = fpga_pci_peek(pci_bar_handle_bar0, BLS12_381_OFFSET + 1*4, &rdata); + fail_on(rc, out, "ERROR: Unable to read from FPGA!\n"); + m_bls12_381_data_axil_offset = rdata; + + rc = fpga_pci_peek(pci_bar_handle_bar0, BLS12_381_OFFSET + 2*4, &rdata); + fail_on(rc, out, "ERROR: Unable to read from FPGA!\n"); + m_bls12_381_data_size = 1 << rdata; + + rc = fpga_pci_peek(pci_bar_handle_bar0, BLS12_381_OFFSET + 3*4, &rdata); + fail_on(rc, out, "ERROR: Unable to read from FPGA!\n"); + m_bls12_381_inst_size = 1 << rdata; + } + + printf("INFO: Finished initializing FPGA.\n"); + + return rc; out: + initialized = false; /* clean up */ if (pci_bar_handle_bar0 >= 0) { rc = fpga_pci_detach(pci_bar_handle_bar0); - if (rc) printf("Failure while detaching bar0 from the fpga.\n"); + if (rc) printf("ERROR: Failure while detaching bar0 from the fpga.\n"); } if (pci_bar_handle_bar4 >= 0) { rc = fpga_pci_detach(pci_bar_handle_bar4); - if (rc) printf("Failure while detaching bar4 from the fpga.\n"); + if (rc) printf("ERROR: Failure while detaching bar4 from the fpga.\n"); } return 1; } @@ -96,31 +148,31 @@ int zcash_fpga::check_afi_ready(int slot_id) { /* get local image description, contains status, vendor id, and device id. */ rc = fpga_mgmt_describe_local_image(slot_id, &info,0); - fail_on(rc, out, "Unable to get AFI information from slot %d. Are you running as root?",slot_id); + fail_on(rc, out, "ERROR: Unable to get AFI information from slot %d. Are you running as root?",slot_id); /* check to see if the slot is ready */ if (info.status != FPGA_STATUS_LOADED) { rc = 1; - fail_on(rc, out, "AFI in Slot %d is not in READY state !", slot_id); + fail_on(rc, out, "ERROR: AFI in Slot %d is not in READY state !", slot_id); } - printf("AFI PCI Vendor ID: 0x%x, Device ID 0x%x\n", + printf("INFO: AFI PCI Vendor ID: 0x%x, Device ID 0x%x\n", info.spec.map[FPGA_APP_PF].vendor_id, info.spec.map[FPGA_APP_PF].device_id); /* confirm that the AFI that we expect is in fact loaded */ if (info.spec.map[FPGA_APP_PF].vendor_id != pci_vendor_id || info.spec.map[FPGA_APP_PF].device_id != pci_device_id) { - printf("AFI does not show expected PCI vendor id and device ID. If the AFI " + printf("INFO: AFI does not show expected PCI vendor id and device ID. If the AFI " "was just loaded, it might need a rescan. Rescanning now.\n"); rc = fpga_pci_rescan_slot_app_pfs(slot_id); - fail_on(rc, out, "Unable to update PF for slot %d",slot_id); + fail_on(rc, out, "ERROR: Unable to update PF for slot %d",slot_id); /* get local image description, contains status, vendor id, and device id. */ rc = fpga_mgmt_describe_local_image(slot_id, &info,0); - fail_on(rc, out, "Unable to get AFI information from slot %d",slot_id); + fail_on(rc, out, "ERROR: Unable to get AFI information from slot %d",slot_id); - printf("AFI PCI Vendor ID: 0x%x, Device ID 0x%x\n", + printf("INFO: AFI PCI Vendor ID: 0x%x, Device ID 0x%x\n", info.spec.map[FPGA_APP_PF].vendor_id, info.spec.map[FPGA_APP_PF].device_id); @@ -128,7 +180,7 @@ int zcash_fpga::check_afi_ready(int slot_id) { if (info.spec.map[FPGA_APP_PF].vendor_id != pci_vendor_id || info.spec.map[FPGA_APP_PF].device_id != pci_device_id) { rc = 1; - fail_on(rc, out, "The PCI vendor id and device of the loaded AFI are not " + fail_on(rc, out, "ERROR: The PCI vendor id and device of the loaded AFI are not " "the expected values."); } } @@ -144,11 +196,16 @@ int zcash_fpga::get_status(fpga_status_rpl_t& status_rpl) { unsigned int timeout = 0; unsigned int read_len = 0; + if (!initialized) { + printf("ERROR: FPGA not initialized!\n"); + goto out; + } + header_t hdr; hdr.cmd = FPGA_STATUS; hdr.len = 8; rc = write_stream((char*)&hdr, sizeof(hdr)); - fail_on(rc, out, "Unable to read from FPGA!"); + fail_on(rc, out, "ERROR: Unable to read from FPGA!"); // Try read reply char reply[256]; @@ -163,8 +220,6 @@ int zcash_fpga::get_status(fpga_status_rpl_t& status_rpl) { } status_rpl = *(fpga_status_rpl_t*)reply; - printf("INFO: Received FPGA reply, FPGA version: 0x%x\n", status_rpl.version); // TODO print more - return rc; out: @@ -177,13 +232,13 @@ int zcash_fpga::write_stream(char* data, unsigned int len) { unsigned int len_send = 0; if (!initialized) { - printf("INFO: FPGA not initialized!\n"); + printf("ERROR: FPGA not initialized!\n"); goto out; } rc = fpga_pci_peek(pci_bar_handle_bar0, AXI_FIFO_OFFSET + 0xCULL, &rdata); - fail_on(rc, out, "Unable to read from FPGA!"); + fail_on(rc, out, "ERROR: Unable to read from FPGA!"); if (len > rdata) { printf("ERROR: write_stream does not have enough space to write %d bytes! (%d free)\n", len, rdata); goto out; @@ -196,20 +251,20 @@ int zcash_fpga::write_stream(char* data, unsigned int len) { len_send += 8; } else { rc = fpga_pci_poke(pci_bar_handle_bar0, AXI_FIFO_OFFSET+0x10ULL, *(uint32_t*)(&data[len_send])); // Reset ISR - fail_on(rc, out, "Unable to write to FPGA!"); + fail_on(rc, out, "ERROR: Unable to write to FPGA!"); len_send += 4; } } rc = fpga_pci_poke(pci_bar_handle_bar0, AXI_FIFO_OFFSET+0x14ULL, len); // Reset ISR - fail_on(rc, out, "Unable to write to FPGA!"); + fail_on(rc, out, "ERROR: Unable to write to FPGA!"); printf("INFO: write_stream::Wrote %d bytes of data\n", len); // Check transmit complete bit and reset it rc = fpga_pci_peek(pci_bar_handle_bar0, AXI_FIFO_OFFSET, &rdata); - fail_on(rc, out, "Unable to read from FPGA!"); + fail_on(rc, out, "ERROR: Unable to read from FPGA!"); if ((rdata & (1 << 27)) == 0) { printf("WARNING: write_stream transmit bit not set, register returned 0x%x\n", rdata); } @@ -229,20 +284,20 @@ int zcash_fpga::read_stream(char* data, unsigned int size) { int rc; if (!initialized) { - printf("INFO: FPGA not initialized!\n"); + printf("ERROR: FPGA not initialized!\n"); goto out; } rc = fpga_pci_peek(pci_bar_handle_bar0, AXI_FIFO_OFFSET, &rdata); - fail_on(rc, out, "Unable to read from FPGA!"); + fail_on(rc, out, "ERROR: Unable to read from FPGA!"); if ((rdata & (1 << 26)) == 0) return 0; // Nothing to read rc = fpga_pci_poke(pci_bar_handle_bar0, AXI_FIFO_OFFSET, 0x04000000); // clear ISR - fail_on(rc, out, "Unable to write to FPGA!"); + fail_on(rc, out, "ERROR: Unable to write to FPGA!"); rc = fpga_pci_peek(pci_bar_handle_bar0, AXI_FIFO_OFFSET + 0x1CULL, &rdata); //RDFO should be non-zero (slots used in FIFO) - fail_on(rc, out, "Unable to read from FPGA!"); + fail_on(rc, out, "ERROR: Unable to read from FPGA!"); if (rdata == 0) { printf("WARNING: Read FIFO shows data but length was 0!\n"); return 0; @@ -260,11 +315,11 @@ int zcash_fpga::read_stream(char* data, unsigned int size) { while(read_len < rdata) { if (AXI4_enabled) { rc = fpga_pci_peek(pci_bar_handle_bar4, 0x1000, (uint32_t*)(&data[read_len])); - fail_on(rc, out, "Unable to read from FPGA PCIS!"); + fail_on(rc, out, "ERROR: Unable to read from FPGA PCIS!"); read_len += 8; } else { rc = fpga_pci_peek(pci_bar_handle_bar0, AXI_FIFO_OFFSET + 0x20ULL, (uint32_t*)(&data[read_len])); - fail_on(rc, out, "Unable to read from FPGA!"); + fail_on(rc, out, "ERROR: Unable to read from FPGA!"); read_len += 4; } } @@ -280,7 +335,11 @@ int zcash_fpga::bls12_381_write_data_slot(unsigned int id, bls12_381_slot_t slot char data[48]; int rc = 0; if (!initialized) { - printf("INFO: FPGA not initialized!\n"); + printf("ERROR: FPGA not initialized!\n"); + goto out; + } + if (id >= m_bls12_381_data_size) { + printf("ERROR: Data slot id (%d) is greater than number of slots on FPGA (%d)!\n", id, m_bls12_381_data_size); goto out; } @@ -290,8 +349,8 @@ int zcash_fpga::bls12_381_write_data_slot(unsigned int id, bls12_381_slot_t slot data[47] |= (slot_data.point_type << 5); for(int i = 0; i < 48/4; i=i+4) { - rc = fpga_pci_poke(pci_bar_handle_bar0, BLS12_381_OFFSET + BLS12_381_DATA_OFFSET + id*64 + i, *((uint32_t*)&data[i])); - fail_on(rc, out, "Unable to write to FPGA!\n"); + rc = fpga_pci_poke(pci_bar_handle_bar0, BLS12_381_OFFSET + m_bls12_381_data_axil_offset + id*64 + i, *((uint32_t*)&data[i])); + fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); } return 0; out: @@ -301,13 +360,17 @@ int zcash_fpga::bls12_381_write_data_slot(unsigned int id, bls12_381_slot_t slot int zcash_fpga::bls12_381_read_data_slot(unsigned int id, bls12_381_slot_t& slot_data) { int rc = 0; if (!initialized) { - printf("INFO: FPGA not initialized!\n"); + printf("ERROR: FPGA not initialized!\n"); + goto out; + } + if (id >= m_bls12_381_data_size) { + printf("ERROR: Data slot id (%d) is greater than number of slots on FPGA (%d)!\n", id, m_bls12_381_data_size); goto out; } for(int i = 0; i < 48/4; i=i+4) { - rc = fpga_pci_peek(pci_bar_handle_bar0, BLS12_381_OFFSET + BLS12_381_DATA_OFFSET + id*64 + i, (uint32_t*)(&slot_data)); - fail_on(rc, out, "Unable to read from FPGA!\n"); + rc = fpga_pci_peek(pci_bar_handle_bar0, BLS12_381_OFFSET + m_bls12_381_data_axil_offset + id*64 + i, (uint32_t*)(&slot_data)); + fail_on(rc, out, "ERROR: Unable to read from FPGA!\n"); } slot_data.point_type = (point_type_t)(*((char*)&slot_data + 47) >> 5); @@ -318,3 +381,129 @@ int zcash_fpga::bls12_381_read_data_slot(unsigned int id, bls12_381_slot_t& slot out: return rc; } + +int zcash_fpga::bls12_381_write_inst_slot(unsigned int id, bls12_381_inst_t inst_data) { + int rc = 0; + if (!initialized) { + printf("ERROR: FPGA not initialized!\n"); + goto out; + } + if (id >= m_bls12_381_inst_size) { + printf("ERROR: Instance slot id (%d) is greater than number of slots on FPGA (%d)!\n", id, m_bls12_381_inst_size); + goto out; + } + + for(int i = 0; i < 2; i=i+1) { + rc = fpga_pci_poke(pci_bar_handle_bar0, BLS12_381_OFFSET + m_bls12_381_inst_axil_offset + id*8 + i*4, *((uint32_t*)&inst_data) + i); + fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); + } + return 0; + out: + return rc; +} + +int zcash_fpga::bls12_381_read_inst_slot(unsigned int id, bls12_381_inst_t& inst_data) { + int rc = 0; + if (!initialized) { + printf("ERROR: FPGA not initialized!\n"); + goto out; + } + if (id >= m_bls12_381_inst_size) { + printf("ERROR: Instance slot id (%d) is greater than number of slots on FPGA (%d)!\n", id, m_bls12_381_inst_size); + goto out; + } + + for(int i = 0; i < 2; i=i+1) { + rc = fpga_pci_peek(pci_bar_handle_bar0, BLS12_381_OFFSET + m_bls12_381_inst_axil_offset + id*8 + i*4, ((uint32_t*)(&inst_data) + i)); + fail_on(rc, out, "ERROR: Unable to read from FPGA!\n"); + } + + return 0; + out: + return rc; +} + +int zcash_fpga::bls12_381_set_curr_inst_slot(unsigned int id) { + int rc = 0; + unsigned int prev_id; + uint32_t rdata; + if (!initialized) { + printf("ERROR: FPGA not initialized!\n"); + goto out; + } + if (id >= m_bls12_381_inst_size) { + printf("ERROR: Instance slot id (%d) is greater than number of slots on FPGA (%d)!\n", id, m_bls12_381_inst_size); + goto out; + } + + rc = fpga_pci_peek(pci_bar_handle_bar0, BLS12_381_OFFSET + 0x10, rdata); + fail_on(rc, out, "ERROR: Unable to read from FPGA!\n"); + prev_id = rdata; + + rc = fpga_pci_poke(pci_bar_handle_bar0, BLS12_381_OFFSET + 0x10, id); + fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); + + rc = fpga_pci_peek(pci_bar_handle_bar0, BLS12_381_OFFSET + 0x10, rdata); + fail_on(rc, out, "ERROR: Unable to read from FPGA!\n"); + + if (rdata != id) { + printf("ERROR: Unable to set BLS12_381 current instruction slot!\n"); + goto out; + } + + printf("INFO: Set BLS12_381 current instruction slot to %d (was %d)\n", id, prev_id); + + return 0; + out: + return rc; +} + +int zcash_fpga::bls12_381_get_curr_inst_slot(unsigned int& id) { + int rc = 0; + + if (!initialized) { + printf("ERROR: FPGA not initialized!\n"); + goto out; + } + if (id >= m_bls12_381_inst_size) { + printf("ERROR: Instance slot id (%d) is greater than number of slots on FPGA (%d)!\n", id, m_bls12_381_inst_size); + goto out; + } + + rc = fpga_pci_peek(pci_bar_handle_bar0, BLS12_381_OFFSET + 0x10, id); + fail_on(rc, out, "ERROR: Unable to read from FPGA!\n"); + + printf("INFO: BLS12_381 current instruction slot is %d\n", id); + + return 0; + out: + return rc; +} + +int zcash_fpga::bls12_381_reset_memory(bool inst_memory, bool data_memory) { + int rc = 0; + uint32_t data = 0; + if (!initialized) { + printf("ERROR: FPGA not initialized!\n"); + goto out; + } + + if (inst_memory) { + data |= 1; + printf("INFO: Resetting instruction memory\n"); + } + + if (data_memory) { + data |= 1 << 1; + printf("INFO: Resetting data memory reset\n"); + } + + rc = fpga_pci_poke(pci_bar_handle_bar0, BLS12_381_OFFSET, ; + fail_on(rc, out, "ERROR: Unable to write to FPGA!\n"); + + return 0; + out: + return rc; +} + + diff --git a/aws/cl_zcash/software/runtime/zcash_fpga.hpp b/aws/cl_zcash/software/runtime/zcash_fpga.hpp index 0aec6c0..8683ec0 100644 --- a/aws/cl_zcash/software/runtime/zcash_fpga.hpp +++ b/aws/cl_zcash/software/runtime/zcash_fpga.hpp @@ -29,9 +29,6 @@ #define AXI_FIFO_OFFSET UINT64_C(0x0) #define BLS12_381_OFFSET UINT64_C(0x1000) -#define BLS12_381_INST_OFFSET UINT64_C(0x1000) -#define BLS12_381_DATA_OFFSET UINT64_C(0x2000) - // These match the structs and commands defined in zcash_fpga_pkg.sv class zcash_fpga { @@ -77,6 +74,29 @@ class zcash_fpga { point_type_t point_type; } bls12_381_slot_t; + typedef enum uint8_t { + NOOP_WAIT = 0x0, + COPY_REG = 0x1, + SEND_INTERRUPT = 0x6, + + SUB_ELEMENT = 0x10, + ADD_ELEMENT = 0x11, + MUL_ELEMENT = 0x12, + INV_ELEMENT = 0x13, + + POINT_MULT = 0x24, + FP_FPOINT_MULT = 0x25, + FP2_FPOINT_MULT = 0x26 + } code_t; + + // Instruction format + typedef struct __attribute__((__packed__)) { + code_t code; + uint16_t a; + uint16_t b; + uint16_t c; + } inst_t; + typedef struct __attribute__((__packed__)) { uint32_t len; command_t cmd; @@ -110,14 +130,19 @@ class zcash_fpga { } fpga_status_rpl_t; private: - static const uint16_t pci_vendor_id = 0x1D0F; /* Amazon PCI Vendor ID */ - static const uint16_t pci_device_id = 0xF000; /* PCI Device ID preassigned by Amazon for F1 applications */ + static const uint16_t s_pci_vendor_id = 0x1D0F; /* Amazon PCI Vendor ID */ + static const uint16_t s_pci_device_id = 0xF000; /* PCI Device ID preassigned by Amazon for F1 applications */ - pci_bar_handle_t pci_bar_handle_bar0 = PCI_BAR_HANDLE_INIT; - pci_bar_handle_t pci_bar_handle_bar4 = PCI_BAR_HANDLE_INIT; + pci_bar_handle_t m_pci_bar_handle_bar0 = PCI_BAR_HANDLE_INIT; + pci_bar_handle_t m_pci_bar_handle_bar4 = PCI_BAR_HANDLE_INIT; - bool AXI4_enabled = false; - bool initialized = false; + unsigned int m_bls12_381_inst_axil_offset; + unsigned int m_bls12_381_data_axil_offset; + unsigned int m_bls12_381_inst_size; + unsigned int m_bls12_381_data_size; + + bool m_AXI4_enabled = false; + bool m_initialized = false; public: static zcash_fpga& get_instance(); @@ -128,6 +153,7 @@ class zcash_fpga { * This connects to the FPGA and must be called at least once */ int init_fpga(int slot_id = 0); + /* * This sends a status request to the FPGA and waits for the reply, * checking for any errors. @@ -135,14 +161,25 @@ class zcash_fpga { int get_status(fpga_status_rpl_t& status_rpl); /* - * Functions for writing and reading data slots in the BLS12_381 coprocessor + * Functions for writing and reading data/instruction slots in the BLS12_381 coprocessor */ int bls12_381_write_data_slot(unsigned int id, bls12_381_slot_t slot_data); int bls12_381_read_data_slot(unsigned int id, bls12_381_slot_t& slot_data); + int bls12_381_write_inst_slot(unsigned int id, bls12_381_inst_t inst_data); + int bls12_381_read_inst_slot(unsigned int id, bls12_381_inst_t inst_data); + + int bls12_381_set_curr_inst_slot(unsigned int id); + int bls12_381_get_curr_inst_slot(unsigned int& id); + + /* + * This will clear the entire memory back to the initial state (will not change instruction pointer) + */ + int bls12_381_reset_memory(bool inst_memory, bool data_memory); + private: - zcash_fpga(){}; - ~zcash_fpga(){}; + zcash_fpga(); + ~zcash_fpga(); int check_afi_ready(int slot_id); int read_stream(char* data, unsigned int size); diff --git a/aws/cl_zcash/verif/tests/test_zcash.sv b/aws/cl_zcash/verif/tests/test_zcash.sv index 0687c3a..ed16715 100644 --- a/aws/cl_zcash/verif/tests/test_zcash.sv +++ b/aws/cl_zcash/verif/tests/test_zcash.sv @@ -61,8 +61,8 @@ initial begin // Run our test cases - // test_status_message(); - // test_block_secp256k1(); + test_status_message(); + test_block_secp256k1(); test_bls12_381(); $display("INFO: All tests passed"); @@ -270,13 +270,13 @@ task test_bls12_381(); // Check we can read it back dat = 0; - for(int i = 0; i < 2; i = i + 4) begin + for(int i = 0; i < 8; i = i + 4) begin read_ocl_reg(.addr(`ZCASH_OFFSET + bls12_381_pkg::INST_AXIL_START + 3*8 + i), .rdata(rdata)); dat[i*8 +: 32] = rdata; end - $display("INFO: Read: 0x%x", dat[48*8-1:0]); + $display("INFO: Read: 0x%x", dat[8*8-1:0]); $display("INFO: Wrote: 0x%x", inst); - assert(dat[2*8-1:0] == inst) else $fatal(1, "ERROR: Writing to slot and reading gave wrong results!"); + assert(dat[8*8-1:0] == inst) else $fatal(1, "ERROR: Writing to slot and reading gave wrong results!"); slot_data = '{dat:in_k, pt:SCALAR}; for(int i = 0; i < 48; i = i + 4) @@ -295,6 +295,7 @@ task test_bls12_381(); fork begin + stream_len = 0; while(stream_len == 0) read_stream(.data(stream_data), .len(stream_len)); interrupt_rpl = stream_data; @@ -319,7 +320,7 @@ task test_bls12_381(); end end begin - repeat(10000) @(posedge tb.card.fpga.clk_main_a0); + repeat(100000) @(posedge tb.card.fpga.clk_main_a0); $fatal(1, "ERROR: No reply received from test_bls12_381"); end join_any diff --git a/zcash_fpga/src/rtl/bls12_381/bls12_381_axi_bridge.sv b/zcash_fpga/src/rtl/bls12_381/bls12_381_axi_bridge.sv index 2dd7cb5..7470d0f 100644 --- a/zcash_fpga/src/rtl/bls12_381/bls12_381_axi_bridge.sv +++ b/zcash_fpga/src/rtl/bls12_381/bls12_381_axi_bridge.sv @@ -110,8 +110,8 @@ always_ff @ (posedge i_clk) begin case(axi_lite_if.araddr) 32'h0: axi_lite_if.rdata <= INST_AXIL_START; 32'h4: axi_lite_if.rdata <= DATA_AXIL_START; - 32'h8: axi_lite_if.rdata <= DATA_RAM_DEPTH*DATA_RAM_ALIGN_BYTE; - 32'hc: axi_lite_if.rdata <= INST_RAM_DEPTH*INST_RAM_ALIGN_BYTE; + 32'h8: axi_lite_if.rdata <= DATA_RAM_DEPTH; + 32'hc: axi_lite_if.rdata <= INST_RAM_DEPTH; 32'h10: axi_lite_if.rdata <= curr_inst_pt; 32'h14: axi_lite_if.rdata <= last_inst_cnt; default: axi_lite_if.rdata <= 32'hbeef;