class _K2MMPacketParser(Module): def __init__(self, dw=32, bufferrized=True, fifo_depth=256): # TX/RX packet ptx = K2MMPacketTX(dw=dw) ptx = SkidBufferInsert({"sink": DIR_SINK})(ptx) self.submodules.ptx = ptx prx = K2MMPacketRX(dw=dw) prx = SkidBufferInsert({"source": DIR_SOURCE})(prx) self.submodules.prx = prx self.sink, self.source = ptx.sink, prx.source from cores.xpm_fifo import XPMStreamFIFO if bufferrized: self.submodules.tx_buffer = tx_buffer = SyncFIFO( ptx.source.description, depth=fifo_depth, buffered=True) self.submodules.rx_buffer = rx_buffer = SyncFIFO( prx.sink.description, depth=fifo_depth, buffered=True) self.comb += [ ptx.source.connect(tx_buffer.sink), rx_buffer.source.connect(prx.sink) ] self.source_packet_tx = Endpoint(tx_buffer.source.description) self.sink_packet_rx = Endpoint(rx_buffer.sink.description) self.comb += [ self.sink_packet_rx.connect(rx_buffer.sink), tx_buffer.source.connect(self.source_packet_tx) ] else: self.source_packet_tx = ptx.source self.sink_packet_rx = prx.sink
class K2MM(Module): def __init__(self, dw=32, cd="sys"): # Packet parser self.submodules.packet = packet = _K2MMPacketParser(dw=dw) self.source_packet_tx = Endpoint(packet.source_packet_tx.description, name="source_packet_tx") self.sink_packet_rx = Endpoint(packet.sink_packet_rx.description, name="sink_packet_rx") self.comb += [ packet.source_packet_tx.connect(self.source_packet_tx), self.sink_packet_rx.connect(packet.sink_packet_rx) ] # function modules self.submodules.probe = probe = K2MMProbe(dw=dw) self.submodules.tester = tester = K2MMTester(dw=dw) self.source_tester_status = Endpoint(tester.source_status.description) self.sink_tester_ctrl = Endpoint(tester.sink_ctrl.description) self.comb += [ tester.source_status.connect(self.source_tester_status), self.sink_tester_ctrl.connect(tester.sink_ctrl) ] # Arbitrate source endpoints self.submodules.arbiter = arbiter = Arbiter([ probe.source, tester.source, ], packet.sink) # Dispatcher self.submodules.dispatcher = dispatcher = Dispatcher( packet.source, [tester.sink, probe.sink]) self.comb += [dispatcher.sel.eq(packet.source.pf)] def get_ios(self): return [ self.source_packet_tx, self.sink_packet_rx, self.source_tester_status, self.sink_tester_ctrl, ]
class K2MMTester(Module): def __init__(self, dw=32, max_latency=65536): self.sink = sink = Endpoint(K2MMPacket.packet_user_description(dw)) self.source = source = Endpoint(K2MMPacket.packet_user_description(dw)) # # # self.submodules.tfg = tfg = TestFrameGenerator(data_width=dw) self.sink_ctrl = Endpoint(tfg.sink_ctrl.description) self.submodules.tfc = tfc = TestFrameChecker(dw=dw) self.comb += [sink.connect(tfc.sink), tfg.source.connect(source)] self.latency = latency = Signal(max=max_latency) fsm = FSM(reset_state="STOP") fsm.act( "STOP", self.sink_ctrl.connect(tfg.sink_ctrl), If( tfg.sink_ctrl.valid & tfg.sink_ctrl.ready, NextState("COUNT_LATENCY"), NextValue(latency, 0), ), ) fsm.act( "COUNT_LATENCY", NextValue(latency, latency + 1), tfc.source_tf_status.ready.eq(1), If(tfc.source_tf_status.valid == 1, NextState("STOP")), ) self.submodules += fsm self.source_status = Endpoint( EndpointDescription( tfc.source_tf_status.description.payload_layout + [("latency", latency.nbits)], tfc.source_tf_status.description.param_layout)) self.comb += [ tfc.source_tf_status.connect(self.source_status, omit={"latency"}), self.source_status.latency.eq(latency), self.source_status.ready.eq(1) ]
def __init__(self, args, platform): self.submodules.crg = CRG(platform) counter = Signal(24) ulpi_pads = platform.request("usb0") ulpi_data = TSTriple(8) reset = Signal() self.comb += ulpi_pads.rst.eq(~reset) luna_wrapper(platform, USBSerialDevice()) usb_tx = Endpoint([("data", 8)]) usb_rx = Endpoint([("data", 8)]) self.specials += ulpi_data.get_tristate(ulpi_pads.data) self.params = dict( # Clock / Reset i_clk_usb = ClockSignal("usb"), i_clk_sync = ClockSignal("sys"), i_rst_sync = ResetSignal(), o_ulpi__data__o = ulpi_data.o, o_ulpi__data__oe = ulpi_data.oe, i_ulpi__data__i = ulpi_data.i, o_ulpi__clk__o = ulpi_pads.clk, o_ulpi__stp = ulpi_pads.stp, i_ulpi__nxt__i = ulpi_pads.nxt, i_ulpi__dir__i = ulpi_pads.dir, o_ulpi__rst = reset, # Tx stream (Data out to computer) o_tx__ready = usb_tx.ready, i_tx__valid = usb_tx.valid, i_tx__first = usb_tx.first, i_tx__last = usb_tx.last, i_tx__payload = usb_tx.data, # Rx Stream (Data in from a Computer) i_rx__ready = usb_rx.ready, o_rx__valid = usb_rx.valid, o_rx__first = usb_rx.first, o_rx__last = usb_rx.last, o_rx__payload = usb_rx.data, ) # Loopback toggle case self.comb += [ # Litex ordering when connecting streams: # [Source] -> connect -> [Sink] usb_rx.connect(usb_tx), # If we have [A-Za-z] toggle case If(((usb_rx.data >= ord('A')) & (usb_rx.data <= ord('Z'))) | ((usb_rx.data >= ord('a')) & (usb_rx.data <= ord('z'))), usb_tx.data.eq(usb_rx.data ^ 0x20) ) ] # ButterStick r1.0 requires # VccIO set on port 2 before ULPI signals work. vccio_pins = platform.request("vccio_ctrl") pwm_timer = Signal(14) self.sync += pwm_timer.eq(pwm_timer + 1) self.comb += [ vccio_pins.pdm[0].eq(pwm_timer < int(2**14 * (0.1))), # 3.3v vccio_pins.pdm[1].eq(pwm_timer < int(2**14 * (0.1))), # 3.3v vccio_pins.pdm[2].eq(pwm_timer < int(2**14 * (0.70))), # 1.8v vccio_pins.en.eq(1), ] self.sync += [ counter.eq(counter + 1) ] self.comb += [ platform.request("leda").eq(1), platform.request("ledc").eq(counter[23]) ]
def __init__(self, args, platform): self.submodules.crg = CRG(platform) platform = platform # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, 60e6, ident = "LiteX SoC", ident_version = True, cpu_type = "serv", integrated_rom_size = 32 * 1024, uart_name = "stream", ) cpu_release = Signal() self.comb += self.cpu.reset.eq(~cpu_release) counter = Signal(24) ulpi_pads = platform.request("usb0") ulpi_data = TSTriple(8) reset = Signal() self.comb += ulpi_pads.rst.eq(~reset) luna_wrapper(platform, USBSerialDevice()) usb_tx = Endpoint([("data", 8)]) usb_rx = Endpoint([("data", 8)]) self.specials += ulpi_data.get_tristate(ulpi_pads.data) self.params = dict( # Clock / Reset i_clk_usb = ClockSignal("sys"), i_clk_sync = ClockSignal("sys"), i_rst_sync = ResetSignal(), o_ulpi__data__o = ulpi_data.o, o_ulpi__data__oe = ulpi_data.oe, i_ulpi__data__i = ulpi_data.i, o_ulpi__clk__o = ulpi_pads.clk, o_ulpi__stp = ulpi_pads.stp, i_ulpi__nxt__i = ulpi_pads.nxt, i_ulpi__dir__i = ulpi_pads.dir, o_ulpi__rst = reset, # Tx stream (Data out to computer) o_tx__ready = usb_tx.ready, i_tx__valid = usb_tx.valid, i_tx__first = usb_tx.first, i_tx__last = usb_tx.last, i_tx__payload = usb_tx.data, # Rx Stream (Data in from a Computer) i_rx__ready = usb_rx.ready, o_rx__valid = usb_rx.valid, o_rx__first = usb_rx.first, o_rx__last = usb_rx.last, o_rx__payload = usb_rx.data, ) # Connect UART stream to CPU self.comb += [ # Litex ordering when connecting streams: # [Source] -> connect -> [Sink] self.uart.source.connect(usb_tx, omit={'last'}), usb_rx.connect(self.uart.sink), usb_tx.last.eq(1), ] self.sync += [ #If(usb_tx.ready, #) ] # Hold CPU in reset until we transmit a char, # this avoids the CPU transmitting data to the USB core before it's properly enumerated. self.sync += [ If(usb_rx.valid, cpu_release.eq(1) ) ] # ButterStick r1.0 requires # VccIO set on port 2 before ULPI signals work. vccio_pins = platform.request("vccio_ctrl") pwm_timer = Signal(14) self.sync += pwm_timer.eq(pwm_timer + 1) self.comb += [ vccio_pins.pdm[0].eq(pwm_timer < int(2**14 * (0.1))), # 3.3v vccio_pins.pdm[1].eq(pwm_timer < int(2**14 * (0.1))), # 3.3v vccio_pins.pdm[2].eq(pwm_timer < int(2**14 * (0.70))), # 1.8v vccio_pins.en.eq(1), ] self.sync += [ counter.eq(counter + 1) ] self.comb += [ platform.request("leda").eq(1), platform.request("ledc").eq(counter[23]) ]