From 1d0b06e7f76c54b6a9a655bb88188637d54dc321 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 18 Mar 2026 21:25:44 -0700 Subject: [PATCH] cndm: Add board control logic to AS02MC04 Signed-off-by: Alex Forencich --- src/cndm/board/AS02MC04/fpga/README.md | 2 +- src/cndm/board/AS02MC04/fpga/fpga.xdc | 46 ++++--- src/cndm/board/AS02MC04/fpga/fpga/Makefile | 1 + .../board/AS02MC04/fpga/fpga_10g/Makefile | 1 + src/cndm/board/AS02MC04/fpga/rtl/fpga.sv | 127 ++++++++++++++++- src/cndm/board/AS02MC04/fpga/rtl/fpga_core.sv | 129 +++++++++++++++++- .../board/AS02MC04/fpga/tb/fpga_core/Makefile | 1 + .../fpga/tb/fpga_core/test_fpga_core.py | 60 ++++++++ .../fpga/tb/fpga_core/test_fpga_core.sv | 36 +++++ 9 files changed, 382 insertions(+), 21 deletions(-) diff --git a/src/cndm/board/AS02MC04/fpga/README.md b/src/cndm/board/AS02MC04/fpga/README.md index 9db7f24..b594e57 100644 --- a/src/cndm/board/AS02MC04/fpga/README.md +++ b/src/cndm/board/AS02MC04/fpga/README.md @@ -5,7 +5,7 @@ This design targets the Alibaba AS02MC04 FPGA board. * SFP+ cages - * Looped-back 10GBASE-R or 25GBASE-R MAC via GTY transceiver + * 10GBASE-R or 25GBASE-R MAC via GTY transceiver ## Board details diff --git a/src/cndm/board/AS02MC04/fpga/fpga.xdc b/src/cndm/board/AS02MC04/fpga/fpga.xdc index f36d4c7..eac70b3 100644 --- a/src/cndm/board/AS02MC04/fpga/fpga.xdc +++ b/src/cndm/board/AS02MC04/fpga/fpga.xdc @@ -53,6 +53,9 @@ set_input_delay 0 [get_ports {reset}] #set_property -dict {LOC C9 IOSTANDARD LVCMOS33} [get_ports {gpio[4]}] ;# J5.11,12 #set_property -dict {LOC D9 IOSTANDARD LVCMOS33} [get_ports {gpio[5]}] ;# J5.13,14 +# 1-wire for DS28E15 +#set_property -dict {LOC A15 IOSTANDARD LVCMOS33} [get_ports {onewire}] ;# U3 DS28E15 + # SFP28 Interfaces set_property -dict {LOC A4 } [get_ports {sfp_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 set_property -dict {LOC A3 } [get_ports {sfp_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 @@ -70,10 +73,10 @@ set_property -dict {LOC B14 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {sfp_tx set_property -dict {LOC F9 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {sfp_tx_fault[1]}] set_property -dict {LOC D13 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {sfp_los[0]}] set_property -dict {LOC E10 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {sfp_los[1]}] -#set_property -dict {LOC C13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {sfp_i2c_scl[0]}] -#set_property -dict {LOC D10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {sfp_i2c_scl[1]}] -#set_property -dict {LOC C14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {sfp_i2c_sda[0]}] -#set_property -dict {LOC D11 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {sfp_i2c_sda[1]}] +set_property -dict {LOC C13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {sfp_i2c_scl[0]}] +set_property -dict {LOC D10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {sfp_i2c_scl[1]}] +set_property -dict {LOC C14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {sfp_i2c_sda[0]}] +set_property -dict {LOC D11 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {sfp_i2c_sda[1]}] # 156.25 MHz MGT reference clock create_clock -period 6.4 -name sfp_mgt_refclk [get_ports {sfp_mgt_refclk_p}] @@ -81,21 +84,32 @@ create_clock -period 6.4 -name sfp_mgt_refclk [get_ports {sfp_mgt_refclk_p}] set_false_path -from [get_ports {sfp_npres[*] sfp_tx_fault[*] sfp_los[*]}] set_input_delay 0 [get_ports {sfp_npres[*] sfp_tx_fault[*] sfp_los[*]}] -#set_false_path -to [get_ports {sfp_i2c_sda[*] sfp_i2c_scl[*]}] -#set_output_delay 0 [get_ports {sfp_i2c_sda[*] sfp_i2c_scl[*]}] -#set_false_path -from [get_ports {sfp_i2c_sda[*] sfp_i2c_scl[*]}] -#set_input_delay 0 [get_ports {sfp_i2c_sda[*] sfp_i2c_scl[*]}] +set_false_path -to [get_ports {sfp_i2c_sda[*] sfp_i2c_scl[*]}] +set_output_delay 0 [get_ports {sfp_i2c_sda[*] sfp_i2c_scl[*]}] +set_false_path -from [get_ports {sfp_i2c_sda[*] sfp_i2c_scl[*]}] +set_input_delay 0 [get_ports {sfp_i2c_sda[*] sfp_i2c_scl[*]}] # I2C interface -#set_property -dict {LOC G9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {i2c_scl[0]}] -#set_property -dict {LOC G10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {i2c_sda[0]}] -#set_property -dict {LOC J14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {i2c_scl[1]}] -#set_property -dict {LOC J15 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {i2c_sda[1]}] +# U12 M24C24 0x51 "FPGA_FRU" +set_property -dict {LOC J14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {i2c_scl}] +set_property -dict {LOC J15 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {i2c_sda}] -#set_false_path -to [get_ports {i2c_sda[*] i2c_scl[*]}] -#set_output_delay 0 [get_ports {i2c_sda[*] i2c_scl[*]}] -#set_false_path -from [get_ports {i2c_sda[*] i2c_scl[*]}] -#set_input_delay 0 [get_ports {i2c_sda[*] i2c_scl[*]}] +set_false_path -to [get_ports {i2c_sda i2c_scl}] +set_output_delay 0 [get_ports {i2c_sda i2c_scl}] +set_false_path -from [get_ports {i2c_sda i2c_scl}] +set_input_delay 0 [get_ports {i2c_sda i2c_scl}] + +# SMBus interface +# PCIe SMBus pins +# U4 PCA9535 0x20 +# U10 M24C24 0x50 "SYS_FRU" +set_property -dict {LOC G9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {smbclk}] +set_property -dict {LOC G10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {smbdat}] + +set_false_path -to [get_ports {smbdat smbclk}] +set_output_delay 0 [get_ports {smbdat smbclk}] +set_false_path -from [get_ports {smbdat smbclk}] +set_input_delay 0 [get_ports {smbdat smbclk}] # PCIe Interface set_property -dict {LOC P2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1 diff --git a/src/cndm/board/AS02MC04/fpga/fpga/Makefile b/src/cndm/board/AS02MC04/fpga/fpga/Makefile index 264fd0c..9599285 100644 --- a/src/cndm/board/AS02MC04/fpga/fpga/Makefile +++ b/src/cndm/board/AS02MC04/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/us/taxi_eth_mac_25g_us.f SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv diff --git a/src/cndm/board/AS02MC04/fpga/fpga_10g/Makefile b/src/cndm/board/AS02MC04/fpga/fpga_10g/Makefile index f4a0620..492fd66 100644 --- a/src/cndm/board/AS02MC04/fpga/fpga_10g/Makefile +++ b/src/cndm/board/AS02MC04/fpga/fpga_10g/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/us/taxi_eth_mac_25g_us.f SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv diff --git a/src/cndm/board/AS02MC04/fpga/rtl/fpga.sv b/src/cndm/board/AS02MC04/fpga/rtl/fpga.sv index f1abd51..03c2f84 100644 --- a/src/cndm/board/AS02MC04/fpga/rtl/fpga.sv +++ b/src/cndm/board/AS02MC04/fpga/rtl/fpga.sv @@ -64,6 +64,18 @@ module fpga # output wire logic led_g, output wire logic led_hb, + /* + * I2C + */ + inout wire logic i2c_scl, + inout wire logic i2c_sda, + + /* + * SMBus + */ + inout wire logic smbclk, + inout wire logic smbdat, + /* * Ethernet: SFP+ */ @@ -76,6 +88,8 @@ module fpga # input wire logic [1:0] sfp_npres, input wire logic [1:0] sfp_tx_fault, input wire logic [1:0] sfp_los, + inout wire logic [1:0] sfp_i2c_scl, + inout wire logic [1:0] sfp_i2c_sda, /* * PCIe @@ -207,6 +221,92 @@ sync_reset_125mhz_inst ( .out(rst_125mhz_int) ); +// GPIO +wire [1:0] sfp_npres_int; +wire [1:0] sfp_tx_fault_int; +wire [1:0] sfp_los_int; +wire [1:0] sfp_i2c_scl_i; +wire [1:0] sfp_i2c_scl_o; +wire [1:0] sfp_i2c_sda_i; +wire [1:0] sfp_i2c_sda_o; + +reg [1:0] sfp_i2c_scl_o_reg; +reg [1:0] sfp_i2c_sda_o_reg; + +always @(posedge pcie_user_clk) begin + sfp_i2c_scl_o_reg <= sfp_i2c_scl_o; + sfp_i2c_sda_o_reg <= sfp_i2c_sda_o; +end + +taxi_sync_signal #( + .WIDTH(5*2), + .N(2) +) +sfp_sync_inst ( + .clk(pcie_user_clk), + .in({sfp_npres, sfp_tx_fault, sfp_los, + sfp_i2c_scl, sfp_i2c_sda}), + .out({sfp_npres_int, sfp_tx_fault_int, sfp_los_int, + sfp_i2c_scl_i, sfp_i2c_sda_i}) +); + +for (genvar n = 0; n < 2; n = n + 1) begin + assign sfp_i2c_scl[n] = sfp_i2c_scl_o_reg[n] ? 1'bz : sfp_i2c_scl_o_reg[n]; + assign sfp_i2c_sda[n] = sfp_i2c_sda_o_reg[n] ? 1'bz : sfp_i2c_sda_o_reg[n]; +end + +wire i2c_scl_i; +wire i2c_scl_o; +wire i2c_sda_i; +wire i2c_sda_o; + +reg i2c_scl_o_reg; +reg i2c_sda_o_reg; + +always @(posedge pcie_user_clk) begin + i2c_scl_o_reg <= i2c_scl_o; + i2c_sda_o_reg <= i2c_sda_o; +end + +taxi_sync_signal #( + .WIDTH(2), + .N(2) +) +i2c_sync_inst ( + .clk(pcie_user_clk), + .in({i2c_scl, i2c_sda}), + .out({i2c_scl_i, i2c_sda_i}) +); + +assign i2c_scl = i2c_scl_o_reg ? 1'bz : i2c_scl_o_reg; +assign i2c_sda = i2c_sda_o_reg ? 1'bz : i2c_sda_o_reg; + +wire smbclk_i; +wire smbclk_o; +wire smbdat_i; +wire smbdat_o; + +reg smbclk_o_reg; +reg smbdat_o_reg; + +always @(posedge pcie_user_clk) begin + smbclk_o_reg <= smbclk_o; + smbdat_o_reg <= smbdat_o; +end + +taxi_sync_signal #( + .WIDTH(2), + .N(2) +) +smb_sync_inst ( + .clk(pcie_user_clk), + .in({smbclk, smbdat}), + .out({smbclk_i, smbdat_i}) +); + +assign smbclk = smbclk_o_reg ? 1'bz : smbclk_o_reg; +assign smbdat = smbdat_o_reg ? 1'bz : smbdat_o_reg; + // Flash wire qspi_clk_int; wire [3:0] qspi_dq_int; @@ -738,6 +838,22 @@ core_inst ( .led_g(led_g), .led_hb(led_hb), + /* + * I2C + */ + .i2c_scl_i(i2c_scl_i), + .i2c_scl_o(i2c_scl_o), + .i2c_sda_i(i2c_sda_i), + .i2c_sda_o(i2c_sda_o), + + /* + * SMBus + */ + .smbclk_i(smbclk_i), + .smbclk_o(smbclk_o), + .smbdat_i(smbdat_i), + .smbdat_o(smbdat_o), + /* * Ethernet: SFP+ */ @@ -748,9 +864,14 @@ core_inst ( .sfp_mgt_refclk_p(sfp_mgt_refclk_p), .sfp_mgt_refclk_n(sfp_mgt_refclk_n), .sfp_mgt_refclk_out(), - .sfp_npres(sfp_npres), - .sfp_tx_fault(sfp_tx_fault), - .sfp_los(sfp_los), + .sfp_npres(sfp_npres_int), + .sfp_tx_fault(sfp_tx_fault_int), + .sfp_los(sfp_los_int), + + .sfp_i2c_scl_i(sfp_i2c_scl_i), + .sfp_i2c_scl_o(sfp_i2c_scl_o), + .sfp_i2c_sda_i(sfp_i2c_sda_i), + .sfp_i2c_sda_o(sfp_i2c_sda_o), /* * PCIe diff --git a/src/cndm/board/AS02MC04/fpga/rtl/fpga_core.sv b/src/cndm/board/AS02MC04/fpga/rtl/fpga_core.sv index c6bbc03..220f896 100644 --- a/src/cndm/board/AS02MC04/fpga/rtl/fpga_core.sv +++ b/src/cndm/board/AS02MC04/fpga/rtl/fpga_core.sv @@ -66,6 +66,22 @@ module fpga_core # output wire logic led_g, output wire logic led_hb, + /* + * I2C + */ + input wire logic i2c_scl_i, + output wire logic i2c_scl_o, + input wire logic i2c_sda_i, + output wire logic i2c_sda_o, + + /* + * SMBus + */ + input wire logic smbclk_i, + output wire logic smbclk_o, + input wire logic smbdat_i, + output wire logic smbdat_o, + /* * Ethernet: SFP+ */ @@ -80,6 +96,11 @@ module fpga_core # input wire logic [1:0] sfp_tx_fault, input wire logic [1:0] sfp_los, + input wire logic [1:0] sfp_i2c_scl_i, + output wire logic [1:0] sfp_i2c_scl_o, + input wire logic [1:0] sfp_i2c_sda_i, + output wire logic [1:0] sfp_i2c_sda_o, + /* * PCIe */ @@ -211,6 +232,42 @@ pyrite_inst ( .qspi_1_cs() ); +// I2C +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'b0; +localparam PLL_IDX = EEPROM_IDX + (EEPROM_EN ? 1 : 0); + +localparam logic MUX_EN = 1'b0; +localparam MUX_CNT = 1; +localparam logic [MUX_CNT-1:0][6:0] MUX_I2C_ADDR = '0; + +// localparam DEV_CNT = PLL_IDX + (PLL_EN ? 1 : 0); +localparam DEV_CNT = 4; +localparam logic [DEV_CNT-1:0][6:0] DEV_I2C_ADDR = {7'h50, 7'h51, 7'h50, 7'h50}; +localparam logic [DEV_CNT-1:0][31:0] DEV_ADDR_CFG = {32'h00_00_0001, 32'h00_00_0001, 32'h00_00_0040, 32'h00_00_0040}; +localparam logic [DEV_CNT-1:0][MUX_CNT-1:0][7:0] DEV_MUX_MASK = '0; + +localparam CYC_PER_US = 250; +localparam PAGE_SEL_DELAY_US = SIM ? 20 : 2000; +localparam I2C_PRESCALE = SIM ? 2 : 250000/(400*4); +localparam I2C_TBUF_CYC = 20; + taxi_axis_if #( .DATA_W(32), .KEEP_EN(1), @@ -220,6 +277,76 @@ taxi_axis_if #( .USER_W(1) ) axis_brd_ctrl_cmd(), axis_brd_ctrl_rsp(); +wire [DEV_CNT-1:0] i2c_dev_sel; + +wire int_i2c_scl_i; +wire int_i2c_scl_o; +wire int_i2c_sda_i; +wire int_i2c_sda_o; + +assign {smbclk_o, i2c_scl_o, sfp_i2c_scl_o} = {DEV_CNT{int_i2c_scl_o}} | ~i2c_dev_sel; +assign {smbdat_o, i2c_sda_o, sfp_i2c_sda_o} = {DEV_CNT{int_i2c_sda_o}} | ~i2c_dev_sel; + +assign int_i2c_scl_i = &({smbclk_i, i2c_scl_i, sfp_i2c_scl_i} | ~i2c_dev_sel); +assign int_i2c_sda_i = &({smbdat_i, i2c_sda_i, sfp_i2c_sda_i} | ~i2c_dev_sel); + +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), + + .CYC_PER_US(CYC_PER_US), + .PAGE_SEL_DELAY_US(PAGE_SEL_DELAY_US), + .I2C_PRESCALE(I2C_PRESCALE), + .I2C_TBUF_CYC(I2C_TBUF_CYC) +) +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(int_i2c_scl_i), + .i2c_scl_o(int_i2c_scl_o), + .i2c_sda_i(int_i2c_sda_i), + .i2c_sda_o(int_i2c_sda_o), + + .dev_sel(i2c_dev_sel), + .dev_rst() +); + // SFP+ wire sfp_tx_clk[2]; wire sfp_tx_rst[2]; @@ -576,7 +703,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/AS02MC04/fpga/tb/fpga_core/Makefile b/src/cndm/board/AS02MC04/fpga/tb/fpga_core/Makefile index 1c9392c..1651671 100644 --- a/src/cndm/board/AS02MC04/fpga/tb/fpga_core/Makefile +++ b/src/cndm/board/AS02MC04/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/us/taxi_eth_mac_25g_us.f VERILOG_SOURCES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f VERILOG_SOURCES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv diff --git a/src/cndm/board/AS02MC04/fpga/tb/fpga_core/test_fpga_core.py b/src/cndm/board/AS02MC04/fpga/tb/fpga_core/test_fpga_core.py index 1cc2c95..6dbc0bb 100644 --- a/src/cndm/board/AS02MC04/fpga/tb/fpga_core/test_fpga_core.py +++ b/src/cndm/board/AS02MC04/fpga/tb/fpga_core/test_fpga_core.py @@ -11,6 +11,7 @@ Authors: import logging import os +import struct import sys import pytest @@ -22,6 +23,7 @@ from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus from cocotbext.eth import XgmiiFrame +from cocotbext.i2c import I2cMemory from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice @@ -328,6 +330,41 @@ class TB: dut.sfp_tx_fault.setimmediatevalue(0) dut.sfp_los.setimmediatevalue(0) + # I2C + self.sfp0_i2c = I2cMemory(sda=dut.sfp_i2c_sda_o[0], sda_o=dut.sfp_i2c_sda_i[0], + scl=dut.sfp_i2c_scl_o[0], scl_o=dut.sfp_i2c_scl_i[0], addr=0x50, size=256) + + self.sfp0_i2c.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.sfp1_i2c = I2cMemory(sda=dut.sfp_i2c_sda_o[1], sda_o=dut.sfp_i2c_sda_i[1], + scl=dut.sfp_i2c_scl_o[1], scl_o=dut.sfp_i2c_scl_i[1], addr=0x50, size=256) + + self.sfp1_i2c.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.eeprom_i2c = I2cMemory(sda=dut.i2c_sda_o, sda_o=dut.i2c_sda_i, + scl=dut.i2c_scl_o, scl_o=dut.i2c_scl_i, addr=0x51, size=2**13) + + self.eeprom_smb = I2cMemory(sda=dut.smbdat_o, sda_o=dut.smbdat_i, + scl=dut.smbclk_o, scl_o=dut.smbclk_i, addr=0x50, size=2**13) + self.loopback_enable = False cocotb.start_soon(self._run_loopback()) @@ -375,6 +412,28 @@ async def run_test(dut): tb.log.info("Init complete") + tb.log.info("Read SFP0") + + rsp = await driver.exec_cmd(struct.pack("