diff --git a/common/Definitions.h b/common/Definitions.h index f56b02b9..dc0588c6 100644 --- a/common/Definitions.h +++ b/common/Definitions.h @@ -49,7 +49,7 @@ // For FPGA #define ACTION_TYPE 0x52324158 -#define RELEASE_LEVEL 0x003E +#define RELEASE_LEVEL 0x003F #define MODE_CONV 0x0001L @@ -62,7 +62,8 @@ #define PIXEL_OUT_GAINBIT_2 (INT16_MIN) #define LOAD_CALIBRATION_BRAM_SIZE 1024 - +#define LOAD_CALIBRATION_DEST_CALIB 0 +#define LOAD_CALIBRATION_DEST_INTEGRATION 1 // FPGA register map #define ADDR_CTRL_REGISTER 0x0000 diff --git a/fpga/hls/hls_jfjoch.h b/fpga/hls/hls_jfjoch.h index f1e10921..122d7d99 100644 --- a/fpga/hls/hls_jfjoch.h +++ b/fpga/hls/hls_jfjoch.h @@ -104,9 +104,10 @@ void load_calibration(ap_uint<256> *d_hbm_p0, ap_uint<8> modules, ap_uint<5> storage_cells, ap_uint<32> hbm_size_bytes, + ap_uint<8> destination, hls::stream &datamover_in_cmd, hls::stream > &host_memory_in, - uint64_t in_mem_location[LOAD_CALIBRATION_BRAM_SIZE]); + uint64_t in_mem_location[(3 * 16 + 3) * MAX_MODULES_FPGA]) ; void frame_generator(STREAM_512 &data_out, ap_uint<512> *uram, diff --git a/fpga/hls/load_calibration.cpp b/fpga/hls/load_calibration.cpp index 5b7dbb13..bc0a49f5 100644 --- a/fpga/hls/load_calibration.cpp +++ b/fpga/hls/load_calibration.cpp @@ -26,13 +26,14 @@ void read_module(ap_uint<256> *d_hbm_p0, } void load_calibration(ap_uint<256> *d_hbm_p0, - ap_uint<256> *d_hbm_p1, - ap_uint<8> modules, - ap_uint<5> storage_cells, - ap_uint<32> hbm_size_bytes, - hls::stream &datamover_in_cmd, - hls::stream > &host_memory_in, - uint64_t in_mem_location[(3 * 16 + 3) * MAX_MODULES_FPGA]) { + ap_uint<256> *d_hbm_p1, + ap_uint<8> modules, + ap_uint<5> storage_cells, + ap_uint<32> hbm_size_bytes, + ap_uint<8> destination, + hls::stream &datamover_in_cmd, + hls::stream > &host_memory_in, + uint64_t in_mem_location[(3 * 16 + 3) * MAX_MODULES_FPGA]) { #pragma HLS INTERFACE mode=s_axilite port=return #pragma HLS INTERFACE mode=s_axilite port=in_mem_location #pragma HLS INTERFACE register both axis port=datamover_in_cmd @@ -40,6 +41,7 @@ void load_calibration(ap_uint<256> *d_hbm_p0, #pragma HLS INTERFACE mode=s_axilite port=modules #pragma HLS INTERFACE mode=s_axilite port=storage_cells +#pragma HLS INTERFACE mode=s_axilite port=destination #pragma HLS INTERFACE mode=ap_none port=hbm_size_bytes #pragma HLS INTERFACE mode=m_axi port=d_hbm_p0 bundle=d_hbm_p0 depth=512 offset=off \ @@ -47,28 +49,41 @@ void load_calibration(ap_uint<256> *d_hbm_p0, #pragma HLS INTERFACE mode=m_axi port=d_hbm_p1 bundle=d_hbm_p1 depth=512 offset=off \ max_read_burst_length=2 max_write_burst_length=16 latency=120 num_write_outstanding=8 num_read_outstanding=2 - if (storage_cells > 16) - return; if (modules > MAX_MODULES_FPGA) return; - for (int c = 0; c < 3; c++) { - for (int m = 0; m < modules; m++) { -#pragma HLS PIPELINE OFF - setup_datamover(datamover_in_cmd, in_mem_location[c * modules + m], RAW_MODULE_SIZE * sizeof(int16_t)); - size_t offset_hbm_0 = (2 * c) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; - size_t offset_hbm_1 = (2 * c + 1) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; - read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1); - } - } + if (destination == LOAD_CALIBRATION_DEST_CALIB) { + if (storage_cells > 16) + return; - for (int c = 0; c < 3; c++) { - for (int m = 0; m < modules * storage_cells; m++) { + for (int c = 0; c < 3; c++) { + for (int m = 0; m < modules; m++) { #pragma HLS PIPELINE OFF - setup_datamover(datamover_in_cmd, in_mem_location[3 * modules + c * modules * storage_cells + m], RAW_MODULE_SIZE * sizeof(int16_t)); - size_t offset_hbm_0 = (6 + 2 * c) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; - size_t offset_hbm_1 = (6 + 2 * c + 1) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; - read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1); - } - } + setup_datamover(datamover_in_cmd, in_mem_location[c * modules + m], RAW_MODULE_SIZE * sizeof(int16_t)); + size_t offset_hbm_0 = (2 * c) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; + size_t offset_hbm_1 = (2 * c + 1) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; + read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1); + } + } + + for (int c = 0; c < 3; c++) { + for (int m = 0; m < modules * storage_cells; m++) { +#pragma HLS PIPELINE OFF + setup_datamover(datamover_in_cmd, in_mem_location[3 * modules + c * modules * storage_cells + m], + RAW_MODULE_SIZE * sizeof(int16_t)); + size_t offset_hbm_0 = (6 + 2 * c) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; + size_t offset_hbm_1 = + (6 + 2 * c + 1) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; + read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1); + } + } + } else if (destination == LOAD_CALIBRATION_DEST_INTEGRATION) { + for (int m = 0; m < modules; m++) { +#pragma HLS PIPELINE OFF + setup_datamover(datamover_in_cmd, in_mem_location[m], RAW_MODULE_SIZE * sizeof(int16_t)); + size_t offset_hbm_0 = 16 * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; + size_t offset_hbm_1 = 17 * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64; + read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1); + } + } } diff --git a/fpga/pcie_driver/jfjoch_drv.h b/fpga/pcie_driver/jfjoch_drv.h index 12d30bb3..78852b6a 100644 --- a/fpga/pcie_driver/jfjoch_drv.h +++ b/fpga/pcie_driver/jfjoch_drv.h @@ -46,6 +46,7 @@ #define ADDR_LOAD_CALIBRATION_CTRL (LOAD_CALIBRATION_OFFSET | 0x000000) #define ADDR_LOAD_CALIBRATION_MOD (LOAD_CALIBRATION_OFFSET | 0x000010) #define ADDR_LOAD_CALIBRATION_SC (LOAD_CALIBRATION_OFFSET | 0x000018) +#define ADDR_LOAD_CALIBRATION_DEST (LOAD_CALIBRATION_OFFSET | 0x000020) #define ADDR_LOAD_CALIBRATION_MEM (LOAD_CALIBRATION_OFFSET | 0x002000) #define ADDR_FRAME_GEN_CTRL (FRAME_GEN_OFFSET | 0x000000) @@ -124,6 +125,7 @@ void jfjoch_get_ipv4_addr(struct jfjoch_drvdata *drvdata, u32 *addr); void jfjoch_load_int_pkt_gen(struct jfjoch_drvdata *drvdata, char* output); void jfjoch_save_int_pkt_gen(struct jfjoch_drvdata *drvdata, const char* input); int jfjoch_load_calibration(struct jfjoch_drvdata *drvdata, struct ActionConfig *config); +int jfjoch_load_integration_map(struct jfjoch_drvdata *drvdata, struct ActionConfig *config); int jfjoch_run_frame_gen(struct jfjoch_drvdata *drvdata, struct FrameGeneratorConfig *config); u32 jfjoch_get_c2h_descriptors(struct jfjoch_drvdata *drvdata); diff --git a/fpga/pcie_driver/jfjoch_function.c b/fpga/pcie_driver/jfjoch_function.c index 8ae3464a..ff5b3692 100644 --- a/fpga/pcie_driver/jfjoch_function.c +++ b/fpga/pcie_driver/jfjoch_function.c @@ -310,6 +310,7 @@ int jfjoch_load_calibration(struct jfjoch_drvdata *drvdata, struct ActionConfig iowrite32(config->nmodules, drvdata->bar0 + ADDR_LOAD_CALIBRATION_MOD); iowrite32(config->nstorage_cells, drvdata->bar0 + ADDR_LOAD_CALIBRATION_SC); + iowrite32(LOAD_CALIBRATION_DEST_CALIB, drvdata->bar0 + ADDR_LOAD_CALIBRATION_DEST); iowrite32(0x1, drvdata->bar0 + ADDR_LOAD_CALIBRATION_CTRL); i = 0; @@ -331,6 +332,52 @@ int jfjoch_load_calibration(struct jfjoch_drvdata *drvdata, struct ActionConfig return 0; } +int jfjoch_load_integration_map(struct jfjoch_drvdata *drvdata, struct ActionConfig *config) { + struct device *const dev = &drvdata->pdev->dev; + u32 i; + u32 cell_count = config->nmodules; + + if (cell_count > drvdata->nbuf) { + dev_err(dev, "Not enough buffers to support this card\n"); + return -EINVAL; + } + + for (i = 0; i < cell_count; i++) { + u64 addr = drvdata->bufs[i].dma_address; + iowrite32(PCI_DMA_L(addr), drvdata->bar0 + ADDR_LOAD_CALIBRATION_MEM + i * 2 * 4); + iowrite32(PCI_DMA_H(addr), drvdata->bar0 + ADDR_LOAD_CALIBRATION_MEM + (i * 2 + 1) * 4); + } + + // Start DMA + // Clear counters and RUN H2C + iowrite32((1 << 1), drvdata->bar0 + PCIE_OFFSET + (0<<12) + 0xC0); + iowrite32((1 << 2), drvdata->bar0 + PCIE_OFFSET + (0<<12) + 0xC0); + iowrite32(JFJOCH_DMA_SETTINGS, drvdata->bar0 + PCIE_OFFSET + (0<<12) + 0x04); + + iowrite32(config->nmodules, drvdata->bar0 + ADDR_LOAD_CALIBRATION_MOD); + iowrite32(LOAD_CALIBRATION_DEST_INTEGRATION, drvdata->bar0 + ADDR_LOAD_CALIBRATION_DEST); + iowrite32(0x1, drvdata->bar0 + ADDR_LOAD_CALIBRATION_CTRL); + + i = 0; + while (i < 1000) { + if (ioread32(drvdata->bar0 + ADDR_LOAD_CALIBRATION_CTRL) & (1 << 1)) + break; + msleep(10); + i++; + } + + // STOP H2C channel + iowrite32(0, drvdata->bar0 + PCIE_OFFSET + (0<<12) + 0x04); + + if (i == 1000) { + dev_err(dev, "Load calibration didn't finish in 10 seconds\n"); + return -ETIMEDOUT; + } + + return 0; + +} + int jfjoch_run_frame_gen(struct jfjoch_drvdata *drvdata, struct FrameGeneratorConfig *config) { struct device *const dev = &drvdata->pdev->dev; diff --git a/fpga/pcie_driver/jfjoch_ioctl.c b/fpga/pcie_driver/jfjoch_ioctl.c index 64a24fc6..c998ba27 100644 --- a/fpga/pcie_driver/jfjoch_ioctl.c +++ b/fpga/pcie_driver/jfjoch_ioctl.c @@ -42,6 +42,10 @@ long jfjoch_cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { if (copy_from_user(&config, (char *) arg, sizeof(struct ActionConfig)) != 0) return -EFAULT; return jfjoch_load_calibration(drvdata, &config); + case IOCTL_JFJOCH_LOAD_INT_MAP: + if (copy_from_user(&config, (char *) arg, sizeof(struct ActionConfig)) != 0) + return -EFAULT; + return jfjoch_load_integration_map(drvdata, &config); case IOCTL_JFJOCH_GET_ENV_DATA: jfjoch_get_env_data(drvdata, &env_params); if (copy_to_user((char *) arg, &env_params, sizeof(struct ActionEnvParams)) != 0) diff --git a/fpga/pcie_driver/jfjoch_ioctl.h b/fpga/pcie_driver/jfjoch_ioctl.h index d30a0e2e..d8da320a 100644 --- a/fpga/pcie_driver/jfjoch_ioctl.h +++ b/fpga/pcie_driver/jfjoch_ioctl.h @@ -35,7 +35,8 @@ #define IOCTL_JFJOCH_SET_INT_PKT _IOW(IOCTL_JFJOCH_MAGIC, 19, char *) #define IOCTL_JFJOCH_GET_INT_PKT _IOR(IOCTL_JFJOCH_MAGIC, 20, char *) #define IOCTL_JFJOCH_LOAD_CALIB _IOW(IOCTL_JFJOCH_MAGIC, 21, struct ActionConfig) -#define IOCTL_JFJOCH_RUN_FRAME_GEN _IOW(IOCTL_JFJOCH_MAGIC, 22, struct FrameGeneratorConfig) -#define IOCTL_JFJOCH_C2H_DMA_DESC _IOR(IOCTL_JFJOCH_MAGIC, 23, uint32_t) +#define IOCTL_JFJOCH_LOAD_INT_MAP _IOW(IOCTL_JFJOCH_MAGIC, 22, struct ActionConfig) +#define IOCTL_JFJOCH_RUN_FRAME_GEN _IOW(IOCTL_JFJOCH_MAGIC, 23, struct FrameGeneratorConfig) +#define IOCTL_JFJOCH_C2H_DMA_DESC _IOR(IOCTL_JFJOCH_MAGIC, 24, uint32_t) #endif //JUNGFRAUJOCH_JFJOCH_IOCTL_H diff --git a/receiver/HLSSimulatedDevice.cpp b/receiver/HLSSimulatedDevice.cpp index 1ec228ab..0601d5a9 100644 --- a/receiver/HLSSimulatedDevice.cpp +++ b/receiver/HLSSimulatedDevice.cpp @@ -445,6 +445,7 @@ void HLSSimulatedDevice::HW_LoadCalibration(uint32_t modules, uint32_t storage_c modules, storage_cells, hbm_if_size, + LOAD_CALIBRATION_DEST_CALIB, datamover_in.GetCtrlStream(), datamover_in.GetDataStream(), calibration_addr_bram);