From 907f9d0d6e3eedf8b57d54c28acb9a5a12cf4e68 Mon Sep 17 00:00:00 2001 From: Reinier van der Walle <walle@astron.nl> Date: Mon, 19 Dec 2022 16:43:54 +0100 Subject: [PATCH] corrected tb and added PCS registers --- libraries/io/eth/eth.peripheral.yaml | 102 +++++++++++++++++++ libraries/technology/tse/tb_tech_tse_pkg.vhd | 96 ++++++++++++++++- libraries/technology/tse/tech_tse_pkg.vhd | 1 + 3 files changed, 196 insertions(+), 3 deletions(-) diff --git a/libraries/io/eth/eth.peripheral.yaml b/libraries/io/eth/eth.peripheral.yaml index 3bf3936d47..70a08c66a5 100644 --- a/libraries/io/eth/eth.peripheral.yaml +++ b/libraries/io/eth/eth.peripheral.yaml @@ -463,6 +463,108 @@ peripherals: address_offset: 0x3E * MM_BUS_SIZE access_mode: RO + - - field_name: pcs_control + field_description: | + "PCS control register. Use this register to control and + configure the PCS function." + address_offset: ( 0x80 + 0x00 ) * MM_BUS_SIZE + mm_width: 16 + access_mode: RW + + - - field_name: pcs_status + field_description: | + "Status register. Provides information on the operation of the + PCS function." + address_offset: ( 0x80 + 0x01 ) * MM_BUS_SIZE + mm_width: 16 + access_mode: RO + + - - field_name: pcs_phy_identifier_msb + field_description: | + "32-bit PHY identification register. This register is set to the + value of the PHY ID parameter. Bits 31:16 are written to + word offset 0x02. Bits 15:0 are written to word offset 0x03." + address_offset: ( 0x80 + 0x02 ) * MM_BUS_SIZE + mm_width: 16 + access_mode: RO + + - - field_name: pcs_phy_identifier_lsb + field_description: | + "see pcs_phy_identifier_msb" + address_offset: ( 0x80 + 0x03 ) * MM_BUS_SIZE + mm_width: 16 + access_mode: RO + + - - field_name: pcs_dev_ability + field_description: | + "Use this register to advertise the device abilities to a link + partner during auto-negotiation. In SGMII MAC mode, the + PHY does not use this register during auto-negotiation." + address_offset: ( 0x80 + 0x04 ) * MM_BUS_SIZE + mm_width: 16 + access_mode: RW + + - - field_name: pcs_partner_ability + field_description: | + "Contains the device abilities advertised by the link partner + during auto-negotiation." + address_offset: ( 0x80 + 0x05 ) * MM_BUS_SIZE + mm_width: 16 + access_mode: RO + + - - field_name: pcs_an_expansion + field_description: | + "Auto-negotiation expansion register. Contains the PCS + function capability and auto-negotiation status." + address_offset: ( 0x80 + 0x06 ) * MM_BUS_SIZE + mm_width: 16 + access_mode: RO + + - - field_name: pcs_scratch + field_description: | + "Scratch register. Provides a memory location to test register + read and write operations." + address_offset: ( 0x80 + 0x10 ) * MM_BUS_SIZE + mm_width: 16 + access_mode: RW + + - - field_name: pcs_rev + field_description: | + "The PCS function revision. Always set to the current version + of the IP." + address_offset: ( 0x80 + 0x11 ) * MM_BUS_SIZE + mm_width: 16 + access_mode: RO + + - - field_name: pcs_link_timer_lsb + field_description: | + "21-bit auto-negotiation link timer. Set the link timer value + from 0 to 16 ms in 8 ns steps (125 MHz clock periods). The + reset value sets the link timer to 10 ms. + . Bits 15:0 are written to word offset 0x12. Bit 0 of word + offset 0x12 is always set to 0, thus any value written to + it is ignored. + . Bits 20:16 are written to word offset 0x13. The + remaining bits are reserved and always set to 0." + address_offset: ( 0x80 + 0x12 ) * MM_BUS_SIZE + mm_width: 16 + access_mode: RW + + - - field_name: pcs_link_timer_msb + field_description: | + "see pcs_link_timer_lsb" + address_offset: ( 0x80 + 0x13 ) * MM_BUS_SIZE + mm_width: 16 + access_mode: RW + + - - field_name: pcs_if_mode + field_description: | + "Interface mode. Use this register to specify the operating + mode of the PCS function; 1000BASE-X or SGMII." + address_offset: ( 0x80 + 0x14 ) * MM_BUS_SIZE + mm_width: 16 + access_mode: RW + - - field_name: tx_period field_description: | "Clock period for timestamp adjustment on the transmit diff --git a/libraries/technology/tse/tb_tech_tse_pkg.vhd b/libraries/technology/tse/tb_tech_tse_pkg.vhd index 43c6110b8d..0fcdd7b552 100644 --- a/libraries/technology/tse/tb_tech_tse_pkg.vhd +++ b/libraries/technology/tse/tb_tech_tse_pkg.vhd @@ -113,6 +113,10 @@ PACKAGE BODY tb_tech_tse_pkg IS RETURN pcs_addr * 2 + c_tech_tse_byte_addr_pcs_offset; END func_map_pcs_addr; + FUNCTION func_map_pcs_addr_arria10(pcs_addr : NATURAL) RETURN NATURAL IS + BEGIN + RETURN pcs_addr + c_tech_tse_reg_addr_pcs_offset; + END func_map_pcs_addr_arria10; ------------------------------------------------------------------------------ -- GLOBAL ITEMS @@ -252,7 +256,7 @@ PACKAGE BODY tb_tech_tse_pkg IS WAIT UNTIL rising_edge(mm_clk); END proc_tech_tse_setup_stratixiv; - -- It is noticed that the arria10 variant needs longer setup time. + -- It is noticed that the arria10 variant needs longer setup time and uses the mac register space with offset 0x80 to access the PCS registers. PROCEDURE proc_tech_tse_setup_arria10(CONSTANT c_promis_en : IN BOOLEAN; CONSTANT c_tse_tx_fifo_depth : IN NATURAL; CONSTANT c_tse_rx_fifo_depth : IN NATURAL; @@ -262,8 +266,94 @@ PACKAGE BODY tb_tech_tse_pkg IS SIGNAL mm_clk : IN STD_LOGIC; SIGNAL mm_miso : IN t_mem_miso; SIGNAL mm_mosi : OUT t_mem_mosi) IS - BEGIN - proc_tech_tse_setup_stratixiv(c_promis_en, c_tse_tx_fifo_depth, c_tse_rx_fifo_depth, c_tx_ready_latency, src_mac, psc_access, mm_clk, mm_miso, mm_mosi); + CONSTANT c_mac0 : INTEGER := TO_SINT(hton(src_mac(47 DOWNTO 16), 4)); + CONSTANT c_mac1 : INTEGER := TO_SINT(hton(src_mac(15 DOWNTO 0), 2)); + BEGIN + -- PSC control + psc_access <= '1'; + proc_mem_mm_bus_rd(func_map_pcs_addr_arria10(16#11#), mm_clk, mm_miso, mm_mosi); -- REV --> 0x0901 + proc_mem_mm_bus_wr(func_map_pcs_addr_arria10(16#14#), 16#0008#, mm_clk, mm_miso, mm_mosi); -- IF_MODE <-- Force 1GbE, no autonegatiation + proc_mem_mm_bus_rd(func_map_pcs_addr_arria10(16#00#), mm_clk, mm_miso, mm_mosi); -- CONTROL --> 0x1140 + proc_mem_mm_bus_rd(func_map_pcs_addr_arria10(16#01#), mm_clk, mm_miso, mm_mosi); -- STATUS --> 0x000D + proc_mem_mm_bus_wr(func_map_pcs_addr_arria10(16#00#), 16#0140#, mm_clk, mm_miso, mm_mosi); -- CONTROL <-- Auto negotiate disable + psc_access <= '0'; + + -- MAC control + proc_mem_mm_bus_rd(16#000#, mm_clk, mm_miso, mm_mosi); -- REV --> CUST_VERSION & 0x0901 + IF c_promis_en=FALSE THEN + proc_mem_mm_bus_wr(16#002#, 16#0100004B#, mm_clk, mm_miso, mm_mosi); + ELSE + proc_mem_mm_bus_wr(16#002#, 16#0100005B#, mm_clk, mm_miso, mm_mosi); + END IF; + -- COMMAND_CONFIG <-- + -- Only the bits relevant to UniBoard are explained here, others are 0 + -- [ 0] = TX_ENA = 1, enable tx datapath + -- [ 1] = RX_ENA = 1, enable rx datapath + -- [ 2] = XON_GEN = 0 + -- [ 3] = ETH_SPEED = 1, enable 1GbE operation + -- [ 4] = PROMIS_EN = 0, when 1 then receive all frames + -- [ 5] = PAD_EN = 0, when 1 enable receive padding removal (requires ethertype=payload length) + -- [ 6] = CRC_FWD = 1, enable receive CRC forward + -- [ 7] = PAUSE_FWD = 0 + -- [ 8] = PAUSE_IGNORE = 0 + -- [ 9] = TX_ADDR_INS = 0, when 1 then MAX overwrites tx SRC MAC with mac_0,1 or one of the supplemental mac + -- [ 10] = HD_ENA = 0 + -- [ 11] = EXCESS_COL = 0 + -- [ 12] = LATE_COL = 0 + -- [ 13] = SW_RESET = 0, when 1 MAC disables tx and rx, clear statistics and flushes receive FIFO + -- [ 14] = MHAS_SEL = 0, select multicast address resolutions hash-code mode + -- [ 15] = LOOP_ENA = 0 + -- [18-16] = TX_ADDR_SEL[2:0] = 000, TX_ADDR_INS insert mac_0,1 or one of the supplemental mac + -- [ 19] = MAGIC_EN = 0 + -- [ 20] = SLEEP = 0 + -- [ 21] = WAKEUP = 0 + -- [ 22] = XOFF_GEN = 0 + -- [ 23] = CNT_FRM_ENA = 0 + -- [ 24] = NO_LGTH_CHECK = 1, when 0 then check payload length of received frames (requires ethertype=payload length) + -- [ 25] = ENA_10 = 0 + -- [ 26] = RX_ERR_DISC = 0, when 1 then discard erroneous frames (requires store and forward mode, so rx_section_full=0) + -- when 0 then pass on with rx_err[0]=1 + -- [ 27] = DISABLE_RD_TIMEOUT = 0 + -- [30-28] = RSVD = 000 + -- [ 31] = CNT_RESET = 0, when 1 clear statistics + proc_mem_mm_bus_wr(16#03#, c_mac0, mm_clk, mm_miso, mm_mosi); -- MAC_0 + proc_mem_mm_bus_wr(16#04#, c_mac1, mm_clk, mm_miso, mm_mosi); -- MAC_1 <-- SRC_MAC = 12-34-56-78-9A-BC + proc_mem_mm_bus_wr(16#17#, 16#0000000C#, mm_clk, mm_miso, mm_mosi); -- TX_IPG_LENGTH <-- interpacket gap = 12 + --proc_mem_mm_bus_wr(16#05#, 16#000005EE#, mm_clk, mm_miso, mm_mosi); -- FRM_LENGTH <-- receive max frame length = 1518 + proc_mem_mm_bus_wr(16#05#, 16#0000233A#, mm_clk, mm_miso, mm_mosi); -- FRM_LENGTH <-- receive max frame length = 9018 + + -- FIFO legenda: + -- . Tx section full = There is enough data in the FIFO to start reading it, when 0 then store and forward. + -- . Rx section full = There is enough data in the FIFO to start reading it, when 0 then store and forward. + -- . Tx section empty = There is not much empty space anymore in the FIFO, warn user via ff_tx_septy + -- . Rx section empty = There is not much empty space anymore in the FIFO, inform remote device via XOFF flow control + -- . Tx almost full = Assert ff_tx_a_full and deassert ff_tx_rdy. Furthermore TX_ALMOST_FULL = c_tx_ready_latency+3, + -- so choose 3 for zero tx ready latency + -- . Rx almost full = Assert ff_rx_a_full and if the user is not ready ff_rx_rdy then: + -- --> break off the reception with an error to avoid FIFO overflow + -- . Tx almost empty = Assert ff_tx_a_empty and if the FIFO does not contain a eop yet then: + -- --> break off the transmission with an error to avoid FIFO underflow + -- . Rx almost empty = Assert ff_rx_a_empty + -- Typical FIFO values: + -- . TX_SECTION_FULL = 16 > 8 = TX_ALMOST_EMPTY + -- . RX_SECTION_FULL = 16 > 8 = RX_ALMOST_EMPTY + -- . TX_SECTION_EMPTY = D-16 < D-3 = Tx FIFO depth - TX_ALMOST_FULL + -- . RX_SECTION_EMPTY = D-16 < D-8 = Rx FIFO depth - RX_ALMOST_FULL + -- . c_tse_tx_fifo_depth = 1 M9K = 256*32b = 1k * 8b is sufficient when the Tx user respects ff_tx_rdy, to store a complete + -- ETH packet would require 1518 byte, so 2 M9K = 2k * 8b + -- . c_tse_rx_fifo_depth = 1 M9K = 256*32b = 1k * 8b is sufficient when the Rx user ff_rx_rdy is sufficiently active + proc_mem_mm_bus_wr(16#07#, c_tse_rx_fifo_depth-16, mm_clk, mm_miso, mm_mosi); -- RX_SECTION_EMPTY <-- default FIFO depth - 16, >3 + proc_mem_mm_bus_wr(16#08#, 16, mm_clk, mm_miso, mm_mosi); -- RX_SECTION_FULL <-- default 16 + proc_mem_mm_bus_wr(16#09#, c_tse_tx_fifo_depth-16, mm_clk, mm_miso, mm_mosi); -- TX_SECTION_EMPTY <-- default FIFO depth - 16, >3 + proc_mem_mm_bus_wr(16#0A#, 16, mm_clk, mm_miso, mm_mosi); -- TX_SECTION_FULL <-- default 16, >~ 8 otherwise no tx + proc_mem_mm_bus_wr(16#0B#, 8, mm_clk, mm_miso, mm_mosi); -- RX_ALMOST_EMPTY <-- default 8 + proc_mem_mm_bus_wr(16#0C#, 8, mm_clk, mm_miso, mm_mosi); -- RX_ALMOST_FULL <-- default 8 + proc_mem_mm_bus_wr(16#0D#, 8, mm_clk, mm_miso, mm_mosi); -- TX_ALMOST_EMPTY <-- default 8 + proc_mem_mm_bus_wr(16#0E#, c_tx_ready_latency+3, mm_clk, mm_miso, mm_mosi); -- TX_ALMOST_FULL <-- default 3 + + proc_mem_mm_bus_rd(16#3A#, mm_clk, mm_miso, mm_mosi); -- TX_CMD_STAT --> 0x00040000 : [18]=1 TX_SHIFT16, [17]=0 OMIT_CRC + proc_mem_mm_bus_rd(16#3B#, mm_clk, mm_miso, mm_mosi); -- RX_CMD_STAT --> 0x02000000 : [25]=1 RX_SHIFT16 + WAIT FOR 10 us; WAIT UNTIL rising_edge(mm_clk); END proc_tech_tse_setup_arria10; diff --git a/libraries/technology/tse/tech_tse_pkg.vhd b/libraries/technology/tse/tech_tse_pkg.vhd index 603b85d225..2f4a8327c3 100644 --- a/libraries/technology/tse/tech_tse_pkg.vhd +++ b/libraries/technology/tse/tech_tse_pkg.vhd @@ -28,6 +28,7 @@ PACKAGE tech_tse_pkg IS CONSTANT c_tech_tse_reg_addr_w : NATURAL := 8; -- = max 256 MAC registers CONSTANT c_tech_tse_byte_addr_w : NATURAL := c_tech_tse_reg_addr_w + 2; + CONSTANT c_tech_tse_reg_addr_pcs_offset : NATURAL := 16#80#; -- table 4.8, 4.9 in ug_ethernet.pdf CONSTANT c_tech_tse_byte_addr_pcs_offset : NATURAL := 16#200#; -- table 4.8, 4.9 in ug_ethernet.pdf CONSTANT c_tech_tse_data_w : NATURAL := c_word_w; -- = 32 -- GitLab