diff --git a/misoclib/com/liteusb/LICENSE b/misoclib/com/liteusb/LICENSE deleted file mode 100644 index e0a9ded1b..000000000 --- a/misoclib/com/liteusb/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Unless otherwise noted, LiteUSB is copyright (C) 2015 Florent Kermarrec. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -Other authors retain ownership of their contributions. If a submission can -reasonably be considered independently copyrightable, it's yours and we -encourage you to claim it with appropriate copyright notices. This submission -then falls under the "otherwise noted" category. All submissions are strongly -encouraged to use the two-clause BSD license reproduced above. diff --git a/misoclib/com/liteusb/README b/misoclib/com/liteusb/README deleted file mode 100644 index 0e9d36826..000000000 --- a/misoclib/com/liteusb/README +++ /dev/null @@ -1,89 +0,0 @@ - __ _ __ __ _________ - / / (_) /____ / / / / __/ _ ) - / /__/ / __/ -_) /_/ /\ \/ _ | - /____/_/\__/\__/\____/___/____/ - - Copyright 2015 / EnjoyDigital / M-Labs Ltd - - A small footprint and configurable USB core - powered by Migen - -[> Doc ---------- -XXX - -[> Intro ---------- -LiteUSB provides a small footprint and configurable USB core. - -LiteUSB is part of MiSoC libraries whose aims are to lower entry level of -complex FPGA cores by providing simple, elegant and efficient implementations -ofcomponents used in today's SoC such as Ethernet, SATA, PCIe, SDRAM Controller... - -The core uses simple and specific streaming buses and will provides in the future -adapters to use standardized AXI or Avalon-ST streaming buses. - -Since Python is used to describe the HDL, the core is highly and easily -configurable. - -LiteUSB uses technologies developed in partnership with M-Labs Ltd: - - Migen enables generating HDL with Python in an efficient way. - - MiSoC provides the basic blocks to build a powerful and small footprint SoC. - -LiteUSB can be used as MiSoC library or can be integrated with your standard -design flow by generating the verilog rtl that you will use as a standard core. - -[> Features ------------ -- FTDI2232 slave fifo core (DMA, virtual TTY) + host software - -[> Possible improvements -------------------------- -- add Cypress FX2 support -- add Cypress FX3 support -- add USB3 transceiver support and use Daisho's USB3 stack? -- ... See below Support and consulting :) - -If you want to support these features, please contact us at florent [AT] -enjoy-digital.fr. You can also contact our partner on the public mailing list -devel [AT] lists.m-labs.hk. - - -[> Getting started ------------------- -XXX - -[> Simulations: -XXX - -[> Tests : -XXX - -[> License ------------ -LiteUSB is released under the very permissive two-clause BSD license. Under -the terms of this license, you are authorized to use LiteUSB for closed-source -proprietary designs. -Even though we do not require you to do so, those things are awesome, so please -do them if possible: - - tell us that you are using LiteUSB - - cite LiteUSB in publications related to research it has helped - - send us feedback and suggestions for improvements - - send us bug reports when something goes wrong - - send us the modifications and improvements you have done to LiteUSB. - -[> Support and consulting --------------------------- -We love open-source hardware and like sharing our designs with others. - -LiteUSB is mainly developed and maintained by EnjoyDigital. - -If you would like to know more about LiteUSB or if you are already a happy -user and would like to extend it for your needs, EnjoyDigital can provide standard -commercial support as well as consulting services. - -So feel free to contact us, we'd love to work with you! (and eventually shorten -the list of the possible improvements :) - -[> Contact -E-mail: florent [AT] enjoy-digital.fr \ No newline at end of file diff --git a/misoclib/com/liteusb/__init__.py b/misoclib/com/liteusb/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/misoclib/com/liteusb/common.py b/misoclib/com/liteusb/common.py deleted file mode 100644 index 2cbf00e62..000000000 --- a/misoclib/com/liteusb/common.py +++ /dev/null @@ -1,61 +0,0 @@ -from migen.fhdl.std import * -from migen.genlib.fsm import * -from migen.actorlib.fifo import * -from migen.flow.actor import EndpointDescription -from migen.actorlib.packet import * -from migen.actorlib.structuring import Pipeline - - -packet_header_length = 9 -packet_header_fields = { - "preamble": HeaderField(0, 0, 32), - "dst": HeaderField(4, 0, 8), - "length": HeaderField(5, 0, 32) -} -packet_header = Header(packet_header_fields, - packet_header_length, - swap_field_bytes=True) - - -def phy_description(dw): - payload_layout = [("data", dw)] - return EndpointDescription(payload_layout, packetized=False) - - -def packet_description(dw): - param_layout = packet_header.get_layout() - payload_layout = [ - ("data", dw), - ("error", dw//8) - ] - return EndpointDescription(payload_layout, param_layout, packetized=True) - - -def user_description(dw): - param_layout = [ - ("dst", 8), - ("length", 32) - ] - payload_layout = [ - ("data", dw), - ("error", dw//8) - ] - return EndpointDescription(payload_layout, param_layout, packetized=True) - - -class LiteUSBMasterPort: - def __init__(self, dw): - self.source = Source(user_description(dw)) - self.sink = Sink(user_description(dw)) - - -class LiteUSBSlavePort: - def __init__(self, dw, tag): - self.sink = Sink(user_description(dw)) - self.source = Source(user_description(dw)) - self.tag = tag - - -class LiteUSBUserPort(LiteUSBSlavePort): - def __init__(self, dw, tag): - LiteUSBSlavePort.__init__(self, dw, tag) diff --git a/misoclib/com/liteusb/core/__init__.py b/misoclib/com/liteusb/core/__init__.py deleted file mode 100644 index 9ecd835cb..000000000 --- a/misoclib/com/liteusb/core/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -from misoclib.com.liteusb.common import * -from misoclib.com.liteusb.core.packet import LiteUSBPacketizer, LiteUSBDepacketizer -from misoclib.com.liteusb.core.crc import LiteUSBCRC32Inserter, LiteUSBCRC32Checker -from misoclib.com.liteusb.core.crossbar import LiteUSBCrossbar - -class LiteUSBCore(Module): - def __init__(self, phy, clk_freq, with_crc=True): - rx_pipeline = [phy] - tx_pipeline = [phy] - - # depacketizer / packetizer - self.submodules.depacketizer = LiteUSBDepacketizer(clk_freq) - self.submodules.packetizer = LiteUSBPacketizer() - rx_pipeline += [self.depacketizer] - tx_pipeline += [self.packetizer] - - if with_crc: - # crc checker / inserter - self.submodules.crc_rx = LiteUSBCRC32Checker() - self.submodules.crc_tx = LiteUSBCRC32Inserter() - rx_pipeline += [self.crc_rx] - tx_pipeline += [self.crc_tx] - - # crossbar - self.submodules.crossbar = LiteUSBCrossbar() - rx_pipeline += [self.crossbar.master] - tx_pipeline += [self.crossbar.master] - - # graph - self.submodules.rx_pipeline = Pipeline(*rx_pipeline) - self.submodules.tx_pipeline = Pipeline(*reversed(tx_pipeline)) diff --git a/misoclib/com/liteusb/core/crc.py b/misoclib/com/liteusb/core/crc.py deleted file mode 100644 index 9e57017aa..000000000 --- a/misoclib/com/liteusb/core/crc.py +++ /dev/null @@ -1,291 +0,0 @@ -from collections import OrderedDict -from migen.fhdl.std import * -from migen.genlib.fsm import FSM, NextState -from migen.genlib.record import * -from migen.genlib.misc import chooser, optree -from migen.flow.actor import Sink, Source -from migen.actorlib.fifo import SyncFIFO - -from misoclib.com.liteusb.common import * - - -class CRCEngine(Module): - """Cyclic Redundancy Check Engine - - Compute next CRC value from last CRC value and data input using - an optimized asynchronous LFSR. - - Parameters - ---------- - dat_width : int - Width of the data bus. - width : int - Width of the CRC. - polynom : int - Polynom of the CRC (ex: 0x04C11DB7 for IEEE 802.3 CRC) - - Attributes - ---------- - d : in - Data input. - last : in - last CRC value. - next : - next CRC value. - """ - def __init__(self, dat_width, width, polynom): - self.data = Signal(dat_width) - self.last = Signal(width) - self.next = Signal(width) - - # # # - - def _optimize_eq(l): - """ - Replace even numbers of XORs in the equation - with an equivalent XOR - """ - d = OrderedDict() - for e in l: - if e in d: - d[e] += 1 - else: - d[e] = 1 - r = [] - for key, value in d.items(): - if value%2 != 0: - r.append(key) - return r - - # compute and optimize CRC's LFSR - curval = [[("state", i)] for i in range(width)] - for i in range(dat_width): - feedback = curval.pop() + [("din", i)] - for j in range(width-1): - if (polynom & (1<<(j+1))): - curval[j] += feedback - curval[j] = _optimize_eq(curval[j]) - curval.insert(0, feedback) - - # implement logic - for i in range(width): - xors = [] - for t, n in curval[i]: - if t == "state": - xors += [self.last[n]] - elif t == "din": - xors += [self.data[n]] - self.comb += self.next[i].eq(optree("^", xors)) - - -@DecorateModule(InsertReset) -@DecorateModule(InsertCE) -class CRC32(Module): - """IEEE 802.3 CRC - - Implement an IEEE 802.3 CRC generator/checker. - - Parameters - ---------- - dat_width : int - Width of the data bus. - - Attributes - ---------- - d : in - Data input. - value : out - CRC value (used for generator). - error : out - CRC error (used for checker). - """ - width = 32 - polynom = 0x04C11DB7 - init = 2**width-1 - check = 0xC704DD7B - - def __init__(self, dat_width): - self.data = Signal(dat_width) - self.value = Signal(self.width) - self.error = Signal() - - # # # - - self.submodules.engine = CRCEngine(dat_width, self.width, self.polynom) - reg = Signal(self.width, reset=self.init) - self.sync += reg.eq(self.engine.next) - self.comb += [ - self.engine.data.eq(self.data), - self.engine.last.eq(reg), - - self.value.eq(~reg[::-1]), - self.error.eq(self.engine.next != self.check) - ] - - -class CRCInserter(Module): - """CRC Inserter - - Append a CRC at the end of each packet. - - Parameters - ---------- - layout : layout - Layout of the dataflow. - - Attributes - ---------- - sink : in - Packets input without CRC. - source : out - Packets output with CRC. - """ - def __init__(self, crc_class, layout): - self.sink = sink = Sink(layout) - self.source = source = Source(layout) - self.busy = Signal() - - # # # - - dw = flen(sink.data) - crc = crc_class(dw) - fsm = FSM(reset_state="IDLE") - self.submodules += crc, fsm - - fsm.act("IDLE", - crc.reset.eq(1), - sink.ack.eq(1), - If(sink.stb & sink.sop, - sink.ack.eq(0), - NextState("COPY"), - ) - ) - fsm.act("COPY", - crc.ce.eq(sink.stb & source.ack), - crc.data.eq(sink.data), - Record.connect(sink, source), - source.eop.eq(0), - If(sink.stb & sink.eop & source.ack, - NextState("INSERT"), - ) - ) - ratio = crc.width//dw - if ratio > 1: - cnt = Signal(max=ratio, reset=ratio-1) - cnt_done = Signal() - fsm.act("INSERT", - source.stb.eq(1), - chooser(crc.value, cnt, source.data, reverse=True), - If(cnt_done, - source.eop.eq(1), - If(source.ack, NextState("IDLE")) - ) - ) - self.comb += cnt_done.eq(cnt == 0) - self.sync += \ - If(fsm.ongoing("IDLE"), - cnt.eq(cnt.reset) - ).Elif(fsm.ongoing("INSERT") & ~cnt_done, - cnt.eq(cnt - source.ack) - ) - else: - fsm.act("INSERT", - source.stb.eq(1), - source.eop.eq(1), - source.data.eq(crc.value), - If(source.ack, NextState("IDLE")) - ) - self.comb += self.busy.eq(~fsm.ongoing("IDLE")) - - -class LiteUSBCRC32Inserter(CRCInserter): - def __init__(self): - CRCInserter.__init__(self, CRC32, user_description(8)) - - -class CRCChecker(Module): - """CRC Checker - - Check CRC at the end of each packet. - - Parameters - ---------- - layout : layout - Layout of the dataflow. - - Attributes - ---------- - sink : in - Packets input with CRC. - source : out - Packets output without CRC and "error" set to 0 - on eop when CRC OK / set to 1 when CRC KO. - """ - def __init__(self, crc_class, layout): - self.sink = sink = Sink(layout) - self.source = source = Source(layout) - self.busy = Signal() - - # # # - - dw = flen(sink.data) - crc = crc_class(dw) - self.submodules += crc - ratio = crc.width//dw - - error = Signal() - fifo = InsertReset(SyncFIFO(layout, ratio + 1)) - self.submodules += fifo - - fsm = FSM(reset_state="RESET") - self.submodules += fsm - - fifo_in = Signal() - fifo_out = Signal() - fifo_full = Signal() - - self.comb += [ - fifo_full.eq(fifo.fifo.level == ratio), - fifo_in.eq(sink.stb & (~fifo_full | fifo_out)), - fifo_out.eq(source.stb & source.ack), - - Record.connect(sink, fifo.sink), - fifo.sink.stb.eq(fifo_in), - self.sink.ack.eq(fifo_in), - - source.stb.eq(sink.stb & fifo_full), - source.sop.eq(fifo.source.sop), - source.eop.eq(sink.eop), - fifo.source.ack.eq(fifo_out), - source.payload.eq(fifo.source.payload), - - source.error.eq(sink.error | crc.error), - ] - - fsm.act("RESET", - crc.reset.eq(1), - fifo.reset.eq(1), - NextState("IDLE"), - ) - fsm.act("IDLE", - crc.data.eq(sink.data), - If(sink.stb & sink.sop & sink.ack, - crc.ce.eq(1), - NextState("COPY") - ) - ) - fsm.act("COPY", - crc.data.eq(sink.data), - If(sink.stb & sink.ack, - crc.ce.eq(1), - If(sink.eop, - NextState("RESET") - ) - ) - ) - self.comb += self.busy.eq(~fsm.ongoing("IDLE")) - - -class LiteUSBCRC32Checker(CRCChecker): - def __init__(self): - CRCChecker.__init__(self, CRC32, user_description(8)) diff --git a/misoclib/com/liteusb/core/crossbar.py b/misoclib/com/liteusb/core/crossbar.py deleted file mode 100644 index 59440df5b..000000000 --- a/misoclib/com/liteusb/core/crossbar.py +++ /dev/null @@ -1,33 +0,0 @@ -from collections import OrderedDict - -from misoclib.com.liteusb.common import * - -class LiteUSBCrossbar(Module): - def __init__(self): - self.users = OrderedDict() - self.master = LiteUSBMasterPort(8) - self.dispatch_param = "dst" - - def get_port(self, dst): - port = LiteUSBUserPort(8, dst) - if dst in self.users.keys(): - raise ValueError("Destination {0:#x} already assigned".format(dst)) - self.users[dst] = port - return port - - def do_finalize(self): - # TX arbitrate - sinks = [port.sink for port in self.users.values()] - self.submodules.arbiter = Arbiter(sinks, self.master.source) - - # RX dispatch - sources = [port.source for port in self.users.values()] - self.submodules.dispatcher = Dispatcher(self.master.sink, - sources, - one_hot=True) - cases = {} - cases["default"] = self.dispatcher.sel.eq(0) - for i, (k, v) in enumerate(self.users.items()): - cases[k] = self.dispatcher.sel.eq(2**i) - self.comb += \ - Case(getattr(self.master.sink, self.dispatch_param), cases) diff --git a/misoclib/com/liteusb/core/packet.py b/misoclib/com/liteusb/core/packet.py deleted file mode 100644 index 1773e143c..000000000 --- a/misoclib/com/liteusb/core/packet.py +++ /dev/null @@ -1,158 +0,0 @@ -from misoclib.com.liteusb.common import * -from migen.actorlib.structuring import Pack, Unpack -from migen.genlib.misc import WaitTimer - -class LiteUSBPacketizer(Module): - def __init__(self): - self.sink = sink = Sink(user_description(8)) - self.source = source = Source(phy_description(8)) - - # # # - - # Packet description - # - preamble : 4 bytes - # - dst : 1 byte - # - length : 4 bytes - # - payload - header = [ - # preamble - 0x5A, - 0xA5, - 0x5A, - 0xA5, - # dst - sink.dst, - # length - sink.length[24:32], - sink.length[16:24], - sink.length[8:16], - sink.length[0:8], - ] - - header_unpack = Unpack(len(header), phy_description(8)) - self.submodules += header_unpack - - for i, byte in enumerate(header): - chunk = getattr(header_unpack.sink.payload, "chunk" + str(i)) - self.comb += chunk.data.eq(byte) - - fsm = FSM(reset_state="IDLE") - self.submodules += fsm - - fsm.act("IDLE", - If(sink.stb & sink.sop, - NextState("INSERT_HEADER") - ) - ) - - fsm.act("INSERT_HEADER", - header_unpack.sink.stb.eq(1), - source.stb.eq(1), - source.data.eq(header_unpack.source.data), - header_unpack.source.ack.eq(source.ack), - If(header_unpack.sink.ack, - NextState("COPY") - ) - ) - - fsm.act("COPY", - source.stb.eq(sink.stb), - source.data.eq(sink.data), - sink.ack.eq(source.ack), - If(source.ack & sink.eop, - NextState("IDLE") - ) - ) - - -class LiteUSBDepacketizer(Module): - def __init__(self, clk_freq, timeout=10): - self.sink = sink = Sink(phy_description(8)) - self.source = source = Source(user_description(8)) - - # # # - - # Packet description - # - preamble : 4 bytes - # - dst : 1 byte - # - length : 4 bytes - # - payload - preamble = Array(Signal(8) for i in range(4)) - - header = [ - # dst - source.dst, - # length - source.length[24:32], - source.length[16:24], - source.length[8:16], - source.length[0:8], - ] - - header_pack = InsertReset(Pack(phy_description(8), len(header))) - self.submodules += header_pack - - for i, byte in enumerate(header): - chunk = getattr(header_pack.source.payload, "chunk" + str(i)) - self.comb += byte.eq(chunk.data) - - fsm = FSM(reset_state="IDLE") - self.submodules += fsm - - self.comb += preamble[0].eq(sink.data) - for i in range(1, 4): - self.sync += If(sink.stb & sink.ack, - preamble[i].eq(preamble[i-1]) - ) - fsm.act("IDLE", - sink.ack.eq(1), - If((preamble[3] == 0x5A) & - (preamble[2] == 0xA5) & - (preamble[1] == 0x5A) & - (preamble[0] == 0xA5) & - sink.stb, - NextState("RECEIVE_HEADER") - ), - header_pack.source.ack.eq(1), - ) - - self.submodules.timer = WaitTimer(clk_freq*timeout) - self.comb += self.timer.wait.eq(~fsm.ongoing("IDLE")) - - fsm.act("RECEIVE_HEADER", - header_pack.sink.stb.eq(sink.stb), - header_pack.sink.payload.eq(sink.payload), - If(self.timer.done, - NextState("IDLE") - ).Elif(header_pack.source.stb, - NextState("COPY") - ).Else( - sink.ack.eq(1) - ) - ) - - self.comb += header_pack.reset.eq(self.timer.done) - - sop = Signal() - eop = Signal() - cnt = Signal(32) - - fsm.act("COPY", - source.stb.eq(sink.stb), - source.sop.eq(sop), - source.eop.eq(eop), - source.data.eq(sink.data), - sink.ack.eq(source.ack), - If((source.stb & source.ack & eop) | self.timer.done, - NextState("IDLE") - ) - ) - - self.sync += \ - If(fsm.ongoing("IDLE"), - cnt.eq(0) - ).Elif(source.stb & source.ack, - cnt.eq(cnt + 1) - ) - self.comb += sop.eq(cnt == 0) - self.comb += eop.eq(cnt == source.length - 1) diff --git a/misoclib/com/liteusb/example_designs/build/.keep_me b/misoclib/com/liteusb/example_designs/build/.keep_me deleted file mode 100644 index e69de29bb..000000000 diff --git a/misoclib/com/liteusb/example_designs/make.py b/misoclib/com/liteusb/example_designs/make.py deleted file mode 100644 index e3eed9d3d..000000000 --- a/misoclib/com/liteusb/example_designs/make.py +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env python3 - -import sys -import os -import argparse -import subprocess -import struct -import importlib - -from mibuild.tools import write_to_file -from migen.util.misc import autotype -from migen.fhdl import verilog, edif -from migen.fhdl.structure import _Fragment -from migen.bank.description import CSRStatus -from mibuild import tools -from mibuild.xilinx.common import * - -from misoclib.soc import cpuif -#from misoclib.lit.liteusb.common import * - - -def _import(default, name): - return importlib.import_module(default + "." + name) - - -def _get_args(): - parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, - description="""\ -LiteUSB - based on Migen. - -This program builds and/or loads LiteUSB components. -One or several actions can be specified: - -clean delete previous build(s). -build-rtl build verilog rtl. -build-bitstream build-bitstream build FPGA bitstream. -build-csr-csv save CSR map into CSV file. - -load-bitstream load bitstream into volatile storage. - -all clean, build-csr-csv, build-bitstream, load-bitstream. -""") - - parser.add_argument("-t", "--target", default="simple", help="Core type to build") - parser.add_argument("-s", "--sub-target", default="", help="variant of the Core type to build") - parser.add_argument("-p", "--platform", default=None, help="platform to build for") - parser.add_argument("-Ot", "--target-option", default=[], nargs=2, action="append", help="set target-specific option") - parser.add_argument("-Op", "--platform-option", default=[], nargs=2, action="append", help="set platform-specific option") - parser.add_argument("-Ob", "--build-option", default=[], nargs=2, action="append", help="set build option") - parser.add_argument("--csr_csv", default="./test/csr.csv", help="CSV file to save the CSR map into") - - parser.add_argument("action", nargs="+", help="specify an action") - - return parser.parse_args() - -# Note: misoclib need to be installed as a python library - -if __name__ == "__main__": - args = _get_args() - - # create top-level Core object - target_module = _import("targets", args.target) - if args.sub_target: - top_class = getattr(target_module, args.sub_target) - else: - top_class = target_module.default_subtarget - - if args.platform is None: - if hasattr(top_class, "default_platform"): - platform_name = top_class.default_platform - else: - raise ValueError("Target has no default platform, specify a platform with -p your_platform") - else: - platform_name = args.platform - platform_module = _import("mibuild.platforms", platform_name) - platform_kwargs = dict((k, autotype(v)) for k, v in args.platform_option) - platform = platform_module.Platform(**platform_kwargs) - - build_name = top_class.__name__.lower() + "-" + platform_name - top_kwargs = dict((k, autotype(v)) for k, v in args.target_option) - soc = top_class(platform, **top_kwargs) - soc.finalize() - memory_regions = soc.get_memory_regions() - csr_regions = soc.get_csr_regions() - - # decode actions - action_list = ["clean", "build-csr-csv", "build-bitstream", "load-bitstream", "all"] - actions = {k: False for k in action_list} - for action in args.action: - if action in actions: - actions[action] = True - else: - print("Unknown action: "+action+". Valid actions are:") - for a in action_list: - print(" "+a) - sys.exit(1) - - print(""" - __ _ __ __ _________ - / / (_) /____ / / / / __/ _ ) - / /__/ / __/ -_) /_/ /\ \/ _ | - /____/_/\__/\__/\____/___/____/ - - - A small footprint and configurable USB core - powered by Migen - -====== Building parameters: ====== -System Clk: {} MHz -===============================""".format( - soc.clk_freq/1000000)) - - # dependencies - if actions["all"]: - actions["build-csr-csv"] = True - actions["build-bitstream"] = True - actions["load-bitstream"] = True - - if actions["build-bitstream"]: - actions["build-csr-csv"] = True - actions["build-bitstream"] = True - actions["load-bitstream"] = True - - if actions["clean"]: - subprocess.call(["rm", "-rf", "build/*"]) - - if actions["build-csr-csv"]: - csr_csv = cpuif.get_csr_csv(csr_regions) - write_to_file(args.csr_csv, csr_csv) - - if actions["build-bitstream"]: - build_kwargs = dict((k, autotype(v)) for k, v in args.build_option) - vns = platform.build(soc, build_name=build_name, **build_kwargs) - if hasattr(soc, "do_exit") and vns is not None: - if hasattr(soc.do_exit, '__call__'): - soc.do_exit(vns) - - if actions["load-bitstream"]: - prog = platform.create_programmer() - prog.load_bitstream("build/" + build_name + platform.bitstream_ext) diff --git a/misoclib/com/liteusb/example_designs/targets/__init__.py b/misoclib/com/liteusb/example_designs/targets/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/misoclib/com/liteusb/example_designs/targets/simple.py b/misoclib/com/liteusb/example_designs/targets/simple.py deleted file mode 100644 index eabd6421c..000000000 --- a/misoclib/com/liteusb/example_designs/targets/simple.py +++ /dev/null @@ -1,45 +0,0 @@ -from migen.genlib.io import CRG -from migen.actorlib.fifo import SyncFIFO - -from misoclib.soc import SoC - -from misoclib.com.liteusb.common import * -from misoclib.com.liteusb.phy.ft245 import FT245PHY -from misoclib.com.liteusb.core import LiteUSBCore -from misoclib.com.liteusb.frontend.wishbone import LiteUSBWishboneBridge - -from misoclib.com.gpio import GPIOOut - -class LiteUSBSoC(SoC): - csr_map = {} - csr_map.update(SoC.csr_map) - - usb_map = { - "bridge": 0 - } - - def __init__(self, platform): - clk_freq = int((1/(platform.default_clk_period))*1000000000) - SoC.__init__(self, platform, clk_freq, - cpu_type="none", - with_csr=True, csr_data_width=32, - with_uart=False, - with_identifier=True, - with_timer=False - ) - self.submodules.crg = CRG(platform.request(platform.default_clk_name)) - - self.submodules.usb_phy = FT245PHY(platform.request("usb_fifo"), self.clk_freq) - self.submodules.usb_core = LiteUSBCore(self.usb_phy, self.clk_freq, with_crc=False) - - - # Wishbone Bridge - usb_bridge_port = self.usb_core.crossbar.get_port(self.usb_map["bridge"]) - self.add_cpu_or_bridge(LiteUSBWishboneBridge(usb_bridge_port, self.clk_freq)) - self.add_wb_master(self.cpu_or_bridge.wishbone) - - # Leds - leds = Cat(iter([platform.request("user_led", i) for i in range(8)])) - self.submodules.leds = GPIOOut(leds) - -default_subtarget = LiteUSBSoC diff --git a/misoclib/com/liteusb/example_designs/test/Makefile b/misoclib/com/liteusb/example_designs/test/Makefile deleted file mode 100644 index 82c55fed5..000000000 --- a/misoclib/com/liteusb/example_designs/test/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -LITEUSBDIR=../../software - -dll: - cd $(LITEUSBDIR)/ftdi/windows && make all - cp $(LITEUSBDIR)/ftdi/libftdicom.dll libftdicom.dll - -clean: - rm -f libftdicom.dll diff --git a/misoclib/com/liteusb/example_designs/test/make.py b/misoclib/com/liteusb/example_designs/test/make.py deleted file mode 100644 index 0c337bf15..000000000 --- a/misoclib/com/liteusb/example_designs/test/make.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -import argparse -import importlib - -FTDI_INTERFACE_A = 1 -FTDI_INTERFACE_B = 2 - -def _get_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--tag", default=0, help="USB channel tag") - parser.add_argument("--busword", default=32, help="CSR busword") - - parser.add_argument("test", nargs="+", help="specify a test") - - return parser.parse_args() - -if __name__ == "__main__": - args = _get_args() - from misoclib.com.liteusb.software.wishbone import LiteUSBWishboneDriver - wb = LiteUSBWishboneDriver("ft2232h", FTDI_INTERFACE_B, "asynchronous", - tag=int(args.tag), - busword=int(args.busword), - addrmap="./csr.csv", - debug=False) - - def _import(name): - return importlib.import_module(name) - - for test in args.test: - t = _import(test) - t.main(wb) diff --git a/misoclib/com/liteusb/example_designs/test/test_regs.py b/misoclib/com/liteusb/example_designs/test/test_regs.py deleted file mode 100644 index 2efdd043a..000000000 --- a/misoclib/com/liteusb/example_designs/test/test_regs.py +++ /dev/null @@ -1,11 +0,0 @@ -def main(wb): - wb.open() - regs = wb.regs - # # # - for i in range(64): - wb.regs.leds_out.write(i) - print("sysid : 0x{:04x}".format(regs.identifier_sysid.read())) - print("revision : 0x{:04x}".format(regs.identifier_revision.read())) - print("frequency : {}MHz".format(int(regs.identifier_frequency.read()/1000000))) - # # # - wb.close() diff --git a/misoclib/com/liteusb/frontend/__init__.py b/misoclib/com/liteusb/frontend/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/misoclib/com/liteusb/frontend/dma.py b/misoclib/com/liteusb/frontend/dma.py deleted file mode 100644 index d656eca34..000000000 --- a/misoclib/com/liteusb/frontend/dma.py +++ /dev/null @@ -1,102 +0,0 @@ -from migen.fhdl.std import * -from migen.flow.actor import * -from migen.flow.network import * -from migen.actorlib import structuring, spi -from migen.bank.description import * -from migen.bank.eventmanager import * -from migen.genlib.record import Record - -from misoclib.mem.sdram.frontend import dma_lasmi -from misoclib.com.liteusb.common import * - - -class LiteUSBDMAWriter(Module, AutoCSR): - def __init__(self, lasmim): - self.sink = sink = Sink(user_description(8)) - - # Pack data - pack_factor = lasmim.dw//8 - pack = structuring.Pack(phy_description(8), pack_factor, reverse=True) - cast = structuring.Cast(pack.source.payload.layout, lasmim.dw) - - # DMA - writer = dma_lasmi.Writer(lasmim) - self._reset = CSR() - self.dma = InsertReset(spi.DMAWriteController(writer, mode=spi.MODE_SINGLE_SHOT)) - self.comb += self.dma.reset.eq(self._reset.r & self._reset.re) - - # Remove sop/eop/length/dst fields from payload - self.comb += [ - pack.sink.stb.eq(sink.stb), - pack.sink.payload.eq(sink.payload), - sink.ack.eq(pack.sink.ack) - ] - - # Graph - g = DataFlowGraph() - g.add_pipeline(pack, cast, self.dma) - self.submodules += CompositeActor(g) - - # IRQ - self.submodules.ev = EventManager() - self.ev.done = EventSourcePulse() - self.ev.finalize() - self.comb += self.ev.done.trigger.eq(sink.stb & sink.eop) - - # CRC - self._crc_failed = CSRStatus() - self.sync += \ - If(sink.stb & sink.eop, - self._crc_failed.status.eq(sink.error) - ) - - -class LiteUSBDMAReader(Module, AutoCSR): - def __init__(self, lasmim, tag): - self.source = source = Source(user_description(8)) - - reader = dma_lasmi.Reader(lasmim) - self.dma = spi.DMAReadController(reader, mode=spi.MODE_SINGLE_SHOT) - - pack_factor = lasmim.dw//8 - packed_dat = structuring.pack_layout(8, pack_factor) - cast = structuring.Cast(lasmim.dw, packed_dat) - unpack = structuring.Unpack(pack_factor, phy_description(8), reverse=True) - - # Graph - cnt = Signal(32) - self.sync += \ - If(self.dma.generator._shoot.re, - cnt.eq(0) - ).Elif(source.stb & source.ack, - cnt.eq(cnt + 1) - ) - g = DataFlowGraph() - g.add_pipeline(self.dma, cast, unpack) - self.submodules += CompositeActor(g) - self.comb += [ - source.stb.eq(unpack.source.stb), - source.sop.eq(cnt == 0), - source.eop.eq(cnt == (self.dma.length*pack_factor-1)), - source.length.eq(self.dma.length*pack_factor), - source.data.eq(unpack.source.data), - source.dst.eq(tag), - unpack.source.ack.eq(source.ack) - ] - - # IRQ - self.submodules.ev = EventManager() - self.ev.done = EventSourcePulse() - self.ev.finalize() - self.comb += self.ev.done.trigger.eq(source.stb & source.eop) - - -class LiteUSBDMA(Module, AutoCSR): - def __init__(self, port, lasmim_dma_wr, lasmim_dma_rd): - self.submodules.writer = LiteUSBDMAWriter(lasmim_dma_wr) - self.submodules.reader = LiteUSBDMAReader(lasmim_dma_rd, port.tag) - self.submodules.ev = SharedIRQ(self.writer.ev, self.reader.ev) - self.comb += [ - Record.connect(port.source, self.writer.sink), - Record.connect(self.reader.source, port.sink), - ] diff --git a/misoclib/com/liteusb/frontend/uart.py b/misoclib/com/liteusb/frontend/uart.py deleted file mode 100644 index 648d67639..000000000 --- a/misoclib/com/liteusb/frontend/uart.py +++ /dev/null @@ -1,35 +0,0 @@ -from migen.fhdl.std import * - -from misoclib.com.liteusb.common import * -from misoclib.com.uart import UART - -class LiteUSBUARTPHY: - def __init__(self): - self.sink = Sink([("data", 8)]) - self.source = Source([("data", 8)]) - -class LiteUSBUART(UART): - def __init__(self, port, - tx_fifo_depth=16, - rx_fifo_depth=16): - - phy = LiteUSBUARTPHY() - UART.__init__(self, phy, tx_fifo_depth, rx_fifo_depth) - - # TX - self.comb += [ - port.sink.stb.eq(phy.sink.stb), - port.sink.sop.eq(1), - port.sink.eop.eq(1), - port.sink.length.eq(1), - port.sink.dst.eq(port.tag), - port.sink.data.eq(phy.sink.data), - phy.sink.ack.eq(port.sink.ack) - ] - - # RX - self.comb += [ - phy.source.stb.eq(port.source.stb), - phy.source.data.eq(port.source.data), - port.source.ack.eq(phy.source.ack) - ] diff --git a/misoclib/com/liteusb/frontend/wishbone.py b/misoclib/com/liteusb/frontend/wishbone.py deleted file mode 100644 index 394e2c4ce..000000000 --- a/misoclib/com/liteusb/frontend/wishbone.py +++ /dev/null @@ -1,9 +0,0 @@ -from migen.fhdl.std import * - -from misoclib.com.liteusb.common import * -from misoclib.tools.wishbone import WishboneStreamingBridge - -class LiteUSBWishboneBridge(WishboneStreamingBridge): - def __init__(self, port, clk_freq): - WishboneStreamingBridge.__init__(self, port, clk_freq) - self.comb += port.sink.dst.eq(port.tag) diff --git a/misoclib/com/liteusb/phy/__init__.py b/misoclib/com/liteusb/phy/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/misoclib/com/liteusb/phy/ft245.py b/misoclib/com/liteusb/phy/ft245.py deleted file mode 100644 index 28809c273..000000000 --- a/misoclib/com/liteusb/phy/ft245.py +++ /dev/null @@ -1,319 +0,0 @@ -import math - -from migen.fhdl.std import * -from migen.flow.actor import * -from migen.actorlib.fifo import SyncFIFO, AsyncFIFO -from migen.fhdl.specials import * -from migen.genlib.cdc import MultiReg - -from misoclib.com.liteusb.common import * - - -def anti_starvation(module, timeout): - en = Signal() - max_time = Signal() - if timeout: - t = timeout - 1 - time = Signal(max=t+1) - module.comb += max_time.eq(time == 0) - module.sync += If(~en, - time.eq(t) - ).Elif(~max_time, - time.eq(time - 1) - ) - else: - module.comb += max_time.eq(0) - return en, max_time - - -class FT245PHYSynchronous(Module): - def __init__(self, pads, clk_freq, - fifo_depth=32, - read_time=128, - write_time=128): - dw = flen(pads.data) - - # read fifo (FTDI --> SoC) - read_fifo = RenameClockDomains(AsyncFIFO(phy_description(8), fifo_depth), - {"write": "usb", "read": "sys"}) - read_buffer = RenameClockDomains(SyncFIFO(phy_description(8), 4), - {"sys": "usb"}) - self.comb += read_buffer.source.connect(read_fifo.sink) - - # write fifo (SoC --> FTDI) - write_fifo = RenameClockDomains(AsyncFIFO(phy_description(8), fifo_depth), - {"write": "sys", "read": "usb"}) - - self.submodules += read_fifo, read_buffer, write_fifo - - # sink / source interfaces - self.sink = write_fifo.sink - self.source = read_fifo.source - - # read / write arbitration - wants_write = Signal() - wants_read = Signal() - - txe_n = Signal() - rxf_n = Signal() - - self.comb += [ - txe_n.eq(pads.txe_n), - rxf_n.eq(pads.rxf_n), - wants_write.eq(~txe_n & write_fifo.source.stb), - wants_read.eq(~rxf_n & read_fifo.sink.ack), - ] - - read_time_en, max_read_time = anti_starvation(self, read_time) - write_time_en, max_write_time = anti_starvation(self, write_time) - - data_w_accepted = Signal(reset=1) - - fsm = FSM(reset_state="READ") - self.submodules += RenameClockDomains(fsm, {"sys": "usb"}) - - fsm.act("READ", - read_time_en.eq(1), - If(wants_write, - If(~wants_read | max_read_time, - NextState("RTW") - ) - ) - ) - fsm.act("RTW", - NextState("WRITE") - ) - fsm.act("WRITE", - write_time_en.eq(1), - If(wants_read, - If(~wants_write | max_write_time, - NextState("WTR") - ) - ), - write_fifo.source.ack.eq(wants_write & data_w_accepted) - ) - fsm.act("WTR", - NextState("READ") - ) - - # databus tristate - data_w = Signal(dw) - data_r = Signal(dw) - data_oe = Signal() - self.specials += Tristate(pads.data, data_w, data_oe, data_r) - - # read / write actions - pads.oe_n.reset = 1 - pads.rd_n.reset = 1 - pads.wr_n.reset = 1 - - self.sync.usb += [ - If(fsm.ongoing("READ"), - data_oe.eq(0), - - pads.oe_n.eq(0), - pads.rd_n.eq(~wants_read), - pads.wr_n.eq(1) - - ).Elif(fsm.ongoing("WRITE"), - data_oe.eq(1), - - pads.oe_n.eq(1), - pads.rd_n.eq(1), - pads.wr_n.eq(~wants_write), - - data_w_accepted.eq(~txe_n) - - ).Else( - data_oe.eq(1), - - pads.oe_n.eq(~fsm.ongoing("WTR")), - pads.rd_n.eq(1), - pads.wr_n.eq(1) - ), - read_buffer.sink.stb.eq(~pads.rd_n & ~rxf_n), - read_buffer.sink.data.eq(data_r), - If(~txe_n & data_w_accepted, - data_w.eq(write_fifo.source.data) - ) - ] - - -class FT245PHYAsynchronous(Module): - def __init__(self, pads, clk_freq, - fifo_depth=32, - read_time=128, - write_time=128): - dw = flen(pads.data) - self.clk_freq = clk_freq - - # timings - tRD = self.ns(30) # RD# active pulse width (t4) - tRDDataSetup = self.ns(14) # RD# to DATA (t3) - tWRDataSetup = self.ns(5) # DATA to WR# active setup time (t8) - tWR = self.ns(30) # WR# active pulse width (t10) - tMultiReg = 2 - - # read fifo (FTDI --> SoC) - read_fifo = SyncFIFO(phy_description(8), fifo_depth) - - # write fifo (SoC --> FTDI) - write_fifo = SyncFIFO(phy_description(8), fifo_depth) - - self.submodules += read_fifo, write_fifo - - # sink / source interfaces - self.sink = write_fifo.sink - self.source = read_fifo.source - - # read / write arbitration - wants_write = Signal() - wants_read = Signal() - - txe_n = Signal() - rxf_n = Signal() - - self.specials += [ - MultiReg(pads.txe_n, txe_n), - MultiReg(pads.rxf_n, rxf_n) - ] - - self.comb += [ - wants_write.eq(~txe_n & write_fifo.source.stb), - wants_read.eq(~rxf_n & read_fifo.sink.ack), - ] - - read_time_en, max_read_time = anti_starvation(self, read_time) - write_time_en, max_write_time = anti_starvation(self, write_time) - - fsm = FSM(reset_state="READ") - self.submodules += fsm - - read_done = Signal() - write_done = Signal() - commuting = Signal() - - fsm.act("READ", - read_time_en.eq(1), - If(wants_write & read_done, - If(~wants_read | max_read_time, - commuting.eq(1), - NextState("RTW") - ) - ) - ) - fsm.act("RTW", - NextState("WRITE") - ) - fsm.act("WRITE", - write_time_en.eq(1), - If(wants_read & write_done, - If(~wants_write | max_write_time, - commuting.eq(1), - NextState("WTR") - ) - ) - ) - fsm.act("WTR", - NextState("READ") - ) - - # databus tristate - data_w = Signal(dw) - data_r_async = Signal(dw) - data_r = Signal(dw) - data_oe = Signal() - self.specials += [ - Tristate(pads.data, data_w, data_oe, data_r_async), - MultiReg(data_r_async, data_r) - ] - - - # read actions - pads.rd_n.reset = 1 - - read_fsm = FSM(reset_state="IDLE") - read_counter = Counter(8) - self.submodules += read_fsm, read_counter - - read_fsm.act("IDLE", - read_done.eq(1), - read_counter.reset.eq(1), - If(fsm.ongoing("READ") & wants_read, - If(~commuting, - NextState("PULSE_RD_N") - ) - ) - ) - read_fsm.act("PULSE_RD_N", - pads.rd_n.eq(0), - read_counter.ce.eq(1), - If(read_counter.value == max((tRD-1), (tRDDataSetup + tMultiReg -1)), - NextState("ACQUIRE_DATA") - ) - ) - read_fsm.act("ACQUIRE_DATA", - read_fifo.sink.stb.eq(1), - read_fifo.sink.data.eq(data_r), - NextState("WAIT_RXF_N") - ) - read_fsm.act("WAIT_RXF_N", - If(rxf_n, - NextState("IDLE") - ) - ) - - # write actions - pads.wr_n.reset = 1 - - write_fsm = FSM(reset_state="IDLE") - write_counter = Counter(8) - self.submodules += write_fsm, write_counter - - write_fsm.act("IDLE", - write_done.eq(1), - write_counter.reset.eq(1), - If(fsm.ongoing("WRITE") & wants_write, - If(~commuting, - NextState("SET_DATA") - ) - ) - ) - write_fsm.act("SET_DATA", - data_oe.eq(1), - data_w.eq(write_fifo.source.data), - write_counter.ce.eq(1), - If(write_counter.value == (tWRDataSetup-1), - write_counter.reset.eq(1), - NextState("PULSE_WR_N") - ) - ) - write_fsm.act("PULSE_WR_N", - data_oe.eq(1), - data_w.eq(write_fifo.source.data), - pads.wr_n.eq(0), - write_counter.ce.eq(1), - If(write_counter.value == (tWR-1), - NextState("WAIT_TXE_N") - ) - ) - write_fsm.act("WAIT_TXE_N", - If(txe_n, - write_fifo.source.ack.eq(1), - NextState("IDLE") - ) - ) - - def ns(self, t, margin=True): - clk_period_ns = 1000000000/self.clk_freq - if margin: - t += clk_period_ns/2 - return math.ceil(t/clk_period_ns) - - -def FT245PHY(pads, *args, **kwargs): - # autodetect PHY - if hasattr(pads, "oe_n"): - return FT245PHYSynchronous(pads, *args, **kwargs) - else: - return FT245PHYAsynchronous(pads, *args, **kwargs) diff --git a/misoclib/com/liteusb/software/__init__.py b/misoclib/com/liteusb/software/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/misoclib/com/liteusb/software/ftdi/README b/misoclib/com/liteusb/software/ftdi/README deleted file mode 100644 index 81aa546fe..000000000 --- a/misoclib/com/liteusb/software/ftdi/README +++ /dev/null @@ -1,14 +0,0 @@ -[> Libftdicom ------------------------------- - -[> Windows build --------------------------- -1. Install MinGW32 -2. Download libusbx windows binaries (tested version: libusbx-1.0.17-win) -3. Put libusb-1.0.dll.a in mingw lib directory -4. Download Zadig and use WinUSB driver for Interface A and Interface B -5. make all in libftdicom/win - -[> Linux build --------------------------- -1. make all in libftdicom/linux \ No newline at end of file diff --git a/misoclib/com/liteusb/software/ftdi/__init__.py b/misoclib/com/liteusb/software/ftdi/__init__.py deleted file mode 100644 index 006868fed..000000000 --- a/misoclib/com/liteusb/software/ftdi/__init__.py +++ /dev/null @@ -1,364 +0,0 @@ -import platform -import ctypes -import os -import time -import queue -import threading - -if platform.system() == "Windows": - libftdicom = ctypes.cdll.LoadLibrary("./libftdicom.dll") -else: - libftdicom = ctypes.cdll.LoadLibrary("./libftdicom.so") - - -class FTDI_Device(ctypes.Structure): - _fields_ = [ - ('_1', ctypes.c_void_p), - ('_2', ctypes.c_void_p), - ] - -pFTDI_Device = ctypes.POINTER(FTDI_Device) - -# FTDIDevice_Open -FTDIDevice_Open = libftdicom.FTDIDevice_Open -FTDIDevice_Open.argtypes = [ - pFTDI_Device, # Dev - ctypes.c_int # Interface - ] -FTDIDevice_Open.restype = ctypes.c_int - -# FTDIDevice_Close -FTDIDevice_Close = libftdicom.FTDIDevice_Close -FTDIDevice_Close.argtypes = [pFTDI_Device] - -FTDIDevice_SetMode = libftdicom.FTDIDevice_SetMode -FTDIDevice_SetMode.argtypes = [ - pFTDI_Device, # Dev - ctypes.c_int, # Interface - ctypes.c_int, # Mode - ctypes.c_char, # PinDirection - ctypes.c_char, # baudrate - ] - - -FTDIDevice_Write = libftdicom.FTDIDevice_Write -FTDIDevice_Write.argtypes = [ - pFTDI_Device, # Dev - ctypes.c_int, # Interface - ctypes.c_char_p, # Buf - ctypes.c_size_t, # N - ctypes.c_bool, # async - ] -FTDIDevice_Write.restype = ctypes.c_int - -p_cb_StreamCallback = ctypes.CFUNCTYPE( - ctypes.c_int, # retval - ctypes.POINTER(ctypes.c_uint8), # buf - ctypes.c_int, # length - ctypes.c_void_p, # progress - ctypes.c_void_p) # userdata - -FTDIDevice_ReadStream = libftdicom.FTDIDevice_ReadStream -FTDIDevice_ReadStream.argtypes = [ - pFTDI_Device, # dev - ctypes.c_int, # interface - p_cb_StreamCallback, # callback - ctypes.c_void_p, # userdata - ctypes.c_int, # packetsPerTransfer - ctypes.c_int, # numTransfers - ] -FTDIDevice_ReadStream.restype = ctypes.c_int - -FTDI_INTERFACE_A = 1 -FTDI_INTERFACE_B = 2 - -FTDI_BITMODE_SYNC_FIFO = (1 << 6) - - -class FTDIDevice: - def __init__(self, interface, mode): - self.__is_open = False - self._dev = FTDI_Device() - self.interface = interface - self.mode = mode - - def __del__(self): - if self.__is_open: - self.__is_open = False - FTDIDevice_Close(self._dev) - - def open(self): - err = FTDIDevice_Open(self._dev, self.interface) - if err: - return err - else: - self.__is_open = True - - if self.mode == "synchronous": - err = FTDIDevice_SetMode(self._dev, interface, FTDI_BITMODE_SYNC_FIFO, 0xFF, 0) - - return err - - def write(self, intf, buf, async=False): - if not isinstance(buf, bytes): - raise TypeError("buf must be bytes") - - return FTDIDevice_Write(self._dev, intf, buf, len(buf), async) - - def read(self, intf, n): - buf = [] - - def callback(b, prog): - buf.extend(b) - return int(len(buf) >= n) - - self.read_async(intf, callback, 4, 4) - - return buf - - def read_async(self, intf, callback, packetsPerTransfer, numTransfers): - def callback_wrapper(buf, ll, prog, user): - if ll: - b = ctypes.string_at(buf, ll) - else: - b = b'' - return callback(b, prog) - - cb = p_cb_StreamCallback(callback_wrapper) - - return FTDIDevice_ReadStream(self._dev, intf, cb, - None, packetsPerTransfer, numTransfers) - - -class ProtocolError(Exception): - pass - - -class TimeoutError(Exception): - pass - - -INCOMPLETE = -1 -UNMATCHED = 0 -class BaseService: - def match_identifier(self, byt): - r = True - r = r and (byt[0] == 0x5A) - r = r and (byt[1] == 0xA5) - r = r and (byt[2] == 0x5A) - r = r and (byt[3] == 0xA5) - r = r and (byt[4] == self.tag) - return r - - def get_needed_size_for_identifier(self): - return self.NEEDED_FOR_SIZE - - def present_bytes(self, b): - if len(b) < self.get_needed_size_for_identifier(): - return INCOMPLETE - - if not self.match_identifier(b): - return UNMATCHED - - size = self.get_packet_size(b) - - if len(b) < size: - return INCOMPLETE - - self.consume(b[:size]) - - return size - - -class UART: - class __UARTService(BaseService): - NEEDED_FOR_SIZE = 9 - - def __init__(self, tag): - self.tag = tag - self.q = queue.Queue() - - def get_packet_size(self, buf): - payload_size = buf[5] << 24 - payload_size |= buf[6] << 16 - payload_size |= buf[7] << 8 - payload_size |= buf[8] << 0 - return 9 + payload_size - - def consume(self, buf): - for value in buf[9:]: - self.q.put(value) - - def __init__(self, tag): - self.tag = tag - self.service = UART.__UARTService(self.tag) - - def do_read(self, timeout=None): - try: - resp = self.service.q.get(True, timeout) - except queue.Empty: - return -1 - return resp - - def do_write(self, data): - if isinstance(data, int): - data = [data] - msg = [0x5A, 0xA5, 0x5A, 0xA5] - msg.append(self.tag) - length = len(data) - msg.append((length >> 24) & 0xff) - msg.append((length >> 16) & 0xff) - msg.append((length >> 8) & 0xff) - msg.append((length >> 0) & 0xff) - for value in data: - msg.append(value&0xff) - self.service.write(bytes(msg)) - - -class DMA: - class __DMAService(BaseService): - NEEDED_FOR_SIZE = 9 - - def __init__(self, tag): - self.tag = tag - self.q = queue.Queue() - - def get_packet_size(self, buf): - payload_size = buf[5] << 24 - payload_size |= buf[6] << 16 - payload_size |= buf[7] << 8 - payload_size |= buf[8] << 0 - return 9 + payload_size - - def consume(self, buf): - self.q.put(buf[9:]) - - def __init__(self, tag): - self.tag = tag - self.service = DMA.__DMAService(self.tag) - - def do_read(self, timeout=None): - try: - resp = list(self.service.q.get(True, timeout)) - except queue.Empty: - raise TimeoutError("DMA read timed out") - return resp - - def do_write(self, data): - length = len(data) - msg = [0x5A, 0xA5, 0x5A, 0xA5, self.tag, - (length & 0xff000000) >> 24, - (length & 0x00ff0000) >> 16, - (length & 0x0000ff00) >> 8, - (length & 0x000000ff) >> 0] - msg += data - self.service.write(bytes(msg)) - - -class FTDIComDevice: - def __init__(self, interface, mode, uart_tag=0, dma_tag=1, verbose=False): - self.__is_open = False - - self.interface = interface - self.mode = mode - - self.dev = FTDIDevice(interface, mode) - self.verbose = verbose - - self.uart = UART(uart_tag) - self.dma = DMA(dma_tag) - - self.__services = [self.uart.service, self.dma.service] - - # Inject a write function into the services - for service in self.__services: - def write(msg): - if self.verbose: - print("< %s" % " ".join("%02x" % i for i in msg)) - - self.dev.write(self.interface, msg, async=False) - - service.write = write - - def __comms(self): - self.__buf = b"" - - def callback(b, prog): - try: - if self.verbose and b: - print("> %s" % " ".join("%02x" % i for i in b)) - - self.__buf += b - - incomplete = False - - while self.__buf and not incomplete: - for service in self.__services: - code = service.present_bytes(self.__buf) - if code == INCOMPLETE: - incomplete = True - break - elif code: - self.__buf = self.__buf[code:] - break - else: - self.__buf = self.__buf[1:] - - return int(self.__comm_term) - except Exception as e: - self.__comm_term = True - self.__comm_exc = e - return 1 - - while not self.__comm_term: - self.dev.read_async(self.interface, callback, 8, 16) - - if self.__comm_exc: - raise self.__comm_exc - - def __del__(self): - if self.__is_open: - self.close() - - def open(self): - if self.__is_open: - raise ValueError("FTDICOMDevice doubly opened") - - stat = self.dev.open() - if stat: - print("USB: Error opening device\n") - return stat - - self.commthread = threading.Thread(target=self.__comms, daemon=True) - self.__comm_term = False - self.__comm_exc = None - - self.commthread.start() - - self.__comm_term = False - self.__is_open = True - - def close(self): - if not self.__is_open: - raise ValueError("FTDICOMDevice doubly closed") - - self.__comm_term = True - self.commthread.join() - - self.__is_open = False - - def uartflush(self, timeout=0.25): - while (self.uartread(timeout) != -1): - pass - - def uartread(self, timeout=None): - return self.uart.do_read(timeout) - - def uartwrite(self, data): - return self.uart.do_write(data) - - def dmaread(self): - return self.dma.do_read() - - def dmawrite(self, data): - return self.dma.do_write(data) diff --git a/misoclib/com/liteusb/software/ftdi/example.py b/misoclib/com/liteusb/software/ftdi/example.py deleted file mode 100644 index b1cdbba8a..000000000 --- a/misoclib/com/liteusb/software/ftdi/example.py +++ /dev/null @@ -1,81 +0,0 @@ -import platform -import os -import sys -import time -import threading - -# XXX FTDI Communication POC - -sys.path.append("../") -from ftdi import FTDIComDevice, FTDI_INTERFACE_B - -def uart_console(ftdi_com): - def read(): - while True: - print(chr(ftdi_com.uartread()), end="") - - readthread = threading.Thread(target=read, daemon=True) - readthread.start() - - def write(): - while True: - for e in input(): - c = ord(e) - ftdi_com.uartwrite(c) - ftdi_com.uartwrite(ord("\n")) - - - writethread = threading.Thread(target=write, daemon=True) - writethread.start() - - -def uart_virtual(ftdi_com): - import pty, serial - master, slave = pty.openpty() - s_name = os.ttyname(slave) - ser = serial.Serial(s_name) - - def read(): - while True: - s = ftdi_com.uartread() - s = bytes(chr(s).encode('utf-8')) - os.write(master, s) - - readthread = threading.Thread(target=read, daemon=True) - readthread.start() - - def write(): - while True: - for c in list(os.read(master, 100)): - ftdi_com.uartwrite(c) - - writethread = threading.Thread(target=write, daemon=True) - writethread.start() - - return s_name - - -ftdi_map = { - "uart": 0, - "dma": 1 -} -ftdi_com = FTDIComDevice(FTDI_INTERFACE_B, - mode="asynchronous", - uart_tag=ftdi_map["uart"], - dma_tag=ftdi_map["dma"], - verbose=False) -ftdi_com.open() -# test DMA -for i in range(256): - ftdi_com.dmawrite([i]) - print("%02x" %(ftdi_com.dmaread()[0]), end="") - sys.stdout.flush() -print("") -# test UART -if platform.system() == "Windows": - uart_console(ftdi_com) # redirect uart to console since pty does not exist on Windows platforms -else: - s_name = uart_virtual(ftdi_com) - print(s_name) -while True: - time.sleep(1) diff --git a/misoclib/com/liteusb/software/ftdi/fastftdi.c b/misoclib/com/liteusb/software/ftdi/fastftdi.c deleted file mode 100644 index 9f49b4162..000000000 --- a/misoclib/com/liteusb/software/ftdi/fastftdi.c +++ /dev/null @@ -1,548 +0,0 @@ -/* - * fastftdi.c - A minimal FTDI FT2232H interface for which supports bit-bang - * mode, but focuses on very high-performance support for - * synchronous FIFO mode. Requires libusb-1.0 - * - * Copyright (C) 2009 Micah Elizabeth Scott - * Copyright (C) 2015 Florent Kermarrec - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include -#include -#include "fastftdi.h" - -#if defined _WIN32 || defined _WIN64 - #include - #include - int gettimeofday (struct timeval *tp, void *tz) - { - struct _timeb timebuffer; - _ftime (&timebuffer); - tp->tv_sec = timebuffer.time; - tp->tv_usec = timebuffer.millitm * 1000; - return 0; - } -#endif - -typedef struct { - FTDIStreamCallback *callback; - void *userdata; - int result; - FTDIProgressInfo progress; -} FTDIStreamState; - -static int -DeviceInit(FTDIDevice *dev, FTDIInterface interface) -{ - int err; - - if (libusb_kernel_driver_active(dev->handle, (interface-1)) == 1) { - if ((err = libusb_detach_kernel_driver(dev->handle, (interface-1)))) { - perror("Error detaching kernel driver"); - return err; - } - } - - if ((err = libusb_set_configuration(dev->handle, 1))) { - perror("Error setting configuration"); - return err; - } - - if ((err = libusb_claim_interface(dev->handle, (interface-1)))) { - perror("Error claiming interface"); - return err; - } - - return 0; -} - - -int -FTDIDevice_Open(FTDIDevice *dev, FTDIInterface interface) -{ - int err; - - memset(dev, 0, sizeof *dev); - - if ((err = libusb_init(&dev->libusb))) { - return err; - } - - libusb_set_debug(dev->libusb, 0); - - - if (!dev->handle) { - dev->handle = libusb_open_device_with_vid_pid(dev->libusb, - FTDI_VENDOR, - FTDI_PRODUCT_FT2232H); - } - - if (!dev->handle) { - return LIBUSB_ERROR_NO_DEVICE; - } - - return DeviceInit(dev, interface); -} - - -void -FTDIDevice_Close(FTDIDevice *dev) -{ - libusb_close(dev->handle); - libusb_exit(dev->libusb); -} - - -int -FTDIDevice_Reset(FTDIDevice *dev, FTDIInterface interface) -{ - int err; - - err = libusb_reset_device(dev->handle); - if (err) - return err; - - return DeviceInit(dev, interface); -} - - -int -FTDIDevice_SetMode(FTDIDevice *dev, FTDIInterface interface, - FTDIBitmode mode, uint8_t pinDirections, - int baudRate) -{ - int err; - - err = libusb_control_transfer(dev->handle, - LIBUSB_REQUEST_TYPE_VENDOR - | LIBUSB_RECIPIENT_DEVICE - | LIBUSB_ENDPOINT_OUT, - FTDI_SET_BITMODE_REQUEST, - pinDirections | (mode << 8), - interface, - NULL, 0, - FTDI_COMMAND_TIMEOUT); - if (err) - return err; - - if (baudRate) { - int divisor; - - if (mode == FTDI_BITMODE_BITBANG) - baudRate <<= 2; - - divisor = 240000000 / baudRate; - if (divisor < 1 || divisor > 0xFFFF) { - return LIBUSB_ERROR_INVALID_PARAM; - } - - err = libusb_control_transfer(dev->handle, - LIBUSB_REQUEST_TYPE_VENDOR - | LIBUSB_RECIPIENT_DEVICE - | LIBUSB_ENDPOINT_OUT, - FTDI_SET_BAUD_REQUEST, - divisor, - interface, - NULL, 0, - FTDI_COMMAND_TIMEOUT); - if (err) - return err; - } - - return err; -} - - -/* - * Internal callback for cleaning up async writes. - */ - -static void -WriteAsyncCallback(struct libusb_transfer *transfer) -{ - free(transfer->buffer); - libusb_free_transfer(transfer); -} - - -/* - * Write to an FTDI interface, either synchronously or asynchronously. - * Async writes have no completion callback, they finish 'eventually'. - */ - -int -FTDIDevice_Write(FTDIDevice *dev, FTDIInterface interface, - uint8_t *data, size_t length, bool async) -{ - int err; - - if (async) { - struct libusb_transfer *transfer = libusb_alloc_transfer(0); - - if (!transfer) { - return LIBUSB_ERROR_NO_MEM; - } - - libusb_fill_bulk_transfer(transfer, dev->handle, FTDI_EP_OUT(interface), - malloc(length), length, (libusb_transfer_cb_fn) WriteAsyncCallback, 0, 0); - - if (!transfer->buffer) { - libusb_free_transfer(transfer); - return LIBUSB_ERROR_NO_MEM; - } - - memcpy(transfer->buffer, data, length); - err = libusb_submit_transfer(transfer); - - } else { - int transferred; - err = libusb_bulk_transfer(dev->handle, FTDI_EP_OUT(interface), - data, length, &transferred, - FTDI_COMMAND_TIMEOUT); - } - - if (err < 0) - return err; - else - return 0; -} - - -int -FTDIDevice_WriteByteSync(FTDIDevice *dev, FTDIInterface interface, uint8_t byte) -{ - return FTDIDevice_Write(dev, interface, &byte, sizeof byte, false); -} - - -int -FTDIDevice_ReadByteSync(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte) -{ - /* - * This is a simplified synchronous read, intended for bit-banging mode. - * Ignores the modem/buffer status bytes, returns just the data. - * - */ - - uint8_t packet[3]; - int transferred, err; - - err = libusb_bulk_transfer(dev->handle, FTDI_EP_IN(interface), - packet, sizeof packet, &transferred, - FTDI_COMMAND_TIMEOUT); - if (err < 0) { - return err; - } - if (transferred != sizeof packet) { - return -1; - } - - if (byte) { - *byte = packet[sizeof packet - 1]; - } - - return 0; -} - - -/* - * Internal callback for one transfer's worth of stream data. - * Split it into packets and invoke the callbacks. - */ - -static void -ReadStreamCallback(struct libusb_transfer *transfer) -{ - FTDIStreamState *state = transfer->user_data; - - if (state->result == 0) { - if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { - - int i; - uint8_t *ptr = transfer->buffer; - int length = transfer->actual_length; - int numPackets = (length + FTDI_PACKET_SIZE - 1) >> FTDI_LOG_PACKET_SIZE; - - for (i = 0; i < numPackets; i++) { - int payloadLen; - int packetLen = length; - - if (packetLen > FTDI_PACKET_SIZE) - packetLen = FTDI_PACKET_SIZE; - - payloadLen = packetLen - FTDI_HEADER_SIZE; - state->progress.current.totalBytes += payloadLen; - - state->result = state->callback(ptr + FTDI_HEADER_SIZE, payloadLen, - NULL, state->userdata); - if (state->result) - break; - - ptr += packetLen; - length -= packetLen; - } - - } else { - state->result = LIBUSB_ERROR_IO; - } - } - - if (state->result == 0) { - transfer->status = -1; - state->result = libusb_submit_transfer(transfer); - } -} - - -static double -TimevalDiff(const struct timeval *a, const struct timeval *b) -{ - return (a->tv_sec - b->tv_sec) + 1e-6 * (a->tv_usec - b->tv_usec); -} - - -/* - * Use asynchronous transfers in libusb-1.0 for high-performance - * streaming of data from a device interface back to the PC. This - * function continuously transfers data until either an error occurs - * or the callback returns a nonzero value. This function returns - * a libusb error code or the callback's return value. - * - * For every contiguous block of received data, the callback will - * be invoked. - */ - -int -FTDIDevice_ReadStream(FTDIDevice *dev, FTDIInterface interface, - FTDIStreamCallback *callback, void *userdata, - int packetsPerTransfer, int numTransfers) -{ - struct libusb_transfer **transfers; - FTDIStreamState state = { callback, userdata }; - int bufferSize = packetsPerTransfer * FTDI_PACKET_SIZE; - int xferIndex; - int err = 0; - - /* - * Set up all transfers - */ - - transfers = calloc(numTransfers, sizeof *transfers); - if (!transfers) { - err = LIBUSB_ERROR_NO_MEM; - goto cleanup; - } - - for (xferIndex = 0; xferIndex < numTransfers; xferIndex++) { - struct libusb_transfer *transfer; - - transfer = libusb_alloc_transfer(0); - transfers[xferIndex] = transfer; - if (!transfer) { - err = LIBUSB_ERROR_NO_MEM; - goto cleanup; - } - - libusb_fill_bulk_transfer(transfer, dev->handle, FTDI_EP_IN(interface), - malloc(bufferSize), bufferSize, (libusb_transfer_cb_fn) ReadStreamCallback, - &state, 0); - - if (!transfer->buffer) { - err = LIBUSB_ERROR_NO_MEM; - goto cleanup; - } - - transfer->status = -1; - err = libusb_submit_transfer(transfer); - if (err) - goto cleanup; - } - - /* - * Run the transfers, and periodically assess progress. - */ - - gettimeofday(&state.progress.first.time, NULL); - - do { - FTDIProgressInfo *progress = &state.progress; - const double progressInterval = 0.1; - struct timeval timeout = { 0, 10000 }; - struct timeval now; - - int err = libusb_handle_events_timeout(dev->libusb, &timeout); - if (!state.result) { - state.result = err; - } - - // If enough time has elapsed, update the progress - gettimeofday(&now, NULL); - if (TimevalDiff(&now, &progress->current.time) >= progressInterval) { - - progress->current.time = now; - - if (progress->prev.totalBytes) { - // We have enough information to calculate rates - - double currentTime; - - progress->totalTime = TimevalDiff(&progress->current.time, - &progress->first.time); - currentTime = TimevalDiff(&progress->current.time, - &progress->prev.time); - - progress->totalRate = progress->current.totalBytes / progress->totalTime; - progress->currentRate = (progress->current.totalBytes - - progress->prev.totalBytes) / currentTime; - } - - state.result = state.callback(NULL, 0, progress, state.userdata); - progress->prev = progress->current; - } - } while (!state.result); - - /* - * Cancel any outstanding transfers, and free memory. - */ - - cleanup: - if (transfers) { - bool done_cleanup = false; - while (!done_cleanup) - { - done_cleanup = true; - - for (xferIndex = 0; xferIndex < numTransfers; xferIndex++) { - struct libusb_transfer *transfer = transfers[xferIndex]; - - if (transfer) { - // If a transfer is in progress, cancel it - if (transfer->status == -1) { - libusb_cancel_transfer(transfer); - - // And we need to wait until we get a clean sweep - done_cleanup = false; - - // If a transfer is complete or cancelled, nuke it - } else if (transfer->status == 0 || - transfer->status == LIBUSB_TRANSFER_CANCELLED) { - free(transfer->buffer); - libusb_free_transfer(transfer); - transfers[xferIndex] = NULL; - } - } - } - - // pump events - struct timeval timeout = { 0, 10000 }; - libusb_handle_events_timeout(dev->libusb, &timeout); - } - free(transfers); - } - - if (err) - return err; - else - return state.result; -} - -/* MPSSE mode support -- see - * http://www.ftdichip.com/Support/Documents/AppNotes/AN_108_Command_Processor_for_MPSSE_and_MCU_Host_Bus_Emulation_Modes.pdf - */ - -int -FTDIDevice_MPSSE_Enable(FTDIDevice *dev, FTDIInterface interface) -{ - int err; - - /* Reset interface */ - - err = FTDIDevice_SetMode(dev, interface, FTDI_BITMODE_RESET, 0, 0); - if (err) - return err; - - /* Enable MPSSE mode */ - - err = FTDIDevice_SetMode(dev, interface, FTDI_BITMODE_MPSSE, - FTDI_SET_BITMODE_REQUEST, 0); - - return err; -} - -int -FTDIDevice_MPSSE_SetDivisor(FTDIDevice *dev, FTDIInterface interface, - uint8_t ValueL, uint8_t ValueH) -{ - uint8_t buf[3] = {FTDI_MPSSE_SETDIVISOR, 0, 0}; - - buf[1] = ValueL; - buf[2] = ValueH; - - return FTDIDevice_Write(dev, interface, buf, 3, false); -} - -int -FTDIDevice_MPSSE_SetLowByte(FTDIDevice *dev, FTDIInterface interface, uint8_t data, uint8_t dir) -{ - uint8_t buf[3] = {FTDI_MPSSE_SETLOW, 0, 0}; - - buf[1] = data; - buf[2] = dir; - - return FTDIDevice_Write(dev, interface, buf, 3, false); -} - -int -FTDIDevice_MPSSE_SetHighByte(FTDIDevice *dev, FTDIInterface interface, uint8_t data, uint8_t dir) -{ - uint8_t buf[3] = {FTDI_MPSSE_SETHIGH, 0, 0}; - - buf[1] = data; - buf[2] = dir; - - return FTDIDevice_Write(dev, interface, buf, 3, false); -} - -int -FTDIDevice_MPSSE_GetLowByte(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte) -{ - int err; - - err = FTDIDevice_WriteByteSync(dev, interface, FTDI_MPSSE_GETLOW); - if (err) - return err; - - return FTDIDevice_ReadByteSync(dev, interface, byte); -} - -int -FTDIDevice_MPSSE_GetHighByte(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte) -{ - int err; - - err = FTDIDevice_WriteByteSync(dev, interface, FTDI_MPSSE_GETHIGH); - if (err) - return err; - - return FTDIDevice_ReadByteSync(dev, interface, byte); -} diff --git a/misoclib/com/liteusb/software/ftdi/fastftdi.h b/misoclib/com/liteusb/software/ftdi/fastftdi.h deleted file mode 100644 index b42514270..000000000 --- a/misoclib/com/liteusb/software/ftdi/fastftdi.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * fastftdi.h - A minimal FTDI FT232H interface for Linux which supports - * bit-bang mode, but focuses on very high-performance support - * for synchronous FIFO mode. - * - * Copyright (C) 2009 Micah Elizabeth Scott - * Copyright (C) 2015 Florent Kermarrec - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __FASTFTDI_H -#define __FASTFTDI_H - -#include -#include -#include - -typedef enum { - FTDI_BITMODE_RESET = 0, - FTDI_BITMODE_BITBANG = 1 << 0, - FTDI_BITMODE_MPSSE = 1 << 1, - FTDI_BITMODE_SYNC_BITBANG = 1 << 2, - FTDI_BITMODE_MCU = 1 << 3, - FTDI_BITMODE_OPTO = 1 << 4, - FTDI_BITMODE_CBUS = 1 << 5, - FTDI_BITMODE_SYNC_FIFO = 1 << 6, -} FTDIBitmode; - -typedef enum { - FTDI_MPSSE_SETLOW = 0x80, - FTDI_MPSSE_SETHIGH = 0x82, - FTDI_MPSSE_GETLOW = 0x81, - FTDI_MPSSE_GETHIGH = 0x83, - FTDI_MPSSE_SETDIVISOR = 0x86, -} FTDIMPSSEOpcode; - -typedef enum { - FTDI_INTERFACE_A = 1, - FTDI_INTERFACE_B = 2, -} FTDIInterface; - -typedef struct { - libusb_context *libusb; - libusb_device_handle *handle; -} FTDIDevice; - -typedef struct { - struct { - uint64_t totalBytes; - struct timeval time; - } first, prev, current; - - double totalTime; - double totalRate; - double currentRate; -} FTDIProgressInfo; - - -/* - * USB Constants - */ - -#define FTDI_VENDOR 0x0403 -#define FTDI_PRODUCT_FT2232H 0x6010 - -#define FTDI_COMMAND_TIMEOUT 1000 - -#define FTDI_SET_BAUD_REQUEST 0x03 -#define FTDI_SET_BITMODE_REQUEST 0x0B - -#define FTDI_EP_IN(i) (0x81 + (i-1)*2) -#define FTDI_EP_OUT(i) (0x02 + (i-1)*2) - -#define FTDI_PACKET_SIZE 512 // Specific to FT2232H -#define FTDI_LOG_PACKET_SIZE 9 // 512 == 1 << 9 -#define FTDI_HEADER_SIZE 2 - -typedef int (FTDIStreamCallback)(uint8_t *buffer, int length, - FTDIProgressInfo *progress, void *userdata); - - -/* - * Public Functions - */ - -int FTDIDevice_Open(FTDIDevice *dev, FTDIInterface interface); -void FTDIDevice_Close(FTDIDevice *dev); -int FTDIDevice_Reset(FTDIDevice *dev, FTDIInterface interface); - -int FTDIDevice_SetMode(FTDIDevice *dev, FTDIInterface interface, - FTDIBitmode mode, uint8_t pinDirections, - int baudRate); - -int FTDIDevice_Write(FTDIDevice *dev, FTDIInterface interface, - uint8_t *data, size_t length, bool async); - -int FTDIDevice_WriteByteSync(FTDIDevice *dev, FTDIInterface interface, uint8_t byte); -int FTDIDevice_ReadByteSync(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte); - -int FTDIDevice_ReadStream(FTDIDevice *dev, FTDIInterface interface, - FTDIStreamCallback *callback, void *userdata, - int packetsPerTransfer, int numTransfers); - -int FTDIDevice_MPSSE_Enable(FTDIDevice *dev, FTDIInterface interface); -int FTDIDevice_MPSSE_SetDivisor(FTDIDevice *dev, FTDIInterface interface, - uint8_t ValueL, uint8_t ValueH); - -int FTDIDevice_MPSSE_SetLowByte(FTDIDevice *dev, FTDIInterface interface, - uint8_t data, uint8_t dir); -int FTDIDevice_MPSSE_SetHighByte(FTDIDevice *dev, FTDIInterface interface, - uint8_t data, uint8_t dir); - -int FTDIDevice_MPSSE_GetLowByte(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte); -int FTDIDevice_MPSSE_GetHighByte(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte); - -#endif /* __FASTFTDI_H */ diff --git a/misoclib/com/liteusb/software/ftdi/linux/Makefile b/misoclib/com/liteusb/software/ftdi/linux/Makefile deleted file mode 100644 index 14af27e71..000000000 --- a/misoclib/com/liteusb/software/ftdi/linux/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -UNAME := $(shell uname) - -LIBNAME := libftdicom - - -# Load libusb via pkg-config -PACKAGES := libusb-1.0 -CFLAGS += $(shell pkg-config --cflags $(PACKAGES)) -LDFLAGS += $(shell pkg-config --libs $(PACKAGES)) - -# Large file support -CFLAGS += $(shell getconf LFS_CFLAGS) - -CFLAGS += -fPIC - -SO := $(LIBNAME).so -SO_LDFLAGS := $(LDFLAGS) -shared - -# Local headers -CFLAGS += -I../include - -SO_OBJS := ../fastftdi.o - -CFLAGS += -O3 -g --std=c99 - -all: $(SO) - cp libftdicom.so ../libftdicom.so - -$(SO): $(SO_OBJS) - cc -o $@ $^ $(SO_LDFLAGS) - -*.o: *.h Makefile - -clean: - rm -f $(SO) $(OBJS) $(SO_OBJS) diff --git a/misoclib/com/liteusb/software/ftdi/windows/Makefile b/misoclib/com/liteusb/software/ftdi/windows/Makefile deleted file mode 100644 index 61e41b496..000000000 --- a/misoclib/com/liteusb/software/ftdi/windows/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -CC=gcc -CFLAGS_DLL =-Wall -O0 -g -shared -Wl,--subsystem,windows -DDLL -LIBS= -lusb-1.0 - -all: libftdicom.dll - cp libftdicom.dll ../libftdicom.dll - -libftdicom.dll: ../fastftdi.c - $(CC) -o $@ $(CFLAGS_DLL) $^ $(LIBS) - -clean: - rm -f libftdicom.dll ../libftdicom.dll diff --git a/misoclib/com/liteusb/software/wishbone.py b/misoclib/com/liteusb/software/wishbone.py deleted file mode 100644 index e0eeb30d1..000000000 --- a/misoclib/com/liteusb/software/wishbone.py +++ /dev/null @@ -1,81 +0,0 @@ -from misoclib.tools.litescope.software.driver.reg import * -from misoclib.com.liteusb.software.ftdi import FTDIComDevice - -class LiteUSBWishboneDriverFTDI: - cmds = { - "write": 0x01, - "read": 0x02 - } - def __init__(self, interface, mode, tag, addrmap=None, busword=8, debug=False): - self.interface = interface - self.mode = mode - self.tag = tag - self.debug = debug - self.com = FTDIComDevice(self.interface, - mode=mode, - uart_tag=tag, - dma_tag=16, # XXX FIXME - verbose=debug) - if addrmap is not None: - self.regs = build_map(addrmap, busword, self.read, self.write) - - def open(self): - self.com.open() - - def close(self): - self.com.close() - - def read(self, addr, burst_length=1): - datas = [] - msg = [] - self.com.uartflush() - msg.append(self.cmds["read"]) - msg.append(burst_length) - word_addr = addr//4 - msg.append((word_addr >> 24) & 0xff) - msg.append((word_addr >> 16) & 0xff) - msg.append((word_addr >> 8) & 0xff) - msg.append((word_addr >> 0) & 0xff) - self.com.uartwrite(msg) - for i in range(burst_length): - data = 0 - for k in range(4): - data = data << 8 - data |= self.com.uartread() - if self.debug: - print("RD {:08X} @ {:08X}".format(data, addr + 4*i)) - datas.append(data) - if burst_length == 1: - return datas[0] - else: - return datas - - def write(self, addr, data): - if isinstance(data, list): - burst_length = len(data) - else: - burst_length = 1 - data = [data] - msg = [] - msg.append(self.cmds["write"]) - msg.append(burst_length) - word_addr = addr//4 - msg.append((word_addr >> 24) & 0xff) - msg.append((word_addr >> 16) & 0xff) - msg.append((word_addr >> 8) & 0xff) - msg.append((word_addr >> 0) & 0xff) - for i in range(len(data)): - dat = data[i] - for j in range(4): - msg.append((dat >> 24) & 0xff) - dat = dat << 8 - if self.debug: - print("WR {:08X} @ {:08X}".format(data[i], addr + 4*i)) - self.com.uartwrite(msg) - - -def LiteUSBWishboneDriver(chip="ft2232h", *args, **kwargs): - drivers = { - "ft2232h": LiteUSBWishboneDriverFTDI - } - return drivers[chip](*args, **kwargs) diff --git a/misoclib/com/liteusb/test/Makefile b/misoclib/com/liteusb/test/Makefile deleted file mode 100644 index bf90b0741..000000000 --- a/misoclib/com/liteusb/test/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -MSCDIR = ../../ -PYTHON = python3 - -CMD = PYTHONPATH=$(MSCDIR) $(PYTHON) - -ft245_sync_tb: - $(CMD) ft245_sync_tb.py - -ft245_async_tb: - $(CMD) ft245_async_tb.py - -core_tb: - $(CMD) core_tb.py diff --git a/misoclib/com/liteusb/test/__init__.py b/misoclib/com/liteusb/test/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/misoclib/com/liteusb/test/common.py b/misoclib/com/liteusb/test/common.py deleted file mode 100644 index 3355987ec..000000000 --- a/misoclib/com/liteusb/test/common.py +++ /dev/null @@ -1,16 +0,0 @@ -import random - -def randn(max_n): - return random.randint(0, max_n-1) - - -class RandRun: - def __init__(self, level=0): - self.run = True - self.level = level - - def do_simulation(self, selfp): - self.run = True - n = randn(100) - if n < self.level: - self.run = False diff --git a/misoclib/com/liteusb/test/core_tb.py b/misoclib/com/liteusb/test/core_tb.py deleted file mode 100644 index 813691d73..000000000 --- a/misoclib/com/liteusb/test/core_tb.py +++ /dev/null @@ -1,148 +0,0 @@ -import binascii - -from migen.fhdl.std import * -from migen.flow.actor import * -from migen.fhdl.specials import * - -from migen.sim.generic import run_simulation - -from misoclib.com.liteusb.common import * -from misoclib.com.liteusb.core import LiteUSBCore -from misoclib.com.liteusb.test.common import * - -# XXX for now use it from liteeth to avoid duplication -from misoclib.com.liteeth.test.common import * - -def crc32(l): - crc = [] - crc_bytes = split_bytes(binascii.crc32(bytes(l)), 4, "little") - for byte in crc_bytes: - crc.append(int(byte)) - return crc - - -class USBPacket(Packet): - def __init__(self, init=[]): - Packet.__init__(self, init) - self.crc_error = False - - def check_remove_crc(self): - if comp(self[-4:], crc32(self[:-4])): - for i in range(4): - self.pop() - return False - else: - return True - - def decode_remove_header(self): - header = [] - for byte in self[:packet_header.length]: - header.append(self.pop(0)) - for k, v in sorted(packet_header.fields.items()): - setattr(self, k, get_field_data(v, header)) - - def decode(self): - # XXX Header should be protected by CRC - self.decode_remove_header() - self.crc_error = self.check_remove_crc() - if self.crc_error: - raise ValueError # XXX handle this properly - - def encode_header(self): - header = 0 - for k, v in sorted(packet_header.fields.items()): - value = merge_bytes(split_bytes(getattr(self, k), - math.ceil(v.width/8)), - "little") - header += (value << v.offset+(v.byte*8)) - for d in split_bytes(header, packet_header.length): - self.insert(0, d) - - def insert_crc(self): - for d in crc32(self): - self.append(d) - - def encode(self): - # XXX Header should be protected by CRC - self.insert_crc() - self.encode_header() - - def __repr__(self): - r = "--------\n" - for k in sorted(packet_header.fields.keys()): - r += k + " : 0x{:0x}\n".format(getattr(self, k)) - r += "payload: " - for d in self: - r += "{:02x}".format(d) - return r - - -class PHYModel(Module): - def __init__(self): - self.sink = Sink(phy_description(8)) - self.source = Source(phy_description(8)) - -class TB(Module): - def __init__(self): - self.submodules.phy = PHYModel() - self.submodules.core = LiteUSBCore(self.phy) - - self.submodules.phy_streamer = PacketStreamer(phy_description(8)) - self.submodules.phy_streamer_randomizer = AckRandomizer(phy_description(8), level=0) - - self.submodules.phy_logger_randomizer = AckRandomizer(phy_description(8), level=0) - self.submodules.phy_logger = PacketLogger(phy_description(8)) - - self.submodules.core_streamer = PacketStreamer(user_description(8)) - self.submodules.core_streamer_randomizer = AckRandomizer(user_description(8), level=10) - - self.submodules.core_logger = PacketLogger(user_description(8)) - self.submodules.core_logger_randomizer = AckRandomizer(user_description(8), level=10) - - - user_port = self.core.crossbar.get_port(0x12) - - - self.comb += [ - Record.connect(self.phy_streamer.source, self.phy_streamer_randomizer.sink), - Record.connect(self.phy_streamer_randomizer.source, self.phy.source), - - Record.connect(self.core_streamer.source, self.core_streamer_randomizer.sink), - Record.connect(self.core_streamer_randomizer.source, user_port.sink), - - Record.connect(user_port.source, self.core_logger_randomizer.sink), - Record.connect(self.core_logger_randomizer.source, self.core_logger.sink), - - Record.connect(self.phy.sink, self.phy_logger_randomizer.sink), - Record.connect(self.phy_logger_randomizer.source, self.phy_logger.sink) - ] - - def gen_simulation(self, selfp): - packet = USBPacket([i for i in range(128)]) - packet.preamble = 0x5AA55AA5 - packet.dst = 0x12 - packet.length = 128 + 4 - packet.encode() - yield from self.phy_streamer.send(packet) - for i in range(32): - yield - print(self.core_logger.packet) - - selfp.core_streamer.source.dst = 0x12 - selfp.core_streamer.source.length = 128 + 4 - packet = Packet([i for i in range(128)]) - yield from self.core_streamer.send(packet) - for i in range(32): - yield - for d in self.phy_logger.packet: - print("%02x" %d, end="") - print("") - packet = USBPacket(self.phy_logger.packet) - packet.decode() - print(packet) - -def main(): - run_simulation(TB(), ncycles=2000, vcd_name="my.vcd", keep_files=True) - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/misoclib/com/liteusb/test/ft245_async_tb.py b/misoclib/com/liteusb/test/ft245_async_tb.py deleted file mode 100644 index dcc259923..000000000 --- a/misoclib/com/liteusb/test/ft245_async_tb.py +++ /dev/null @@ -1,139 +0,0 @@ -from migen.fhdl.std import * -from migen.flow.actor import * -from migen.fhdl.specials import * - -from migen.sim.generic import run_simulation - -from misoclib.com.liteusb.common import * -from misoclib.com.liteusb.phy.ft245 import FT245PHYAsynchronous -from misoclib.com.liteusb.test.common import * - -# XXX for now use it from liteeth to avoid duplication -from misoclib.com.liteeth.test.common import * - -class FT245AsynchronousModel(Module): - def __init__(self, clk_freq, rd_data): - self.clk_freq = clk_freq - self.rd_data = [0] + rd_data - self.rd_idx = 0 - - # timings - self.tRDInactive = self.ns(49) # RXF# inactive after RD# cycle - self.tWRInactive = self.ns(49) # TXE# inactive after WR# cycle - - # pads - self.data = Signal(8) - self.rxf_n = Signal(reset=1) - self.txe_n = Signal(reset=1) - self.rd_n = Signal(reset=1) - self.wr_n = Signal(reset=1) - - self.init = True - self.wr_data = [] - self.wait_wr_n = False - self.rd_done = 0 - - - self.data_w = Signal(8) - self.data_r = Signal(8) - - self.specials += Tristate(self.data, self.data_r, ~self.rd_n, self.data_w) - - self.last_wr_n = 1 - self.last_rd_n = 1 - - self.wr_delay = 0 - self.rd_delay = 0 - - def wr_sim(self, selfp): - if self.wr_delay: - selfp.txe_n = 1 - self.wr_delay = self.wr_delay - 1 - else: - if (not selfp.wr_n and self.last_wr_n) and not selfp.txe_n: - self.wr_data.append(selfp.data_w) - self.wr_delay = self.tWRInactive - self.last_wr_n = selfp.wr_n - - selfp.txe_n = 0 - - def rd_sim(self, selfp): - if self.rd_delay: - selfp.rxf_n = 1 - self.rd_delay = self.rd_delay - 1 - else: - rxf_n = selfp.rxf_n - if self.rd_idx < len(self.rd_data)-1: - self.rd_done = selfp.rxf_n - selfp.rxf_n = 0 - else: - selfp.rxf_n = self.rd_done - - if not selfp.rd_n and self.last_rd_n: - if self.rd_idx < len(self.rd_data)-1: - self.rd_idx += not rxf_n - selfp.data_r = self.rd_data[self.rd_idx] - self.rd_done = 1 - if selfp.rd_n and not self.last_rd_n: - self.rd_delay = self.tRDInactive - - self.last_rd_n = selfp.rd_n - - def do_simulation(self, selfp): - if self.init: - selfp.rxf_n = 0 - self.wr_data = [] - self.init = False - self.wr_sim(selfp) - self.rd_sim(selfp) - - def ns(self, t, margin=True): - clk_period_ns = 1000000000/self.clk_freq - if margin: - t += clk_period_ns/2 - return math.ceil(t/clk_period_ns) - - -test_packet = [i%256 for i in range(128)] - - -class TB(Module): - def __init__(self): - clk_freq = 50*1000000 - self.submodules.model = FT245AsynchronousModel(clk_freq, test_packet) - self.submodules.phy = FT245PHYAsynchronous(self.model, clk_freq) - - self.submodules.streamer = PacketStreamer(phy_description(8)) - self.submodules.streamer_randomizer = AckRandomizer(phy_description(8), level=10) - - self.submodules.logger_randomizer = AckRandomizer(phy_description(8), level=10) - self.submodules.logger = PacketLogger(phy_description(8)) - - self.comb += [ - Record.connect(self.streamer.source, self.streamer_randomizer.sink), - self.phy.sink.stb.eq(self.streamer_randomizer.source.stb), - self.phy.sink.data.eq(self.streamer_randomizer.source.data), - self.streamer_randomizer.source.ack.eq(self.phy.sink.ack), - - self.logger_randomizer.sink.stb.eq(self.phy.source.stb), - self.logger_randomizer.sink.data.eq(self.phy.source.data), - self.phy.source.ack.eq(self.logger_randomizer.sink.ack), - Record.connect(self.logger_randomizer.source, self.logger.sink) - ] - - def gen_simulation(self, selfp): - yield from self.streamer.send(Packet(test_packet)) - for i in range(4000): - yield - s, l, e = check(test_packet, self.model.wr_data) - print("shift " + str(s) + " / length " + str(l) + " / errors " + str(e)) - - s, l, e = check(test_packet, self.logger.packet) - print("shift " + str(s) + " / length " + str(l) + " / errors " + str(e)) - - -def main(): - run_simulation(TB(), ncycles=8000, vcd_name="my.vcd", keep_files=True) - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/misoclib/com/liteusb/test/ft245_sync_tb.py b/misoclib/com/liteusb/test/ft245_sync_tb.py deleted file mode 100644 index ffa2faf34..000000000 --- a/misoclib/com/liteusb/test/ft245_sync_tb.py +++ /dev/null @@ -1,127 +0,0 @@ -from migen.fhdl.std import * -from migen.flow.actor import * -from migen.fhdl.specials import * - -from migen.sim.generic import run_simulation - -from misoclib.com.liteusb.common import * -from misoclib.com.liteusb.phy.ft245 import FT245PHYSynchronous -from misoclib.com.liteusb.test.common import * - -# XXX for now use it from liteeth to avoid duplication -from misoclib.com.liteeth.test.common import * - -class FT245SynchronousModel(Module, RandRun): - def __init__(self, rd_data): - RandRun.__init__(self, 10) - self.rd_data = [0] + rd_data - self.rd_idx = 0 - - # pads - self.data = Signal(8) - self.rxf_n = Signal(reset=1) - self.txe_n = Signal(reset=1) - self.rd_n = Signal(reset=1) - self.wr_n = Signal(reset=1) - self.oe_n = Signal(reset=1) - self.siwua = Signal() - self.pwren_n = Signal(reset=1) - - self.init = True - self.wr_data = [] - self.wait_wr_n = False - self.rd_done = 0 - - - self.data_w = Signal(8) - self.data_r = Signal(8) - - self.specials += Tristate(self.data, self.data_r, ~self.oe_n, self.data_w) - - def wr_sim(self, selfp): - if not selfp.wr_n and not selfp.txe_n: - self.wr_data.append(selfp.data_w) - self.wait_wr_n = False - - if not self.wait_wr_n: - if self.run: - selfp.txe_n = 1 - else: - if selfp.txe_n: - self.wait_wr_n = True - selfp.txe_n = 0 - - def rd_sim(self, selfp): - rxf_n = selfp.rxf_n - if self.run: - if self.rd_idx < len(self.rd_data)-1: - self.rd_done = selfp.rxf_n - selfp.rxf_n = 0 - else: - selfp.rxf_n = self.rd_done - else: - selfp.rxf_n = self.rd_done - - if not selfp.rd_n and not selfp.oe_n: - if self.rd_idx < len(self.rd_data)-1: - self.rd_idx += not rxf_n - selfp.data_r = self.rd_data[self.rd_idx] - self.rd_done = 1 - - def do_simulation(self, selfp): - RandRun.do_simulation(self, selfp) - if self.init: - selfp.rxf_n = 0 - self.wr_data = [] - self.init = False - self.wr_sim(selfp) - self.rd_sim(selfp) - -test_packet = [i%256 for i in range(512)] - - -class TB(Module): - def __init__(self): - self.submodules.model = FT245SynchronousModel(test_packet) - self.submodules.phy = FT245PHYSynchronous(self.model) - - self.submodules.streamer = PacketStreamer(phy_description(8)) - self.submodules.streamer_randomizer = AckRandomizer(phy_description(8), level=10) - - self.submodules.logger_randomizer = AckRandomizer(phy_description(8), level=10) - self.submodules.logger = PacketLogger(phy_description(8)) - - self.comb += [ - Record.connect(self.streamer.source, self.streamer_randomizer.sink), - self.phy.sink.stb.eq(self.streamer_randomizer.source.stb), - self.phy.sink.data.eq(self.streamer_randomizer.source.data), - self.streamer_randomizer.source.ack.eq(self.phy.sink.ack), - - self.logger_randomizer.sink.stb.eq(self.phy.source.stb), - self.logger_randomizer.sink.data.eq(self.phy.source.data), - self.phy.source.ack.eq(self.logger_randomizer.sink.ack), - Record.connect(self.logger_randomizer.source, self.logger.sink) - ] - - # Use sys_clk as ftdi_clk in simulation - self.comb += [ - ClockSignal("ftdi").eq(ClockSignal()), - ResetSignal("ftdi").eq(ResetSignal()) - ] - - def gen_simulation(self, selfp): - yield from self.streamer.send(Packet(test_packet)) - for i in range(2000): - yield - s, l, e = check(test_packet, self.model.wr_data) - print("shift " + str(s) + " / length " + str(l) + " / errors " + str(e)) - - s, l, e = check(test_packet, self.logger.packet[1:]) - print("shift " + str(s) + " / length " + str(l) + " / errors " + str(e)) - - -def main(): - run_simulation(TB(), ncycles=8000, vcd_name="my.vcd", keep_files=True) - -if __name__ == "__main__": - main() \ No newline at end of file