From 35e3853f6ede3a55e3dbd1411e6b2d90fc8293b4 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 7 Sep 2015 11:11:43 +0200 Subject: [PATCH] move litepcie to a separate repo (https://github.com/enjoy-digital/litepcie) --- README | 1 - misoclib/com/litepcie/LICENSE | 28 - misoclib/com/litepcie/README | 123 ---- misoclib/com/litepcie/__init__.py | 0 misoclib/com/litepcie/common.py | 67 -- misoclib/com/litepcie/core/__init__.py | 40 -- misoclib/com/litepcie/core/irq/__init__.py | 0 .../litepcie/core/irq/interrupt_controller.py | 26 - misoclib/com/litepcie/core/packet/__init__.py | 0 misoclib/com/litepcie/core/packet/common.py | 117 ---- .../com/litepcie/core/packet/depacketizer.py | 160 ----- .../com/litepcie/core/packet/packetizer.py | 187 ----- misoclib/com/litepcie/core/switch/__init__.py | 0 misoclib/com/litepcie/core/switch/common.py | 34 - misoclib/com/litepcie/core/switch/crossbar.py | 120 ---- .../core/switch/request_controller.py | 175 ----- misoclib/com/litepcie/doc/.keep_me | 0 .../com/litepcie/example_designs/__init__.py | 0 .../litepcie/example_designs/build/.keep_me | 0 misoclib/com/litepcie/example_designs/make.py | 148 ---- .../example_designs/targets/__init__.py | 0 .../litepcie/example_designs/targets/dma.py | 99 --- .../com/litepcie/example_designs/test/make.py | 41 -- .../example_designs/test/test_regs.py | 14 - misoclib/com/litepcie/frontend/__init__.py | 0 .../com/litepcie/frontend/dma/__init__.py | 121 ---- misoclib/com/litepcie/frontend/dma/common.py | 164 ----- misoclib/com/litepcie/frontend/dma/reader.py | 79 --- misoclib/com/litepcie/frontend/dma/writer.py | 88 --- misoclib/com/litepcie/frontend/wishbone.py | 67 -- misoclib/com/litepcie/litepcie-version.txt | 2 - misoclib/com/litepcie/phy/__init__.py | 0 misoclib/com/litepcie/phy/s7pciephy.py | 163 ----- misoclib/com/litepcie/software/__init__.py | 0 .../litepcie/software/linux/kernel/Makefile | 16 - .../com/litepcie/software/linux/kernel/README | 9 - .../litepcie/software/linux/kernel/config.h | 13 - .../litepcie/software/linux/kernel/flags.h | 10 - .../litepcie/software/linux/kernel/init.sh | 7 - .../litepcie/software/linux/kernel/litepcie.h | 50 -- .../com/litepcie/software/linux/kernel/main.c | 639 ------------------ .../com/litepcie/software/linux/user/Makefile | 19 - .../com/litepcie/software/linux/user/cutils.h | 31 - .../software/linux/user/litepcie_lib.c | 182 ----- .../software/linux/user/litepcie_lib.h | 53 -- .../software/linux/user/litepcie_util.c | 259 ------- misoclib/com/litepcie/software/wishbone.py | 65 -- misoclib/com/litepcie/test/Makefile | 10 - misoclib/com/litepcie/test/common.py | 36 - misoclib/com/litepcie/test/dma_tb.py | 177 ----- misoclib/com/litepcie/test/model/__init__.py | 0 misoclib/com/litepcie/test/model/chipset.py | 142 ---- misoclib/com/litepcie/test/model/host.py | 64 -- misoclib/com/litepcie/test/model/phy.py | 144 ---- misoclib/com/litepcie/test/model/tlp.py | 94 --- misoclib/com/litepcie/test/wishbone_tb.py | 40 -- 56 files changed, 4124 deletions(-) delete mode 100644 misoclib/com/litepcie/LICENSE delete mode 100644 misoclib/com/litepcie/README delete mode 100644 misoclib/com/litepcie/__init__.py delete mode 100644 misoclib/com/litepcie/common.py delete mode 100644 misoclib/com/litepcie/core/__init__.py delete mode 100644 misoclib/com/litepcie/core/irq/__init__.py delete mode 100644 misoclib/com/litepcie/core/irq/interrupt_controller.py delete mode 100644 misoclib/com/litepcie/core/packet/__init__.py delete mode 100644 misoclib/com/litepcie/core/packet/common.py delete mode 100644 misoclib/com/litepcie/core/packet/depacketizer.py delete mode 100644 misoclib/com/litepcie/core/packet/packetizer.py delete mode 100644 misoclib/com/litepcie/core/switch/__init__.py delete mode 100644 misoclib/com/litepcie/core/switch/common.py delete mode 100644 misoclib/com/litepcie/core/switch/crossbar.py delete mode 100644 misoclib/com/litepcie/core/switch/request_controller.py delete mode 100644 misoclib/com/litepcie/doc/.keep_me delete mode 100644 misoclib/com/litepcie/example_designs/__init__.py delete mode 100644 misoclib/com/litepcie/example_designs/build/.keep_me delete mode 100755 misoclib/com/litepcie/example_designs/make.py delete mode 100644 misoclib/com/litepcie/example_designs/targets/__init__.py delete mode 100644 misoclib/com/litepcie/example_designs/targets/dma.py delete mode 100755 misoclib/com/litepcie/example_designs/test/make.py delete mode 100644 misoclib/com/litepcie/example_designs/test/test_regs.py delete mode 100644 misoclib/com/litepcie/frontend/__init__.py delete mode 100644 misoclib/com/litepcie/frontend/dma/__init__.py delete mode 100644 misoclib/com/litepcie/frontend/dma/common.py delete mode 100644 misoclib/com/litepcie/frontend/dma/reader.py delete mode 100644 misoclib/com/litepcie/frontend/dma/writer.py delete mode 100644 misoclib/com/litepcie/frontend/wishbone.py delete mode 100644 misoclib/com/litepcie/litepcie-version.txt delete mode 100644 misoclib/com/litepcie/phy/__init__.py delete mode 100644 misoclib/com/litepcie/phy/s7pciephy.py delete mode 100644 misoclib/com/litepcie/software/__init__.py delete mode 100644 misoclib/com/litepcie/software/linux/kernel/Makefile delete mode 100644 misoclib/com/litepcie/software/linux/kernel/README delete mode 100644 misoclib/com/litepcie/software/linux/kernel/config.h delete mode 100644 misoclib/com/litepcie/software/linux/kernel/flags.h delete mode 100755 misoclib/com/litepcie/software/linux/kernel/init.sh delete mode 100644 misoclib/com/litepcie/software/linux/kernel/litepcie.h delete mode 100644 misoclib/com/litepcie/software/linux/kernel/main.c delete mode 100644 misoclib/com/litepcie/software/linux/user/Makefile delete mode 100644 misoclib/com/litepcie/software/linux/user/cutils.h delete mode 100644 misoclib/com/litepcie/software/linux/user/litepcie_lib.c delete mode 100644 misoclib/com/litepcie/software/linux/user/litepcie_lib.h delete mode 100644 misoclib/com/litepcie/software/linux/user/litepcie_util.c delete mode 100644 misoclib/com/litepcie/software/wishbone.py delete mode 100644 misoclib/com/litepcie/test/Makefile delete mode 100644 misoclib/com/litepcie/test/common.py delete mode 100644 misoclib/com/litepcie/test/dma_tb.py delete mode 100644 misoclib/com/litepcie/test/model/__init__.py delete mode 100644 misoclib/com/litepcie/test/model/chipset.py delete mode 100644 misoclib/com/litepcie/test/model/host.py delete mode 100644 misoclib/com/litepcie/test/model/phy.py delete mode 100644 misoclib/com/litepcie/test/model/tlp.py delete mode 100644 misoclib/com/litepcie/test/wishbone_tb.py diff --git a/README b/README index ca8b19c9..a5742005 100644 --- a/README +++ b/README @@ -29,7 +29,6 @@ and logic, etc. * Possibility to encapsulate legacy Verilog/VHDL code. * Complex FPGA cores that can be used integrated in MiSoC or standalone: - - LitePcie: a small footprint and configuragle PCIe core - LiteEth: a small footprint and configurable Ethernet core - LiteSATA: a small footprint and configurable SATA core - LiteScope: a small footprint and configurable logic analyzer core diff --git a/misoclib/com/litepcie/LICENSE b/misoclib/com/litepcie/LICENSE deleted file mode 100644 index 9a4df7d1..00000000 --- a/misoclib/com/litepcie/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Unless otherwise noted, LitePCIe 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/litepcie/README b/misoclib/com/litepcie/README deleted file mode 100644 index 82b4959d..00000000 --- a/misoclib/com/litepcie/README +++ /dev/null @@ -1,123 +0,0 @@ - __ _ __ ___ _________ - / / (_) /____ / _ \/ ___/ _/__ - / /__/ / __/ -_) ___/ /___/ // -_) - /____/_/\__/\__/_/ \___/___/\__/ - - Copyright 2015 / EnjoyDigital / M-Labs Ltd - - A small footprint and configurable PCIe core - with MMAP interface and scatter-gather DMA - developed by EnjoyDigital - -[> Doc ---------- -XXX - -[> Intro ---------- -LitePCIe provides a small footprint and configurable PCIe gen1/2 core. - -LitePCIe 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. - -LitePCIe 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. - -LitePCIe 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 ------------ -- 7-Series Artix7/Kintex7 PHY (up to PCIe Gen2 X2) -- Scatter-gather DMA -- Wishbone bridge -- Linux driver with DMA loopback demo and Sysfs - - -[> Possibles improvements -------------------------- -- add standardized interfaces (AXI, Avalon-ST) -- add support for PCIe Gen2 X4 and X8 on 7-Series -- clean up 7-Series wrappers -- add Altera/Lattice support -- ... 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 ------------------- -1. Install Python3 and your vendor's software - -2. Obtain Migen and install it: - git clone https://github.com/m-labs/migen - cd migen - python3 setup.py install - cd .. - -3. Obtain MiSoC: - git clone https://github.com/m-labs/misoc --recursive - -4. Build and load PCIe DMA loopback design (only for KC705 for now): - go to misoclib/com/litepcie/example_designs/ - run ./make.py all load-bitstream - -5. Build and load Linux Driver: - go to misoclib/com/litepcie/software/linux/kernel - make all - ./init.sh - -5. Build and load Linux utilities: - go to misoclib/com/litepcie/software/linux/user - make all - ./litepcie_util dma_loopback_test - -[> Simulations: - Simulations are available in misoclib/com/litepcie/test: - - wishbone_tb - - dma_tb - To run a simulation, move to misoclib/com/litepcie/test/ and run: - make simulation_name - -[> Tests : - A DMA loopback example with Wishbone over Sysfs is provided. - Please go to Getting Started section to see how to run the tests. - -[> License ------------ -LitePCIe is released under the very permissive two-clause BSD license. Under -the terms of this license, you are authorized to use LiteEth 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 LitePCIe - - cite LitePCIe 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 LitePCIe. - -[> Support and consulting --------------------------- -We love open-source hardware and like sharing our designs with others. - -LitePCIe is mainly developed and maintained by EnjoyDigital. - -If you would like to know more about LitePCIe 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 diff --git a/misoclib/com/litepcie/__init__.py b/misoclib/com/litepcie/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/com/litepcie/common.py b/misoclib/com/litepcie/common.py deleted file mode 100644 index 81f75cb7..00000000 --- a/misoclib/com/litepcie/common.py +++ /dev/null @@ -1,67 +0,0 @@ -from migen.fhdl.std import * -from migen.genlib.record import * -from migen.genlib.misc import reverse_bytes -from migen.flow.actor import * -from migen.actorlib.packet import Arbiter, Dispatcher - -KB = 1024 -MB = 1024*KB -GB = 1024*MB - - -def get_bar_mask(size): - mask = 0 - found = 0 - for i in range(32): - if size%2: - found = 1 - if found: - mask |= (1 << i) - size = size >> 1 - return mask - -def phy_layout(dw): - layout = [ - ("dat", dw), - ("be", dw//8) - ] - return EndpointDescription(layout, packetized=True) - - -def request_layout(dw): - layout = [ - ("we", 1), - ("adr", 32), - ("len", 10), - ("req_id", 16), - ("tag", 8), - ("dat", dw), - ("channel", 8), # for routing - ("user_id", 8) # for packet identification - ] - return EndpointDescription(layout, packetized=True) - - -def completion_layout(dw): - layout = [ - ("adr", 32), - ("len", 10), - ("last", 1), - ("req_id", 16), - ("cmp_id", 16), - ("err", 1), - ("tag", 8), - ("dat", dw), - ("channel", 8), # for routing - ("user_id", 8) # for packet identification - ] - return EndpointDescription(layout, packetized=True) - - -def interrupt_layout(): - return [("dat", 8)] - - -def dma_layout(dw): - layout = [("data", dw)] - return EndpointDescription(layout, packetized=True) diff --git a/misoclib/com/litepcie/core/__init__.py b/misoclib/com/litepcie/core/__init__.py deleted file mode 100644 index 2ab8da2f..00000000 --- a/misoclib/com/litepcie/core/__init__.py +++ /dev/null @@ -1,40 +0,0 @@ -from migen.fhdl.std import * -from migen.bank.description import * -from migen.genlib.record import * - -from misoclib.com.litepcie.core.packet.depacketizer import Depacketizer -from misoclib.com.litepcie.core.packet.packetizer import Packetizer -from misoclib.com.litepcie.core.switch.crossbar import Crossbar - - -class Endpoint(Module): - def __init__(self, phy, max_pending_requests=4, with_reordering=False): - self.phy = phy - self.max_pending_requests = max_pending_requests - - # # # - - # TLP Packetizer / Depacketizer - depacketizer = Depacketizer(phy.dw, phy.bar0_mask) - packetizer = Packetizer(phy.dw) - self.submodules += depacketizer, packetizer - self.comb += [ - phy.source.connect(depacketizer.sink), - packetizer.source.connect(phy.sink) - ] - - # Crossbar - self.crossbar = crossbar = Crossbar(phy.dw, max_pending_requests, with_reordering) - self.submodules += crossbar - - # (Slave) HOST initiates the transactions - self.comb += [ - Record.connect(depacketizer.req_source, crossbar.phy_slave.sink), - Record.connect(crossbar.phy_slave.source, packetizer.cmp_sink) - ] - - # (Master) FPGA initiates the transactions - self.comb += [ - Record.connect(crossbar.phy_master.source, packetizer.req_sink), - Record.connect(depacketizer.cmp_source, crossbar.phy_master.sink) - ] diff --git a/misoclib/com/litepcie/core/irq/__init__.py b/misoclib/com/litepcie/core/irq/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/com/litepcie/core/irq/interrupt_controller.py b/misoclib/com/litepcie/core/irq/interrupt_controller.py deleted file mode 100644 index cc5bcb6c..00000000 --- a/misoclib/com/litepcie/core/irq/interrupt_controller.py +++ /dev/null @@ -1,26 +0,0 @@ -from migen.fhdl.std import * -from migen.bank.description import * - -from misoclib.com.litepcie.common import * - - -class InterruptController(Module, AutoCSR): - def __init__(self, n_irqs=32): - self.irqs = Signal(n_irqs) - self.source = Source(interrupt_layout()) - - self._enable = CSRStorage(n_irqs) - self._clear = CSR(n_irqs) - self._vector = CSRStatus(n_irqs) - - # # # - - enable = self._enable.storage - clear = Signal(n_irqs) - self.comb += If(self._clear.re, clear.eq(self._clear.r)) - - # memorize and clear irqs - vector = self._vector.status - self.sync += vector.eq(~clear & (vector | self.irqs)) - - self.comb += self.source.stb.eq((vector & enable) != 0) diff --git a/misoclib/com/litepcie/core/packet/__init__.py b/misoclib/com/litepcie/core/packet/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/com/litepcie/core/packet/common.py b/misoclib/com/litepcie/core/packet/common.py deleted file mode 100644 index 2b7dedf3..00000000 --- a/misoclib/com/litepcie/core/packet/common.py +++ /dev/null @@ -1,117 +0,0 @@ -from migen.fhdl.std import * -from migen.genlib.record import * -from migen.flow.actor import EndpointDescription, Sink, Source -from migen.actorlib.packet import HeaderField, Header - -from misoclib.com.litepcie.common import * - -# constants -fmt_type_dict = { - "mem_rd32": 0b0000000, - "mem_wr32": 0b1000000, - "mem_rd64": 0b0100000, - "mem_wr64": 0b1100000, - - "cpld": 0b1001010, - "cpl": 0b0001010 -} - -cpl_dict = { - "sc": 0b000, - "ur": 0b001, - "crs": 0b010, - "ca": 0b011 -} - -max_request_size = 512 - - -# headers -tlp_common_header_length = 16 -tlp_common_header_fields = { - "fmt": HeaderField(0*4, 29, 2), - "type": HeaderField(0*4, 24, 5), -} -tlp_common_header = Header(tlp_common_header_fields, - tlp_common_header_length, - swap_field_bytes=False) - - -tlp_request_header_length = 16 -tlp_request_header_fields = { - "fmt": HeaderField(0*4, 29, 2), - "type": HeaderField(0*4, 24, 5), - "tc": HeaderField(0*4, 20, 3), - "td": HeaderField(0*4, 15, 1), - "ep": HeaderField(0*4, 14, 1), - "attr": HeaderField(0*4, 12, 2), - "length": HeaderField(0*4, 0, 10), - - "requester_id": HeaderField(1*4, 16, 16), - "tag": HeaderField(1*4, 8, 8), - "last_be": HeaderField(1*4, 4, 4), - "first_be": HeaderField(1*4, 0, 4), - - "address": HeaderField(2*4, 2, 30), -} -tlp_request_header = Header(tlp_request_header_fields, - tlp_request_header_length, - swap_field_bytes=False) - - -tlp_completion_header_length = 16 -tlp_completion_header_fields = { - "fmt": HeaderField(0*4, 29, 2), - "type": HeaderField(0*4, 24, 5), - "tc": HeaderField(0*4, 20, 3), - "td": HeaderField(0*4, 15, 1), - "ep": HeaderField(0*4, 14, 1), - "attr": HeaderField(0*4, 12, 2), - "length": HeaderField(0*4, 0, 10), - - "completer_id": HeaderField(1*4, 16, 16), - "status": HeaderField(1*4, 13, 3), - "bcm": HeaderField(1*4, 12, 1), - "byte_count": HeaderField(1*4, 0, 12), - - "requester_id": HeaderField(2*4, 16, 16), - "tag": HeaderField(2*4, 8, 8), - "lower_address": HeaderField(2*4, 0, 7), -} -tlp_completion_header = Header(tlp_completion_header_fields, - tlp_completion_header_length, - swap_field_bytes=False) - - -# layouts -def tlp_raw_layout(dw): - layout = [ - ("header", 4*32), - ("dat", dw), - ("be", dw//8) - ] - return EndpointDescription(layout, packetized=True) - - -def tlp_common_layout(dw): - layout = tlp_common_header.get_layout() + [ - ("dat", dw), - ("be", dw//8) - ] - return EndpointDescription(layout, packetized=True) - - -def tlp_request_layout(dw): - layout = tlp_request_header.get_layout() + [ - ("dat", dw), - ("be", dw//8) - ] - return EndpointDescription(layout, packetized=True) - - -def tlp_completion_layout(dw): - layout = tlp_completion_header.get_layout() + [ - ("dat", dw), - ("be", dw//8) - ] - return EndpointDescription(layout, packetized=True) diff --git a/misoclib/com/litepcie/core/packet/depacketizer.py b/misoclib/com/litepcie/core/packet/depacketizer.py deleted file mode 100644 index f04afe2c..00000000 --- a/misoclib/com/litepcie/core/packet/depacketizer.py +++ /dev/null @@ -1,160 +0,0 @@ -from migen.fhdl.std import * -from migen.actorlib.structuring import * -from migen.genlib.fsm import FSM, NextState - -from misoclib.com.litepcie.core.packet.common import * - - -class HeaderExtracter(Module): - def __init__(self, dw): - self.sink = Sink(phy_layout(dw)) - self.source = Source(tlp_raw_layout(dw)) - - ### - - sink, source = self.sink, self.source - - sop = Signal() - shift = Signal() - - sink_dat_r = Signal(dw) - sink_be_r = Signal(dw//8) - - fsm = FSM(reset_state="HEADER1") - self.submodules += fsm - - fsm.act("HEADER1", - sink.ack.eq(1), - If(sink.stb, - shift.eq(1), - NextState("HEADER2") - ) - ) - fsm.act("HEADER2", - sink.ack.eq(1), - If(sink.stb, - shift.eq(1), - If(sink.eop, - sink.ack.eq(0), - NextState("TERMINATE"), - ).Else( - NextState("COPY") - ) - ) - ) - self.sync += [ - If(shift, self.source.header.eq(Cat(self.source.header[64:], sink.dat))), - If(sink.stb & sink.ack, - sink_dat_r.eq(sink.dat), - sink_be_r.eq(sink.be) - ) - ] - fsm.act("COPY", - sink.ack.eq(source.ack), - source.stb.eq(sink.stb), - source.sop.eq(sop), - source.eop.eq(sink.eop), - source.dat.eq(Cat(reverse_bytes(sink_dat_r[32:]), reverse_bytes(sink.dat[:32]))), - source.be.eq(Cat(freversed(sink_be_r[4:]), freversed(sink.be[:4]))), - If(source.stb & source.ack & source.eop, - NextState("HEADER1") - ) - ) - self.sync += \ - If(fsm.before_entering("COPY"), - sop.eq(1) - ).Elif(source.stb & source.ack, - sop.eq(0) - ) - fsm.act("TERMINATE", - sink.ack.eq(source.ack), - source.stb.eq(1), - source.sop.eq(1), - source.eop.eq(1), - source.dat.eq(reverse_bytes(sink.dat[32:])), - source.be.eq(freversed(sink.be[4:])), - If(source.stb & source.ack & source.eop, - NextState("HEADER1") - ) - ) - - -class Depacketizer(Module): - def __init__(self, dw, address_mask=0): - self.sink = Sink(phy_layout(dw)) - - self.req_source = Source(request_layout(dw)) - self.cmp_source = Source(completion_layout(dw)) - - ### - - # extract raw header - header_extracter = HeaderExtracter(dw) - self.submodules += header_extracter - self.comb += Record.connect(self.sink, header_extracter.sink) - header = header_extracter.source.header - - - # dispatch data according to fmt/type - dispatch_source = Source(tlp_common_layout(dw)) - dispatch_sinks = [Sink(tlp_common_layout(dw)) for i in range(2)] - - self.comb += [ - dispatch_source.stb.eq(header_extracter.source.stb), - header_extracter.source.ack.eq(dispatch_source.ack), - dispatch_source.sop.eq(header_extracter.source.sop), - dispatch_source.eop.eq(header_extracter.source.eop), - dispatch_source.dat.eq(header_extracter.source.dat), - dispatch_source.be.eq(header_extracter.source.be), - tlp_common_header.decode(header, dispatch_source) - ] - - self.submodules.dispatcher = Dispatcher(dispatch_source, dispatch_sinks) - - fmt_type = Cat(dispatch_source.type, dispatch_source.fmt) - self.comb += \ - If((fmt_type == fmt_type_dict["mem_rd32"]) | (fmt_type == fmt_type_dict["mem_wr32"]), - self.dispatcher.sel.eq(0), - ).Elif((fmt_type == fmt_type_dict["cpld"]) | (fmt_type == fmt_type_dict["cpl"]), - self.dispatcher.sel.eq(1), - ) - - # decode TLP request and format local request - tlp_req = Source(tlp_request_layout(dw)) - self.comb += Record.connect(dispatch_sinks[0], tlp_req) - self.comb += tlp_request_header.decode(header, tlp_req) - - req_source = self.req_source - self.comb += [ - req_source.stb.eq(tlp_req.stb), - req_source.we.eq(tlp_req.stb & (Cat(tlp_req.type, tlp_req.fmt) == fmt_type_dict["mem_wr32"])), - tlp_req.ack.eq(req_source.ack), - req_source.sop.eq(tlp_req.sop), - req_source.eop.eq(tlp_req.eop), - req_source.adr.eq(Cat(Signal(2), tlp_req.address & (~address_mask))), - req_source.len.eq(tlp_req.length), - req_source.req_id.eq(tlp_req.requester_id), - req_source.tag.eq(tlp_req.tag), - req_source.dat.eq(tlp_req.dat), - ] - - # decode TLP completion and format local completion - tlp_cmp = Source(tlp_completion_layout(dw)) - self.comb += Record.connect(dispatch_sinks[1], tlp_cmp) - self.comb += tlp_completion_header.decode(header, tlp_cmp) - - cmp_source = self.cmp_source - self.comb += [ - cmp_source.stb.eq(tlp_cmp.stb), - tlp_cmp.ack.eq(cmp_source.ack), - cmp_source.sop.eq(tlp_cmp.sop), - cmp_source.eop.eq(tlp_cmp.eop), - cmp_source.len.eq(tlp_cmp.length), - cmp_source.last.eq(tlp_cmp.length == (tlp_cmp.byte_count[2:])), - cmp_source.adr.eq(tlp_cmp.lower_address), - cmp_source.req_id.eq(tlp_cmp.requester_id), - cmp_source.cmp_id.eq(tlp_cmp.completer_id), - cmp_source.err.eq(tlp_cmp.status != 0), - cmp_source.tag.eq(tlp_cmp.tag), - cmp_source.dat.eq(tlp_cmp.dat) - ] diff --git a/misoclib/com/litepcie/core/packet/packetizer.py b/misoclib/com/litepcie/core/packet/packetizer.py deleted file mode 100644 index 5807456d..00000000 --- a/misoclib/com/litepcie/core/packet/packetizer.py +++ /dev/null @@ -1,187 +0,0 @@ -from migen.fhdl.std import * -from migen.actorlib.structuring import * -from migen.genlib.fsm import FSM, NextState -from migen.genlib.misc import chooser - -from misoclib.com.litepcie.core.packet.common import * - - -class HeaderInserter(Module): - def __init__(self, dw): - self.sink = sink = Sink(tlp_raw_layout(dw)) - self.source = source = Source(phy_layout(dw)) - - ### - - fsm = FSM(reset_state="HEADER1") - self.submodules += fsm - - sink_dat_r = Signal(dw) - sink_eop_r = Signal() - self.sync += \ - If(sink.stb & sink.ack, - sink_dat_r.eq(sink.dat), - sink_eop_r.eq(sink.eop) - ) - - fsm.act("HEADER1", - sink.ack.eq(1), - If(sink.stb & sink.sop, - sink.ack.eq(0), - source.stb.eq(1), - source.sop.eq(1), - source.eop.eq(0), - source.dat.eq(sink.header[:64]), - source.be.eq(0xff), - If(source.stb & source.ack, - NextState("HEADER2"), - ) - ) - ) - fsm.act("HEADER2", - source.stb.eq(1), - source.sop.eq(0), - source.eop.eq(sink.eop), - source.dat.eq(Cat(sink.header[64:96], reverse_bytes(sink.dat[:32]))), - source.be.eq(Cat(Signal(4, reset=0xf), freversed(sink.be[:4]))), - If(source.stb & source.ack, - sink.ack.eq(1), - If(source.eop, - NextState("HEADER1") - ).Else( - NextState("COPY") - ) - ) - ) - fsm.act("COPY", - source.stb.eq(sink.stb | sink_eop_r), - source.sop.eq(0), - source.eop.eq(sink_eop_r), - source.dat.eq(Cat(reverse_bytes(sink_dat_r[32:64]), reverse_bytes(sink.dat[:32]))), - If(sink_eop_r, - source.be.eq(0x0f) - ).Else( - source.be.eq(0xff) - ), - If(source.stb & source.ack, - sink.ack.eq(~sink_eop_r), - If(source.eop, - NextState("HEADER1") - ) - ) - ) - - -class Packetizer(Module): - def __init__(self, dw): - self.req_sink = req_sink = Sink(request_layout(dw)) - self.cmp_sink = cmp_sink = Sink(completion_layout(dw)) - - self.source = Source(phy_layout(dw)) - - ### - - # format TLP request and encode it - tlp_req = Sink(tlp_request_layout(dw)) - self.comb += [ - tlp_req.stb.eq(req_sink.stb), - req_sink.ack.eq(tlp_req.ack), - tlp_req.sop.eq(req_sink.sop), - tlp_req.eop.eq(req_sink.eop), - - If(req_sink.we, - Cat(tlp_req.type, tlp_req.fmt).eq(fmt_type_dict["mem_wr32"]) - ).Else( - Cat(tlp_req.type, tlp_req.fmt).eq(fmt_type_dict["mem_rd32"]) - ), - - tlp_req.tc.eq(0), - tlp_req.td.eq(0), - tlp_req.ep.eq(0), - tlp_req.attr.eq(0), - tlp_req.length.eq(req_sink.len), - - tlp_req.requester_id.eq(req_sink.req_id), - tlp_req.tag.eq(req_sink.tag), - If(req_sink.len > 1, - tlp_req.last_be.eq(0xf) - ).Else( - tlp_req.last_be.eq(0x0) - ), - tlp_req.first_be.eq(0xf), - tlp_req.address.eq(req_sink.adr[2:]), - - tlp_req.dat.eq(req_sink.dat), - If(req_sink.we, - tlp_req.be.eq(0xff) - ).Else( - tlp_req.be.eq(0x00) - ), - ] - - tlp_raw_req = Sink(tlp_raw_layout(dw)) - self.comb += [ - tlp_raw_req.stb.eq(tlp_req.stb), - tlp_req.ack.eq(tlp_raw_req.ack), - tlp_raw_req.sop.eq(tlp_req.sop), - tlp_raw_req.eop.eq(tlp_req.eop), - tlp_request_header.encode(tlp_req, tlp_raw_req.header), - tlp_raw_req.dat.eq(tlp_req.dat), - tlp_raw_req.be.eq(tlp_req.be), - ] - - # format TLP completion and encode it - tlp_cmp = Sink(tlp_completion_layout(dw)) - self.comb += [ - tlp_cmp.stb.eq(cmp_sink.stb), - cmp_sink.ack.eq(tlp_cmp.ack), - tlp_cmp.sop.eq(cmp_sink.sop), - tlp_cmp.eop.eq(cmp_sink.eop), - - tlp_cmp.tc.eq(0), - tlp_cmp.td.eq(0), - tlp_cmp.ep.eq(0), - tlp_cmp.attr.eq(0), - tlp_cmp.length.eq(cmp_sink.len), - - tlp_cmp.completer_id.eq(cmp_sink.cmp_id), - If(cmp_sink.err, - Cat(tlp_cmp.type, tlp_cmp.fmt).eq(fmt_type_dict["cpl"]), - tlp_cmp.status.eq(cpl_dict["ur"]) - ).Else( - Cat(tlp_cmp.type, tlp_cmp.fmt).eq(fmt_type_dict["cpld"]), - tlp_cmp.status.eq(cpl_dict["sc"]) - ), - tlp_cmp.bcm.eq(0), - tlp_cmp.byte_count.eq(cmp_sink.len*4), - - tlp_cmp.requester_id.eq(cmp_sink.req_id), - tlp_cmp.tag.eq(cmp_sink.tag), - tlp_cmp.lower_address.eq(cmp_sink.adr), - - tlp_cmp.dat.eq(cmp_sink.dat), - tlp_cmp.be.eq(0xff) - ] - - tlp_raw_cmp = Sink(tlp_raw_layout(dw)) - self.comb += [ - tlp_raw_cmp.stb.eq(tlp_cmp.stb), - tlp_cmp.ack.eq(tlp_raw_cmp.ack), - tlp_raw_cmp.sop.eq(tlp_cmp.sop), - tlp_raw_cmp.eop.eq(tlp_cmp.eop), - tlp_completion_header.encode(tlp_cmp, tlp_raw_cmp.header), - tlp_raw_cmp.dat.eq(tlp_cmp.dat), - tlp_raw_cmp.be.eq(tlp_cmp.be), - ] - - # arbitrate - tlp_raw = Sink(tlp_raw_layout(dw)) - self.submodules.arbitrer = Arbiter([tlp_raw_req, tlp_raw_cmp], tlp_raw) - - # insert header - header_inserter = HeaderInserter(dw) - self.submodules += header_inserter - self.comb += [ - Record.connect(tlp_raw, header_inserter.sink), - Record.connect(header_inserter.source, self.source) - ] diff --git a/misoclib/com/litepcie/core/switch/__init__.py b/misoclib/com/litepcie/core/switch/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/com/litepcie/core/switch/common.py b/misoclib/com/litepcie/core/switch/common.py deleted file mode 100644 index 13debf83..00000000 --- a/misoclib/com/litepcie/core/switch/common.py +++ /dev/null @@ -1,34 +0,0 @@ -from migen.fhdl.std import * -from migen.bank.description import * - -from misoclib.com.litepcie.common import * - - -class SlaveInternalPort: - def __init__(self, dw, address_decoder=None): - self.address_decoder = address_decoder - self.sink = Sink(completion_layout(dw)) - self.source = Source(request_layout(dw)) - - -class MasterInternalPort: - def __init__(self, dw, channel=None, write_only=False, read_only=False): - self.channel = channel - self.write_only = write_only - self.read_only = read_only - self.sink = Sink(request_layout(dw)) - self.source = Source(completion_layout(dw)) - - -class SlavePort: - def __init__(self, port): - self.address_decoder = port.address_decoder - self.sink = port.source - self.source = port.sink - - -class MasterPort: - def __init__(self, port): - self.channel = port.channel - self.sink = port.source - self.source = port.sink diff --git a/misoclib/com/litepcie/core/switch/crossbar.py b/misoclib/com/litepcie/core/switch/crossbar.py deleted file mode 100644 index a5ee1af3..00000000 --- a/misoclib/com/litepcie/core/switch/crossbar.py +++ /dev/null @@ -1,120 +0,0 @@ -from migen.fhdl.std import * -from migen.bank.description import * - -from misoclib.com.litepcie.common import * -from misoclib.com.litepcie.core.switch.common import * -from misoclib.com.litepcie.core.switch.request_controller import RequestController - - -class Crossbar(Module, AutoCSR): - def __init__(self, dw, max_pending_requests, with_reordering=False): - self.dw = dw - self.max_pending_requests = max_pending_requests - self.with_reordering = with_reordering - - self.master = MasterInternalPort(dw) - self.slave = SlaveInternalPort(dw) - self.phy_master = MasterPort(self.master) - self.phy_slave = SlavePort(self.slave) - - self.user_masters = [] - self.user_masters_channel = 0 - self.user_slaves = [] - - def get_slave_port(self, address_decoder): - s = SlaveInternalPort(self.dw, address_decoder) - self.user_slaves.append(s) - return SlavePort(s) - - def get_master_port(self, write_only=False, read_only=False): - m = MasterInternalPort(self.dw, self.user_masters_channel, write_only, read_only) - self.user_masters_channel += 1 - self.user_masters.append(m) - return MasterPort(m) - - def filter_masters(self, write_only, read_only): - masters = [] - for m in self.user_masters: - if m.write_only == write_only and m.read_only == read_only: - masters.append(m) - return masters - - def slave_dispatch_arbitrate(self, slaves, slave): - # dispatch - s_sources = [s.source for s in slaves] - s_dispatcher = Dispatcher(slave.source, s_sources, one_hot=True) - self.submodules += s_dispatcher - for i, s in enumerate(slaves): - self.comb += s_dispatcher.sel[i].eq(s.address_decoder(slave.source.adr)) - - # arbitrate - s_sinks = [s.sink for s in slaves] - s_arbiter = Arbiter(s_sinks, slave.sink) - self.submodules += s_arbiter - - def master_arbitrate_dispatch(self, masters, master): - # arbitrate - m_sinks = [m.sink for m in masters] - m_arbiter = Arbiter(m_sinks, master.sink) - self.submodules += m_arbiter - - # dispatch - m_sources = [m.source for m in masters] - m_dispatcher = Dispatcher(master.source, m_sources) - self.submodules += m_dispatcher - self.comb += m_dispatcher.sel.eq(master.source.channel) - - def do_finalize(self): - # Slave path - # Dispatch request to user sources (according to address decoder) - # Arbitrate completion from user sinks - if self.user_slaves != []: - self.slave_dispatch_arbitrate(self.user_slaves, self.slave) - - # Master path - # Abritrate requests from user sinks - # Dispatch completion to user sources (according to channel) - - # +-------+ - # reqs---> | RD | - # cmps<--- | PORTS |---------+ - # +-------+ +---+----+ +----------+ - # |Arb/Disp|-->|Controller|--+ - # +-------+ +---+----+ +----------+ | - # reqs---> | RW | | | - # cmps<--- | PORTS |---------+ | - # +-------+ +---+----+ - # |Arb/Disp|<--> to/from Packetizer/ - # +-------+ +---+----+ Depacketizer - # reqs---> | WR | +--------+ | - # cmps<--- | PORTS |-----|Arb/Disp|-----------------+ - # +-------+ +--------+ - # - # The controller blocks RD requests when the max number of pending - # requests have been sent (max_pending_requests parameters). - # To avoid blocking write_only ports when RD requests are blocked, - # a separate arbitration stage is used. - - if self.user_masters != []: - masters = [] - - # Arbitrate / dispatch read_only / read_write ports - # and insert controller - rd_rw_masters = self.filter_masters(False, True) - rd_rw_masters += self.filter_masters(False, False) - if rd_rw_masters != []: - rd_rw_master = MasterInternalPort(self.dw) - controller = RequestController(self.dw, self.max_pending_requests, self.with_reordering) - self.submodules += controller - self.master_arbitrate_dispatch(rd_rw_masters, controller.master_in) - masters.append(controller.master_out) - - # Arbitrate / dispatch write_only ports - wr_masters = self.filter_masters(True, False) - if wr_masters != []: - wr_master = MasterInternalPort(self.dw) - self.master_arbitrate_dispatch(wr_masters, wr_master) - masters.append(wr_master) - - # Final Arbitrate / dispatch stage - self.master_arbitrate_dispatch(masters, self.master) diff --git a/misoclib/com/litepcie/core/switch/request_controller.py b/misoclib/com/litepcie/core/switch/request_controller.py deleted file mode 100644 index 9a4980b8..00000000 --- a/misoclib/com/litepcie/core/switch/request_controller.py +++ /dev/null @@ -1,175 +0,0 @@ -from migen.fhdl.std import * -from migen.actorlib.structuring import * -from migen.genlib.fifo import SyncFIFO -from migen.genlib.fsm import FSM, NextState -from migen.actorlib.fifo import SyncFIFO as SyncFlowFIFO - -from misoclib.com.litepcie.common import * -from misoclib.com.litepcie.core.packet.common import * -from misoclib.com.litepcie.core.switch.common import * - - -class Reordering(Module): - def __init__(self, dw, max_pending_requests): - self.sink = Sink(completion_layout(dw)) - self.source = Source(completion_layout(dw)) - - self.req_we = Signal() - self.req_tag = Signal(log2_int(max_pending_requests)) - - # # # - - tag_buffer = SyncFIFO(log2_int(max_pending_requests), 2*max_pending_requests) - self.submodules += tag_buffer - self.comb += [ - tag_buffer.we.eq(self.req_we), - tag_buffer.din.eq(self.req_tag) - ] - - reorder_buffers = [SyncFlowFIFO(completion_layout(dw), 2*max_request_size//(dw//8), buffered=True) - for i in range(max_pending_requests)] - self.submodules += iter(reorder_buffers) - - # store incoming completion in "sink.tag" buffer - cases = {} - for i in range(max_pending_requests): - cases[i] = [Record.connect(self.sink, reorder_buffers[i].sink)] - cases["default"] = [self.sink.ack.eq(1)] - self.comb += Case(self.sink.tag, cases) - - # read buffer according to tag_buffer order - cases = {} - for i in range(max_pending_requests): - cases[i] = [Record.connect(reorder_buffers[i].source, self.source)] - cases["default"] = [] - self.comb += [ - Case(tag_buffer.dout, cases), - If(self.source.stb & self.source.eop & self.source.last, - tag_buffer.re.eq(self.source.ack) - ) - ] - - -class RequestController(Module): - def __init__(self, dw, max_pending_requests, with_reordering=False): - self.master_in = MasterInternalPort(dw) - self.master_out = MasterInternalPort(dw) - - # # # - - req_sink, req_source = self.master_in.sink, self.master_out.sink - cmp_sink, cmp_source = self.master_out.source, self.master_in.source - - tag_fifo = SyncFIFO(log2_int(max_pending_requests), max_pending_requests) - self.submodules += tag_fifo - - info_mem = Memory(16, max_pending_requests) - info_mem_wr_port = info_mem.get_port(write_capable=True) - info_mem_rd_port = info_mem.get_port(async_read=False) - self.specials += info_mem, info_mem_wr_port, info_mem_rd_port - - req_tag = Signal(max=max_pending_requests) - self.sync += \ - If(tag_fifo.re, - req_tag.eq(tag_fifo.dout) - ) - - # requests mgt - req_fsm = FSM(reset_state="IDLE") - self.submodules += req_fsm - - req_fsm.act("IDLE", - req_sink.ack.eq(0), - If(req_sink.stb & req_sink.sop & ~req_sink.we & tag_fifo.readable, - tag_fifo.re.eq(1), - NextState("SEND_READ") - ).Elif(req_sink.stb & req_sink.sop & req_sink.we, - NextState("SEND_WRITE") - ) - ) - req_fsm.act("SEND_READ", - Record.connect(req_sink, req_source), - req_sink.ack.eq(0), - req_source.tag.eq(req_tag), - If(req_source.stb & req_source.eop & req_source.ack, - NextState("UPDATE_INFO_MEM") - ) - ) - req_fsm.act("SEND_WRITE", - Record.connect(req_sink, req_source), - req_source.tag.eq(32), - If(req_source.stb & req_source.eop & req_source.ack, - NextState("IDLE") - ) - ) - req_fsm.act("UPDATE_INFO_MEM", - info_mem_wr_port.we.eq(1), - info_mem_wr_port.adr.eq(req_tag), - info_mem_wr_port.dat_w[0:8].eq(req_sink.channel), - info_mem_wr_port.dat_w[8:16].eq(req_sink.user_id), - req_sink.ack.eq(1), - NextState("IDLE") - ) - - - # completions mgt - if with_reordering: - self.submodules.reordering = Reordering(dw, max_pending_requests) - self.comb += [ - self.reordering.req_we.eq(info_mem_wr_port.we), - self.reordering.req_tag.eq(info_mem_wr_port.adr), - Record.connect(self.reordering.source, cmp_source) - ] - cmp_source = self.reordering.sink - - cmp_fsm = FSM(reset_state="INIT") - self.submodules += cmp_fsm - - tag_cnt = Signal(max=max_pending_requests) - inc_tag_cnt = Signal() - self.sync += \ - If(inc_tag_cnt, - tag_cnt.eq(tag_cnt+1) - ) - - cmp_fsm.act("INIT", - inc_tag_cnt.eq(1), - tag_fifo.we.eq(1), - tag_fifo.din.eq(tag_cnt), - If(tag_cnt == (max_pending_requests-1), - NextState("IDLE") - ) - ) - cmp_fsm.act("IDLE", - cmp_sink.ack.eq(1), - info_mem_rd_port.adr.eq(cmp_sink.tag), - If(cmp_sink.stb & cmp_sink.sop, - cmp_sink.ack.eq(0), - NextState("COPY"), - ) - ) - cmp_fsm.act("COPY", - info_mem_rd_port.adr.eq(cmp_sink.tag), - If(cmp_sink.stb & cmp_sink.eop & cmp_sink.last, - cmp_sink.ack.eq(0), - NextState("UPDATE_TAG_FIFO"), - ).Else( - Record.connect(cmp_sink, cmp_source), - If(cmp_sink.stb & cmp_sink.eop & cmp_sink.ack, - NextState("IDLE") - ) - ), - cmp_source.channel.eq(info_mem_rd_port.dat_r[0:8]), - cmp_source.user_id.eq(info_mem_rd_port.dat_r[8:16]), - ) - cmp_fsm.act("UPDATE_TAG_FIFO", - tag_fifo.we.eq(1), - tag_fifo.din.eq(cmp_sink.tag), - info_mem_rd_port.adr.eq(cmp_sink.tag), - Record.connect(cmp_sink, cmp_source), - If(cmp_sink.stb & cmp_sink.ack, - NextState("IDLE") - ), - cmp_source.channel.eq(info_mem_rd_port.dat_r[0:8]), - cmp_source.user_id.eq(info_mem_rd_port.dat_r[8:16]), - ) diff --git a/misoclib/com/litepcie/doc/.keep_me b/misoclib/com/litepcie/doc/.keep_me deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/com/litepcie/example_designs/__init__.py b/misoclib/com/litepcie/example_designs/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/com/litepcie/example_designs/build/.keep_me b/misoclib/com/litepcie/example_designs/build/.keep_me deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/com/litepcie/example_designs/make.py b/misoclib/com/litepcie/example_designs/make.py deleted file mode 100755 index 1e15368d..00000000 --- a/misoclib/com/litepcie/example_designs/make.py +++ /dev/null @@ -1,148 +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.com.litepcie.common import * - - -def _import(default, name): - return importlib.import_module(default + "." + name) - - -def _get_args(): - parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, - description="""\ -LitePCIe - based on Migen. - -This program builds and/or loads LitePCIe 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. -build-csr-header save CSR map into C header file. - -load-bitstream load bitstream into volatile storage. - -all clean, build-csr-csv, build-bitstream, load-bitstream. -""") - - parser.add_argument("-t", "--target", default="dma", 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("--csr_csv", default="./test/csr.csv", help="CSV file to save the CSR map into") - parser.add_argument("--csr_header", default="../software/linux/kernel/csr.h", help="C header 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: - platform_name = top_class.default_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-csr-header", "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 PCIe - core powered by Migen -====== Building options: ====== -Platform: {} -Target: {} -Subtarget: {} -System Clk: {} MHz -===============================""".format( - platform_name, - args.target, - top_class.__name__, - soc.clk_freq/1000000 - ) -) - - # dependencies - if actions["all"]: - actions["build-csr-csv"] = True - actions["build-csr-header"] = True - actions["build-bitstream"] = True - actions["load-bitstream"] = True - - if actions["build-bitstream"]: - actions["build-csr-csv"] = True - actions["build-csr-header"] = 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-csr-header"]: - csr_header = cpuif.get_csr_header(csr_regions, soc.get_constants(), with_access_functions=False) - write_to_file(args.csr_header, csr_header) - - if actions["build-bitstream"]: - vns = platform.build(soc, build_name=build_name) - 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/litepcie/example_designs/targets/__init__.py b/misoclib/com/litepcie/example_designs/targets/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/com/litepcie/example_designs/targets/dma.py b/misoclib/com/litepcie/example_designs/targets/dma.py deleted file mode 100644 index b8db65fc..00000000 --- a/misoclib/com/litepcie/example_designs/targets/dma.py +++ /dev/null @@ -1,99 +0,0 @@ -from migen.bus import wishbone -from migen.genlib.io import CRG -from migen.genlib.resetsync import AsyncResetSynchronizer -from migen.genlib.misc import timeline - -from misoclib.soc import SoC -from misoclib.tools.litescope.common import * - -from misoclib.com.uart.bridge import UARTWishboneBridge - -from misoclib.com.litepcie.phy.s7pciephy import S7PCIEPHY -from misoclib.com.litepcie.core import Endpoint -from misoclib.com.litepcie.core.irq.interrupt_controller import InterruptController -from misoclib.com.litepcie.frontend.dma import DMA -from misoclib.com.litepcie.frontend.wishbone import LitePCIeWishboneBridge - - -class _CRG(Module, AutoCSR): - def __init__(self, platform): - self.clock_domains.cd_sys = ClockDomain("sys") - self.clock_domains.cd_clk125 = ClockDomain("clk125") - - # soft reset generaton - self._soft_rst = CSR() - soft_rst = Signal() - # trigger soft reset 1us after CSR access to terminate - # Wishbone access when reseting from PCIe - self.sync += [ - timeline(self._soft_rst.re & self._soft_rst.r, [(125, [soft_rst.eq(1)])]), - ] - - # sys_clk / sys_rst (from PCIe) - self.comb += self.cd_sys.clk.eq(self.cd_clk125.clk) - self.specials += AsyncResetSynchronizer(self.cd_sys, self.cd_clk125.rst | soft_rst) - - # scratch register - self._scratch = CSR(32) - self.sync += If(self._scratch.re, self._scratch.w.eq(self._scratch.r)) - - -class PCIeDMASoC(SoC): - default_platform = "kc705" - csr_map = { - "crg": 16, - "pcie_phy": 17, - "dma": 18, - "irq_controller": 19 - } - csr_map.update(SoC.csr_map) - interrupt_map = { - "dma_writer": 0, - "dma_reader": 1 - } - interrupt_map.update(SoC.interrupt_map) - mem_map = { - "csr": 0x00000000, # (shadow @0x80000000) - } - mem_map.update(SoC.csr_map) - - def __init__(self, platform, with_uart_bridge=True): - clk_freq = 125*1000000 - SoC.__init__(self, platform, clk_freq, - cpu_type="none", - shadow_base=0x00000000, - with_csr=True, csr_data_width=32, - with_uart=False, - with_identifier=True, - with_timer=False - ) - self.submodules.crg = _CRG(platform) - platform.misoc_path = "../../../../" - - # PCIe endpoint - self.submodules.pcie_phy = S7PCIEPHY(platform, link_width=2) - self.submodules.pcie_endpoint = Endpoint(self.pcie_phy, with_reordering=True) - - # PCIe Wishbone bridge - self.add_cpu_or_bridge(LitePCIeWishboneBridge(self.pcie_endpoint, lambda a: 1)) - self.add_wb_master(self.cpu_or_bridge.wishbone) - - # PCIe DMA - self.submodules.dma = DMA(self.pcie_phy, self.pcie_endpoint, with_loopback=True) - self.dma.source.connect(self.dma.sink) - - if with_uart_bridge: - self.submodules.uart_bridge = UARTWishboneBridge(platform.request("serial"), clk_freq, baudrate=115200) - self.add_wb_master(self.uart_bridge.wishbone) - - # IRQs - self.submodules.irq_controller = InterruptController() - self.comb += self.irq_controller.source.connect(self.pcie_phy.interrupt) - self.interrupts = { - "dma_writer": self.dma.writer.table.irq, - "dma_reader": self.dma.reader.table.irq - } - for k, v in sorted(self.interrupts.items()): - self.comb += self.irq_controller.irqs[self.interrupt_map[k]].eq(v) - -default_subtarget = PCIeDMASoC diff --git a/misoclib/com/litepcie/example_designs/test/make.py b/misoclib/com/litepcie/example_designs/test/make.py deleted file mode 100755 index 344e5a40..00000000 --- a/misoclib/com/litepcie/example_designs/test/make.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python3 -import argparse -import importlib - - -def _get_args(): - parser = argparse.ArgumentParser() - parser.add_argument("-b", "--bridge", default="uart", help="Bridge to use") - parser.add_argument("--port", default="2", help="UART port") - parser.add_argument("--baudrate", default=115200, help="UART baudrate") - parser.add_argument("--ip_address", default="192.168.0.42", help="Etherbone IP address") - parser.add_argument("--udp_port", default=20000, help="Etherbone UDP port") - parser.add_argument("--bar", default="/sys/bus/pci/devices/0000:04:00.0/resource0", help="PCIe BAR") - parser.add_argument("--bar_size", default=1*1024*1024, help="PCIe BAR size") - 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() - if args.bridge == "uart": - from misoclib.com.uart.software.wishbone import UARTWishboneBridgeDriver - port = args.port if not args.port.isdigit() else int(args.port) - wb = UARTWishboneBridgeDriver(port, args.baudrate, "./csr.csv", int(args.busword), debug=False) - elif args.bridge == "etherbone": - from misoclib.com.liteeth.software.wishbone import LiteETHWishboneDriver - wb = LiteETHWishboneDriver(args.ip_address, int(args.udp_port), "./csr.csv", int(args.busword), debug=False) - elif args.bridge == "pcie": - from misoclib.com.litepcie.software.linux.wishbone import LitePCIeWishboneDriver - wb = LitePCIeWishboneDriver(args.bar, args.bar_size, "./csr.csv", int(args.busword), debug=False) - else: - ValueError("Invalid bridge {}".format(args.bridge)) - - def _import(name): - return importlib.import_module(name) - - for test in args.test: - t = _import(test) - t.main(wb) diff --git a/misoclib/com/litepcie/example_designs/test/test_regs.py b/misoclib/com/litepcie/example_designs/test/test_regs.py deleted file mode 100644 index a6e5c40d..00000000 --- a/misoclib/com/litepcie/example_designs/test/test_regs.py +++ /dev/null @@ -1,14 +0,0 @@ -def main(wb): - wb.open() - regs = wb.regs - # # # - 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))) - print("link up : {}".format(regs.pcie_phy_lnk_up.read())) - print("bus_master_enable : {}".format(regs.pcie_phy_bus_master_enable.read())) - print("msi_enable : {}".format(regs.pcie_phy_msi_enable.read())) - print("max_req_request_size : {}".format(regs.pcie_phy_max_request_size.read())) - print("max_payload_size : {}".format(regs.pcie_phy_max_payload_size.read())) - # # # - wb.close() diff --git a/misoclib/com/litepcie/frontend/__init__.py b/misoclib/com/litepcie/frontend/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/com/litepcie/frontend/dma/__init__.py b/misoclib/com/litepcie/frontend/dma/__init__.py deleted file mode 100644 index 62560443..00000000 --- a/misoclib/com/litepcie/frontend/dma/__init__.py +++ /dev/null @@ -1,121 +0,0 @@ -from migen.fhdl.std import * -from migen.bank.description import * -from migen.actorlib.fifo import SyncFIFO as FIFO - -from misoclib.com.litepcie.common import * -from misoclib.com.litepcie.frontend.dma.common import * -from misoclib.com.litepcie.frontend.dma.writer import DMAWriter -from misoclib.com.litepcie.frontend.dma.reader import DMAReader - - -class DMALoopback(Module, AutoCSR): - def __init__(self, dw): - self._enable = CSRStorage() - - self.sink = Sink(dma_layout(dw)) - self.source = Source(dma_layout(dw)) - - self.next_source = Source(dma_layout(dw)) - self.next_sink = Sink(dma_layout(dw)) - - # # # - - enable = self._enable.storage - self.comb += \ - If(enable, - Record.connect(self.sink, self.source) - ).Else( - Record.connect(self.sink, self.next_source), - Record.connect(self.next_sink, self.source) - ) - - -class DMASynchronizer(Module, AutoCSR): - def __init__(self, dw): - self._bypass = CSRStorage() - self._enable = CSRStorage() - self.ready = Signal(reset=1) - self.pps = Signal() - - self.sink = Sink(dma_layout(dw)) - self.source = Source(dma_layout(dw)) - - self.next_source = Source(dma_layout(dw)) - self.next_sink = Sink(dma_layout(dw)) - - # # # - - bypass = self._bypass.storage - enable = self._enable.storage - synced = Signal() - - self.sync += \ - If(~enable, - synced.eq(0) - ).Else( - If(self.ready & self.sink.stb & (self.pps | bypass), - synced.eq(1) - ) - ) - - self.comb += \ - If(synced, - Record.connect(self.sink, self.next_source), - Record.connect(self.next_sink, self.source), - ).Else( - # Block sink - self.next_source.stb.eq(0), - self.sink.ack.eq(0), - - # Ack next_sink - self.source.stb.eq(0), - self.next_sink.ack.eq(1), - ) - - -class DMABuffering(Module, AutoCSR): - def __init__(self, dw, depth): - tx_fifo = FIFO(dma_layout(dw), depth//(dw//8), buffered=True) - rx_fifo = FIFO(dma_layout(dw), depth//(dw//8), buffered=True) - self.submodules += tx_fifo, rx_fifo - - self.sink = tx_fifo.sink - self.source = rx_fifo.source - - self.next_source = tx_fifo.source - self.next_sink = rx_fifo.sink - - -class DMA(Module, AutoCSR): - def __init__(self, phy, endpoint, - with_buffering=False, buffering_depth=256*8, - with_loopback=False, - with_synchronizer=False): - - # Writer, Reader - self.submodules.writer = DMAWriter(endpoint, endpoint.crossbar.get_master_port(write_only=True)) - self.submodules.reader = DMAReader(endpoint, endpoint.crossbar.get_master_port(read_only=True)) - self.sink, self.source = self.writer.sink, self.reader.source - - # Loopback - if with_loopback: - self.submodules.loopback = DMALoopback(phy.dw) - self.insert_optional_module(self.loopback) - - # Synchronizer - if with_synchronizer: - self.submodules.synchronizer = DMASynchronizer(phy.dw) - self.insert_optional_module(self.synchronizer) - - # Buffering - if with_buffering: - self.submodules.buffering = DMABuffering(phy.dw, buffering_depth) - self.insert_optional_module(self.buffering) - - - def insert_optional_module(self, m): - self.comb += [ - Record.connect(self.source, m.sink), - Record.connect(m.source, self.sink) - ] - self.sink, self.source = m.next_sink, m.next_source diff --git a/misoclib/com/litepcie/frontend/dma/common.py b/misoclib/com/litepcie/frontend/dma/common.py deleted file mode 100644 index bda38302..00000000 --- a/misoclib/com/litepcie/frontend/dma/common.py +++ /dev/null @@ -1,164 +0,0 @@ -from migen.fhdl.std import * -from migen.bank.description import * -from migen.genlib.fifo import SyncFIFOBuffered as SyncFIFO -from migen.genlib.fsm import FSM, NextState -from migen.genlib.misc import chooser, displacer -from migen.flow.plumbing import Buffer - -from misoclib.com.litepcie.common import * - - -def descriptor_layout(with_user_id=False): - layout = [ - ("address", 32), - ("length", 16) - ] - if with_user_id: - layout += [("user_id", 8)] - return EndpointDescription(layout, packetized=True) - - -class DMARequestTable(Module, AutoCSR): - def __init__(self, depth): - self.source = source = Source(descriptor_layout()) - - aw = flen(source.address) - lw = flen(source.length) - - self._value = CSRStorage(aw+lw) - self._we = CSR() - self._loop_prog_n = CSRStorage() - self._loop_status = CSRStatus(32) - self._level = CSRStatus(log2_int(depth)) - self._flush = CSR() - self.irq = Signal() - - # # # - - # CSR signals - value = self._value.storage - we = self._we.r & self._we.re - loop_prog_n = self._loop_prog_n.storage - loop_index = self._loop_status.status[:log2_int(depth)] - loop_count = self._loop_status.status[16:] - level = self._level.status - flush = self._flush.r & self._flush.re - - # FIFO - # instance - fifo_layout = [("address", aw), ("length", lw), ("start", 1)] - fifo = InsertReset(SyncFIFO(fifo_layout, depth)) - self.submodules += fifo - self.comb += [ - fifo.reset.eq(flush), - level.eq(fifo.level) - ] - - # write part - self.sync += [ - # in "loop" mode, each data output of the fifo is - # written back - If(loop_prog_n, - fifo.din.address.eq(fifo.dout.address), - fifo.din.length.eq(fifo.dout.length), - fifo.din.start.eq(fifo.dout.start), - fifo.we.eq(fifo.re) - # in "program" mode, fifo input is connected - # to registers - ).Else( - fifo.din.address.eq(value[:aw]), - fifo.din.length.eq(value[aw:aw+lw]), - fifo.din.start.eq(~fifo.readable), - fifo.we.eq(we) - ) - ] - - # read part - self.comb += [ - source.stb.eq(fifo.readable), - fifo.re.eq(source.stb & source.ack), - source.address.eq(fifo.dout.address), - source.length.eq(fifo.dout.length) - ] - - # loop_index, loop_count - # used by the software for synchronization in - # "loop" mode - self.sync += \ - If(flush, - loop_index.eq(0), - loop_count.eq(0), - ).Elif(source.stb & source.ack, - If(fifo.dout.start, - loop_index.eq(0), - loop_count.eq(loop_count+1) - ).Else( - loop_index.eq(loop_index+1) - ) - ) - - # IRQ - self.comb += self.irq.eq(source.stb & source.ack) - - -class DMARequestSplitter(Module, AutoCSR): - def __init__(self, max_size, buffered=True): - self.sink = sink = Sink(descriptor_layout()) - if buffered: - self.submodules.buffer = Buffer(descriptor_layout(True)) - source = self.buffer.d - self.source = self.buffer.q - else: - self.source = source = Source(descriptor_layout(True)) - - # # # - - offset = Signal(32) - clr_offset = Signal() - inc_offset = Signal() - self.sync += \ - If(clr_offset, - offset.eq(0) - ).Elif(inc_offset, - offset.eq(offset + max_size) - ) - user_id = Signal(8) - self.sync += \ - If(sink.stb & sink.ack, - user_id.eq(user_id+1) - ) - - fsm = FSM(reset_state="IDLE") - self.submodules += fsm - - length = Signal(16) - update_length = Signal() - self.sync += If(update_length, length.eq(sink.length)) - - fsm.act("IDLE", - sink.ack.eq(1), - clr_offset.eq(1), - If(sink.stb, - update_length.eq(1), - sink.ack.eq(0), - NextState("RUN") - ) - ) - fsm.act("RUN", - source.stb.eq(1), - source.address.eq(sink.address + offset), - source.user_id.eq(user_id), - If((length - offset) > max_size, - source.length.eq(max_size), - inc_offset.eq(source.ack) - ).Else( - source.length.eq(length - offset), - If(source.ack, - NextState("ACK") - ) - ) - ) - fsm.act("ACK", - sink.ack.eq(1), - NextState("IDLE") - ) diff --git a/misoclib/com/litepcie/frontend/dma/reader.py b/misoclib/com/litepcie/frontend/dma/reader.py deleted file mode 100644 index de39e5e8..00000000 --- a/misoclib/com/litepcie/frontend/dma/reader.py +++ /dev/null @@ -1,79 +0,0 @@ -from migen.fhdl.std import * -from migen.bank.description import * -from migen.genlib.fsm import FSM, NextState -from migen.actorlib.fifo import SyncFIFO as FIFO - -from misoclib.com.litepcie.common import * -from misoclib.com.litepcie.core.packet.common import * -from misoclib.com.litepcie.frontend.dma.common import * - - -class DMAReader(Module, AutoCSR): - def __init__(self, endpoint, port, table_depth=256): - self.source = Source(dma_layout(endpoint.phy.dw)) - self._enable = CSRStorage() - - # # # - - enable = self._enable.storage - - max_words_per_request = max_request_size//(endpoint.phy.dw//8) - max_pending_words = endpoint.max_pending_requests*max_words_per_request - - fifo_depth = 2*max_pending_words - - # Request generation - # requests from table are splitted in chunks of "max_size" - self.table = table = DMARequestTable(table_depth) - splitter = InsertReset(DMARequestSplitter(endpoint.phy.max_request_size)) - self.submodules += table, splitter - self.comb += splitter.reset.eq(~enable) - self.comb += table.source.connect(splitter.sink) - - # Request FSM - self.submodules.fsm = fsm = FSM(reset_state="IDLE") - - request_ready = Signal() - fsm.act("IDLE", - If(request_ready, - NextState("REQUEST"), - ) - ) - fsm.act("REQUEST", - port.source.stb.eq(1), - port.source.channel.eq(port.channel), - port.source.user_id.eq(splitter.source.user_id), - port.source.sop.eq(1), - port.source.eop.eq(1), - port.source.we.eq(0), - port.source.adr.eq(splitter.source.address), - port.source.len.eq(splitter.source.length[2:]), - port.source.req_id.eq(endpoint.phy.id), - port.source.dat.eq(0), - If(port.source.ack, - splitter.source.ack.eq(1), - NextState("IDLE"), - ) - ) - - # Data FIFO - # issue read requests when enough space available in fifo - fifo = InsertReset(FIFO(dma_layout(endpoint.phy.dw), fifo_depth, buffered=True)) - self.submodules += fifo - self.comb += fifo.reset.eq(~enable) - - last_user_id = Signal(8, reset=255) - self.sync += \ - If(port.sink.stb & port.sink.sop & port.sink.ack, - last_user_id.eq(port.sink.user_id) - ) - self.comb += [ - fifo.sink.stb.eq(port.sink.stb), - fifo.sink.sop.eq(port.sink.sop & (port.sink.user_id != last_user_id)), - fifo.sink.data.eq(port.sink.dat), - port.sink.ack.eq(fifo.sink.ack | ~enable), - ] - self.comb += Record.connect(fifo.source, self.source) - - fifo_ready = fifo.fifo.level < (fifo_depth//2) - self.comb += request_ready.eq(splitter.source.stb & fifo_ready) diff --git a/misoclib/com/litepcie/frontend/dma/writer.py b/misoclib/com/litepcie/frontend/dma/writer.py deleted file mode 100644 index 2f6131d0..00000000 --- a/misoclib/com/litepcie/frontend/dma/writer.py +++ /dev/null @@ -1,88 +0,0 @@ -from migen.fhdl.std import * -from migen.bank.description import * -from migen.genlib.fifo import SyncFIFOBuffered as SyncFIFO -from migen.genlib.fsm import FSM, NextState - -from misoclib.com.litepcie.common import * -from misoclib.com.litepcie.core.packet.common import * -from misoclib.com.litepcie.frontend.dma.common import * - - -class DMAWriter(Module, AutoCSR): - def __init__(self, endpoint, port, table_depth=256): - self.sink = sink = Sink(dma_layout(endpoint.phy.dw)) - self._enable = CSRStorage() - - # # # - - enable = self._enable.storage - - max_words_per_request = max_request_size//(endpoint.phy.dw//8) - fifo_depth = 4*max_words_per_request - - # Data FIFO - # store data until we have enough data to issue a - # write request - fifo = InsertReset(SyncFIFO(endpoint.phy.dw, fifo_depth)) - self.submodules += fifo - self.comb += [ - fifo.we.eq(sink.stb & enable), - sink.ack.eq(fifo.writable & sink.stb & enable), - fifo.din.eq(sink.data), - fifo.reset.eq(~enable) - ] - - # Request generation - # requests from table are splitted in chunks of "max_size" - self.table = table = DMARequestTable(table_depth) - splitter = InsertReset(DMARequestSplitter(endpoint.phy.max_payload_size)) - self.submodules += table, splitter - self.comb += splitter.reset.eq(~enable) - self.comb += table.source.connect(splitter.sink) - - # Request FSM - cnt = Signal(max=(2**flen(endpoint.phy.max_payload_size))/8) - clr_cnt = Signal() - inc_cnt = Signal() - self.sync += \ - If(clr_cnt, - cnt.eq(0) - ).Elif(inc_cnt, - cnt.eq(cnt + 1) - ) - - self.submodules.fsm = fsm = FSM(reset_state="IDLE") - - request_ready = Signal() - fsm.act("IDLE", - clr_cnt.eq(1), - If(request_ready, - NextState("REQUEST"), - ) - ) - fsm.act("REQUEST", - inc_cnt.eq(port.source.stb & port.source.ack), - - port.source.stb.eq(1), - port.source.channel.eq(port.channel), - port.source.user_id.eq(splitter.source.user_id), - port.source.sop.eq(cnt == 0), - port.source.eop.eq(cnt == splitter.source.length[3:]-1), - port.source.we.eq(1), - port.source.adr.eq(splitter.source.address), - port.source.req_id.eq(endpoint.phy.id), - port.source.tag.eq(0), - port.source.len.eq(splitter.source.length[2:]), - port.source.dat.eq(fifo.dout), - - If(port.source.ack, - fifo.re.eq(1), - If(port.source.eop, - splitter.source.ack.eq(1), - NextState("IDLE"), - ) - ) - ) - - fifo_ready = fifo.level >= splitter.source.length[3:] - self.sync += request_ready.eq(splitter.source.stb & fifo_ready) diff --git a/misoclib/com/litepcie/frontend/wishbone.py b/misoclib/com/litepcie/frontend/wishbone.py deleted file mode 100644 index 2eca9f3e..00000000 --- a/misoclib/com/litepcie/frontend/wishbone.py +++ /dev/null @@ -1,67 +0,0 @@ -from migen.fhdl.std import * -from migen.genlib.fsm import FSM, NextState -from migen.bus import wishbone - -from misoclib.com.litepcie.common import * - - -class LitePCIeWishboneBridge(Module): - def __init__(self, endpoint, address_decoder): - self.wishbone = wishbone.Interface() - - # # # - - port = endpoint.crossbar.get_slave_port(address_decoder) - self.submodules.fsm = fsm = FSM() - - fsm.act("IDLE", - If(port.sink.stb & port.sink.sop, - If(port.sink.we, - NextState("WRITE"), - ).Else( - NextState("READ") - ) - ).Else( - port.sink.ack.eq(port.sink.stb) - ) - ) - fsm.act("WRITE", - self.wishbone.adr.eq(port.sink.adr[2:]), - self.wishbone.dat_w.eq(port.sink.dat[:32]), - self.wishbone.sel.eq(0xf), - self.wishbone.stb.eq(1), - self.wishbone.we.eq(1), - self.wishbone.cyc.eq(1), - If(self.wishbone.ack, - port.sink.ack.eq(1), - NextState("IDLE") - ) - ) - fsm.act("READ", - self.wishbone.adr.eq(port.sink.adr[2:]), - self.wishbone.stb.eq(1), - self.wishbone.we.eq(0), - self.wishbone.cyc.eq(1), - If(self.wishbone.ack, - NextState("COMPLETION") - ) - ) - self.sync += \ - If(self.wishbone.stb & self.wishbone.ack, - port.source.dat.eq(self.wishbone.dat_r), - ) - fsm.act("COMPLETION", - port.source.stb.eq(1), - port.source.sop.eq(1), - port.source.eop.eq(1), - port.source.len.eq(1), - port.source.err.eq(0), - port.source.tag.eq(port.sink.tag), - port.source.adr.eq(port.sink.adr), - port.source.cmp_id.eq(endpoint.phy.id), - port.source.req_id.eq(port.sink.req_id), - If(port.source.ack, - port.sink.ack.eq(1), - NextState("IDLE") - ) - ) diff --git a/misoclib/com/litepcie/litepcie-version.txt b/misoclib/com/litepcie/litepcie-version.txt deleted file mode 100644 index eba33402..00000000 --- a/misoclib/com/litepcie/litepcie-version.txt +++ /dev/null @@ -1,2 +0,0 @@ -0.9.0 - diff --git a/misoclib/com/litepcie/phy/__init__.py b/misoclib/com/litepcie/phy/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/com/litepcie/phy/s7pciephy.py b/misoclib/com/litepcie/phy/s7pciephy.py deleted file mode 100644 index 40869213..00000000 --- a/misoclib/com/litepcie/phy/s7pciephy.py +++ /dev/null @@ -1,163 +0,0 @@ -import os -from migen.fhdl.std import * -from migen.bank.description import * - -from misoclib.com.litepcie.common import * - - -def get_gt(device): - if device[:4] == "xc7k": - return "GTX" - elif device[:4] == "xc7a": - return "GTP" - else: - raise ValueError("Unsupported device"+device) - - -class S7PCIEPHY(Module, AutoCSR): - def __init__(self, platform, dw=64, link_width=2, bar0_size=1*MB): - pads = platform.request("pcie_x"+str(link_width)) - device = platform.device - self.dw = dw - self.link_width = link_width - - self.sink = Sink(phy_layout(dw)) - self.source = Source(phy_layout(dw)) - self.interrupt = Sink(interrupt_layout()) - - self.id = Signal(16) - - self.tx_buf_av = Signal(8) - self.tx_terr_drop = Signal() - self.tx_cfg_req = Signal() - self.tx_cfg_gnt = Signal(reset=1) - - self.rx_np_ok = Signal(reset=1) - self.rx_np_req = Signal(reset=1) - - self.cfg_to_turnoff = Signal() - - self._lnk_up = CSRStatus() - self._msi_enable = CSRStatus() - self._bus_master_enable = CSRStatus() - self._max_request_size = CSRStatus(16) - self._max_payload_size = CSRStatus(16) - self.max_request_size = self._max_request_size.status - self.max_payload_size = self._max_payload_size.status - - self.bar0_size = bar0_size - self.bar0_mask = get_bar_mask(bar0_size) - - # SHARED clock - # In case we want to use the second QPLL of the quad - self.shared_qpll_pd = Signal(reset=1) - self.shared_qpll_rst = Signal(reset=1) - self.shared_qpll_refclk = Signal() - self.shared_qpll_outclk = Signal() - self.shared_qpll_outrefclk = Signal() - self.shared_qpll_lock = Signal() - - # # # - - clk100 = Signal() - self.specials += Instance("IBUFDS_GTE2", - i_CEB=0, - i_I=pads.clk_p, - i_IB=pads.clk_n, - o_O=clk100, - o_ODIV2=Signal() - ) - - bus_number = Signal(8) - device_number = Signal(5) - function_number = Signal(3) - command = Signal(16) - dcommand = Signal(16) - - self.specials += Instance("pcie_phy", - p_C_DATA_WIDTH=dw, - p_C_PCIE_GT_DEVICE=get_gt(device), - p_C_BAR0=get_bar_mask(self.bar0_size), - - i_sys_clk=clk100, - i_sys_rst_n=pads.rst_n, - - o_pci_exp_txp=pads.tx_p, - o_pci_exp_txn=pads.tx_n, - - i_pci_exp_rxp=pads.rx_p, - i_pci_exp_rxn=pads.rx_n, - - o_user_clk=ClockSignal("clk125"), - o_user_reset=ResetSignal("clk125"), - o_user_lnk_up=self._lnk_up.status, - - o_tx_buf_av=self.tx_buf_av, - o_tx_terr_drop=self.tx_terr_drop, - o_tx_cfg_req=self.tx_cfg_req, - i_tx_cfg_gnt=self.tx_cfg_gnt, - - i_s_axis_tx_tvalid=self.sink.stb, - i_s_axis_tx_tlast=self.sink.eop, - o_s_axis_tx_tready=self.sink.ack, - i_s_axis_tx_tdata=self.sink.dat, - i_s_axis_tx_tkeep=self.sink.be, - i_s_axis_tx_tuser=0, - - i_rx_np_ok=self.rx_np_ok, - i_rx_np_req=self.rx_np_req, - - o_m_axis_rx_tvalid=self.source.stb, - o_m_axis_rx_tlast=self.source.eop, - i_m_axis_rx_tready=self.source.ack, - o_m_axis_rx_tdata=self.source.dat, - o_m_axis_rx_tkeep=self.source.be, - o_m_axis_rx_tuser=Signal(4), - - o_cfg_to_turnoff=self.cfg_to_turnoff, - o_cfg_bus_number=bus_number, - o_cfg_device_number=device_number, - o_cfg_function_number=function_number, - o_cfg_command=command, - o_cfg_dcommand=dcommand, - o_cfg_interrupt_msienable=self._msi_enable.status, - - i_cfg_interrupt=self.interrupt.stb, - o_cfg_interrupt_rdy=self.interrupt.ack, - i_cfg_interrupt_di=self.interrupt.dat, - - i_SHARED_QPLL_PD=self.shared_qpll_pd, - i_SHARED_QPLL_RST=self.shared_qpll_rst, - i_SHARED_QPLL_REFCLK=self.shared_qpll_refclk, - o_SHARED_QPLL_OUTCLK=self.shared_qpll_outclk, - o_SHARED_QPLL_OUTREFCLK=self.shared_qpll_outrefclk, - o_SHARED_QPLL_LOCK=self.shared_qpll_lock, - ) - - # id - self.comb += self.id.eq(Cat(function_number, device_number, bus_number)) - - # config - def convert_size(command, size): - cases = {} - value = 128 - for i in range(6): - cases[i] = size.eq(value) - value = value*2 - return Case(command, cases) - - self.sync += [ - self._bus_master_enable.status.eq(command[2]), - convert_size(dcommand[12:15], self.max_request_size), - convert_size(dcommand[5:8], self.max_payload_size) - ] - if hasattr(platform, "misoc_path"): - misoc_path = platform.misoc_path - else: - misoc_path = "./" - litepcie_phy_wrapper_path = os.path.join(misoc_path, "extcores", "litepcie_phy_wrappers") - platform.add_source_dir(os.path.join(litepcie_phy_wrapper_path, "xilinx", "7-series", "common")) - if device[:4] == "xc7k": - platform.add_source_dir(os.path.join(litepcie_phy_wrapper_path, "xilinx", "7-series", "kintex7")) - elif device[:4] == "xc7a": - platform.add_source_dir(os.path.join(litepcie_phy_wrapper_path, "xilinx", "7-series", "artix7")) diff --git a/misoclib/com/litepcie/software/__init__.py b/misoclib/com/litepcie/software/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/com/litepcie/software/linux/kernel/Makefile b/misoclib/com/litepcie/software/linux/kernel/Makefile deleted file mode 100644 index d50f989b..00000000 --- a/misoclib/com/litepcie/software/linux/kernel/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# Makefile for kernel module - -KERNEL_VERSION:=$(shell uname -r) -KERNEL_PATH:=/lib/modules/$(KERNEL_VERSION)/build - -obj-m = litepcie.o -litepcie-objs = main.o - -all: litepcie.ko - -litepcie.ko: main.c - make -C $(KERNEL_PATH) M=$(PWD) modules - -clean: - make -C $(KERNEL_PATH) M=$(PWD) clean - rm -f *~ diff --git a/misoclib/com/litepcie/software/linux/kernel/README b/misoclib/com/litepcie/software/linux/kernel/README deleted file mode 100644 index 9ec9bb60..00000000 --- a/misoclib/com/litepcie/software/linux/kernel/README +++ /dev/null @@ -1,9 +0,0 @@ -- Use 'make' to build the driver - -- Install the driver and create the device with : - - ./init.sh - -- Remove driver with - - rmmod litepcie diff --git a/misoclib/com/litepcie/software/linux/kernel/config.h b/misoclib/com/litepcie/software/linux/kernel/config.h deleted file mode 100644 index 787ae1d9..00000000 --- a/misoclib/com/litepcie/software/linux/kernel/config.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __HW_CONFIG_H -#define __HW_CONFIG_H - -/* pci */ -#define PCI_FPGA_VENDOR_ID 0x10ee -#define PCI_FPGA_DEVICE_ID 0x7022 -#define PCI_FPGA_BAR0_SIZE 0xa000 - -/* dma */ -#define DMA_BUFFER_COUNT 128 - - -#endif /* __HW_CONFIG_H */ diff --git a/misoclib/com/litepcie/software/linux/kernel/flags.h b/misoclib/com/litepcie/software/linux/kernel/flags.h deleted file mode 100644 index 744333a0..00000000 --- a/misoclib/com/litepcie/software/linux/kernel/flags.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __HW_FLAGS_H -#define __HW_FLAGS_H - -/* dma */ -#define DMA_LOOPBACK_ENABLE 0x1 - -#define DMA_TABLE_LOOP_INDEX 1 << 0 -#define DMA_TABLE_LOOP_COUNT 1 << 16 - -#endif /* __HW_FLAGS_H */ diff --git a/misoclib/com/litepcie/software/linux/kernel/init.sh b/misoclib/com/litepcie/software/linux/kernel/init.sh deleted file mode 100755 index 82cb4533..00000000 --- a/misoclib/com/litepcie/software/linux/kernel/init.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -# TODO: use udev instead - -insmod litepcie.ko - -major=$(awk '/ litepcie$/{print $1}' /proc/devices) -mknod -m 666 /dev/litepcie0 c $major 0 diff --git a/misoclib/com/litepcie/software/linux/kernel/litepcie.h b/misoclib/com/litepcie/software/linux/kernel/litepcie.h deleted file mode 100644 index 8fd80b70..00000000 --- a/misoclib/com/litepcie/software/linux/kernel/litepcie.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * LitePCIe driver - * - */ -#ifndef _LINUX_LITEPCIE_H -#define _LINUX_LITEPCIE_H - -#include - -struct litepcie_ioctl_mmap_info { - unsigned long reg_offset; - unsigned long reg_size; - - unsigned long dma_tx_buf_offset; - unsigned long dma_tx_buf_size; - unsigned long dma_tx_buf_count; - - unsigned long dma_rx_buf_offset; - unsigned long dma_rx_buf_size; - unsigned long dma_rx_buf_count; -}; - -struct litepcie_ioctl_dma_start { - __u32 dma_flags; /* see LITEPCIE_DMA_FLAGS_x */ - __u32 tx_buf_size; /* in bytes, must be < dma_buf_pitch. 0 means no TX */ - __u32 tx_buf_count; - __u32 rx_buf_size; /* in bytes, must be < dma_buf_pitch. 0 means no RX */ - __u32 rx_buf_count; -}; - -/* if tx_wait is true, wait until the current TX bufffer is - different from tx_buf_num. If tx_wait is false, wait until the - current RX buffer is different from rx_buf_num. Return the last - TX buffer in tx_buf_num and the last RX buffer in - rx_buf_num. */ -struct litepcie_ioctl_dma_wait { - __s32 timeout; /* in ms. Return -EAGAIN if timeout occured without event */ - __u32 tx_wait; - __u32 tx_buf_num; /* read/write */ - __u32 rx_buf_num; /* read/write */ -}; - -#define LITEPCIE_IOCTL 'S' - -#define LITEPCIE_IOCTL_GET_MMAP_INFO _IOR(LITEPCIE_IOCTL, 0, struct litepcie_ioctl_mmap_info) -#define LITEPCIE_IOCTL_DMA_START _IOW(LITEPCIE_IOCTL, 1, struct litepcie_ioctl_dma_start) -#define LITEPCIE_IOCTL_DMA_STOP _IO(LITEPCIE_IOCTL, 2) -#define LITEPCIE_IOCTL_DMA_WAIT _IOWR(LITEPCIE_IOCTL, 3, struct litepcie_ioctl_dma_wait) - -#endif /* _LINUX_LITEPCIE_H */ diff --git a/misoclib/com/litepcie/software/linux/kernel/main.c b/misoclib/com/litepcie/software/linux/kernel/main.c deleted file mode 100644 index aa9b18d5..00000000 --- a/misoclib/com/litepcie/software/linux/kernel/main.c +++ /dev/null @@ -1,639 +0,0 @@ -/* - * LitePCIe driver - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "litepcie.h" -#include "config.h" -#include "csr.h" -#include "flags.h" - -#define LITEPCIE_NAME "litepcie" -#define LITEPCIE_MINOR_COUNT 4 - -#define DMA_BUFFER_SIZE PAGE_ALIGN(32768) -#define DMA_BUFFER_MAP_SIZE (DMA_BUFFER_SIZE * DMA_BUFFER_COUNT) - -#define IRQ_MASK_DMA_READER (1 << DMA_READER_INTERRUPT) -#define IRQ_MASK_DMA_WRITER (1 << DMA_WRITER_INTERRUPT) - -typedef struct { - int minor; - struct pci_dev *dev; - - phys_addr_t bar0_phys_addr; - uint8_t *bar0_addr; /* virtual address of BAR0 */ - - uint8_t *dma_tx_bufs[DMA_BUFFER_COUNT]; - unsigned long dma_tx_bufs_addr[DMA_BUFFER_COUNT]; - uint8_t *dma_rx_bufs[DMA_BUFFER_COUNT]; - unsigned long dma_rx_bufs_addr[DMA_BUFFER_COUNT]; - uint8_t tx_dma_started; - uint8_t rx_dma_started; - wait_queue_head_t dma_waitqueue; -} LitePCIeState; - -static dev_t litepcie_cdev; -static struct cdev litepcie_cdev_struct; -static LitePCIeState *litepcie_minor_table[LITEPCIE_MINOR_COUNT]; - -static void litepcie_end(struct pci_dev *dev, LitePCIeState *s); -static int litepcie_dma_stop(LitePCIeState *s); - -static inline uint32_t litepcie_readl(LitePCIeState *s, uint32_t addr) -{ - return readl(s->bar0_addr + addr); -} - -static inline void litepcie_writel(LitePCIeState *s, uint32_t addr, uint32_t val) -{ - return writel(val, s->bar0_addr + addr); -} - -static void litepcie_enable_interrupt(LitePCIeState *s, int irq_num) -{ - uint32_t v; - v = litepcie_readl(s, CSR_IRQ_CONTROLLER_ENABLE_ADDR); - v |= (1 << irq_num); - litepcie_writel(s, CSR_IRQ_CONTROLLER_ENABLE_ADDR, v); -} - -static void litepcie_disable_interrupt(LitePCIeState *s, int irq_num) -{ - uint32_t v; - v = litepcie_readl(s, CSR_IRQ_CONTROLLER_ENABLE_ADDR); - v &= ~(1 << irq_num); - litepcie_writel(s, CSR_IRQ_CONTROLLER_ENABLE_ADDR, v); -} - -static int litepcie_open(struct inode *inode, struct file *file) -{ - LitePCIeState *s; - int minor; - - /* find PCI device */ - minor = iminor(inode); - if (minor < 0 || minor >= LITEPCIE_MINOR_COUNT) - return -ENODEV; - s = litepcie_minor_table[minor]; - if (!s) - return -ENODEV; - file->private_data = s; - return 0; -} - -/* mmap the DMA buffers and registers to user space */ -static int litepcie_mmap(struct file *file, struct vm_area_struct *vma) -{ - LitePCIeState *s = file->private_data; - unsigned long pfn; - int is_tx, i; - - if (vma->vm_pgoff == 0) { - if (vma->vm_end - vma->vm_start != DMA_BUFFER_MAP_SIZE) - return -EINVAL; - is_tx = 1; - goto remap_ram; - } else if (vma->vm_pgoff == (DMA_BUFFER_MAP_SIZE >> PAGE_SHIFT)) { - if (vma->vm_end - vma->vm_start != DMA_BUFFER_MAP_SIZE) - return -EINVAL; - is_tx = 0; - remap_ram: - for(i = 0; i < DMA_BUFFER_COUNT; i++) { - if (is_tx) - pfn = __pa(s->dma_tx_bufs[i]) >> PAGE_SHIFT; - else - pfn = __pa(s->dma_rx_bufs[i]) >> PAGE_SHIFT; - /* Note: the memory is cached, so the user must explicitly - flush the CPU caches on architectures which require it. */ - if (remap_pfn_range(vma, vma->vm_start + i * DMA_BUFFER_SIZE, pfn, - DMA_BUFFER_SIZE, vma->vm_page_prot)) { - printk(KERN_ERR LITEPCIE_NAME " remap_pfn_range failed\n"); - return -EAGAIN; - } - } - } else if (vma->vm_pgoff == ((2 * DMA_BUFFER_MAP_SIZE) >> PAGE_SHIFT)) { - if (vma->vm_end - vma->vm_start != PCI_FPGA_BAR0_SIZE) - return -EINVAL; - pfn = s->bar0_phys_addr >> PAGE_SHIFT; - /* not cached */ - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - vma->vm_flags |= VM_IO; - if (io_remap_pfn_range(vma, vma->vm_start, pfn, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) { - printk(KERN_ERR LITEPCIE_NAME " io_remap_pfn_range failed\n"); - return -EAGAIN; - } - } else { - return -EINVAL; - } - - return 0; -} - -static int litepcie_release(struct inode *inode, struct file *file) -{ - LitePCIeState *s = file->private_data; - - litepcie_dma_stop(s); /* just in case: stop the DMA */ - return 0; -} - -static irqreturn_t litepcie_interrupt(int irq, void *data) -{ - LitePCIeState *s = data; - uint32_t clear_mask, irq_vector; - - irq_vector = litepcie_readl(s, CSR_IRQ_CONTROLLER_VECTOR_ADDR); - clear_mask = 0; - if (irq_vector & (IRQ_MASK_DMA_READER | IRQ_MASK_DMA_WRITER)) { - /* wake up processes waiting on dma_wait() */ - wake_up_interruptible(&s->dma_waitqueue); - clear_mask |= (IRQ_MASK_DMA_READER | IRQ_MASK_DMA_WRITER); - } - - litepcie_writel(s, CSR_IRQ_CONTROLLER_CLEAR_ADDR, clear_mask); - - return IRQ_HANDLED; -} - -static int litepcie_dma_start(LitePCIeState *s, struct litepcie_ioctl_dma_start *m) -{ - int i, val; - - if (s->tx_dma_started || s->rx_dma_started) - return -EIO; - - if (m->tx_buf_size == 0 && m->rx_buf_size == 0) - return -EINVAL; - /* check alignment (XXX: what is the exact constraint ?) */ - if ((m->tx_buf_size & 7) != 0 || - (m->rx_buf_size & 7) != 0 || - m->tx_buf_size > DMA_BUFFER_SIZE || - m->rx_buf_size > DMA_BUFFER_SIZE) - return -EINVAL; - - /* check buffer count */ - if (m->tx_buf_count > DMA_BUFFER_COUNT) - return -EINVAL; - if (m->rx_buf_count > DMA_BUFFER_COUNT) - return -EINVAL; - - val = ((m->dma_flags & DMA_LOOPBACK_ENABLE) != 0); - litepcie_writel(s, CSR_DMA_LOOPBACK_ENABLE_ADDR, val); - - /* init DMA write */ - if (m->rx_buf_size != 0) { - litepcie_writel(s, CSR_DMA_WRITER_ENABLE_ADDR, 0); - litepcie_writel(s, CSR_DMA_WRITER_TABLE_FLUSH_ADDR, 1); - litepcie_writel(s, CSR_DMA_WRITER_TABLE_LOOP_PROG_N_ADDR, 0); - for(i = 0; i < m->rx_buf_count; i++) { - litepcie_writel(s, CSR_DMA_WRITER_TABLE_VALUE_ADDR, m->rx_buf_size); - litepcie_writel(s, CSR_DMA_WRITER_TABLE_VALUE_ADDR + 4, - s->dma_rx_bufs_addr[i]); - litepcie_writel(s, CSR_DMA_WRITER_TABLE_WE_ADDR, 1); - } - litepcie_writel(s, CSR_DMA_WRITER_TABLE_LOOP_PROG_N_ADDR, 1); - } - - /* init DMA read */ - if (m->tx_buf_size != 0) { - litepcie_writel(s, CSR_DMA_READER_ENABLE_ADDR, 0); - litepcie_writel(s, CSR_DMA_READER_TABLE_FLUSH_ADDR, 1); - litepcie_writel(s, CSR_DMA_READER_TABLE_LOOP_PROG_N_ADDR, 0); - for(i = 0; i < m->tx_buf_count; i++) { - litepcie_writel(s, CSR_DMA_READER_TABLE_VALUE_ADDR, m->tx_buf_size); - litepcie_writel(s, CSR_DMA_READER_TABLE_VALUE_ADDR + 4, - s->dma_tx_bufs_addr[i]); - litepcie_writel(s, CSR_DMA_READER_TABLE_WE_ADDR, 1); - } - litepcie_writel(s, CSR_DMA_READER_TABLE_LOOP_PROG_N_ADDR, 1); - } - - /* start DMA */ - if (m->rx_buf_size != 0) { - litepcie_writel(s, CSR_DMA_WRITER_ENABLE_ADDR, 1); - s->rx_dma_started = 1; - } - if (m->tx_buf_size != 0) { - litepcie_writel(s, CSR_DMA_READER_ENABLE_ADDR, 1); - s->tx_dma_started = 1; - } - - return 0; -} - -static int litepcie_dma_wait(LitePCIeState *s, struct litepcie_ioctl_dma_wait *m) -{ - unsigned long timeout; - int ret, last_buf_num; - DECLARE_WAITQUEUE(wait, current); - - if (m->tx_wait) { - if (!s->tx_dma_started) - return -EIO; - last_buf_num = m->tx_buf_num; - litepcie_enable_interrupt(s, DMA_READER_INTERRUPT); - } else { - if (!s->rx_dma_started) - return -EIO; - last_buf_num = m->rx_buf_num; - litepcie_enable_interrupt(s, DMA_WRITER_INTERRUPT); - } - - add_wait_queue(&s->dma_waitqueue, &wait); - - timeout = jiffies + msecs_to_jiffies(m->timeout); - for (;;) { - /* set current buffer */ - if (s->tx_dma_started) { - m->tx_buf_num = (litepcie_readl(s, CSR_DMA_READER_TABLE_LOOP_STATUS_ADDR) & 0xffff); - } else { - m->tx_buf_num = 0; - } - if (s->rx_dma_started) { - m->rx_buf_num = (litepcie_readl(s, CSR_DMA_WRITER_TABLE_LOOP_STATUS_ADDR) & 0xfffff); - } else { - m->rx_buf_num = 0; - } - if (m->tx_wait) { - if (m->tx_buf_num != last_buf_num) - break; - } else { - if (m->rx_buf_num != last_buf_num) - break; - } - if ((long)(jiffies - timeout) > 0) { - ret = -EAGAIN; - goto done; - } - set_current_state(TASK_INTERRUPTIBLE); - if (signal_pending(current)) { - ret = -EINTR; - goto done; - } - schedule(); - } - ret = 0; - done: - if (m->tx_wait) { - litepcie_disable_interrupt(s, DMA_READER_INTERRUPT); - } else { - litepcie_disable_interrupt(s, DMA_WRITER_INTERRUPT); - } - - __set_current_state(TASK_RUNNING); - remove_wait_queue(&s->dma_waitqueue, &wait); - return ret; -} - -static int litepcie_dma_stop(LitePCIeState *s) -{ - /* just to be sure, we disable the interrupts */ - litepcie_disable_interrupt(s, DMA_READER_INTERRUPT); - litepcie_disable_interrupt(s, DMA_WRITER_INTERRUPT); - - s->tx_dma_started = 0; - litepcie_writel(s, CSR_DMA_READER_TABLE_LOOP_PROG_N_ADDR, 0); - litepcie_writel(s, CSR_DMA_READER_TABLE_FLUSH_ADDR, 1); - udelay(100); - litepcie_writel(s, CSR_DMA_READER_ENABLE_ADDR, 0); - - s->rx_dma_started = 0; - litepcie_writel(s, CSR_DMA_WRITER_TABLE_LOOP_PROG_N_ADDR, 0); - litepcie_writel(s, CSR_DMA_WRITER_TABLE_FLUSH_ADDR, 1); - udelay(100); - litepcie_writel(s, CSR_DMA_WRITER_ENABLE_ADDR, 0); - - return 0; -} - -static long litepcie_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - LitePCIeState *s = file->private_data; - long ret; - - switch(cmd) { - case LITEPCIE_IOCTL_GET_MMAP_INFO: - { - struct litepcie_ioctl_mmap_info m; - m.dma_tx_buf_offset = 0; - m.dma_tx_buf_size = DMA_BUFFER_SIZE; - m.dma_tx_buf_count = DMA_BUFFER_COUNT; - - m.dma_rx_buf_offset = DMA_BUFFER_MAP_SIZE; - m.dma_rx_buf_size = DMA_BUFFER_SIZE; - m.dma_rx_buf_count = DMA_BUFFER_COUNT; - - m.reg_offset = 2 * DMA_BUFFER_MAP_SIZE; - m.reg_size = PCI_FPGA_BAR0_SIZE; - if (copy_to_user((void *)arg, &m, sizeof(m))) { - ret = -EFAULT; - break; - } - ret = 0; - } - break; - case LITEPCIE_IOCTL_DMA_START: - { - struct litepcie_ioctl_dma_start m; - - if (copy_from_user(&m, (void *)arg, sizeof(m))) { - ret = -EFAULT; - break; - } - ret = litepcie_dma_start(s, &m); - } - break; - case LITEPCIE_IOCTL_DMA_STOP: - { - ret = litepcie_dma_stop(s); - } - break; - case LITEPCIE_IOCTL_DMA_WAIT: - { - struct litepcie_ioctl_dma_wait m; - - if (copy_from_user(&m, (void *)arg, sizeof(m))) { - ret = -EFAULT; - break; - } - ret = litepcie_dma_wait(s, &m); - if (ret == 0) { - if (copy_to_user((void *)arg, &m, sizeof(m))) { - ret = -EFAULT; - break; - } - } - } - break; - default: - ret = -ENOIOCTLCMD; - break; - } - return ret; -} - -static const struct file_operations litepcie_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = litepcie_ioctl, - .open = litepcie_open, - .release = litepcie_release, - .mmap = litepcie_mmap, - .llseek = no_llseek, -}; - -static int litepcie_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - LitePCIeState *s = NULL; - uint8_t rev_id; - int ret, minor, i; - - printk(KERN_INFO LITEPCIE_NAME " Probing device\n"); - - /* find available minor */ - for(minor = 0; minor < LITEPCIE_MINOR_COUNT; minor++) { - if (!litepcie_minor_table[minor]) - break; - } - if (minor == LITEPCIE_MINOR_COUNT) { - printk(KERN_ERR LITEPCIE_NAME " Cannot allocate a minor\n"); - ret = -ENODEV; - goto fail1; - } - - s = kzalloc(sizeof(LitePCIeState), GFP_KERNEL); - if (!s) { - printk(KERN_ERR LITEPCIE_NAME " Cannot allocate memory\n"); - ret = -ENOMEM; - goto fail1; - } - s->minor = minor; - s->dev = dev; - pci_set_drvdata(dev, s); - - ret = pci_enable_device(dev); - if (ret != 0) { - printk(KERN_ERR LITEPCIE_NAME " Cannot enable device\n"); - goto fail1; - } - - /* check device version */ - pci_read_config_byte(dev, PCI_REVISION_ID, &rev_id); - if (rev_id != 1) { - printk(KERN_ERR LITEPCIE_NAME " Unsupported device version %d\n", rev_id); - goto fail2; - } - - if (pci_request_regions(dev, LITEPCIE_NAME) < 0) { - printk(KERN_ERR LITEPCIE_NAME " Could not request regions\n"); - goto fail2; - } - - /* check BAR0 config */ - if (!(pci_resource_flags(dev, 0) & IORESOURCE_MEM)) { - printk(KERN_ERR LITEPCIE_NAME " Invalid BAR0 config\n"); - goto fail3; - } - - s->bar0_phys_addr = pci_resource_start(dev, 0); - s->bar0_addr = pci_ioremap_bar(dev, 0); - if (!s->bar0_addr) { - printk(KERN_ERR LITEPCIE_NAME " Could not map BAR0\n"); - goto fail3; - } - - pci_set_master(dev); - ret = pci_set_dma_mask(dev, DMA_BIT_MASK(32)); - if (ret) { - printk(KERN_ERR LITEPCIE_NAME " Failed to set DMA mask\n"); - goto fail4; - }; - - ret = pci_enable_msi(dev); - if (ret) { - printk(KERN_ERR LITEPCIE_NAME " Failed to enable MSI\n"); - goto fail4; - } - - if (request_irq(dev->irq, litepcie_interrupt, IRQF_SHARED, LITEPCIE_NAME, s) < 0) { - printk(KERN_ERR LITEPCIE_NAME " Failed to allocate irq %d\n", dev->irq); - goto fail5; - } - - /* soft reset */ - litepcie_writel(s, CSR_CRG_SOFT_RST_ADDR, 1); - udelay(5); - - /* allocate DMA buffers */ - for(i = 0; i < DMA_BUFFER_COUNT; i++) { - s->dma_tx_bufs[i] = kzalloc(DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA32); - if (!s->dma_tx_bufs[i]) { - printk(KERN_ERR LITEPCIE_NAME " Failed to allocate dma_tx_buf\n"); - goto fail6; - } - s->dma_tx_bufs_addr[i] = pci_map_single(dev, s->dma_tx_bufs[i], - DMA_BUFFER_SIZE, - DMA_TO_DEVICE); - if (!s->dma_tx_bufs_addr[i]) { - ret = -ENOMEM; - goto fail6; - } - } - - for(i = 0; i < DMA_BUFFER_COUNT; i++) { - s->dma_rx_bufs[i] = kzalloc(DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA32); - if (!s->dma_rx_bufs[i]) { - printk(KERN_ERR LITEPCIE_NAME " Failed to allocate dma_rx_buf\n"); - goto fail6; - } - - s->dma_rx_bufs_addr[i] = pci_map_single(dev, s->dma_rx_bufs[i], - DMA_BUFFER_SIZE, - DMA_FROM_DEVICE); - if (!s->dma_rx_bufs_addr[i]) { - ret = -ENOMEM; - goto fail6; - } - } - - init_waitqueue_head(&s->dma_waitqueue); - - litepcie_minor_table[minor] = s; - printk(KERN_INFO LITEPCIE_NAME " Assigned to minor %d\n", minor); - return 0; - - fail6: - litepcie_end(dev, s); - free_irq(dev->irq, s); - fail5: - pci_disable_msi(dev); - fail4: - pci_iounmap(dev, s->bar0_addr); - fail3: - pci_release_regions(dev); - fail2: - pci_disable_device(dev); - ret = -EIO; - fail1: - kfree(s); - printk(KERN_ERR LITEPCIE_NAME " Error while probing device\n"); - return ret; -} - -static void litepcie_end(struct pci_dev *dev, LitePCIeState *s) -{ - int i; - - for(i = 0; i < DMA_BUFFER_COUNT; i++) { - if (s->dma_tx_bufs_addr[i]) { - dma_unmap_single(&dev->dev, s->dma_tx_bufs_addr[i], - DMA_BUFFER_SIZE, DMA_TO_DEVICE); - } - kfree(s->dma_tx_bufs[i]); - } - - for(i = 0; i < DMA_BUFFER_COUNT; i++) { - if (s->dma_rx_bufs_addr[i]) { - dma_unmap_single(&dev->dev, s->dma_rx_bufs_addr[i], - DMA_BUFFER_SIZE, DMA_FROM_DEVICE); - } - kfree(s->dma_rx_bufs[i]); - } -} - -static void litepcie_pci_remove(struct pci_dev *dev) -{ - LitePCIeState *s = pci_get_drvdata(dev); - - printk(KERN_INFO LITEPCIE_NAME " Removing device\n"); - litepcie_minor_table[s->minor] = NULL; - - litepcie_end(dev, s); - free_irq(dev->irq, s); - pci_disable_msi(dev); - pci_iounmap(dev, s->bar0_addr); - pci_disable_device(dev); - pci_release_regions(dev); - kfree(s); -}; - -static const struct pci_device_id litepcie_pci_ids[] = { - { PCI_DEVICE(PCI_FPGA_VENDOR_ID, PCI_FPGA_DEVICE_ID), }, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, litepcie_pci_ids); - - -static struct pci_driver litepcie_pci_driver = { - .name = LITEPCIE_NAME, - .id_table = litepcie_pci_ids, - .probe = litepcie_pci_probe, - .remove = litepcie_pci_remove, -}; - -static int __init litepcie_module_init(void) -{ - int ret; - - ret = pci_register_driver(&litepcie_pci_driver); - if (ret < 0) { - printk(KERN_ERR LITEPCIE_NAME " Error while registering PCI driver\n"); - goto fail1; - } - - ret = alloc_chrdev_region(&litepcie_cdev, 0, LITEPCIE_MINOR_COUNT, LITEPCIE_NAME); - if (ret < 0) { - printk(KERN_ERR LITEPCIE_NAME " Could not allocate char device\n"); - goto fail2; - } - - cdev_init(&litepcie_cdev_struct, &litepcie_fops); - ret = cdev_add(&litepcie_cdev_struct, litepcie_cdev, LITEPCIE_MINOR_COUNT); - if (ret < 0) { - printk(KERN_ERR LITEPCIE_NAME " Could not register char device\n"); - goto fail3; - } - return 0; - fail3: - unregister_chrdev_region(litepcie_cdev, LITEPCIE_MINOR_COUNT); - fail2: - pci_unregister_driver(&litepcie_pci_driver); - fail1: - return ret; -} - -static void __exit litepcie_module_exit(void) -{ - cdev_del(&litepcie_cdev_struct); - unregister_chrdev_region(litepcie_cdev, LITEPCIE_MINOR_COUNT); - - pci_unregister_driver(&litepcie_pci_driver); -} - - -module_init(litepcie_module_init); -module_exit(litepcie_module_exit); - -MODULE_LICENSE("GPL"); diff --git a/misoclib/com/litepcie/software/linux/user/Makefile b/misoclib/com/litepcie/software/linux/user/Makefile deleted file mode 100644 index 3a68e9e5..00000000 --- a/misoclib/com/litepcie/software/linux/user/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -CFLAGS=-O2 -Wall -g -I../kernel -MMD -LDFLAGS=-g -CC=gcc -AR=ar - -PROGS=litepcie_util - -all: $(PROGS) - -litepcie_util: litepcie_util.o litepcie_lib.o - $(CC) $(LDFLAGS) -o $@ $^ -lrt -lm - -clean: - rm -f $(PROGS) *.o *.a *.d *~ - -%.o: %.c - $(CC) -c $(CFLAGS) -o $@ $< - --include $(wildcard *.d) diff --git a/misoclib/com/litepcie/software/linux/user/cutils.h b/misoclib/com/litepcie/software/linux/user/cutils.h deleted file mode 100644 index 0d51daa9..00000000 --- a/misoclib/com/litepcie/software/linux/user/cutils.h +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include - -#ifndef _BOOL_defined -#define _BOOL_defined -#undef FALSE -#undef TRUE - -typedef int BOOL; -enum { - FALSE = 0, - TRUE = 1, -}; -#endif - -static inline int sub_mod_int(int a, int b, int m) -{ - a -= b; - if (a < 0) - a += m; - return a; -} - -static inline int add_mod_int(int a, int b, int m) -{ - a += b; - if (a >= m) - a -= m; - return a; -} diff --git a/misoclib/com/litepcie/software/linux/user/litepcie_lib.c b/misoclib/com/litepcie/software/linux/user/litepcie_lib.c deleted file mode 100644 index e1d64758..00000000 --- a/misoclib/com/litepcie/software/linux/user/litepcie_lib.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * LitePCIe library - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "litepcie.h" -#include "cutils.h" -#include "config.h" -#include "csr.h" -#include "flags.h" - -#include "litepcie_lib.h" - -/* - TODO: - - DMA overflow/underflow detection -*/ - -void *litepcie_malloc(int size) -{ - return malloc(size); -} - -void *litepcie_mallocz(int size) -{ - void *ptr; - ptr = litepcie_malloc(size); - if (!ptr) - return NULL; - memset(ptr, 0, size); - return ptr; -} - -void litepcie_free(void *ptr) -{ - free(ptr); -} - -void __attribute__((format(printf, 2, 3))) litepcie_log(LitePCIeState *s, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -/* in ms */ -int64_t litepcie_get_time_ms(void) -{ - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (int64_t)ts.tv_sec * 1000 + (ts.tv_nsec / 1000000U); -} - -LitePCIeState *litepcie_open(const char *device_name) -{ - LitePCIeState *s; - - s = litepcie_mallocz(sizeof(LitePCIeState)); - if (!s) - return NULL; - - s->litepcie_fd = open(device_name, O_RDWR); - if (s->litepcie_fd < 0) { - perror(device_name); - goto fail; - } - - /* map the DMA buffers */ - if (ioctl(s->litepcie_fd, LITEPCIE_IOCTL_GET_MMAP_INFO, &s->mmap_info) != 0) { - perror("LITEPCIE_IOCTL_GET_MMAP_INFO"); - exit(1); - } - - s->dma_tx_buf = mmap(NULL, s->mmap_info.dma_tx_buf_size * - s->mmap_info.dma_tx_buf_count, - PROT_READ | PROT_WRITE, MAP_SHARED, s->litepcie_fd, - s->mmap_info.dma_tx_buf_offset); - if (s->dma_tx_buf == MAP_FAILED) { - perror("mmap1"); - exit(1); - } - - s->dma_rx_buf = mmap(NULL, s->mmap_info.dma_rx_buf_size * - s->mmap_info.dma_rx_buf_count, - PROT_READ | PROT_WRITE, MAP_SHARED, s->litepcie_fd, - s->mmap_info.dma_rx_buf_offset); - if (s->dma_rx_buf == MAP_FAILED) { - perror("mmap2"); - exit(1); - } - - /* map the registers */ - s->reg_buf = mmap(NULL, s->mmap_info.reg_size, - PROT_READ | PROT_WRITE, MAP_SHARED, s->litepcie_fd, - s->mmap_info.reg_offset); - if (s->reg_buf == MAP_FAILED) { - perror("mmap2"); - exit(1); - } - - s->dma_tx_buf_size = s->mmap_info.dma_tx_buf_size; - s->dma_rx_buf_size = s->mmap_info.dma_rx_buf_size; - - pthread_mutex_init(&s->fifo_mutex, NULL); - - return s; - fail: - litepcie_close(s); - return NULL; -} - -void litepcie_dma_start(LitePCIeState *s, int buf_size, int buf_count, BOOL is_loopback) -{ - struct litepcie_ioctl_dma_start dma_start; - - if (buf_count > DMA_BUFFER_COUNT) { - litepcie_log(s, "unsupported buf_count\n"); - exit(1); - } - - s->tx_buf_size = s->rx_buf_size = buf_size; - s->tx_buf_count = s->rx_buf_count = buf_count; - - dma_start.dma_flags = 0; - if (is_loopback) - dma_start.dma_flags |= DMA_LOOPBACK_ENABLE; - dma_start.tx_buf_size = s->tx_buf_size; - dma_start.tx_buf_count = s->tx_buf_count; - dma_start.rx_buf_size = s->rx_buf_size; - dma_start.rx_buf_count = s->rx_buf_count; - if (ioctl(s->litepcie_fd, LITEPCIE_IOCTL_DMA_START, &dma_start) < 0) { - perror("LITEPCIE_IOCTL_DMA_START"); - } -} - -void litepcie_dma_stop(LitePCIeState *s) -{ - if (ioctl(s->litepcie_fd, LITEPCIE_IOCTL_DMA_STOP, NULL) < 0) { - perror("LITEPCIE_IOCTL_DMA_STOP"); - } -} - -void litepcie_writel(LitePCIeState *s, uint32_t addr, uint32_t val) -{ - *(volatile uint32_t *)(s->reg_buf + addr) = val; -} - -uint32_t litepcie_readl(LitePCIeState *s, uint32_t addr) -{ - return *(volatile uint32_t *)(s->reg_buf + addr); -} - -void litepcie_close(LitePCIeState *s) -{ - pthread_mutex_destroy(&s->fifo_mutex); - - if (s->dma_tx_buf) { - munmap(s->dma_tx_buf, s->mmap_info.dma_tx_buf_size * - s->mmap_info.dma_tx_buf_count); - } - if (s->dma_rx_buf) { - munmap(s->dma_rx_buf, s->mmap_info.dma_rx_buf_size * - s->mmap_info.dma_rx_buf_count); - } - if (s->reg_buf) - munmap(s->reg_buf, s->mmap_info.reg_size); - if (s->litepcie_fd >= 0) - close(s->litepcie_fd); - litepcie_free(s); -} diff --git a/misoclib/com/litepcie/software/linux/user/litepcie_lib.h b/misoclib/com/litepcie/software/linux/user/litepcie_lib.h deleted file mode 100644 index d4415ef0..00000000 --- a/misoclib/com/litepcie/software/linux/user/litepcie_lib.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * LitePCIe library - * - */ -#ifndef LITEPCIE_LIB_H -#define LITEPCIE_LIB_H - -#include -#include - -#define LITEPCIE_FILENAME "/dev/litepcie0" - -typedef struct { - int litepcie_fd; - struct litepcie_ioctl_mmap_info mmap_info; - uint8_t *dma_tx_buf; - int dma_tx_buf_size; - uint8_t *dma_rx_buf; - int dma_rx_buf_size; - uint8_t *reg_buf; - - unsigned int tx_buf_size; /* in bytes */ - unsigned int tx_buf_count; /* number of buffers */ - unsigned int rx_buf_size; /* in bytes */ - unsigned int rx_buf_count; /* number of buffers */ - - unsigned int tx_buf_len; /* in samples */ - unsigned int rx_buf_len; /* in samples */ - - pthread_mutex_t fifo_mutex; - int64_t rx_timestamp; /* timestamp (in samples) of the current RX buffer */ - unsigned int rx_buf_index; /* index of the current RX buffer */ - unsigned int rx_buf_next; /* index of the next buffer after the - last received buffer */ - BOOL has_rx_timestamp; /* true if received at least one buffer */ - - int64_t tx_underflow_count; /* TX too late */ - int64_t rx_overflow_count; /* RX too late */ -} LitePCIeState; - -void *litepcie_malloc(int size); -void *litepcie_mallocz(int size); -void litepcie_free(void *ptr); -void __attribute__((format(printf, 2, 3))) litepcie_log(LitePCIeState *s, const char *fmt, ...); -int64_t litepcie_get_time_ms(void); -LitePCIeState *litepcie_open(const char *device_name); -void litepcie_close(LitePCIeState *s); -void litepcie_dma_start(LitePCIeState *s, int buf_size, int buf_count, BOOL is_loopback); -void litepcie_dma_stop(LitePCIeState *s); -void litepcie_writel(LitePCIeState *s, uint32_t addr, uint32_t val); -uint32_t litepcie_readl(LitePCIeState *s, uint32_t addr); - -#endif /* LITEPCIE_LIB_H */ diff --git a/misoclib/com/litepcie/software/linux/user/litepcie_util.c b/misoclib/com/litepcie/software/linux/user/litepcie_util.c deleted file mode 100644 index 031f34d8..00000000 --- a/misoclib/com/litepcie/software/linux/user/litepcie_util.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * LitePCIe utilities - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "litepcie.h" -#include "cutils.h" -#include "config.h" -#include "csr.h" -#include "flags.h" -#include "litepcie_lib.h" - -static inline uint32_t seed_to_data(uint32_t seed) -{ -#if 1 - /* more random but slower */ - return seed * 0x31415976 + 1; -#else - /* simplify debug: just copy the counter */ - return seed; -#endif -} - -static void write_pn_data(uint32_t *dst, int count, uint32_t *pseed) -{ - int i; - uint32_t seed; - - seed = *pseed; - for(i = 0; i < count; i++) { - dst[i] = seed_to_data(seed); - seed++; - } - *pseed = seed; -} - -/* Return the number of errors */ -static int check_pn_data(const uint32_t *tab, int count, - uint32_t *pseed) -{ - int i, errors; - uint32_t seed; - - errors = 0; - seed = *pseed; - for(i = 0; i < count; i++) { - if (tab[i] != seed_to_data(seed)) { - errors++; - } - seed++; - } - *pseed = seed; - return errors; -} - -#define MAX_SHIFT_OFFSET 128 - -/* test DMA with a buffer size of buf_size bytes in loopback - mode. */ -void dma_test(LitePCIeState *s, int buf_size, int buf_count, BOOL is_loopback) -{ - int is_first, tx_buf_num, buf_num_cur, buf_num_next; - struct litepcie_ioctl_dma_wait dma_wait; - int buf_stats_count; /* statistics */ - int64_t last_time; - uint32_t tx_seed, rx_seed; - int buf_rx_count, first_rx_buf, rx_errors, shift, d, tx_underflows; - - litepcie_dma_start(s, buf_size, buf_count, is_loopback); - - is_first = 1; - buf_num_cur = 0; /* next buffer to receive */ - /* PN data TX and RX state */ - tx_seed = MAX_SHIFT_OFFSET; - rx_seed = 0; - buf_rx_count = 0; - first_rx_buf = 1; - - /* statistics */ - buf_stats_count = 0; - last_time = litepcie_get_time_ms(); - rx_errors = 0; - shift = 0; - tx_underflows = 0; - - for(;;) { - /* wait until at least one buffer is received */ - dma_wait.timeout = 1000; /* 1 second timeout */ - dma_wait.tx_wait = FALSE; - dma_wait.tx_buf_num = -1; /* not used */ - if (is_first) { - dma_wait.rx_buf_num = -1; /* don't wait, just get the last - received buffer number */ - } else { - dma_wait.rx_buf_num = sub_mod_int(buf_num_cur, 1, buf_count); - } - /* wait until the current buffer number is different from - dma_wait.buf_num */ - if (ioctl(s->litepcie_fd, LITEPCIE_IOCTL_DMA_WAIT, &dma_wait) < 0) { - perror("LITEPCIE_IOCTL_DMA_WAIT"); - } - if (is_first) { - buf_num_cur = dma_wait.rx_buf_num; - is_first = 0; - } - buf_num_next = add_mod_int(dma_wait.rx_buf_num, 1, buf_count); - - while (buf_num_cur != buf_num_next) { - - /* write the TX data 4/10 of a DMA cycle in the future */ - tx_buf_num = add_mod_int(buf_num_cur, 4*buf_count/10, buf_count); - d = sub_mod_int(tx_buf_num, buf_num_next, buf_count); - if (d >= (buf_count / 2)) { - /* we are too late in writing data, which necessarily - gives read errors. */ - tx_underflows++; - } - - write_pn_data((uint32_t *)(s->dma_tx_buf + - tx_buf_num * s->dma_tx_buf_size), - s->tx_buf_size >> 2, &tx_seed); - - if (buf_rx_count >= 4*buf_count/10) { - const uint32_t *rx_buf; - int rx_buf_len; - - rx_buf = (uint32_t *)(s->dma_rx_buf + buf_num_cur * s->dma_rx_buf_size); - rx_buf_len = s->rx_buf_size >> 2; - - if (first_rx_buf) { - uint32_t seed; - - /* find the initial shift */ - for(shift = 0; shift < 2 * MAX_SHIFT_OFFSET; shift++) { - seed = rx_seed + shift; - rx_errors = check_pn_data(rx_buf, rx_buf_len, &seed); - if (rx_errors <= (rx_buf_len / 2)) { - rx_seed = seed; - break; - } - } - if (shift == 2 * MAX_SHIFT_OFFSET) { - printf("Cannot find initial data\n"); - exit(1); - } else { - printf("RX shift = %d\n", - -(shift - MAX_SHIFT_OFFSET)); - } - first_rx_buf = 0; - } else { - /* count the number of errors */ - rx_errors += check_pn_data(rx_buf, rx_buf_len, &rx_seed); - } - } else { - buf_rx_count++; - } - - buf_num_cur = add_mod_int(buf_num_cur, 1, buf_count); - - /* statistics */ - if (++buf_stats_count == 10000) { - int64_t duration; - duration = litepcie_get_time_ms() - last_time; - printf("%0.1f Gb/sec %0.1f bufs/sec tx_underflows=%d errors=%d\n", - (double)buf_stats_count * buf_size * 8 / ((double)duration * 1e6), - (double)buf_stats_count * 1000 / (double)duration, - tx_underflows, rx_errors); - last_time = litepcie_get_time_ms(); - buf_stats_count = 0; - tx_underflows = 0; - rx_errors = 0; - } - } - } - - litepcie_dma_stop(s); -} - -void dma_loopback_test(void) -{ - LitePCIeState *s; - - s = litepcie_open(LITEPCIE_FILENAME); - if (!s) { - fprintf(stderr, "Could not init driver\n"); - exit(1); - } - dma_test(s, 16*1024, DMA_BUFFER_COUNT, TRUE); - - litepcie_close(s); -} - -void dump_version(void) -{ - LitePCIeState *s; - - s = litepcie_open(LITEPCIE_FILENAME); - if (!s) { - fprintf(stderr, "Could not init driver\n"); - exit(1); - } - printf("sysid=0x%x\n", litepcie_readl(s, CSR_IDENTIFIER_SYSID_ADDR)); - printf("frequency=%d\n", litepcie_readl(s, CSR_IDENTIFIER_FREQUENCY_ADDR)); - - litepcie_close(s); -} - -void help(void) -{ - printf("usage: litepcie_util cmd [args...]\n" - "\n" - "available commands:\n" - "dma_loopback_test test DMA loopback operation\n" - "version return fpga version\n" - ); - exit(1); -} - -int main(int argc, char **argv) -{ - const char *cmd; - int c; - - for(;;) { - c = getopt(argc, argv, "h"); - if (c == -1) - break; - switch(c) { - case 'h': - help(); - break; - default: - exit(1); - } - } - - if (optind >= argc) - help(); - cmd = argv[optind++]; - - if (!strcmp(cmd, "dma_loopback_test")) { - dma_loopback_test(); - } else if (!strcmp(cmd, "version")) { - dump_version(); - } else { - help(); - } - - return 0; -} diff --git a/misoclib/com/litepcie/software/wishbone.py b/misoclib/com/litepcie/software/wishbone.py deleted file mode 100644 index fb632af9..00000000 --- a/misoclib/com/litepcie/software/wishbone.py +++ /dev/null @@ -1,65 +0,0 @@ -import string -import mmap -import sys - -from misoclib.tools.litescope.software.driver.reg import * - - -class LitePCIeWishboneDriverLinux: - def __init__(self, bar, bar_size, addrmap=None, busword=8, debug=False): - self.bar = bar - self.bar_size = bar_size - self.debug = debug - self.f = None - self.mmap = None - self.regs = build_map(addrmap, busword, self.read, self.write) - - def open(self): - self.f = open(self.bar, "r+b") - self.f.flush() - self.mmap = mmap.mmap(self.f.fileno(), self.bar_size) - - def close(self): - self.mmap.close() - self.f.close() - - def read(self, addr, burst_length=1): - datas = [] - for i in range(burst_length): - self.mmap.seek(addr + 4*i) - dat = self.mmap.read(4) - val = dat[3] << 24 - val |= dat[2] << 16 - val |= dat[1] << 8 - val |= dat[0] << 0 - if self.debug: - print("RD {:08X} @ {:08X}".format(val, addr + 4*i)) - datas.append(val) - 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] - - for i, dat in enumerate(data): - dat_bytes = [0, 0, 0, 0] - dat_bytes[3] = (dat >> 24) & 0xff - dat_bytes[2] = (dat >> 16) & 0xff - dat_bytes[1] = (dat >> 8) & 0xff - dat_bytes[0] = (dat >> 0) & 0xff - self.mmap[addr + 4*i:addr + 4*(i+1)] = bytes(dat_bytes) - if self.debug: - print("WR {:08X} @ {:08X}".format(dat, (addr + i)*4)) - - -def LitePCIeWishboneDriver(*args, **kwargs): - if sys.platform == "win32" or sys.platform == "cygwin": - raise NotImplementedError - else: - return LitePCIeWishboneDriverLinux(*args, **kwargs) diff --git a/misoclib/com/litepcie/test/Makefile b/misoclib/com/litepcie/test/Makefile deleted file mode 100644 index 4f3210ad..00000000 --- a/misoclib/com/litepcie/test/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -MSCDIR = ../../../../ -PYTHON = python3 - -CMD = PYTHONPATH=$(MSCDIR) $(PYTHON) - -wishbone_tb: - $(CMD) wishbone_tb.py - -dma_tb: - $(CMD) dma_tb.py diff --git a/misoclib/com/litepcie/test/common.py b/misoclib/com/litepcie/test/common.py deleted file mode 100644 index eacf8ee4..00000000 --- a/misoclib/com/litepcie/test/common.py +++ /dev/null @@ -1,36 +0,0 @@ -import random - - -def print_with_prefix(s, prefix=""): - if not isinstance(s, str): - s = s.__repr__() - s = s.split("\n") - for l in s: - print(prefix + l) - - -def seed_to_data(seed, random=True): - if random: - return (seed * 0x31415979 + 1) & 0xffffffff - else: - return seed - - -def check(ref, res): - if isinstance(ref, int): - return 0, 1, int(ref != res) - else: - shift = 0 - while((ref[0] != res[0]) and (len(res) > 1)): - res.pop(0) - shift += 1 - length = min(len(ref), len(res)) - errors = 0 - for i in range(length): - if ref.pop(0) != res.pop(0): - errors += 1 - return shift, length, errors - - -def randn(max_n): - return random.randint(0, max_n-1) diff --git a/misoclib/com/litepcie/test/dma_tb.py b/misoclib/com/litepcie/test/dma_tb.py deleted file mode 100644 index fff3f3af..00000000 --- a/misoclib/com/litepcie/test/dma_tb.py +++ /dev/null @@ -1,177 +0,0 @@ -import random -from migen.fhdl.std import * -from migen.sim.generic import run_simulation -from migen.actorlib.structuring import Converter - -from misoclib.com.litepcie.common import * -from misoclib.com.litepcie.core import Endpoint -from misoclib.com.litepcie.core.irq import interrupt_controller -from misoclib.com.litepcie.frontend.dma import writer, reader - -from misoclib.com.litepcie.test.common import * -from misoclib.com.litepcie.test.model.host import * - -DMA_READER_IRQ = 1 -DMA_WRITER_IRQ = 2 - -root_id = 0x100 -endpoint_id = 0x400 -max_length = Signal(8, reset=128) -dma_size = 1024 - - -class DMADriver(): - def __init__(self, dma, selfp): - self.dma = dma - self.selfp = selfp - - def set_prog_mode(self): - dma = getattr(self.selfp, self.dma) - dma.table._loop_prog_n.storage = 0 - yield - - def set_loop_mode(self): - dma = getattr(self.selfp, self.dma) - dma.table._loop_prog_n.storage = 1 - yield - - def flush(self): - dma = getattr(self.selfp, self.dma) - dma.table._flush.re = 1 - yield - dma.table._flush.re = 0 - yield - - def program_descriptor(self, address, length): - value = address - value |= (length << 32) - - dma = getattr(self.selfp, self.dma) - - dma.table._value.storage = value - dma.table._we.r = 1 - dma.table._we.re = 1 - yield - dma.table._we.re = 0 - yield - - def enable(self): - dma = getattr(self.selfp, self.dma) - dma._enable.storage = 1 - yield - - def disable(self): - dma = getattr(self.selfp, self.dma) - dma._enable.storage = 0 - yield - - -class InterruptHandler(Module): - def __init__(self, debug=False): - self.debug = debug - self.sink = Sink(interrupt_layout()) - self.dma_writer_irq = 0 - - def set_tb_selfp(self, tb_selfp): - self.tb_selfp = tb_selfp - - def do_simulation(self, selfp): - tb_selfp = self.tb_selfp - tb_selfp.irq_controller._clear.r = 0 - tb_selfp.irq_controller._clear.re = 0 - selfp.sink.ack = 1 - self.dma_writer_irq = 0 - if selfp.sink.stb and (selfp.simulator.cycle_counter%4 == 0): - # get vector - irq_vector = tb_selfp.irq_controller._vector.status - - # handle irq - if irq_vector & DMA_READER_IRQ: - if self.debug: - print("DMA_READER IRQ : {}".format(tb_selfp.dma_reader.table._index.status)) - # clear irq_controller - tb_selfp.irq_controller._clear.re = 1 - tb_selfp.irq_controller._clear.r |= DMA_READER_IRQ - - if irq_vector & DMA_WRITER_IRQ: - if self.debug: - print("DMA_WRITER IRQ : {}".format(tb_selfp.dma_writer.table._index.status)) - # clear irq_controller - tb_selfp.irq_controller._clear.re = 1 - tb_selfp.irq_controller._clear.r |= DMA_WRITER_IRQ - self.dma_writer_irq = 1 - - -test_size = 16*1024 - - -class TB(Module): - def __init__(self, with_converter=False): - self.submodules.host = Host(64, root_id, endpoint_id, - phy_debug=False, - chipset_debug=False, chipset_split=True, chipset_reordering=True, - host_debug=True) - self.submodules.endpoint = Endpoint(self.host.phy, max_pending_requests=8, with_reordering=True) - self.submodules.dma_reader = reader.DMAReader(self.endpoint, self.endpoint.crossbar.get_master_port(read_only=True)) - self.submodules.dma_writer = writer.DMAWriter(self.endpoint, self.endpoint.crossbar.get_master_port(write_only=True)) - - if with_converter: - self.submodules.up_converter = Converter(dma_layout(16), dma_layout(64)) - self.submodules.down_converter = Converter(dma_layout(64), dma_layout(16)) - - self.comb += [ - self.dma_reader.source.connect(self.down_converter.sink), - self.down_converter.source.connect(self.up_converter.sink), - self.up_converter.source.connect(self.dma_writer.sink) - ] - else: - self.comb += self.dma_reader.source.connect(self.dma_writer.sink) - - self.submodules.irq_controller = interrupt_controller.InterruptController(2) - self.comb += [ - self.irq_controller.irqs[log2_int(DMA_READER_IRQ)].eq(self.dma_reader.table.irq), - self.irq_controller.irqs[log2_int(DMA_WRITER_IRQ)].eq(self.dma_writer.table.irq) - ] - self.submodules.irq_handler = InterruptHandler() - self.comb += self.irq_controller.source.connect(self.irq_handler.sink) - - def gen_simulation(self, selfp): - self.host.malloc(0x00000000, test_size*2) - self.host.chipset.enable() - host_datas = [seed_to_data(i, True) for i in range(test_size//4)] - self.host.write_mem(0x00000000, host_datas) - - dma_reader_driver = DMADriver("dma_reader", selfp) - dma_writer_driver = DMADriver("dma_writer", selfp) - - self.irq_handler.set_tb_selfp(selfp) - - yield from dma_reader_driver.set_prog_mode() - yield from dma_reader_driver.flush() - for i in range(8): - yield from dma_reader_driver.program_descriptor((test_size//8)*i, test_size//8) - - yield from dma_writer_driver.set_prog_mode() - yield from dma_writer_driver.flush() - for i in range(8): - yield from dma_writer_driver.program_descriptor(test_size + (test_size//8)*i, test_size//8) - - selfp.irq_controller._enable.storage = DMA_READER_IRQ | DMA_WRITER_IRQ - - yield from dma_reader_driver.enable() - yield from dma_writer_driver.enable() - - i = 0 - while i != 8: - i += self.irq_handler.dma_writer_irq - yield - - for i in range(100): - yield - loopback_datas = self.host.read_mem(test_size, test_size) - - s, l, e = check(host_datas, loopback_datas) - print("shift " + str(s) + " / length " + str(l) + " / errors " + str(e)) - -if __name__ == "__main__": - run_simulation(TB(with_converter=False), ncycles=4000, vcd_name="my.vcd", keep_files=True) diff --git a/misoclib/com/litepcie/test/model/__init__.py b/misoclib/com/litepcie/test/model/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/com/litepcie/test/model/chipset.py b/misoclib/com/litepcie/test/model/chipset.py deleted file mode 100644 index f11c180b..00000000 --- a/misoclib/com/litepcie/test/model/chipset.py +++ /dev/null @@ -1,142 +0,0 @@ -from misoclib.com.litepcie.common import * -from misoclib.com.litepcie.core.packet.common import * -from misoclib.com.litepcie.test.common import * -from misoclib.com.litepcie.test.model.tlp import * - - -def print_chipset(s): - print_with_prefix(s, "[CHIPSET] ") - - -def find_cmp_tags(queue): - tags = [] - for tag, dwords in queue: - if tag not in tags: - tags.append(tag) - return tags - - -def find_first_cmp_msg(queue, msg_tag): - for i, (tag, dwords) in enumerate(queue): - if tag == msg_tag: - return i - - -# Chipset model -class Chipset(Module): - def __init__(self, phy, root_id, debug=False, with_reordering=False): - self.phy = phy - self.root_id = root_id - self.debug = debug - self.with_reordering = with_reordering - ### - self.rd32_data = [] - self.cmp_queue = [] - self.en = False - - def set_host_callback(self, callback): - self.host_callback = callback - - def enable(self): - self.en = True - - def disable(self): - self.en = False - - def wr32(self, adr, data): - wr32 = WR32() - wr32.fmt = 0b10 - wr32.type = 0b00000 - wr32.length = len(data) - wr32.first_be = 0xf - wr32.address = adr - wr32.requester_id = self.root_id - dwords = wr32.encode_dwords(data) - if self.debug: - print_chipset(">>>>>>>>") - print_chipset(parse_dwords(dwords)) - yield from self.phy.send_blocking(dwords) - - def rd32(self, adr, length=1): - rd32 = RD32() - rd32.fmt = 0b00 - rd32.type = 0b00000 - rd32.length = length - rd32.first_be = 0xf - rd32.address = adr - rd32.requester_id = self.root_id - dwords = rd32.encode_dwords() - if self.debug: - print_chipset(">>>>>>>>") - print_chipset(parse_dwords(dwords)) - yield from self.phy.send_blocking(dwords) - dwords = None - while dwords is None: - dwords = self.phy.receive() - yield - cpld = CPLD(dwords) - self.rd32_data = cpld.data - if self.debug: - print_chipset("<<<<<<<<") - print_chipset(cpld) - - def cmp(self, req_id, data, byte_count=None, lower_address=0, tag=0, with_split=False): - if with_split: - d = random.choice([64, 128, 256]) - n = byte_count//d - if n == 0: - self.cmp(req_id, data, byte_count=byte_count, tag=tag) - else: - for i in range(n): - cmp_data = data[i*byte_count//(4*n):(i+1)*byte_count//(4*n)] - self.cmp(req_id, cmp_data, byte_count=byte_count-i*byte_count//n, tag=tag) - else: - if len(data) == 0: - fmt = 0b00 - cpl = CPL() - else: - fmt = 0b10 - cpl = CPLD() - cpl.fmt = fmt - cpl.type = 0b01010 - cpl.length = len(data) - cpl.lower_address = lower_address - cpl.requester_id = req_id - cpl.completer_id = self.root_id - if byte_count is None: - cpl.byte_count = len(data)*4 - else: - cpl.byte_count = byte_count - cpl.tag = tag - if len(data) == 0: - dwords = cpl.encode_dwords() - else: - dwords = cpl.encode_dwords(data) - self.cmp_queue.append((tag, dwords)) - - def cmp_callback(self): - if len(self.cmp_queue): - if self.with_reordering: - tags = find_cmp_tags(self.cmp_queue) - tag = random.choice(tags) - n = find_first_cmp_msg(self.cmp_queue, tag) - tag, dwords = self.cmp_queue.pop(n) - else: - tag, dwords = self.cmp_queue.pop(0) - if self.debug: - print_chipset(">>>>>>>>") - print_chipset(parse_dwords(dwords)) - self.phy.send(dwords) - - def gen_simulation(self, selfp): - while True: - if self.en: - dwords = self.phy.receive() - if dwords is not None: - msg = parse_dwords(dwords) - if self.debug: - print_chipset(" <<<<<<<< (Callback)") - print_chipset(msg) - self.host_callback(msg) - self.cmp_callback() - yield diff --git a/misoclib/com/litepcie/test/model/host.py b/misoclib/com/litepcie/test/model/host.py deleted file mode 100644 index b8207bc7..00000000 --- a/misoclib/com/litepcie/test/model/host.py +++ /dev/null @@ -1,64 +0,0 @@ -from misoclib.com.litepcie.common import * -from misoclib.com.litepcie.core.packet.common import * -from misoclib.com.litepcie.test.common import * -from misoclib.com.litepcie.test.model.phy import PHY -from misoclib.com.litepcie.test.model.tlp import * -from misoclib.com.litepcie.test.model.chipset import Chipset - - -def print_host(s): - print_with_prefix(s, "[HOST] ") - - -# Host model -class Host(Module): - def __init__(self, dw, root_id, endpoint_id, bar0_size=1*MB, - phy_debug=False, - chipset_debug=False, chipset_split=False, chipset_reordering=False, - host_debug=False): - self.debug = host_debug - self.chipset_split = chipset_split - ### - self.submodules.phy = PHY(dw, endpoint_id, bar0_size, phy_debug) - self.submodules.chipset = Chipset(self.phy, root_id, chipset_debug, chipset_reordering) - self.chipset.set_host_callback(self.callback) - - self.rd32_queue = [] - - def malloc(self, base, length): - self.base = base - self.buffer = [0]*(length//4) - - def write_mem(self, adr, data): - if self.debug: - print_host("Writing {} bytes at 0x{:08x}".format(len(data)*4, adr)) - current_adr = (adr-self.base)//4 - for i in range(len(data)): - self.buffer[current_adr+i] = data[i] - - def read_mem(self, adr, length=1): - if self.debug: - print_host("Reading {} bytes at 0x{:08x}".format(length, adr)) - current_adr = (adr-self.base)//4 - data = [] - for i in range(length//4): - data.append(self.buffer[current_adr+i]) - return data - - def callback(self, msg): - if isinstance(msg, WR32): - address = msg.address*4 - self.write_mem(address, msg.data) - elif isinstance(msg, RD32): - self.rd32_queue.append(msg) - - def gen_simulation(self, selfp): - while True: - if len(self.rd32_queue): - msg = self.rd32_queue.pop(0) - address = msg.address*4 - length = msg.length*4 - data = self.read_mem(address, length) - self.chipset.cmp(msg.requester_id, data, byte_count=length, tag=msg.tag, with_split=self.chipset_split) - else: - yield diff --git a/misoclib/com/litepcie/test/model/phy.py b/misoclib/com/litepcie/test/model/phy.py deleted file mode 100644 index dc723de5..00000000 --- a/misoclib/com/litepcie/test/model/phy.py +++ /dev/null @@ -1,144 +0,0 @@ -import math -from misoclib.com.litepcie.common import * -from misoclib.com.litepcie.core.packet.common import * -from misoclib.com.litepcie.test.common import * - - -def print_chipset(s): - print_with_prefix(s, "[PHY] ") - - -# PHY Layer model -class PHYPacket(): - def __init__(self, dat=[], be=[]): - self.dat = dat - self.be = be - self.start = 1 - self.done = 0 - - -class PHYSource(Module): - def __init__(self, dw): - self.source = Source(phy_layout(dw)) - ### - self.packets = [] - self.packet = PHYPacket() - self.packet.done = 1 - - def send(self, packet): - self.packets.append(packet) - - def send_blocking(self, packet): - self.send(packet) - while packet.done == 0: - yield - - def do_simulation(self, selfp): - if len(self.packets) and self.packet.done: - self.packet = self.packets.pop(0) - if self.packet.start and not self.packet.done: - selfp.source.stb = 1 - selfp.source.sop = 1 - selfp.source.dat = self.packet.dat.pop(0) - selfp.source.be = self.packet.be.pop(0) - self.packet.start = 0 - elif selfp.source.stb == 1 and selfp.source.ack == 1: - selfp.source.sop = 0 - selfp.source.eop = (len(self.packet.dat) == 1) - if len(self.packet.dat) > 0: - selfp.source.stb = 1 - selfp.source.dat = self.packet.dat.pop(0) - selfp.source.be = self.packet.be.pop(0) - else: - self.packet.done = 1 - selfp.source.stb = 0 - - -class PHYSink(Module): - def __init__(self, dw): - self.sink = Sink(phy_layout(dw)) - ### - self.packet = PHYPacket() - - def receive(self): - self.packet.done = 0 - while self.packet.done == 0: - yield - - def do_simulation(self, selfp): - self.packet.done = 0 - selfp.sink.ack = 1 - if selfp.sink.stb == 1 and selfp.sink.sop == 1: - self.packet.start = 1 - self.packet.dat = [selfp.sink.dat] - self.packet.be = [selfp.sink.be] - elif selfp.sink.stb: - self.packet.start = 0 - self.packet.dat.append(selfp.sink.dat) - self.packet.be.append(selfp.sink.be) - if (selfp.sink.stb == 1 and selfp.sink.eop == 1): - self.packet.done = 1 - - -class PHY(Module): - def __init__(self, dw, id, bar0_size, debug): - self.dw = dw - - self.id = id - - self.bar0_size = bar0_size - self.bar0_mask = get_bar_mask(bar0_size) - - self.max_request_size = 512 - self.max_payload_size = 128 - - self.submodules.phy_source = PHYSource(dw) - self.submodules.phy_sink = PHYSink(dw) - - self.source = self.phy_source.source - self.sink = self.phy_sink.sink - - def dwords2packet(self, dwords): - ratio = self.dw//32 - length = math.ceil(len(dwords)/ratio) - dat = [0]*length - be = [0]*length - for n in range(length): - for i in reversed(range(ratio)): - dat[n] = dat[n] << 32 - be[n] = be[n] << 4 - try: - dat[n] |= dwords[2*n+i] - be[n] |= 0xF - except: - pass - return dat, be - - def send(self, dwords): - dat, be = self.dwords2packet(dwords) - packet = PHYPacket(dat, be) - self.phy_source.send(packet) - - def send_blocking(self, dwords): - dat, be = self.dwords2packet(dwords) - packet = PHYPacket(dat, be) - yield from self.phy_source.send_blocking(packet) - - def packet2dwords(self, p_dat, p_be): - ratio = self.dw//32 - dwords = [] - for dat, be in zip(p_dat, p_be): - for i in range(ratio): - dword_be = (be >> (4*i)) & 0xf - dword_dat = (dat >> (32*i)) & 0xffffffff - if dword_be == 0xf: - dwords.append(dword_dat) - return dwords - - def receive(self): - if self.phy_sink.packet.done: - self.phy_sink.packet.done = 0 - return self.packet2dwords(self.phy_sink.packet.dat, self.phy_sink.packet.be) - else: - return None - diff --git a/misoclib/com/litepcie/test/model/tlp.py b/misoclib/com/litepcie/test/model/tlp.py deleted file mode 100644 index 78185d02..00000000 --- a/misoclib/com/litepcie/test/model/tlp.py +++ /dev/null @@ -1,94 +0,0 @@ -from misoclib.com.litepcie.common import * -from misoclib.com.litepcie.core.packet.common import * - - -# TLP Layer model -def get_field_data(field, dwords): - return (dwords[field.byte//4] >> field.offset) & (2**field.width-1) - -tlp_headers_dict = { - "RD32": tlp_request_header, - "WR32": tlp_request_header, - "CPLD": tlp_completion_header, - "CPL": tlp_completion_header -} - - -class TLP(): - def __init__(self, name, dwords=[0, 0, 0]): - self.name = name - self.header = dwords[:3] - self.data = dwords[3:] - self.dwords = self.header + self.data - self.decode_dwords() - - def decode_dwords(self): - for k, v in tlp_headers_dict[self.name].fields.items(): - setattr(self, k, get_field_data(v, self.header)) - - def encode_dwords(self, data=[]): - self.header = [0, 0, 0] - for k, v in tlp_headers_dict[self.name].fields.items(): - field = tlp_headers_dict[self.name].fields[k] - self.header[field.byte//4] |= (getattr(self, k) << field.offset) - self.data = data - self.dwords = self.header + self.data - return self.dwords - - def __repr__(self): - r = self.name + "\n" - r += "--------\n" - for k in sorted(tlp_headers_dict[self.name].keys()): - r += k + " : 0x{:x}".format(getattr(self, k) + "\n") - if len(self.data) != 0: - r += "data:\n" - for d in self.data: - r += "{:08x}\n".format(d) - return r - - -class RD32(TLP): - def __init__(self, dwords=[0, 0, 0]): - TLP.__init__(self, "RD32", dwords) - - -class WR32(TLP): - def __init__(self, dwords=[0, 0, 0]): - TLP.__init__(self, "WR32", dwords) - - -class CPLD(TLP): - def __init__(self, dwords=[0, 0, 0]): - TLP.__init__(self, "CPLD", dwords) - - -class CPL(): - def __init__(self, dwords=[0, 0, 0]): - TLP.__init__(self, "CPL", dwords) - - -class Unknown(): - def __repr__(self): - r = "UNKNOWN\n" - return r - -fmt_type_dict = { - fmt_type_dict["mem_rd32"]: (RD32, 3), - fmt_type_dict["mem_wr32"]: (WR32, 4), - fmt_type_dict["cpld"]: (CPLD, 4), - fmt_type_dict["cpl"]: (CPL, 3) -} - - -def parse_dwords(dwords): - f = get_field_data(tlp_common_header.fields["fmt"], dwords) - t = get_field_data(tlp_common_header.fields["type"], dwords) - fmt_type = (f << 5) | t - try: - tlp, min_len = fmt_type_dict[fmt_type] - if len(dwords) >= min_len: - return tlp(dwords) - else: - return Unknown() - except: - return Unknown() diff --git a/misoclib/com/litepcie/test/wishbone_tb.py b/misoclib/com/litepcie/test/wishbone_tb.py deleted file mode 100644 index cde4a3e2..00000000 --- a/misoclib/com/litepcie/test/wishbone_tb.py +++ /dev/null @@ -1,40 +0,0 @@ -from migen.fhdl.std import * -from migen.bus import wishbone -from migen.sim.generic import run_simulation - -from misoclib.com.litepcie.core import Endpoint -from misoclib.com.litepcie.frontend.bridge.wishbone import WishboneBridge - -from misoclib.com.litepcie.test.common import * -from misoclib.com.litepcie.test.model.host import * - -root_id = 0x100 -endpoint_id = 0x400 - - -class TB(Module): - def __init__(self): - self.submodules.host = Host(64, root_id, endpoint_id, - phy_debug=False, - chipset_debug=False, - host_debug=False) - self.submodules.endpoint = Endpoint(self.host.phy) - - self.submodules.wishbone_bridge = WishboneBridge(self.endpoint, lambda a: 1) - self.submodules.sram = wishbone.SRAM(1024, bus=self.wishbone_bridge.wishbone) - - def gen_simulation(self, selfp): - wr_datas = [seed_to_data(i, True) for i in range(64)] - for i in range(64): - yield from self.host.chipset.wr32(i, [wr_datas[i]]) - - rd_datas = [] - for i in range(64): - yield from self.host.chipset.rd32(i) - rd_datas.append(self.host.chipset.rd32_data[0]) - - s, l, e = check(wr_datas, rd_datas) - print("shift " + str(s) + " / length " + str(l) + " / errors " + str(e)) - -if __name__ == "__main__": - run_simulation(TB(), ncycles=1000, vcd_name="my.vcd", keep_files=True) -- 2.30.2