From 15fe14ab888c39608ae5654fd1d7a31448093113 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 10 Jun 2023 20:24:08 -0700 Subject: [PATCH] fpga/mqnic/Nexus_K35_S: Add virtual I2C switch to control modsel pins Signed-off-by: Alex Forencich --- fpga/mqnic/Nexus_K35_S/fpga/fpga/Makefile | 1 + .../fpga/fpga_app_dma_bench/Makefile | 1 + fpga/mqnic/Nexus_K35_S/fpga/rtl/fpga_core.v | 63 ++++++++++++------- .../Nexus_K35_S/fpga/tb/fpga_core/Makefile | 1 + .../fpga/tb/fpga_core/test_fpga_core.py | 1 + 5 files changed, 46 insertions(+), 21 deletions(-) diff --git a/fpga/mqnic/Nexus_K35_S/fpga/fpga/Makefile b/fpga/mqnic/Nexus_K35_S/fpga/fpga/Makefile index 49bc49698..98d791be2 100644 --- a/fpga/mqnic/Nexus_K35_S/fpga/fpga/Makefile +++ b/fpga/mqnic/Nexus_K35_S/fpga/fpga/Makefile @@ -56,6 +56,7 @@ SYN_FILES += rtl/common/tx_scheduler_rr.v SYN_FILES += rtl/common/tdma_scheduler.v SYN_FILES += rtl/common/tdma_ber.v SYN_FILES += rtl/common/tdma_ber_ch.v +SYN_FILES += rtl/common/i2c_single_reg.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v diff --git a/fpga/mqnic/Nexus_K35_S/fpga/fpga_app_dma_bench/Makefile b/fpga/mqnic/Nexus_K35_S/fpga/fpga_app_dma_bench/Makefile index 0ea895dd8..63870f481 100644 --- a/fpga/mqnic/Nexus_K35_S/fpga/fpga_app_dma_bench/Makefile +++ b/fpga/mqnic/Nexus_K35_S/fpga/fpga_app_dma_bench/Makefile @@ -56,6 +56,7 @@ SYN_FILES += rtl/common/tx_scheduler_rr.v SYN_FILES += rtl/common/tdma_scheduler.v SYN_FILES += rtl/common/tdma_ber.v SYN_FILES += rtl/common/tdma_ber_ch.v +SYN_FILES += rtl/common/i2c_single_reg.v SYN_FILES += app/dma_bench/rtl/mqnic_app_block_dma_bench.v SYN_FILES += app/dma_bench/rtl/dma_bench.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v diff --git a/fpga/mqnic/Nexus_K35_S/fpga/rtl/fpga_core.v b/fpga/mqnic/Nexus_K35_S/fpga/rtl/fpga_core.v index 7adfb5a52..26cfe217f 100644 --- a/fpga/mqnic/Nexus_K35_S/fpga/rtl/fpga_core.v +++ b/fpga/mqnic/Nexus_K35_S/fpga/rtl/fpga_core.v @@ -413,8 +413,12 @@ 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 sfp_1_sel_reg = 1'b0; -reg sfp_2_sel_reg = 1'b0; +wire sfp_i2c_select_scl_o; +wire sfp_i2c_select_sda_o; +wire [7:0] sfp_i2c_select; + +wire sfp_i2c_scl_i_int = sfp_i2c_scl_i & sfp_i2c_scl_o; +wire sfp_i2c_sda_i_int = (sfp_1_i2c_sda_i || !sfp_i2c_select[0]) && (sfp_2_i2c_sda_i || !sfp_i2c_select[1]) & sfp_i2c_sda_o_reg & sfp_i2c_select_sda_o; reg sfp_1_tx_disable_reg = 1'b0; reg sfp_1_rs_reg = 1'b0; @@ -451,17 +455,17 @@ assign sfp_2_tx_disable = !sfp_2_tx_disable_reg; assign sfp_1_rs = sfp_1_rs_reg; assign sfp_2_rs = sfp_2_rs_reg; -assign sfp_i2c_scl_o = sfp_i2c_scl_o_reg; -assign sfp_i2c_scl_t = sfp_i2c_scl_o_reg; -assign sfp_1_i2c_sda_o = sfp_1_sel_reg ? sfp_i2c_sda_o_reg : 1'b1; -assign sfp_1_i2c_sda_t = sfp_1_sel_reg ? sfp_i2c_sda_o_reg : 1'b1; -assign sfp_2_i2c_sda_o = sfp_2_sel_reg ? sfp_i2c_sda_o_reg : 1'b1; -assign sfp_2_i2c_sda_t = sfp_2_sel_reg ? sfp_i2c_sda_o_reg : 1'b1; +assign sfp_i2c_scl_o = sfp_i2c_scl_o_reg & sfp_i2c_select_scl_o; +assign sfp_i2c_scl_t = sfp_i2c_scl_o; +assign sfp_1_i2c_sda_o = sfp_i2c_select[0] ? sfp_i2c_sda_o_reg & sfp_i2c_select_sda_o : 1'b1; +assign sfp_1_i2c_sda_t = sfp_1_i2c_sda_o; +assign sfp_2_i2c_sda_o = sfp_i2c_select[1] ? sfp_i2c_sda_o_reg & sfp_i2c_select_sda_o : 1'b1; +assign sfp_2_i2c_sda_t = sfp_2_i2c_sda_o; assign eeprom_i2c_scl_o = eeprom_i2c_scl_o_reg; -assign eeprom_i2c_scl_t = eeprom_i2c_scl_o_reg; +assign eeprom_i2c_scl_t = eeprom_i2c_scl_o; assign eeprom_i2c_sda_o = eeprom_i2c_sda_o_reg; -assign eeprom_i2c_sda_t = eeprom_i2c_sda_o_reg; +assign eeprom_i2c_sda_t = eeprom_i2c_sda_o; assign fpga_boot = fpga_boot_reg; @@ -475,6 +479,32 @@ assign flash_oe_n = flash_oe_n_reg; assign flash_we_n = flash_we_n_reg; assign flash_adv_n = flash_adv_n_reg; +i2c_single_reg #( + .FILTER_LEN(4), + .DEV_ADDR(7'h74) +) +qsfp_i2c_select_inst ( + .clk(clk_250mhz), + .rst(rst_250mhz), + + /* + * I2C interface + */ + .scl_i(sfp_i2c_scl_i_int), + .scl_o(sfp_i2c_select_scl_o), + .scl_t(), + .sda_i(sfp_i2c_sda_i_int), + .sda_o(sfp_i2c_select_sda_o), + .sda_t(), + + /* + * Data register + */ + .data_in(8'd0), + .data_latch(1'b0), + .data_out(sfp_i2c_select) +); + always @(posedge clk_250mhz) begin ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_rd_data_reg <= {AXIL_CTRL_DATA_WIDTH{1'b0}}; @@ -498,10 +528,6 @@ always @(posedge clk_250mhz) begin if (ctrl_reg_wr_strb[1]) begin sfp_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; end - if (ctrl_reg_wr_strb[2]) begin - sfp_1_sel_reg <= ctrl_reg_wr_data[16]; - sfp_2_sel_reg <= ctrl_reg_wr_data[17]; - end end // I2C 1 RBB+8'h1C: begin @@ -565,12 +591,10 @@ always @(posedge clk_250mhz) begin RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header RBB+8'h0C: begin // I2C ctrl: control - ctrl_reg_rd_data_reg[0] <= sfp_i2c_scl_i; + ctrl_reg_rd_data_reg[0] <= sfp_i2c_scl_i_int; ctrl_reg_rd_data_reg[1] <= sfp_i2c_scl_o_reg; - ctrl_reg_rd_data_reg[8] <= (sfp_1_i2c_sda_i || !sfp_1_sel_reg) && (sfp_2_i2c_sda_i || !sfp_2_sel_reg); + ctrl_reg_rd_data_reg[8] <= sfp_i2c_sda_i_int; ctrl_reg_rd_data_reg[9] <= sfp_i2c_sda_o_reg; - ctrl_reg_rd_data_reg[16] <= sfp_1_sel_reg; - ctrl_reg_rd_data_reg[17] <= sfp_2_sel_reg; end // I2C 1 RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type @@ -632,9 +656,6 @@ always @(posedge clk_250mhz) begin ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_rd_ack_reg <= 1'b0; - sfp_1_sel_reg <= 1'b0; - sfp_2_sel_reg <= 1'b0; - sfp_1_tx_disable_reg <= 1'b0; sfp_1_rs_reg <= 1'b0; sfp_2_tx_disable_reg <= 1'b0; diff --git a/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/Makefile b/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/Makefile index 5d51cae8e..952d6c7df 100644 --- a/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/Makefile +++ b/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/Makefile @@ -85,6 +85,7 @@ VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v VERILOG_SOURCES += ../../rtl/common/tdma_ber.v VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../rtl/common/i2c_single_reg.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v diff --git a/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/test_fpga_core.py index 14ba2bd50..a61c257f8 100644 --- a/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/test_fpga_core.py @@ -600,6 +600,7 @@ def test_fpga_core(request): os.path.join(rtl_dir, "common", "tdma_scheduler.v"), os.path.join(rtl_dir, "common", "tdma_ber.v"), os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(rtl_dir, "common", "i2c_single_reg.v"), os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"),