def encode_sequence(seq): output = [] dut = line_coding.Encoder() def pump(): for w in seq: if isinstance(w, Control): yield dut.k[0].eq(1) yield dut.d[0].eq(w.value) else: yield dut.k[0].eq(0) yield dut.d[0].eq(w) yield output.append((yield dut.output[0])) for _ in range(2): yield output.append((yield dut.output[0])) run_simulation(dut, pump()) return output[2:]
def __init__(self, lsb_first=False): self.config_stb = Signal() self.config_reg = Signal(16) self.tx_stb = Signal() self.tx_ack = Signal() self.tx_data = Signal(8) self.submodules.encoder = code_8b10b.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)) ] fsm = FSM() self.submodules += fsm fsm.act( "START", If( self.config_stb, self.tx_ack.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_stb, # the first byte sent is replaced by /S/ self.tx_ack.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_ack.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_stb, self.tx_ack.eq((timer == 0)), timer_en.eq(1), self.encoder.d[0].eq(self.tx_data)).Else( self.tx_ack.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"))
def __init__(self, lsb_first=False): self.config_stb = Signal() self.config_reg = Signal(16) self.tx_stb = Signal() self.tx_ack = Signal() self.tx_data = Signal(8) self.submodules.encoder = code_8b10b.Encoder(lsb_first=lsb_first) # # # 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)) fsm = FSM() self.submodules += fsm fsm.act("START", self.tx_ack.eq(1), # discard TX data if we are in config_reg phase If(self.config_stb, 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_stb, # the first byte of the preamble is replaced by /S/ self.encoder.k[0].eq(1), self.encoder.d[0].eq(K(27, 7)), NextState("DATA") ).Else( 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", self.tx_ack.eq(1), If(self.tx_stb, self.encoder.d[0].eq(self.tx_data) ).Else( # /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") )