diff --git a/src/cndm/board/KCU105/fpga/fpga/Makefile b/src/cndm/board/KCU105/fpga/fpga/Makefile index 3982bce..a73dab7 100644 --- a/src/cndm/board/KCU105/fpga/fpga/Makefile +++ b/src/cndm/board/KCU105/fpga/fpga/Makefile @@ -19,6 +19,7 @@ TAXI_SRC_DIR = $(LIB_DIR)/taxi/src SYN_FILES = $(RTL_DIR)/fpga.sv SYN_FILES += $(RTL_DIR)/fpga_core.sv SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f +SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_brd_ctrl_i2c.f SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/taxi_eth_mac_1g_fifo.f SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f diff --git a/src/cndm/board/KCU105/fpga/rtl/fpga_core.sv b/src/cndm/board/KCU105/fpga/rtl/fpga_core.sv index 6c4b6cc..66c51fa 100644 --- a/src/cndm/board/KCU105/fpga/rtl/fpga_core.sv +++ b/src/cndm/board/KCU105/fpga/rtl/fpga_core.sv @@ -354,6 +354,14 @@ stat_mux_inst ( ); // I2C +wire [1:0] i2c_scl_o_int; +wire [1:0] i2c_sda_o_int; + +assign i2c_scl_o = &i2c_scl_o_int; +assign i2c_sda_o = &i2c_sda_o_int; +wire i2c_scl_i_int = i2c_scl_i & i2c_scl_o; +wire i2c_sda_i_int = i2c_sda_i & i2c_sda_o; + taxi_xfcp_mod_i2c_master #( .XFCP_EXT_ID_STR("I2C"), .DEFAULT_PRESCALE(16'(125000000/200000/4)) @@ -371,12 +379,43 @@ xfcp_mod_i2c_inst ( /* * I2C interface */ - .i2c_scl_i(i2c_scl_i), - .i2c_scl_o(i2c_scl_o), - .i2c_sda_i(i2c_sda_i), - .i2c_sda_o(i2c_sda_o) + .i2c_scl_i(i2c_scl_i_int), + .i2c_scl_o(i2c_scl_o_int[0]), + .i2c_sda_i(i2c_sda_i_int), + .i2c_sda_o(i2c_sda_o_int[0]) ); +localparam logic OPTIC_EN = 1'b1; +localparam OPTIC_CNT = 2; + +localparam logic EEPROM_EN = 1'b1; +localparam EEPROM_IDX = OPTIC_EN ? OPTIC_CNT : 0; + +localparam logic MAC_EEPROM_EN = EEPROM_EN; +localparam MAC_EEPROM_IDX = EEPROM_IDX; +localparam MAC_EEPROM_OFFSET = 32; +localparam MAC_COUNT = OPTIC_CNT; +localparam logic MAC_FROM_BASE = 1'b1; + +localparam logic SN_EEPROM_EN = EEPROM_EN; +localparam SN_EEPROM_IDX = EEPROM_IDX; +localparam SN_EEPROM_OFFSET = 0; +localparam SN_LEN = 32; + +localparam logic PLL_EN = 1'b1; +localparam PLL_IDX = EEPROM_IDX + (EEPROM_EN ? 1 : 0); + +localparam logic MUX_EN = 1'b1; +localparam MUX_CNT = 2; +localparam logic [MUX_CNT-1:0][6:0] MUX_I2C_ADDR = {7'h75, 7'h74}; + +localparam DEV_CNT = PLL_IDX + (PLL_EN ? 1 : 0); +localparam logic [DEV_CNT-1:0][6:0] DEV_I2C_ADDR = {7'h5D, 7'h54, 7'h50, 7'h50}; +localparam logic [DEV_CNT-1:0][31:0] DEV_ADDR_CFG = {32'h00_00_0000, 32'h00_00_0040, 32'h7e_7f_0070, 32'h7e_7f_0070}; +localparam logic [DEV_CNT-1:0][MUX_CNT-1:0][7:0] DEV_MUX_MASK = {{8'h00, 8'h01}, {8'h07, 8'h00}, {8'h00, 8'h08}, {8'h00, 8'h04}}; + +localparam I2C_PRESCALE = SIM ? 2 : 250000/(400*4); + taxi_axis_if #( .DATA_W(32), .KEEP_EN(1), @@ -386,6 +425,60 @@ taxi_axis_if #( .USER_W(1) ) axis_brd_ctrl_cmd(), axis_brd_ctrl_rsp(); +cndm_brd_ctrl_i2c #( + .OPTIC_EN(OPTIC_EN), + .OPTIC_CNT(OPTIC_CNT), + + .EEPROM_EN(EEPROM_EN), + .EEPROM_IDX(EEPROM_IDX), + + .MAC_EEPROM_EN(MAC_EEPROM_EN), + .MAC_EEPROM_IDX(MAC_EEPROM_IDX), + .MAC_EEPROM_OFFSET(MAC_EEPROM_OFFSET), + .MAC_COUNT(MAC_COUNT), + .MAC_FROM_BASE(MAC_FROM_BASE), + + .SN_EEPROM_EN(SN_EEPROM_EN), + .SN_EEPROM_IDX(SN_EEPROM_IDX), + .SN_EEPROM_OFFSET(SN_EEPROM_OFFSET), + .SN_LEN(SN_LEN), + + .PLL_EN(PLL_EN), + .PLL_IDX(PLL_IDX), + + .MUX_EN(MUX_EN), + .MUX_CNT(MUX_CNT), + .MUX_I2C_ADDR(MUX_I2C_ADDR), + + .DEV_CNT(DEV_CNT), + .DEV_I2C_ADDR(DEV_I2C_ADDR), + .DEV_ADDR_CFG(DEV_ADDR_CFG), + .DEV_MUX_MASK(DEV_MUX_MASK), + + .I2C_PRESCALE(I2C_PRESCALE) +) +board_ctrl_i2c_ch_inst ( + .clk(pcie_clk), + .rst(pcie_rst), + + /* + * Board control command interface + */ + .s_axis_cmd(axis_brd_ctrl_cmd), + .m_axis_rsp(axis_brd_ctrl_rsp), + + /* + * I2C interface + */ + .i2c_scl_i(i2c_scl_i_int), + .i2c_scl_o(i2c_scl_o_int[1]), + .i2c_sda_i(i2c_sda_i_int), + .i2c_sda_o(i2c_sda_o_int[1]), + + .dev_sel(), + .dev_rst() +); + // BASE-T PHY assign phy_reset_n = !rst_125mhz; @@ -841,7 +934,7 @@ cndm_micro_pcie_us #( // Structural configuration .PORTS($size(axis_sfp_tx)), - .BRD_CTRL_EN(1'b0), + .BRD_CTRL_EN(1'b1), .SYS_CLK_PER_NS_NUM(4), .SYS_CLK_PER_NS_DEN(1), diff --git a/src/cndm/board/KCU105/fpga/tb/fpga_core/Makefile b/src/cndm/board/KCU105/fpga/tb/fpga_core/Makefile index 8691c23..924f63b 100644 --- a/src/cndm/board/KCU105/fpga/tb/fpga_core/Makefile +++ b/src/cndm/board/KCU105/fpga/tb/fpga_core/Makefile @@ -25,6 +25,7 @@ TOPLEVEL = $(COCOTB_TOPLEVEL) VERILOG_SOURCES += $(COCOTB_TOPLEVEL).sv VERILOG_SOURCES += $(RTL_DIR)/$(DUT).sv VERILOG_SOURCES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f +VERILOG_SOURCES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_brd_ctrl_i2c.f VERILOG_SOURCES += $(TAXI_SRC_DIR)/eth/rtl/taxi_eth_mac_1g_fifo.f VERILOG_SOURCES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f VERILOG_SOURCES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f diff --git a/src/cndm/board/KCU105/fpga/tb/fpga_core/test_fpga_core.py b/src/cndm/board/KCU105/fpga/tb/fpga_core/test_fpga_core.py index 021c2b6..74e5297 100644 --- a/src/cndm/board/KCU105/fpga/tb/fpga_core/test_fpga_core.py +++ b/src/cndm/board/KCU105/fpga/tb/fpga_core/test_fpga_core.py @@ -11,6 +11,7 @@ Authors: import logging import os +import struct import sys import cocotb_test.simulator @@ -23,6 +24,7 @@ from cocotbext.axi import AxiStreamBus from cocotbext.eth import GmiiFrame, GmiiSource, GmiiSink from cocotbext.eth import XgmiiFrame from cocotbext.uart import UartSource, UartSink +from cocotbext.i2c import I2cMemory from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePcieDevice @@ -297,9 +299,61 @@ class TB: gbx_cfg=gbx_cfg )) + # UART self.uart_source = UartSource(dut.uart_rxd, baud=921600, bits=8, stop_bits=1) self.uart_sink = UartSink(dut.uart_txd, baud=921600, bits=8, stop_bits=1) + # I2C + self.i2c_eeprom = I2cMemory(sda=dut.i2c_sda_o, sda_o=dut.i2c_sda_i, + scl=dut.i2c_scl_o, scl_o=dut.i2c_scl_i, addr=0x54, size=256) + self.sfp0 = I2cMemory(sda=dut.i2c_sda_o, sda_o=dut.i2c_sda_i, + scl=dut.i2c_scl_o, scl_o=dut.i2c_scl_i, addr=0x50, size=256) + self.si570 = I2cMemory(sda=dut.i2c_sda_o, sda_o=dut.i2c_sda_i, + scl=dut.i2c_scl_o, scl_o=dut.i2c_scl_i, addr=0x5D, size=256) + + self.i2c_eeprom.write_mem(0, bytes.fromhex(""" + 37 35 37 35 31 39 32 37 31 37 33 32 2d 36 39 39 + 39 36 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 00 0a 35 03 72 c9 00 00 00 00 00 00 00 00 00 00 + 54 53 53 30 31 36 35 2d 30 32 20 20 20 20 20 20 + 5b 31 31 31 31 31 31 31 31 31 5d 20 20 20 20 20 + 57 65 64 2c 20 31 36 20 41 75 67 20 32 30 31 37 + 31 30 3a 33 35 3a 35 36 2b 30 38 30 30 20 20 20 + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + 4b 43 55 31 30 35 20 20 20 20 20 20 20 20 20 20 + 31 2e 31 20 20 20 20 20 20 20 20 20 20 20 20 20 + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + """)) + + self.sfp0.write_mem(0, bytes.fromhex(""" + 03 04 21 00 00 00 00 00 04 00 00 00 67 00 00 00 + 00 00 03 00 41 6d 70 68 65 6e 6f 6c 20 20 20 20 + 20 20 20 20 00 41 50 48 35 37 31 35 34 30 30 30 + 32 20 20 20 20 20 20 20 4b 20 20 20 01 00 00 f7 + 00 00 00 00 41 50 46 30 39 34 38 30 30 32 30 32 + 37 39 20 20 30 39 31 31 32 34 20 20 00 00 00 c1 + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00 + """ + " ff"*128)) + + self.si570.write_mem(0, bytes.fromhex(""" + 4f 02 32 a1 3d 20 00 01 c2 bb ff 84 82 07 c2 c0 + 00 00 00 00 c2 c0 00 00 00 07 c2 c0 00 00 00 0c + b9 09 80 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 20 7f 86 81 7b 81 03 00 10 08 00 00 00 00 02 bb + ff 84 82 00 00 00 62 00 00 00 00 00 00 00 00 00 + """)) + dut.phy_gmii_clk_en.setimmediatevalue(1) dut.btnu.setimmediatevalue(0) @@ -360,6 +414,28 @@ async def run_test(dut): tb.log.info("Init complete") + tb.log.info("Read MAC address") + + rsp = await driver.exec_cmd(struct.pack("