diff --git a/liteeth/phy/a7_1000basex.py b/liteeth/phy/a7_1000basex.py index 14d8471..2c31087 100644 --- a/liteeth/phy/a7_1000basex.py +++ b/liteeth/phy/a7_1000basex.py @@ -90,7 +90,7 @@ class A7_1000BASEX(LiteXModule): # RX Byte and Word Alignment Attributes p_ALIGN_COMMA_DOUBLE = "FALSE", p_ALIGN_COMMA_ENABLE = 0b1111111111, - p_ALIGN_COMMA_WORD = 1, + p_ALIGN_COMMA_WORD = 2, p_ALIGN_MCOMMA_DET = "TRUE", p_ALIGN_MCOMMA_VALUE = 0b1010000011, p_ALIGN_PCOMMA_DET = "TRUE", @@ -212,7 +212,7 @@ class A7_1000BASEX(LiteXModule): # CDR Attributes p_RXCDR_CFG = { - 1.25e9 : 0x0001107FE086021101010, + 1.25e9 : 0x0000107FE106001041010, 3.125e9 : 0x0000107FE206001041010, }[self.linerate], p_RXCDR_FR_RESET_ON_EIDLE = 0b0, @@ -505,9 +505,9 @@ class A7_1000BASEX(LiteXModule): o_RXBYTEISALIGNED = Open(), o_RXBYTEREALIGN = Open(), o_RXCOMMADET = Open(), - i_RXCOMMADETEN = 0, - i_RXMCOMMAALIGNEN = 0, - i_RXPCOMMAALIGNEN = 0, + i_RXCOMMADETEN = 0b1, + i_RXMCOMMAALIGNEN = pcs.align, + i_RXPCOMMAALIGNEN = pcs.align, i_RXSLIDE = 0, # Receive Ports - RX Channel Bonding Ports o_RXCHANBONDSEQ = Open(), diff --git a/liteeth/phy/k7_1000basex.py b/liteeth/phy/k7_1000basex.py index d9e9526..a872c73 100644 --- a/liteeth/phy/k7_1000basex.py +++ b/liteeth/phy/k7_1000basex.py @@ -484,9 +484,9 @@ class K7_1000BASEX(LiteXModule): o_RXBYTEISALIGNED = Open(), o_RXBYTEREALIGN = Open(), o_RXCOMMADET = Open(), - i_RXCOMMADETEN = 1, - i_RXMCOMMAALIGNEN = 1, - i_RXPCOMMAALIGNEN = 1, + i_RXCOMMADETEN = 0b1, + i_RXMCOMMAALIGNEN = pcs.align, + i_RXPCOMMAALIGNEN = pcs.align, # Receive Ports - RX Channel Bonding Ports o_RXCHANBONDSEQ = Open(), diff --git a/liteeth/phy/ku_1000basex.py b/liteeth/phy/ku_1000basex.py index 2552fab..4177a12 100644 --- a/liteeth/phy/ku_1000basex.py +++ b/liteeth/phy/ku_1000basex.py @@ -536,7 +536,7 @@ class KU_1000BASEX(LiteXModule): i_RXCHBONDLEVEL = 0b000, i_RXCHBONDMASTER = 0b0, i_RXCHBONDSLAVE = 0b0, - i_RXCOMMADETEN = 0b0, + i_RXCOMMADETEN = 0b1, i_RXDFEAGCCTRL = 0b01, i_RXDFEAGCHOLD = 0b0, i_RXDFEAGCOVRDEN = 0b0, @@ -593,7 +593,7 @@ class KU_1000BASEX(LiteXModule): i_RXLPMLFKLOVRDEN = 0b0, i_RXLPMOSHOLD = 0b0, i_RXLPMOSOVRDEN = 0b0, - i_RXMCOMMAALIGNEN = 0b0, + i_RXMCOMMAALIGNEN = pcs.align, i_RXMONITORSEL = 0b00, i_RXOOBRESET = 0b0, i_RXOSCALRESET = 0b0, @@ -606,7 +606,7 @@ class KU_1000BASEX(LiteXModule): i_RXOSINTTESTOVRDEN = 0b0, i_RXOSOVRDEN = 0b0, i_RXOUTCLKSEL = 0b101, - i_RXPCOMMAALIGNEN = 0b0, + i_RXPCOMMAALIGNEN = pcs.align, i_RXPCSRESET = 0b0, i_RXPD = 0b00, i_RXPHALIGNEN = 0b0, diff --git a/liteeth/phy/pcs_1000basex.py b/liteeth/phy/pcs_1000basex.py index d750d95..7c369d0 100644 --- a/liteeth/phy/pcs_1000basex.py +++ b/liteeth/phy/pcs_1000basex.py @@ -19,244 +19,11 @@ from litex.soc.cores.code_8b10b import K, D, Encoder, Decoder from liteeth.common import * -# PCS TX ------------------------------------------------------------------------------------------- +# PCS Constants / Helpers -------------------------------------------------------------------------- -class PCSTX(LiteXModule): - def __init__(self, lsb_first=False): - self.config_valid = Signal() - self.config_reg = Signal(16) - self.tx_valid = Signal() - self.tx_ready = Signal() - self.tx_data = Signal(8) - - self.encoder = Encoder(lsb_first=lsb_first) - - # SGMII Speed Adaptation - self.sgmii_speed = Signal(2) - - # # # - - parity = Signal() - c_type = Signal() - self.sync += parity.eq(~parity) - - config_reg_buffer = Signal(16) - load_config_reg_buffer = Signal() - self.sync += If(load_config_reg_buffer, config_reg_buffer.eq(self.config_reg)) - - # Timer for SGMII data rates. - timer = Signal(max=1000) - timer_en = Signal() - self.sync += [ - If(~timer_en | (timer == 0), - If(self.sgmii_speed == 0b00, - timer.eq(99) - ).Elif(self.sgmii_speed == 0b01, - timer.eq(9) - ).Elif(self.sgmii_speed == 0b10, - timer.eq(0) - ) - ).Elif(timer_en, - timer.eq(timer - 1) - ) - ] - - self.fsm = fsm = FSM() - fsm.act("START", - If(self.config_valid, - self.tx_ready.eq(1), # Discard TX data if we are in config_reg phase. - load_config_reg_buffer.eq(1), - self.encoder.k[0].eq(1), - self.encoder.d[0].eq(K(28, 5)), - NextState("CONFIG_D") - ).Else( - If(self.tx_valid, - # The first byte sent is replaced by /S/. - self.tx_ready.eq((timer == 0)), - timer_en.eq(1), - self.encoder.k[0].eq(1), - self.encoder.d[0].eq(K(27, 7)), - NextState("DATA") - ).Else( - self.tx_ready.eq(1), # Discard TX data. - self.encoder.k[0].eq(1), - self.encoder.d[0].eq(K(28, 5)), - NextState("IDLE") - ) - ) - ) - fsm.act("CONFIG_D", - If(c_type, - self.encoder.d[0].eq(D(2, 2)) - ).Else( - self.encoder.d[0].eq(D(21, 5)) - ), - NextValue(c_type, ~c_type), - NextState("CONFIG_REG_LSB") - ), - fsm.act("CONFIG_REG_LSB", - self.encoder.d[0].eq(config_reg_buffer[:8]), - NextState("CONFIG_REG_MSB") - ) - fsm.act("CONFIG_REG_MSB", - self.encoder.d[0].eq(config_reg_buffer[8:]), - NextState("START") - ) - fsm.act("IDLE", - # Due to latency in the encoder, we read here the disparity - # just before the K28.5 was sent. K28.5 flips the disparity. - If(self.encoder.disparity[0], - # Correcting /I1/ (D5.6 preserves the disparity). - self.encoder.d[0].eq(D(5, 6)) - ).Else( - # Preserving /I2/ (D16.2 flips the disparity). - self.encoder.d[0].eq(D(16, 2)) - ), - NextState("START") - ) - fsm.act("DATA", - If(self.tx_valid, - self.tx_ready.eq((timer == 0)), - timer_en.eq(1), - self.encoder.d[0].eq(self.tx_data) - ).Else( - self.tx_ready.eq(1), - # /T/ - self.encoder.k[0].eq(1), - self.encoder.d[0].eq(K(29, 7)), - NextState("CARRIER_EXTEND_1") - ) - ) - fsm.act("CARRIER_EXTEND_1", - # /R/ - self.encoder.k[0].eq(1), - self.encoder.d[0].eq(K(23, 7)), - If(parity, - NextState("START") - ).Else( - NextState("CARRIER_EXTEND_2") - ) - ) - fsm.act("CARRIER_EXTEND_2", - # /R/ - self.encoder.k[0].eq(1), - self.encoder.d[0].eq(K(23, 7)), - NextState("START") - ) - -# PCS RX ------------------------------------------------------------------------------------------- - -class PCSRX(LiteXModule): - def __init__(self, lsb_first=False): - self.rx_en = Signal() - self.rx_data = Signal(8) - - self.seen_valid_ci = Signal() - self.seen_config_reg = Signal() - self.config_reg = Signal(16) - - self.decoder = Decoder(lsb_first=lsb_first) - - # SGMII Speed Adaptation. - self.sgmii_speed = Signal(2) - self.sample_en = Signal() - - # # # - - config_reg_lsb = Signal(8) - load_config_reg_lsb = Signal() - load_config_reg_msb = Signal() - self.sync += [ - self.seen_config_reg.eq(0), - If(load_config_reg_lsb, - config_reg_lsb.eq(self.decoder.d) - ), - If(load_config_reg_msb, - self.config_reg.eq(Cat(config_reg_lsb, self.decoder.d)), - self.seen_config_reg.eq(1) - ) - ] - - first_preamble_byte = Signal() - self.comb += self.rx_data.eq(Mux(first_preamble_byte, 0x55, self.decoder.d)) - - # Timer for SGMII data rates. - timer = Signal(max=1000) - timer_en = Signal() - self.sync += [ - If(~timer_en | (timer == 0), - If(self.sgmii_speed == 0b00, - timer.eq(99) - ).Elif(self.sgmii_speed == 0b01, - timer.eq(9) - ).Elif(self.sgmii_speed == 0b10, - timer.eq(0) - ) - ).Elif(timer_en, - timer.eq(timer - 1) - ) - ] - - # Speed adaptation - self.comb += self.sample_en.eq(self.rx_en & (timer == 0)) - - self.fsm = fsm = FSM() - fsm.act("START", - If(self.decoder.k, - If(self.decoder.d == K(28, 5), - NextState("K28_5") - ), - If(self.decoder.d == K(27, 7), - self.rx_en.eq(1), - timer_en.eq(1), - first_preamble_byte.eq(1), - NextState("DATA") - ) - ) - ) - fsm.act("K28_5", - NextState("START"), - If(~self.decoder.k, - If((self.decoder.d == D(21, 5)) | (self.decoder.d == D(2, 2)), - self.seen_valid_ci.eq(1), - NextState("CONFIG_REG_LSB") - ), - If((self.decoder.d == D(5, 6)) | (self.decoder.d == D(16, 2)), - # idle - self.seen_valid_ci.eq(1), - NextState("START") - ), - ) - ) - fsm.act("CONFIG_REG_LSB", - If(self.decoder.k, - If(self.decoder.d == K(27, 7), - self.rx_en.eq(1), - timer_en.eq(1), - first_preamble_byte.eq(1), - NextState("DATA") - ).Else( - NextState("START") # error - ) - ).Else( - load_config_reg_lsb.eq(1), - NextState("CONFIG_REG_MSB") - ) - ) - fsm.act("CONFIG_REG_MSB", - If(~self.decoder.k, - load_config_reg_msb.eq(1) - ), - NextState("START") - ) - fsm.act("DATA", - If(self.decoder.k, - NextState("START") - ).Else( - self.rx_en.eq(1), - timer_en.eq(1) - ) - ) +SGMII_1000MBPS_SPEED = 0b10 +SGMII_100MBPS_SPEED = 0b01 +SGMII_10MBPS_SPEED = 0b00 # PCS Gearbox -------------------------------------------------------------------------------------- @@ -287,8 +54,222 @@ class PCSGearbox(LiteXModule): phase_half.eq(~phase_half), ] +# PCS TX ------------------------------------------------------------------------------------------- + +class PCSTX(LiteXModule): + def __init__(self, lsb_first=False): + self.config_valid = Signal() # Config valid. + self.config_reg = Signal(16) # Config register (16-bit). + self.sgmii_speed = Signal(2) # SGMII speed. + self.sink = sink = stream.Endpoint([("data", 8)]) # Data input. + + self.encoder = Encoder(lsb_first=lsb_first) # 8b/10b Encoder. + + # Signals. + # -------- + count = Signal() # Byte counter for config register. + parity = Signal() # Parity for /R/ extension. + ctype = Signal() # Toggles config type. + + # SGMII Timer. + # ------------ + timer = Signal(max=100) + timer_done = Signal() + timer_enable = Signal() + self.comb += timer_done.eq(timer == 0) + self.sync += [ + timer.eq(timer - 1), + If(~timer_enable | timer_done, + Case(self.sgmii_speed, { + SGMII_10MBPS_SPEED : timer.eq(99), + SGMII_100MBPS_SPEED : timer.eq(9), + SGMII_1000MBPS_SPEED : timer.eq(0), + }) + ) + ] + + # FSM. + # ---- + self.fsm = fsm = FSM() + fsm.act("START", + self.encoder.k[0].eq(1), + self.encoder.d[0].eq(K(28, 5)), + # Wait for valid Config. + If(self.config_valid, + NextValue(count, 0), + NextState("CONFIG-D") + # Wait for valid Data. + ).Else( + If(sink.valid, + self.encoder.d[0].eq(K(27, 7)), # Start-of-packet /S/. + NextState("DATA") + ).Else( + NextState("IDLE") + ) + ) + ) + fsm.act("CONFIG-D", + # Send Configuration Word. + Case(ctype, { + 0b0 : self.encoder.d[0].eq(D(21, 5)), # /C1/. + 0b1 : self.encoder.d[0].eq(D( 2, 2)), # /C2/. + }), + NextValue(ctype, ~ctype), + NextState("CONFIG-REG") + ), + fsm.act("CONFIG-REG", + # Send Configuration Register. + NextValue(count, count + 1), + Case(count, { + 0 : self.encoder.d[0].eq(self.config_reg[:8]), # LSB. + 1 : self.encoder.d[0].eq(self.config_reg[8:]), # MSB. + }), + If(count == (2 - 1), NextState("START")) + ) + fsm.act("IDLE", + # Send Idle words and handle disparity. + Case(self.encoder.disparity[0], { + 0b0 : self.encoder.d[0].eq(D(5, 6)), # /I1/ (Preserves disparity). + 0b1 : self.encoder.d[0].eq(D(16, 2)), # /I2/ (Flips disparity). + }), + NextState("START") + ) + fsm.act("DATA", + # Send Data. + timer_enable.eq(1), + sink.ready.eq(timer_done), + If(sink.valid, + self.encoder.d[0].eq(sink.data), + ).Else( + self.encoder.k[0].eq(1), + self.encoder.d[0].eq(K(29, 7)), # End-of-frame /T/. + NextState("CARRIER-EXTEND") + ) + ) + fsm.act("CARRIER-EXTEND", + # Extend carrier with /R/ symbols. + self.encoder.k[0].eq(1), + self.encoder.d[0].eq(K(23, 7)), # Carrier Extend /R/. + If(parity, + NextState("START") + ) + ) + self.sync += parity.eq(~parity) # Toggle parity for /R/ extension. + +# PCS RX ------------------------------------------------------------------------------------------- + +class PCSRX(LiteXModule): + def __init__(self, lsb_first=False): + self.rx_en = Signal() + self.rx_data = Signal(8) + self.sample_en = Signal() + + self.seen_valid_ci = Signal() + self.seen_config_reg = Signal() + self.config_reg = Signal(16) + + self.decoder = Decoder(lsb_first=lsb_first) + + # SGMII Speed Adaptation. + self.sgmii_speed = Signal(2) + + # # # + + # Signals. + # -------- + count = Signal() # Byte counter for config register. + + # SGMII Timer. + # ------------ + timer = Signal(max=100) + timer_enable = Signal() + timer_done = Signal() + self.comb += timer_done.eq(timer == 0) + self.sync += [ + timer.eq(timer - 1), + If(~timer_enable | timer_done, + Case(self.sgmii_speed, { + SGMII_10MBPS_SPEED : timer.eq(99), + SGMII_100MBPS_SPEED : timer.eq( 9), + SGMII_1000MBPS_SPEED : timer.eq( 0), + }) + ) + ] + + # Speed adaptation + self.comb += self.sample_en.eq(self.rx_en & timer_done) + + # FSM. + # ---- + self.fsm = fsm = FSM() + fsm.act("START", + # Wait for a K-character. + If(self.decoder.k, + # K-character is Config or Idle K28.5. + If(self.decoder.d == K(28, 5), + NextValue(count, 0), + NextState("CONFIG-D-OR-IDLE") + ), + # K-character is Start-of-packet /S/. + If(self.decoder.d == K(27, 7), + timer_enable.eq(1), + self.rx_en.eq(1), + self.rx_data.eq(0x55), # First Preamble Byte. + NextState("DATA") + ) + ) + ) + fsm.act("CONFIG-D-OR-IDLE", + NextState("ERROR"), + If(~self.decoder.k, + # Check for Configuration Word. + If((self.decoder.d == D(21, 5)) | # /C1/. + (self.decoder.d == D( 2, 2)), # /C2/. + self.seen_valid_ci.eq(1), + NextState("CONFIG-REG") + ), + # Check for Idle Word. + If((self.decoder.d == D( 5, 6)) | # /I1/. + (self.decoder.d == D(16, 2)), # /I2/. + self.seen_valid_ci.eq(1), + NextState("START") + ) + ) + ) + fsm.act("CONFIG-REG", + NextState("ERROR"), + If(~self.decoder.k, + # Receive for Configuration Register. + NextState("CONFIG-REG"), + NextValue(count, count + 1), + Case(count, { + 0b0 : NextValue(self.config_reg[:8], self.decoder.d), # LSB. + 0b1 : NextValue(self.config_reg[8:], self.decoder.d), # MSB. + }), + If(count == (2 - 1), + self.seen_config_reg.eq(1), + NextState("START") + ) + ) + ) + fsm.act("DATA", + NextState("START"), + If(~self.decoder.k, + # Receive Data. + timer_enable.eq(1), + self.rx_en.eq(1), + self.rx_data.eq(self.decoder.d), + NextState("DATA") + ) + ) + fsm.act("ERROR", + NextState("START") + ) + # PCS ---------------------------------------------------------------------------------------------- +# FIXME: Needs similar cleanup than PCSTX/RX. + class PCS(LiteXModule): def __init__(self, lsb_first=False, check_period=6e-3, more_ack_time=10e-3): self.tx = ClockDomainsRenamer("eth_tx")(PCSTX(lsb_first=lsb_first)) @@ -301,18 +282,16 @@ class PCS(LiteXModule): self.link_up = Signal() self.restart = Signal() + self.align = Signal() self.lp_abi = BusSynchronizer(16, "eth_rx", "eth_tx") # # # - - # Endpoint interface. - self.comb += [ - self.tx.tx_valid.eq(self.sink.valid), - self.sink.ready.eq(self.tx.tx_ready), - self.tx.tx_data.eq(self.sink.data), - ] + # Sink -> TX. + self.comb += self.sink.connect(self.tx.sink, omit={"last_be", "error"}) + + # RX -> Source. rx_en_d = Signal() self.sync.eth_rx += [ rx_en_d.eq(self.rx.rx_en), @@ -321,11 +300,12 @@ class PCS(LiteXModule): ] self.comb += self.source.last.eq(~self.rx.rx_en & rx_en_d) - # Main module. + # Seen Valid Synchronizer. seen_valid_ci = PulseSynchronizer("eth_rx", "eth_tx") self.submodules += seen_valid_ci self.comb += seen_valid_ci.i.eq(self.rx.seen_valid_ci) + # Checker. checker_max_val = ceil(check_period*125e6) checker_counter = Signal(max=checker_max_val+1) checker_tick = Signal() @@ -352,8 +332,8 @@ class PCS(LiteXModule): # Detect that link is down: # - 1000BASE-X : linkup can be inferred by non-empty reg. # - SGMII : linkup is indicated with bit 15. - linkdown.eq((self.lp_abi.o[0] & ~self.lp_abi.o[15]) | (self.lp_abi.o == 0)), - self.tx.sgmii_speed.eq(Mux(self.lp_abi.o[0], + linkdown.eq((is_sgmii & ~self.lp_abi.o[15]) | (self.lp_abi.o == 0)), + self.tx.sgmii_speed.eq(Mux(is_sgmii, self.lp_abi.o[10:12], 0b10)), self.rx.sgmii_speed.eq(Mux(self.lp_abi.i[0], self.lp_abi.i[10:12], 0b10)) @@ -363,7 +343,7 @@ class PCS(LiteXModule): self.tx.config_reg.eq(Mux(tx_config_empty, 0, (is_sgmii) | # SGMII: SGMII in-use (~is_sgmii << 5) | # 1000BASE-X: Full-duplex - (Mux(self.lp_abi.o[0], # SGMII: Speed + (Mux(is_sgmii, # SGMII: Speed self.lp_abi.o[10:12], 0) << 10) | (is_sgmii << 12) | # SGMII: Full-duplex (autoneg_ack << 14) | # SGMII/1000BASE-X: Acknowledge Bit @@ -391,11 +371,12 @@ class PCS(LiteXModule): ) # ABILITY_DETECT fsm.act("AUTONEG_WAIT_ABI", + self.align.eq(1), self.tx.config_valid.eq(1), If(rx_config_reg_abi.o, NextState("AUTONEG_WAIT_ACK") ), - If(checker_tick & ~checker_ok, + If((checker_tick & ~checker_ok) | rx_config_reg_ack.o, self.restart.eq(1), NextState("AUTONEG_BREAKLINK") ) diff --git a/liteeth/phy/usp_gth_1000basex.py b/liteeth/phy/usp_gth_1000basex.py index 04f253f..09fe8bf 100644 --- a/liteeth/phy/usp_gth_1000basex.py +++ b/liteeth/phy/usp_gth_1000basex.py @@ -612,7 +612,7 @@ class USP_GTH_1000BASEX(LiteXModule): i_RXCHBONDLEVEL = 0b000, i_RXCHBONDMASTER = 0b0, i_RXCHBONDSLAVE = 0b0, - i_RXCOMMADETEN = 0b0, + i_RXCOMMADETEN = 0b1, i_RXDFEAGCCTRL = 0b01, i_RXDFEAGCHOLD = 0b0, i_RXDFEAGCOVRDEN = 0b0, @@ -668,14 +668,14 @@ class USP_GTH_1000BASEX(LiteXModule): i_RXLPMLFKLOVRDEN = 0b0, i_RXLPMOSHOLD = 0b0, i_RXLPMOSOVRDEN = 0b0, - i_RXMCOMMAALIGNEN = 0b0, + i_RXMCOMMAALIGNEN = pcs.align, i_RXMONITORSEL = 0b00, i_RXOOBRESET = 0b0, i_RXOSCALRESET = 0b0, i_RXOSHOLD = 0b0, i_RXOSOVRDEN = 0b0, i_RXOUTCLKSEL = 0b101, - i_RXPCOMMAALIGNEN = 0b0, + i_RXPCOMMAALIGNEN = pcs.align, i_RXPCSRESET = 0b0, i_RXPD = 0b00, i_RXPHALIGNEN = 0b0, diff --git a/liteeth/phy/usp_gty_1000basex.py b/liteeth/phy/usp_gty_1000basex.py index 5e1f3c8..4125fae 100644 --- a/liteeth/phy/usp_gty_1000basex.py +++ b/liteeth/phy/usp_gty_1000basex.py @@ -641,7 +641,7 @@ class USP_GTY_1000BASEX(LiteXModule): i_RXCHBONDSLAVE = 0b0, i_RXCKCALRESET = 0b0, i_RXCKCALSTART = 0b0, - i_RXCOMMADETEN = 0b0, + i_RXCOMMADETEN = 0b1, i_RXDFEAGCHOLD = 0b0, i_RXDFEAGCOVRDEN = 0b0, i_RXDFECFOKFCNUM = 0b0, @@ -704,14 +704,14 @@ class USP_GTY_1000BASEX(LiteXModule): i_RXLPMLFKLOVRDEN = 0b0, i_RXLPMOSHOLD = 0b0, i_RXLPMOSOVRDEN = 0b0, - i_RXMCOMMAALIGNEN = 0b0, + i_RXMCOMMAALIGNEN = pcs.align, i_RXMONITORSEL = 0b00, i_RXOOBRESET = 0b0, i_RXOSCALRESET = 0b0, i_RXOSHOLD = 0b0, i_RXOSOVRDEN = 0b0, i_RXOUTCLKSEL = 0b101, - i_RXPCOMMAALIGNEN = 0b0, + i_RXPCOMMAALIGNEN = pcs.align, i_RXPCSRESET = 0b0, i_RXPD = 0b00, i_RXPHALIGN = 0b0, diff --git a/liteeth/phy/v7_1000basex.py b/liteeth/phy/v7_1000basex.py index 7b899d6..d5bbdf4 100644 --- a/liteeth/phy/v7_1000basex.py +++ b/liteeth/phy/v7_1000basex.py @@ -479,9 +479,9 @@ class V7_1000BASEX(LiteXModule): o_RXBYTEISALIGNED = Open(), o_RXBYTEREALIGN = Open(), o_RXCOMMADET = Open(), - i_RXCOMMADETEN = 1, - i_RXMCOMMAALIGNEN = 1, - i_RXPCOMMAALIGNEN = 1, + i_RXCOMMADETEN = 0b1, + i_RXMCOMMAALIGNEN = pcs.align, + i_RXPCOMMAALIGNEN = pcs.align, # Receive Ports - RX Channel Bonding Ports o_RXCHANBONDSEQ = Open(),