From 0634b865398f0566beab03f2b14f375a8c695399 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 22 Apr 2023 20:24:50 -0700 Subject: [PATCH] fpga/mqnic/DK_DEV_1SDX_P_A: Implement I2C interface on DK-DEV-1SDX-P-A Signed-off-by: Alex Forencich --- fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/fpga.qsf | 28 +-- .../mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga.v | 51 +++++ .../DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga_core.v | 181 ++++-------------- .../fpga_25g/tb/fpga_core/test_fpga_core.py | 23 +-- 4 files changed, 108 insertions(+), 175 deletions(-) diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/fpga.qsf b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/fpga.qsf index 9f5d5ab3e..a4f1dbf79 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/fpga.qsf +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/fpga.qsf @@ -101,29 +101,29 @@ set_instance_assignment -name IO_STANDARD "1.8 V" -to user_led_g[2] set_instance_assignment -name IO_STANDARD "1.8 V" -to user_led_g[3] # I2C +set_location_assignment PIN_R31 -to bmc_i2c1_disable set_location_assignment PIN_N36 -to bmc_i2c2_disable set_location_assignment PIN_P36 -to bmc_i2c3_disable -set_location_assignment PIN_R31 -to bmc_i2c1_disable -set_location_assignment PIN_C32 -to i2c1_1v8_scl -set_location_assignment PIN_G32 -to i2c1_1v8_sda -set_location_assignment PIN_K32 -to i2c2_1v8_scl -set_location_assignment PIN_B33 -to i2c2_1v8_sda -set_location_assignment PIN_G33 -to i2c3_1v8_scl -set_location_assignment PIN_C33 -to i2c3_1v8_sda +set_location_assignment PIN_C32 -to i2c1_scl +set_location_assignment PIN_G32 -to i2c1_sda +set_location_assignment PIN_K32 -to i2c2_scl +set_location_assignment PIN_B33 -to i2c2_sda +set_location_assignment PIN_G33 -to i2c3_scl +set_location_assignment PIN_C33 -to i2c3_sda set_location_assignment PIN_N35 -to i2c_ddr4_dimm_sda set_location_assignment PIN_P35 -to i2c_ddr4_dimm_scl +set_instance_assignment -name IO_STANDARD "1.8 V" -to bmc_i2c1_disable set_instance_assignment -name IO_STANDARD "1.8 V" -to bmc_i2c2_disable set_instance_assignment -name IO_STANDARD "1.8 V" -to bmc_i2c3_disable -set_instance_assignment -name IO_STANDARD "1.8 V" -to bmc_i2c1_disable -set_instance_assignment -name IO_STANDARD "1.8 V" -to i2c1_1v8_scl -set_instance_assignment -name IO_STANDARD "1.8 V" -to i2c1_1v8_sda -set_instance_assignment -name IO_STANDARD "1.8 V" -to i2c2_1v8_scl -set_instance_assignment -name IO_STANDARD "1.8 V" -to i2c2_1v8_sda -set_instance_assignment -name IO_STANDARD "1.8 V" -to i2c3_1v8_scl -set_instance_assignment -name IO_STANDARD "1.8 V" -to i2c3_1v8_sda +set_instance_assignment -name IO_STANDARD "1.8 V" -to i2c1_scl +set_instance_assignment -name IO_STANDARD "1.8 V" -to i2c1_sda +set_instance_assignment -name IO_STANDARD "1.8 V" -to i2c2_scl +set_instance_assignment -name IO_STANDARD "1.8 V" -to i2c2_sda +set_instance_assignment -name IO_STANDARD "1.8 V" -to i2c3_scl +set_instance_assignment -name IO_STANDARD "1.8 V" -to i2c3_sda set_instance_assignment -name IO_STANDARD "1.8 V" -to i2c_ddr4_dimm_sda set_instance_assignment -name IO_STANDARD "1.8 V" -to i2c_ddr4_dimm_scl diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga.v b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga.v index 571708d6f..2b67da59e 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga.v @@ -175,6 +175,13 @@ module fpga # input wire user_pb, output wire [3:0] user_led_g, + /* + * I2C + */ + inout wire i2c2_scl, + inout wire i2c2_sda, + output wire bmc_i2c2_disable, + /* * PCIe: gen 4 x16 */ @@ -250,6 +257,39 @@ sync_reset_100mhz_inst ( .out(rst_100mhz) ); +// GPIO +wire i2c2_scl_i; +wire i2c2_scl_o; +wire i2c2_scl_t; +wire i2c2_sda_i; +wire i2c2_sda_o; +wire i2c2_sda_t; + +reg i2c2_scl_o_reg; +reg i2c2_scl_t_reg; +reg i2c2_sda_o_reg; +reg i2c2_sda_t_reg; + +always @(posedge pcie_clk) begin + i2c2_scl_o_reg <= i2c2_scl_o; + i2c2_scl_t_reg <= i2c2_scl_t; + i2c2_sda_o_reg <= i2c2_sda_o; + i2c2_sda_t_reg <= i2c2_sda_t; +end + +sync_signal #( + .WIDTH(2), + .N(2) +) +sync_signal_inst ( + .clk(pcie_clk), + .in({i2c2_scl, i2c2_sda}), + .out({i2c2_scl_i, i2c2_sda_i}) +); + +assign i2c2_scl = i2c2_scl_t_reg ? 1'bz : i2c2_scl_o_reg; +assign i2c2_sda = i2c2_sda_t_reg ? 1'bz : i2c2_sda_o_reg; + // PCIe wire coreclkout_hip; wire reset_status_n; @@ -1153,6 +1193,17 @@ core_inst ( .user_pb(user_pb), .user_led_g(user_led_g), + /* + * I2C + */ + .i2c2_scl_i(i2c2_scl_i), + .i2c2_scl_o(i2c2_scl_o), + .i2c2_scl_t(i2c2_scl_t), + .i2c2_sda_i(i2c2_sda_i), + .i2c2_sda_o(i2c2_sda_o), + .i2c2_sda_t(i2c2_sda_t), + .bmc_i2c2_disable(bmc_i2c2_disable), + /* * P-Tile interface */ diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga_core.v index 120873660..698ca7e19 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga_core.v @@ -199,6 +199,17 @@ module fpga_core # input wire user_pb, output wire [3:0] user_led_g, + /* + * I2C + */ + input wire i2c2_scl_i, + output wire i2c2_scl_o, + output wire i2c2_scl_t, + input wire i2c2_sda_i, + output wire i2c2_sda_o, + output wire i2c2_sda_t, + output wire bmc_i2c2_disable, + /* * P-Tile interface */ @@ -572,22 +583,8 @@ reg ctrl_reg_wr_ack_reg = 1'b0; reg [AXIL_CTRL_DATA_WIDTH-1:0] ctrl_reg_rd_data_reg = {AXIL_CTRL_DATA_WIDTH{1'b0}}; reg ctrl_reg_rd_ack_reg = 1'b0; -reg qsfp0_reset_reg = 1'b0; -reg qsfp0_lp_mode_reg = 1'b0; -// reg qsfp0_i2c_scl_o_reg = 1'b1; -// reg qsfp0_i2c_sda_o_reg = 1'b1; - -reg qsfp1_reset_reg = 1'b0; -reg qsfp1_lp_mode_reg = 1'b0; -// reg qsfp1_i2c_scl_o_reg = 1'b1; -// reg qsfp1_i2c_sda_o_reg = 1'b1; - -// reg fpga_boot_reg = 1'b0; - -// reg qspi_clk_reg = 1'b0; -// reg qspi_cs_reg = 1'b1; -// reg [3:0] qspi_dq_o_reg = 4'd0; -// reg [3:0] qspi_dq_oe_reg = 4'd0; +reg i2c2_scl_o_reg = 1'b1; +reg i2c2_sda_o_reg = 1'b1; assign ctrl_reg_wr_wait = 1'b0; assign ctrl_reg_wr_ack = ctrl_reg_wr_ack_reg; @@ -595,26 +592,11 @@ assign ctrl_reg_rd_data = ctrl_reg_rd_data_reg; assign ctrl_reg_rd_wait = 1'b0; assign ctrl_reg_rd_ack = ctrl_reg_rd_ack_reg; -// assign qsfp0_reset_n = !qsfp0_reset_reg; -// assign qsfp0_lp_mode = qsfp0_lp_mode_reg; -// assign qsfp0_i2c_scl_o = qsfp0_i2c_scl_o_reg; -// assign qsfp0_i2c_scl_t = qsfp0_i2c_scl_o_reg; -// assign qsfp0_i2c_sda_o = qsfp0_i2c_sda_o_reg; -// assign qsfp0_i2c_sda_t = qsfp0_i2c_sda_o_reg; - -// assign qsfp1_reset_n = !qsfp1_reset_reg; -// assign qsfp1_lp_mode = qsfp1_lp_mode_reg; -// assign qsfp1_i2c_scl_o = qsfp1_i2c_scl_o_reg; -// assign qsfp1_i2c_scl_t = qsfp1_i2c_scl_o_reg; -// assign qsfp1_i2c_sda_o = qsfp1_i2c_sda_o_reg; -// assign qsfp1_i2c_sda_t = qsfp1_i2c_sda_o_reg; - -// assign fpga_boot = fpga_boot_reg; - -// assign qspi_clk = qspi_clk_reg; -// assign qspi_cs = qspi_cs_reg; -// assign qspi_dq_o = qspi_dq_o_reg; -// assign qspi_dq_oe = qspi_dq_oe_reg; +assign i2c2_scl_o = i2c2_scl_o_reg; +assign i2c2_scl_t = i2c2_scl_o_reg; +assign i2c2_sda_o = i2c2_sda_o_reg; +assign i2c2_sda_t = i2c2_sda_o_reg; +assign bmc_i2c2_disable = 1'b1; always @(posedge clk_250mhz) begin ctrl_reg_wr_ack_reg <= 1'b0; @@ -625,54 +607,16 @@ always @(posedge clk_250mhz) begin // write operation ctrl_reg_wr_ack_reg <= 1'b0; case ({ctrl_reg_wr_addr >> 2, 2'b00}) - // 16'h0040: begin - // // FPGA ID - // fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; - // end - // GPIO - // 16'h0110: begin - // // GPIO I2C 0 - // if (ctrl_reg_wr_strb[0]) begin - // qsfp0_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; - // end - // if (ctrl_reg_wr_strb[1]) begin - // qsfp0_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; - // end - // end - // 16'h0114: begin - // // GPIO I2C 1 - // if (ctrl_reg_wr_strb[0]) begin - // qsfp1_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; - // end - // if (ctrl_reg_wr_strb[1]) begin - // qsfp1_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; - // end - // end - // 16'h0120: begin - // // GPIO XCVR 0123 - // if (ctrl_reg_wr_strb[0]) begin - // qsfp0_reset_reg <= ctrl_reg_wr_data[4]; - // qsfp0_lp_mode_reg <= ctrl_reg_wr_data[5]; - // end - // if (ctrl_reg_wr_strb[1]) begin - // qsfp1_reset_reg <= ctrl_reg_wr_data[12]; - // qsfp1_lp_mode_reg <= ctrl_reg_wr_data[13]; - // end - // end - // Flash - // 16'h0144: begin - // // QSPI control - // if (ctrl_reg_wr_strb[0]) begin - // qspi_dq_o_reg <= ctrl_reg_wr_data[3:0]; - // end - // if (ctrl_reg_wr_strb[1]) begin - // qspi_dq_oe_reg <= ctrl_reg_wr_data[11:8]; - // end - // if (ctrl_reg_wr_strb[2]) begin - // qspi_clk_reg <= ctrl_reg_wr_data[16]; - // qspi_cs_reg <= ctrl_reg_wr_data[17]; - // end - // end + // I2C 0 + RBB+8'h0C: begin + // I2C ctrl: control + if (ctrl_reg_wr_strb[0]) begin + i2c2_scl_o_reg <= ctrl_reg_wr_data[1]; + end + if (ctrl_reg_wr_strb[1]) begin + i2c2_sda_o_reg <= ctrl_reg_wr_data[9]; + end + end default: ctrl_reg_wr_ack_reg <= 1'b0; endcase end @@ -681,48 +625,17 @@ always @(posedge clk_250mhz) begin // read operation ctrl_reg_rd_ack_reg <= 1'b1; case ({ctrl_reg_rd_addr >> 2, 2'b00}) - // 16'h0040: ctrl_reg_rd_data_reg <= FPGA_ID; // FPGA ID - // GPIO - // 16'h0110: begin - // // GPIO I2C 0 - // ctrl_reg_rd_data_reg[0] <= qsfp0_i2c_scl_i; - // ctrl_reg_rd_data_reg[1] <= qsfp0_i2c_scl_o_reg; - // ctrl_reg_rd_data_reg[8] <= qsfp0_i2c_sda_i; - // ctrl_reg_rd_data_reg[9] <= qsfp0_i2c_sda_o_reg; - // end - // 16'h0114: begin - // // GPIO I2C 1 - // ctrl_reg_rd_data_reg[0] <= qsfp1_i2c_scl_i; - // ctrl_reg_rd_data_reg[1] <= qsfp1_i2c_scl_o_reg; - // ctrl_reg_rd_data_reg[8] <= qsfp1_i2c_sda_i; - // ctrl_reg_rd_data_reg[9] <= qsfp1_i2c_sda_o_reg; - // end - // 16'h0120: begin - // // GPIO XCVR 0123 - // ctrl_reg_rd_data_reg[0] <= !qsfp0_mod_prsnt_n; - // ctrl_reg_rd_data_reg[1] <= !qsfp0_intr_n; - // ctrl_reg_rd_data_reg[4] <= qsfp0_reset_reg; - // ctrl_reg_rd_data_reg[5] <= qsfp0_lp_mode_reg; - // ctrl_reg_rd_data_reg[8] <= !qsfp1_mod_prsnt_n; - // ctrl_reg_rd_data_reg[9] <= !qsfp1_intr_n; - // ctrl_reg_rd_data_reg[12] <= qsfp1_reset_reg; - // ctrl_reg_rd_data_reg[13] <= qsfp1_lp_mode_reg; - // end - // Flash - // 16'h0140: begin - // // Flash ID - // ctrl_reg_rd_data_reg[7:0] <= 0; // type (SPI) - // ctrl_reg_rd_data_reg[15:8] <= 1; // configuration (one segment) - // ctrl_reg_rd_data_reg[23:16] <= 4; // data width (QSPI) - // ctrl_reg_rd_data_reg[31:24] <= 0; // address width (N/A for SPI) - // end - // 16'h0144: begin - // // QSPI control - // ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i; - // ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe; - // ctrl_reg_rd_data_reg[16] <= qspi_clk; - // ctrl_reg_rd_data_reg[17] <= qspi_cs; - // end + // I2C 0 + RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type + RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version + RBB+8'h08: ctrl_reg_rd_data_reg <= 0; // I2C ctrl: Next header + RBB+8'h0C: begin + // I2C ctrl: control + ctrl_reg_rd_data_reg[0] <= i2c2_scl_i; + ctrl_reg_rd_data_reg[1] <= i2c2_scl_o_reg; + ctrl_reg_rd_data_reg[8] <= i2c2_sda_i; + ctrl_reg_rd_data_reg[9] <= i2c2_sda_o_reg; + end default: ctrl_reg_rd_ack_reg <= 1'b0; endcase end @@ -731,20 +644,8 @@ always @(posedge clk_250mhz) begin ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_rd_ack_reg <= 1'b0; - qsfp0_reset_reg <= 1'b0; - qsfp0_lp_mode_reg <= 1'b0; - // qsfp0_i2c_scl_o_reg <= 1'b1; - // qsfp0_i2c_sda_o_reg <= 1'b1; - - qsfp1_reset_reg <= 1'b0; - qsfp1_lp_mode_reg <= 1'b0; - // qsfp1_i2c_scl_o_reg <= 1'b1; - // qsfp1_i2c_sda_o_reg <= 1'b1; - - // qspi_clk_reg <= 1'b0; - // qspi_cs_reg <= 1'b1; - // qspi_dq_o_reg <= 4'd0; - // qspi_dq_oe_reg <= 4'd0; + i2c2_scl_o_reg <= 1'b1; + i2c2_sda_o_reg <= 1'b1; end end diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/tb/fpga_core/test_fpga_core.py index 6b6d0dde1..d5f86a7ce 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -440,27 +440,8 @@ class TB(object): dut.user_pb.setimmediatevalue(0) - # dut.qsfp0_i2c_scl_i.setimmediatevalue(1) - # dut.qsfp0_i2c_sda_i.setimmediatevalue(1) - # dut.qsfp0_intr_n.setimmediatevalue(1) - # dut.qsfp0_mod_prsnt_n.setimmediatevalue(0) - - # dut.qsfp0_rx_error_count_0.setimmediatevalue(0) - # dut.qsfp0_rx_error_count_1.setimmediatevalue(0) - # dut.qsfp0_rx_error_count_2.setimmediatevalue(0) - # dut.qsfp0_rx_error_count_3.setimmediatevalue(0) - - # dut.qsfp1_i2c_scl_i.setimmediatevalue(1) - # dut.qsfp1_i2c_sda_i.setimmediatevalue(1) - # dut.qsfp1_intr_n.setimmediatevalue(1) - # dut.qsfp1_mod_prsnt_n.setimmediatevalue(0) - - # dut.qsfp1_rx_error_count_0.setimmediatevalue(0) - # dut.qsfp1_rx_error_count_1.setimmediatevalue(0) - # dut.qsfp1_rx_error_count_2.setimmediatevalue(0) - # dut.qsfp1_rx_error_count_3.setimmediatevalue(0) - - # dut.qspi_dq_i.setimmediatevalue(0) + dut.i2c2_scl_i.setimmediatevalue(1) + dut.i2c2_sda_i.setimmediatevalue(1) self.loopback_enable = False cocotb.start_soon(self._run_loopback())