From 9e27d459599fec07633c44b413778e6b249dc2ef Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 5 Feb 2021 16:06:34 -0800 Subject: [PATCH] Add IPROG for ADM-PCIE-9V3 --- .../mqnic_tdma/ADM_PCIE_9V3/fpga_10g/boot.xdc | 4 + .../ADM_PCIE_9V3/fpga_10g/fpga/Makefile | 1 + .../ADM_PCIE_9V3/fpga_10g/rtl/fpga.v | 116 ++++++++++++++++++ .../ADM_PCIE_9V3/fpga_10g/rtl/fpga_core.v | 11 ++ 4 files changed, 132 insertions(+) create mode 100644 fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/boot.xdc diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/boot.xdc b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/boot.xdc new file mode 100644 index 000000000..5fb323e94 --- /dev/null +++ b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/boot.xdc @@ -0,0 +1,4 @@ +# Timing constraints for FPGA boot logic + +set_property ASYNC_REG TRUE [get_cells "fpga_boot_sync_reg_0_reg fpga_boot_sync_reg_1_reg"] +set_false_path -to [get_pins "fpga_boot_sync_reg_0_reg/D"] diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/fpga/Makefile b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/fpga/Makefile index c674833bb..4286525aa 100644 --- a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/fpga/Makefile +++ b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/fpga/Makefile @@ -73,6 +73,7 @@ SYN_FILES += lib/pcie/rtl/pulse_merge.v # XDC files XDC_FILES = fpga.xdc +XDC_FILES += boot.xdc XDC_FILES += lib/axis/syn/axis_async_fifo.tcl XDC_FILES += lib/axis/syn/sync_reset.tcl XDC_FILES += lib/eth/syn/ptp_clock_cdc.tcl diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v index 7ae7d92a7..b0edda14e 100644 --- a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v +++ b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v @@ -370,6 +370,121 @@ startupe3_inst ( .USRDONETS(1'b1) ); +// FPGA boot +wire fpga_boot; + +reg fpga_boot_sync_reg_0 = 1'b0; +reg fpga_boot_sync_reg_1 = 1'b0; +reg fpga_boot_sync_reg_2 = 1'b0; + +wire icap_avail; +reg [2:0] icap_state = 0; +reg icap_csib_reg = 1'b1; +reg icap_rdwrb_reg = 1'b0; +reg [31:0] icap_di_reg = 32'hffffffff; + +wire [31:0] icap_di_rev; + +assign icap_di_rev[ 7] = icap_di_reg[ 0]; +assign icap_di_rev[ 6] = icap_di_reg[ 1]; +assign icap_di_rev[ 5] = icap_di_reg[ 2]; +assign icap_di_rev[ 4] = icap_di_reg[ 3]; +assign icap_di_rev[ 3] = icap_di_reg[ 4]; +assign icap_di_rev[ 2] = icap_di_reg[ 5]; +assign icap_di_rev[ 1] = icap_di_reg[ 6]; +assign icap_di_rev[ 0] = icap_di_reg[ 7]; + +assign icap_di_rev[15] = icap_di_reg[ 8]; +assign icap_di_rev[14] = icap_di_reg[ 9]; +assign icap_di_rev[13] = icap_di_reg[10]; +assign icap_di_rev[12] = icap_di_reg[11]; +assign icap_di_rev[11] = icap_di_reg[12]; +assign icap_di_rev[10] = icap_di_reg[13]; +assign icap_di_rev[ 9] = icap_di_reg[14]; +assign icap_di_rev[ 8] = icap_di_reg[15]; + +assign icap_di_rev[23] = icap_di_reg[16]; +assign icap_di_rev[22] = icap_di_reg[17]; +assign icap_di_rev[21] = icap_di_reg[18]; +assign icap_di_rev[20] = icap_di_reg[19]; +assign icap_di_rev[19] = icap_di_reg[20]; +assign icap_di_rev[18] = icap_di_reg[21]; +assign icap_di_rev[17] = icap_di_reg[22]; +assign icap_di_rev[16] = icap_di_reg[23]; + +assign icap_di_rev[31] = icap_di_reg[24]; +assign icap_di_rev[30] = icap_di_reg[25]; +assign icap_di_rev[29] = icap_di_reg[26]; +assign icap_di_rev[28] = icap_di_reg[27]; +assign icap_di_rev[27] = icap_di_reg[28]; +assign icap_di_rev[26] = icap_di_reg[29]; +assign icap_di_rev[25] = icap_di_reg[30]; +assign icap_di_rev[24] = icap_di_reg[31]; + +always @(posedge clk_125mhz_int) begin + case (icap_state) + 0: begin + icap_state <= 0; + icap_csib_reg <= 1'b1; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'hffffffff; // dummy word + + if (fpga_boot_sync_reg_2 && icap_avail) begin + icap_state <= 1; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'hffffffff; // dummy word + end + end + 1: begin + icap_state <= 2; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'hAA995566; // sync word + end + 2: begin + icap_state <= 3; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h20000000; // type 1 noop + end + 3: begin + icap_state <= 4; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h30008001; // write 1 word to CMD + end + 4: begin + icap_state <= 5; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h0000000F; // IPROG + end + 5: begin + icap_state <= 0; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h20000000; // type 1 noop + end + endcase + + fpga_boot_sync_reg_0 <= fpga_boot; + fpga_boot_sync_reg_1 <= fpga_boot_sync_reg_0; + fpga_boot_sync_reg_2 <= fpga_boot_sync_reg_1; +end + +ICAPE3 +icape3_inst ( + .AVAIL(icap_avail), + .CLK(clk_125mhz_int), + .CSIB(icap_csib_reg), + .I(icap_di_rev), + .O(), + .PRDONE(), + .PRERROR(), + .RDWRB(icap_rdwrb_reg) +); + // PCIe wire pcie_sys_clk; wire pcie_sys_clk_gt; @@ -1518,6 +1633,7 @@ core_inst ( /* * QSPI flash */ + .fpga_boot(fpga_boot), .qspi_clk(qspi_clk_int), .qspi_0_dq_i(qspi_0_dq_i_int), .qspi_0_dq_o(qspi_0_dq_o_int), diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/rtl/fpga_core.v b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/rtl/fpga_core.v index c432055be..fcef70ae0 100644 --- a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/rtl/fpga_core.v +++ b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/rtl/fpga_core.v @@ -265,6 +265,7 @@ module fpga_core # /* * QSPI flash */ + output wire fpga_boot, output wire qspi_clk, input wire [3:0] qspi_0_dq_i, output wire [3:0] qspi_0_dq_o, @@ -513,6 +514,8 @@ reg qsfp_i2c_sda_o_reg = 1'b1; reg eeprom_i2c_scl_o_reg = 1'b1; reg eeprom_i2c_sda_o_reg = 1'b1; +reg fpga_boot_reg = 1'b0; + reg qspi_clk_reg = 1'b0; reg qspi_0_cs_reg = 1'b1; reg [3:0] qspi_0_dq_o_reg = 4'd0; @@ -560,6 +563,8 @@ assign eeprom_i2c_sda_o = eeprom_i2c_sda_o_reg; assign eeprom_i2c_sda_t = eeprom_i2c_sda_o_reg; assign eeprom_wp = 1'b0; +assign fpga_boot = fpga_boot_reg; + assign qspi_clk = qspi_clk_reg; assign qspi_0_cs = qspi_0_cs_reg; assign qspi_0_dq_o = qspi_0_dq_o_reg; @@ -590,6 +595,10 @@ always @(posedge clk_250mhz) begin axil_csr_bvalid_reg <= 1'b1; case ({axil_csr_awaddr[15:2], 2'b00}) + 16'h0040: begin + // FPGA ID + fpga_boot_reg <= axil_csr_wdata == 32'hFEE1DEAD; + end // GPIO 16'h0110: begin // GPIO I2C 0 @@ -781,6 +790,8 @@ always @(posedge clk_250mhz) begin eeprom_i2c_scl_o_reg <= 1'b1; eeprom_i2c_sda_o_reg <= 1'b1; + fpga_boot_reg <= 1'b0; + qspi_clk_reg <= 1'b0; qspi_0_cs_reg <= 1'b1; qspi_0_dq_o_reg <= 4'd0;