From 6de7e15a0c9f475db6edac7e59d5923d1f0c7661 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 16 Jan 2015 23:52:41 +0100 Subject: [PATCH] refactor code --- Makefile | 3 +- README | 45 ++++++-- lib/sata/__init__.py | 21 ---- lib/sata/frontend/crossbar.py | 25 ---- lib/sata/phy/__init__.py | 25 ---- litesata/__init__.py | 23 ++++ {lib/sata => litesata}/common.py | 5 +- litesata/core/__init__.py | 11 ++ .../core}/command/__init__.py | 12 +- {lib/sata => litesata/core}/link/__init__.py | 30 ++--- {lib/sata => litesata/core}/link/cont.py | 10 +- {lib/sata => litesata/core}/link/crc.py | 13 +-- {lib/sata => litesata/core}/link/scrambler.py | 7 +- .../core}/transport/__init__.py | 15 +-- litesata/frontend/__init__.py | 4 + {lib/sata => litesata}/frontend/arbiter.py | 6 +- {lib/sata => litesata/frontend}/bist.py | 34 +++--- {lib/sata => litesata}/frontend/common.py | 6 +- litesata/frontend/crossbar.py | 28 +++++ litesata/phy/__init__.py | 23 ++++ {lib/sata => litesata}/phy/ctrl.py | 39 ++----- {lib/sata => litesata}/phy/datapath.py | 24 ++-- {lib/sata => litesata}/phy/k7/crg.py | 10 +- {lib/sata => litesata}/phy/k7/trx.py | 6 +- {lib/sata => litesata}/test/Makefile | 2 +- {lib/sata => litesata}/test/bist_tb.py | 16 +-- {lib/sata => litesata}/test/command_tb.py | 16 +-- {lib/sata => litesata}/test/common.py | 2 +- {lib/sata => litesata}/test/cont_tb.py | 10 +- {lib/sata => litesata}/test/crc.c | 0 {lib/sata => litesata}/test/crc_tb.py | 8 +- {lib/sata => litesata}/test/hdd.py | 4 +- {lib/sata => litesata}/test/link_tb.py | 10 +- .../sata => litesata}/test/phy_datapath_tb.py | 8 +- {lib/sata => litesata}/test/scrambler.c | 0 {lib/sata => litesata}/test/scrambler_tb.py | 6 +- platforms/kc705.py | 11 +- setup.py | 37 ++++++ targets/{bist.py => bist_kc705.py} | 108 +++++++++--------- test/bist.py | 35 +++--- test/test_link.py | 32 +++--- 41 files changed, 387 insertions(+), 343 deletions(-) delete mode 100644 lib/sata/__init__.py delete mode 100644 lib/sata/frontend/crossbar.py delete mode 100644 lib/sata/phy/__init__.py create mode 100644 litesata/__init__.py rename {lib/sata => litesata}/common.py (96%) create mode 100644 litesata/core/__init__.py rename {lib/sata => litesata/core}/command/__init__.py (97%) rename {lib/sata => litesata/core}/link/__init__.py (85%) rename {lib/sata => litesata/core}/link/cont.py (93%) rename {lib/sata => litesata/core}/link/crc.py (89%) rename {lib/sata => litesata/core}/link/scrambler.py (93%) rename {lib/sata => litesata/core}/transport/__init__.py (95%) create mode 100644 litesata/frontend/__init__.py rename {lib/sata => litesata}/frontend/arbiter.py (88%) rename {lib/sata => litesata/frontend}/bist.py (87%) rename {lib/sata => litesata}/frontend/common.py (86%) create mode 100644 litesata/frontend/crossbar.py create mode 100644 litesata/phy/__init__.py rename {lib/sata => litesata}/phy/ctrl.py (80%) rename {lib/sata => litesata}/phy/datapath.py (89%) rename {lib/sata => litesata}/phy/k7/crg.py (95%) rename {lib/sata => litesata}/phy/k7/trx.py (99%) rename {lib/sata => litesata}/test/Makefile (95%) rename {lib/sata => litesata}/test/bist_tb.py (70%) rename {lib/sata => litesata}/test/command_tb.py (88%) rename {lib/sata => litesata}/test/common.py (99%) rename {lib/sata => litesata}/test/cont_tb.py (89%) rename {lib/sata => litesata}/test/crc.c (100%) rename {lib/sata => litesata}/test/crc_tb.py (90%) rename {lib/sata => litesata}/test/hdd.py (99%) rename {lib/sata => litesata}/test/link_tb.py (85%) rename {lib/sata => litesata}/test/phy_datapath_tb.py (92%) rename {lib/sata => litesata}/test/scrambler.c (100%) rename {lib/sata => litesata}/test/scrambler_tb.py (91%) create mode 100644 setup.py rename targets/{bist.py => bist_kc705.py} (68%) diff --git a/Makefile b/Makefile index deb3bd82..5a3406d1 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,9 @@ MSCDIR = ../misoc CURDIR = ../lite-sata PYTHON = python3 TOOLCHAIN = vivado -PLATFORM = kc705 PROGRAMMER = vivado -CMD = $(PYTHON) make.py -X $(CURDIR) -Op toolchain $(TOOLCHAIN) -Op programmer $(PROGRAMMER) -p $(PLATFORM) -t bist +CMD = $(PYTHON) make.py -X $(CURDIR) -Op toolchain $(TOOLCHAIN) -Op programmer $(PROGRAMMER) -t bist_kc705 csv: cd $(MSCDIR) && $(CMD) --csr_csv $(CURDIR)/test/csr.csv build-csr-csv -Ot export_mila True diff --git a/README b/README index 215829a7..df0e9b63 100644 --- a/README +++ b/README @@ -5,8 +5,35 @@ Copyright 2014-2015 / Florent Kermarrec / florent@enjoy-digital.fr - A lite open-source SATA1/2/3 controller - developed in partnership with M-Labs Ltd & HKU + A generic and configurable SATA1/2/3 core + developed in partnership with M-Labs Ltd & HKU + +[> Features +------------------ +PHY: + - OOB, COMWAKE, COMINIT. + - ALIGN inserter/remover and bytes alignment on K28.5. + - 8B/10B encoding/decoding in transceiver. + - Errors detection and reporting. + - 1.5 / 3.0 / 6.0GBPs supported speeds. + - 37.5 / 75 / 150MHz system clock. +Core: + Link: + - CONT inserter/remover. + - Scrambling/Descrambling of data. + - CRC inserter/checker. + - HOLD insertion/detection. + - Errors detection and reporting. + Transport/Command: + - Easy to use user interface (Can be used with or without CPU). + - 48 bits sector addressing. + - 3 supported commands: READ_DMA(_EXT), WRITE_DMA(_EXT), IDENTIFY_DEVICE. + - Errors detection and reporting. + +Frontend: + - Configurable crossbar (simply use core.crossbar.get_port() to add a new port!) + - Ports arbitration transparent to the user. + - Synthetizable BIST. [> Getting started ------------------ @@ -33,11 +60,11 @@ make all 7. Test design: - go to test directory + go to test directory and run: python3 bist.py [> Simulations : - Simulation are avalaible in ./lib/sata/test: + Simulations are avalaible in ./lib/sata/test: - crc_tb - scrambler_tb - phy_datapath_tb @@ -45,14 +72,14 @@ - command_tb - bist_tb hdd.py is a HDD model implementing all SATA layers. - To run a simulation, move to the simulation directory and run: + To run a simulation, move to ./lib/sata/test and run: make simulation_name [> Tests : - A synthetisable BIST is provided. It can be controled with ./test/bist.py - Using Miscope and the provided example ./test/test_link.py you are able to - visualize every event of the design and even inject your data in the HDD - model! + A synthetisable BIST is provided and can be controlled with ./test/bist.py + By using Miscope and the provided ./test/test_link.py example you are able to + visualize the internal logic of the design and even inject the captured data in + the HDD model! [> Contact E-mail: florent@enjoy-digital.fr diff --git a/lib/sata/__init__.py b/lib/sata/__init__.py deleted file mode 100644 index 0a167bdc..00000000 --- a/lib/sata/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -from lib.sata.common import * -from lib.sata.link import SATALink -from lib.sata.transport import SATATransport -from lib.sata.command import SATACommand - -from lib.sata.frontend.crossbar import SATACrossbar - -class SATACON(Module): - def __init__(self, phy): - ### - # core - self.link = SATALink(phy) - self.transport = SATATransport(self.link) - self.command = SATACommand(self.transport) - - # frontend - self.crossbar = SATACrossbar(32) - self.comb += [ - Record.connect(self.crossbar.master.source, self.command.sink), - Record.connect(self.command.source, self.crossbar.master.sink) - ] diff --git a/lib/sata/frontend/crossbar.py b/lib/sata/frontend/crossbar.py deleted file mode 100644 index 41ac806e..00000000 --- a/lib/sata/frontend/crossbar.py +++ /dev/null @@ -1,25 +0,0 @@ -from lib.sata.common import * -from lib.sata.frontend.common import * -from lib.sata.frontend.arbiter import SATAArbiter - -class SATACrossbar(Module): - def __init__(self, dw): - self.dw = dw - self.slaves = [] - self.master = SATAMasterPort(dw) - - def get_port(self): - master = SATAMasterPort(self.dw) - slave = SATASlavePort(self.dw) - self.comb += master.connect(slave) - self.slaves.append(slave) - return master - - def get_ports(self, n): - masters = [] - for i in range(n): - masters.append(self.get_port()) - return masters - - def do_finalize(self): - self.arbiter = SATAArbiter(self.slaves, self.master) diff --git a/lib/sata/phy/__init__.py b/lib/sata/phy/__init__.py deleted file mode 100644 index 925d7720..00000000 --- a/lib/sata/phy/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -from lib.sata.common import * -from lib.sata.phy.ctrl import SATAPHYHostCtrl -from lib.sata.phy.datapath import SATAPHYDatapath - -class SATAPHY(Module): - def __init__(self, pads, clk_freq, host=True, device_family="k7", speed="SATA1"): - self.speed = speed - # Transceiver / Clocks - if device_family == "k7": - from lib.sata.phy.k7.trx import K7SATAPHYTRX - from lib.sata.phy.k7.crg import K7SATAPHYCRG - self.trx = K7SATAPHYTRX(pads, speed) - self.crg = K7SATAPHYCRG(pads, self.trx, clk_freq, speed) - else: - raise NotImplementedError(device_family + "device family not implemented") - - # Control - if host: - self.ctrl = SATAPHYHostCtrl(self.trx, self.crg, clk_freq) - else: - self.ctrl = SATAPHYDeviceCtrl(self.trx, self.crg, clk_freq) - - # Datapath - self.datapath = SATAPHYDatapath(self.trx, self.ctrl) - self.sink, self.source = self.datapath.sink, self.datapath.source diff --git a/litesata/__init__.py b/litesata/__init__.py new file mode 100644 index 00000000..c75fc32c --- /dev/null +++ b/litesata/__init__.py @@ -0,0 +1,23 @@ +from litesata.common import * +from litesata.phy import * +from litesata.core import * +from litesata.frontend import * + +from migen.bank.description import * + +class LiteSATA(Module, AutoCSR): + def __init__(self, phy, + with_crossbar=False, + with_bist=False, with_bist_csr=False): + # phy + self.phy = phy + + # core + self.core = LiteSATACore(self.phy) + + # frontend + if with_crossbar: + self.crossbar = LiteSATACrossbar(self.core) + if with_bist: + self.bist = LiteSATABIST(self.crossbar, with_bist_csr) + diff --git a/lib/sata/common.py b/litesata/common.py similarity index 96% rename from lib/sata/common.py rename to litesata/common.py index bce3b572..99c5d214 100644 --- a/lib/sata/common.py +++ b/litesata/common.py @@ -4,10 +4,13 @@ from migen.fhdl.std import * from migen.genlib.resetsync import * from migen.genlib.fsm import * from migen.genlib.record import * +from migen.genlib.misc import chooser, optree +from migen.genlib.cdc import * from migen.flow.actor import * +from migen.flow.plumbing import Multiplexer, Demultiplexer from migen.flow.plumbing import Buffer from migen.actorlib.fifo import * -from migen.actorlib.structuring import Pipeline +from migen.actorlib.structuring import Pipeline, Converter # PHY / Link Layers primitives = { diff --git a/litesata/core/__init__.py b/litesata/core/__init__.py new file mode 100644 index 00000000..c32028bb --- /dev/null +++ b/litesata/core/__init__.py @@ -0,0 +1,11 @@ +from litesata.common import * +from litesata.core.link import LiteSATALink +from litesata.core.transport import LiteSATATransport +from litesata.core.command import LiteSATACommand + +class LiteSATACore(Module): + def __init__(self, phy): + self.link = LiteSATALink(phy) + self.transport = LiteSATATransport(self.link) + self.command = LiteSATACommand(self.transport) + self.sink, self.source = self.command.sink, self.command.source diff --git a/lib/sata/command/__init__.py b/litesata/core/command/__init__.py similarity index 97% rename from lib/sata/command/__init__.py rename to litesata/core/command/__init__.py index 810d235f..130b5fc3 100644 --- a/lib/sata/command/__init__.py +++ b/litesata/core/command/__init__.py @@ -1,4 +1,4 @@ -from lib.sata.common import * +from litesata.common import * tx_to_rx = [ ("write", 1), @@ -11,7 +11,7 @@ rx_to_tx = [ ("dma_activate", 1) ] -class SATACommandTX(Module): +class LiteSATACommandTX(Module): def __init__(self, transport): self.sink = sink = Sink(command_tx_description(32)) self.to_rx = to_rx = Source(tx_to_rx) @@ -117,7 +117,7 @@ class SATACommandTX(Module): ) ] -class SATACommandRX(Module): +class LiteSATACommandRX(Module): def __init__(self, transport): self.source = source = Source(command_rx_description(32)) self.to_tx = to_tx = Source(rx_to_tx) @@ -303,10 +303,10 @@ class SATACommandRX(Module): to_tx.dma_activate.eq(dma_activate), ] -class SATACommand(Module): +class LiteSATACommand(Module): def __init__(self, transport): - self.tx = SATACommandTX(transport) - self.rx = SATACommandRX(transport) + self.tx = LiteSATACommandTX(transport) + self.rx = LiteSATACommandRX(transport) self.comb += [ self.rx.to_tx.connect(self.tx.from_rx), self.tx.to_rx.connect(self.rx.from_tx) diff --git a/lib/sata/link/__init__.py b/litesata/core/link/__init__.py similarity index 85% rename from lib/sata/link/__init__.py rename to litesata/core/link/__init__.py index b142e68c..64884eee 100644 --- a/lib/sata/link/__init__.py +++ b/litesata/core/link/__init__.py @@ -1,7 +1,7 @@ -from lib.sata.common import * -from lib.sata.link.crc import SATACRCInserter, SATACRCChecker -from lib.sata.link.scrambler import SATAScrambler -from lib.sata.link.cont import SATACONTInserter, SATACONTRemover +from litesata.common import * +from litesata.core.link.crc import LiteSATACRCInserter, LiteSATACRCChecker +from litesata.core.link.scrambler import LiteSATAScrambler +from litesata.core.link.cont import LiteSATACONTInserter, LiteSATACONTRemover from_rx = [ ("idle", 1), @@ -9,7 +9,7 @@ from_rx = [ ("det", 32) ] -class SATALinkTX(Module): +class LiteSATALinkTX(Module): def __init__(self, phy): self.sink = Sink(link_description(32)) self.from_rx = Sink(from_rx) @@ -19,11 +19,11 @@ class SATALinkTX(Module): self.fsm = fsm = FSM(reset_state="IDLE") # insert CRC - crc = SATACRCInserter(link_description(32)) + crc = LiteSATACRCInserter(link_description(32)) self.submodules += crc # scramble - scrambler = SATAScrambler(link_description(32)) + scrambler = LiteSATAScrambler(link_description(32)) self.submodules += scrambler # connect CRC / scrambler @@ -34,7 +34,7 @@ class SATALinkTX(Module): # inserter CONT and scrambled data between # CONT and next primitive - self.cont = cont = BufferizeEndpoints(SATACONTInserter(phy_description(32)), "source") + self.cont = cont = BufferizeEndpoints(LiteSATACONTInserter(phy_description(32)), "source") # datas / primitives mux insert = Signal(32) @@ -107,7 +107,7 @@ class SATALinkTX(Module): ) ) -class SATALinkRX(Module): +class LiteSATALinkRX(Module): def __init__(self, phy): self.source = Source(link_description(32)) self.to_tx = Source(from_rx) @@ -117,7 +117,7 @@ class SATALinkRX(Module): self.fsm = fsm = FSM(reset_state="IDLE") # CONT remover - self.cont = cont = BufferizeEndpoints(SATACONTRemover(phy_description(32)), "source") + self.cont = cont = BufferizeEndpoints(LiteSATACONTRemover(phy_description(32)), "source") self.comb += Record.connect(phy.source, cont.sink) # datas / primitives detection @@ -129,10 +129,10 @@ class SATALinkRX(Module): ) # descrambler - self.scrambler = scrambler = SATAScrambler(link_description(32)) + self.scrambler = scrambler = LiteSATAScrambler(link_description(32)) # check CRC - self.crc = crc = SATACRCChecker(link_description(32)) + self.crc = crc = LiteSATACRCChecker(link_description(32)) sop = Signal() eop = Signal() @@ -236,9 +236,9 @@ class SATALinkRX(Module): self.to_tx.det.eq(det) ] -class SATALink(Module): +class LiteSATALink(Module): def __init__(self, phy): - self.tx = SATALinkTX(phy) - self.rx = SATALinkRX(phy) + self.tx = LiteSATALinkTX(phy) + self.rx = LiteSATALinkRX(phy) self.comb += Record.connect(self.rx.to_tx, self.tx.from_rx) self.sink, self.source = self.tx.sink, self.rx.source diff --git a/lib/sata/link/cont.py b/litesata/core/link/cont.py similarity index 93% rename from lib/sata/link/cont.py rename to litesata/core/link/cont.py index ece5896c..dff6a28f 100644 --- a/lib/sata/link/cont.py +++ b/litesata/core/link/cont.py @@ -1,9 +1,7 @@ -from lib.sata.common import * -from lib.sata.link.scrambler import Scrambler +from litesata.common import * +from litesata.core.link.scrambler import Scrambler -from migen.genlib.misc import optree - -class SATACONTInserter(Module): +class LiteSATACONTInserter(Module): def __init__(self, description): self.sink = sink = Sink(description) self.source = source = Source(description) @@ -72,7 +70,7 @@ class SATACONTInserter(Module): ) ] -class SATACONTRemover(Module): +class LiteSATACONTRemover(Module): def __init__(self, description): self.sink = sink = Sink(description) self.source = source = Source(description) diff --git a/lib/sata/link/crc.py b/litesata/core/link/crc.py similarity index 89% rename from lib/sata/link/crc.py rename to litesata/core/link/crc.py index 4d6c67b6..1f5ac617 100644 --- a/lib/sata/link/crc.py +++ b/litesata/core/link/crc.py @@ -1,6 +1,5 @@ -from lib.sata.common import * +from litesata.common import * -from migen.genlib.misc import optree from migen.actorlib.crc import CRCInserter, CRCChecker class CRCEngine(Module): @@ -72,7 +71,7 @@ class CRCEngine(Module): @DecorateModule(InsertReset) @DecorateModule(InsertCE) -class SATACRC(Module): +class LiteSATACRC(Module): """SATA CRC Implement a SATA CRC generator/checker @@ -106,10 +105,10 @@ class SATACRC(Module): self.error.eq(self.engine.next != self.check) ] -class SATACRCInserter(CRCInserter): +class LiteSATACRCInserter(CRCInserter): def __init__(self, description): - CRCInserter.__init__(self, SATACRC, description) + CRCInserter.__init__(self, LiteSATACRC, description) -class SATACRCChecker(CRCChecker): +class LiteSATACRCChecker(CRCChecker): def __init__(self, description): - CRCChecker.__init__(self, SATACRC, description) + CRCChecker.__init__(self, LiteSATACRC, description) diff --git a/lib/sata/link/scrambler.py b/litesata/core/link/scrambler.py similarity index 93% rename from lib/sata/link/scrambler.py rename to litesata/core/link/scrambler.py index d2b473f8..4b5b9960 100644 --- a/lib/sata/link/scrambler.py +++ b/litesata/core/link/scrambler.py @@ -1,7 +1,4 @@ -from lib.sata.common import * - -from migen.fhdl.std import * -from migen.genlib.misc import optree +from litesata.common import * @DecorateModule(InsertCE) class Scrambler(Module): @@ -68,7 +65,7 @@ class Scrambler(Module): self.comb += self.value.eq(next_value) @DecorateModule(InsertReset) -class SATAScrambler(Module): +class LiteSATAScrambler(Module): def __init__(self, description): self.sink = sink = Sink(description) self.source = source = Source(description) diff --git a/lib/sata/transport/__init__.py b/litesata/core/transport/__init__.py similarity index 95% rename from lib/sata/transport/__init__.py rename to litesata/core/transport/__init__.py index 6fcb3037..e0030217 100644 --- a/lib/sata/transport/__init__.py +++ b/litesata/core/transport/__init__.py @@ -1,4 +1,4 @@ -from lib.sata.common import * +from litesata.common import * def _get_item(obj, name, width): if "_lsb" in name: @@ -18,7 +18,7 @@ def _encode_cmd(obj, description, signal): r.append(signal[start:end].eq(item)) return r -class SATATransportTX(Module): +class LiteSATATransportTX(Module): def __init__(self, link): self.sink = sink = Sink(transport_tx_description(32)) @@ -110,13 +110,14 @@ def _decode_cmd(signal, description, obj): r.append(item.eq(signal[start:end])) return r -class SATATransportRX(Module): +class LiteSATATransportRX(Module): def __init__(self, link): self.source = source = Source(transport_rx_description(32)) ### - cmd_ndwords = max(fis_reg_d2h_cmd_len, fis_dma_activate_d2h_cmd_len, fis_data_cmd_len) + cmd_ndwords = max(fis_reg_d2h_cmd_len, fis_dma_activate_d2h_cmd_len, + fis_pio_setup_d2h_cmd_len, fis_data_cmd_len) encoded_cmd = Signal(cmd_ndwords*32) self.counter = counter = Counter(max=cmd_ndwords+1) @@ -250,8 +251,8 @@ class SATATransportRX(Module): ) self.comb += cmd_done.eq((counter.value == cmd_len) & link.source.ack) -class SATATransport(Module): +class LiteSATATransport(Module): def __init__(self, link): - self.tx = SATATransportTX(link) - self.rx = SATATransportRX(link) + self.tx = LiteSATATransportTX(link) + self.rx = LiteSATATransportRX(link) self.sink, self.source = self.tx.sink, self.rx.source diff --git a/litesata/frontend/__init__.py b/litesata/frontend/__init__.py new file mode 100644 index 00000000..63785161 --- /dev/null +++ b/litesata/frontend/__init__.py @@ -0,0 +1,4 @@ +from litesata.common import * +from litesata.frontend.crossbar import LiteSATACrossbar +from litesata.frontend.arbiter import LiteSATAArbiter +from litesata.frontend.bist import LiteSATABIST diff --git a/lib/sata/frontend/arbiter.py b/litesata/frontend/arbiter.py similarity index 88% rename from lib/sata/frontend/arbiter.py rename to litesata/frontend/arbiter.py index 678f2d7a..049946c1 100644 --- a/lib/sata/frontend/arbiter.py +++ b/litesata/frontend/arbiter.py @@ -1,9 +1,9 @@ -from lib.sata.common import * -from lib.sata.frontend.common import * +from litesata.common import * +from litesata.frontend.common import * from migen.genlib.roundrobin import * -class SATAArbiter(Module): +class LiteSATAArbiter(Module): def __init__(self, slaves, master): if len(slaves) == 1: self.comb += slaves[0].connect(master) diff --git a/lib/sata/bist.py b/litesata/frontend/bist.py similarity index 87% rename from lib/sata/bist.py rename to litesata/frontend/bist.py index 4dfba893..be994cb4 100644 --- a/lib/sata/bist.py +++ b/litesata/frontend/bist.py @@ -1,10 +1,10 @@ -from lib.sata.common import * -from lib.sata.link.scrambler import Scrambler +from litesata.common import * +from litesata.core.link.scrambler import Scrambler from migen.fhdl.decorators import ModuleDecorator from migen.bank.description import * -class SATABISTGenerator(Module): +class LiteSATABISTGenerator(Module): def __init__(self, sata_master_port): self.start = Signal() self.sector = Signal(48) @@ -62,7 +62,7 @@ class SATABISTGenerator(Module): ) ) -class SATABISTChecker(Module): +class LiteSATABISTChecker(Module): def __init__(self, sata_master_port): self.start = Signal() self.sector = Signal(48) @@ -137,7 +137,7 @@ class SATABISTChecker(Module): ) ) -class SATABISTUnitControl(Module, AutoCSR): +class LiteSATABISTUnitCSR(Module, AutoCSR): def __init__(self, bist_unit): self._start = CSR() self._sector = CSRStorage(48) @@ -148,6 +148,7 @@ class SATABISTUnitControl(Module, AutoCSR): self._cycles = CSRStatus(32) ### + self.bist_unit = bist_unit self.comb += [ bist_unit.start.eq(self._start.r & self._start.re), @@ -165,7 +166,7 @@ class SATABISTUnitControl(Module, AutoCSR): self.cycles_counter.ce.eq(~bist_unit.done) ] -class SATABISTIdentify(Module): +class LiteSATABISTIdentify(Module): def __init__(self, sata_master_port): self.start = Signal() self.done = Signal() @@ -211,7 +212,7 @@ class SATABISTIdentify(Module): ) ) -class SATABISTIdentifyControl(Module, AutoCSR): +class LiteSATABISTIdentifyCSR(Module, AutoCSR): def __init__(self, bist_identify): self._start = CSR() self._done = CSRStatus() @@ -220,6 +221,7 @@ class SATABISTIdentifyControl(Module, AutoCSR): self._source_data = CSRStatus(32) ### + self.bist_identify = bist_identify self.comb += [ bist_identify.start.eq(self._start.r & self._start.re), @@ -230,15 +232,15 @@ class SATABISTIdentifyControl(Module, AutoCSR): bist_identify.source.ack.eq(self._source_ack.r & self._source_ack.re) ] -class SATABIST(Module, AutoCSR): - def __init__(self, sata_master_ports, with_control=False): - generator = SATABISTGenerator(sata_master_ports[0]) - checker = SATABISTChecker(sata_master_ports[1]) - identify = SATABISTIdentify(sata_master_ports[2]) - if with_control: - self.generator = SATABISTUnitControl(generator) - self.checker = SATABISTUnitControl(checker) - self.identify = SATABISTIdentifyControl(identify) +class LiteSATABIST(Module, AutoCSR): + def __init__(self, crossbar, with_csr=False): + generator = LiteSATABISTGenerator(crossbar.get_port()) + checker = LiteSATABISTChecker(crossbar.get_port()) + identify = LiteSATABISTIdentify(crossbar.get_port()) + if with_csr: + self.generator = LiteSATABISTUnitCSR(generator) + self.checker = LiteSATABISTUnitCSR(checker) + self.identify = LiteSATABISTIdentifyCSR(identify) else: self.generator = generator self.checker = checker diff --git a/lib/sata/frontend/common.py b/litesata/frontend/common.py similarity index 86% rename from lib/sata/frontend/common.py rename to litesata/frontend/common.py index 114a0a83..308a6c6e 100644 --- a/lib/sata/frontend/common.py +++ b/litesata/frontend/common.py @@ -1,6 +1,6 @@ -from lib.sata.common import * +from litesata.common import * -class SATAMasterPort: +class LiteSATAMasterPort: def __init__(self, dw): self.source = Source(command_tx_description(dw)) self.sink = Sink(command_rx_description(dw)) @@ -11,7 +11,7 @@ class SATAMasterPort: Record.connect(slave.source, self.sink) ] -class SATASlavePort: +class LiteSATASlavePort: def __init__(self, dw): self.sink = Sink(command_tx_description(dw)) self.source = Source(command_rx_description(dw)) diff --git a/litesata/frontend/crossbar.py b/litesata/frontend/crossbar.py new file mode 100644 index 00000000..f4ca37aa --- /dev/null +++ b/litesata/frontend/crossbar.py @@ -0,0 +1,28 @@ +from litesata.common import * +from litesata.frontend.common import * +from litesata.frontend.arbiter import LiteSATAArbiter + +class LiteSATACrossbar(Module): + def __init__(self, core): + self.slaves = [] + self.master = LiteSATAMasterPort(32) + self.comb += [ + self.master.source.connect(core.sink), + core.source.connect(self.master.sink) + ] + + def get_port(self): + master = LiteSATAMasterPort(32) + slave = LiteSATASlavePort(32) + self.comb += master.connect(slave) + self.slaves.append(slave) + return master + + def get_ports(self, n): + masters = [] + for i in range(n): + masters.append(self.get_port()) + return masters + + def do_finalize(self): + self.arbiter = LiteSATAArbiter(self.slaves, self.master) diff --git a/litesata/phy/__init__.py b/litesata/phy/__init__.py new file mode 100644 index 00000000..fcb206f3 --- /dev/null +++ b/litesata/phy/__init__.py @@ -0,0 +1,23 @@ +from litesata.common import * +from litesata.phy.ctrl import * +from litesata.phy.datapath import * + +class LiteSATAPHY(Module): + def __init__(self, device, pads, speed, clk_freq): + self.speed = speed + # Transceiver / Clocks + if device[:3] == "xc7": # Kintex 7 + from litesata.phy.k7.trx import K7LiteSATAPHYTRX + from litesata.phy.k7.crg import K7LiteSATAPHYCRG + self.trx = K7LiteSATAPHYTRX(pads, speed) + self.crg = K7LiteSATAPHYCRG(pads, self.trx, speed, clk_freq) + else: + msg = "Device" + device + "not (yet) supported." + raise NotImplementedError(msg) + + # Control + self.ctrl = LiteSATAPHYCtrl(self.trx, self.crg, clk_freq) + + # Datapath + self.datapath = LiteSATAPHYDatapath(self.trx, self.ctrl) + self.sink, self.source = self.datapath.sink, self.datapath.source diff --git a/lib/sata/phy/ctrl.py b/litesata/phy/ctrl.py similarity index 80% rename from lib/sata/phy/ctrl.py rename to litesata/phy/ctrl.py index c574d7ec..23d64085 100644 --- a/lib/sata/phy/ctrl.py +++ b/litesata/phy/ctrl.py @@ -1,27 +1,10 @@ -from math import ceil - -from lib.sata.common import * +from litesata.common import * def us(t, clk_freq): clk_period_us = 1000000/clk_freq - return ceil(t/clk_period_us) - -class SATAPHYHostCtrlTimeout(Module): - def __init__(self, load): - self.load = Signal() - self.dec = Signal() - self.reached = Signal() - - cnt = Signal(max=load+1) - self.sync += \ - If(self.load, - cnt.eq(load) - ).Elif(self.dec & ~self.reached, - cnt.eq(cnt-1) - ) - self.comb += self.reached.eq(cnt == 0) + return math.ceil(t/clk_period_us) -class SATAPHYHostCtrl(Module): +class LiteSATAPHYCtrl(Module): def __init__(self, trx, crg, clk_freq): self.ready = Signal() self.need_reset = Signal() @@ -34,8 +17,8 @@ class SATAPHYHostCtrl(Module): sink.ack.eq(1) ] - retry_timeout = SATAPHYHostCtrlTimeout(us(10000, clk_freq)) - align_timeout = SATAPHYHostCtrlTimeout(us(873, clk_freq)) + retry_timeout = Timeout(us(10000, clk_freq)) + align_timeout = Timeout(us(873, clk_freq)) self.submodules += align_timeout, retry_timeout align_detect = Signal() @@ -44,8 +27,8 @@ class SATAPHYHostCtrl(Module): self.fsm = fsm = FSM(reset_state="RESET") fsm.act("RESET", trx.tx_idle.eq(1), - retry_timeout.load.eq(1), - align_timeout.load.eq(1), + retry_timeout.reset.eq(1), + align_timeout.reset.eq(1), If(crg.ready, NextState("COMINIT") ), @@ -59,7 +42,7 @@ class SATAPHYHostCtrl(Module): ) fsm.act("AWAIT_COMINIT", trx.tx_idle.eq(1), - retry_timeout.dec.eq(1), + retry_timeout.ce.eq(1), If(trx.rx_cominit_stb, NextState("AWAIT_NO_COMINIT") ).Else( @@ -70,7 +53,7 @@ class SATAPHYHostCtrl(Module): ) fsm.act("AWAIT_NO_COMINIT", trx.tx_idle.eq(1), - retry_timeout.load.eq(1), + retry_timeout.reset.eq(1), If(~trx.rx_cominit_stb, NextState("CALIBRATE") ), @@ -88,7 +71,7 @@ class SATAPHYHostCtrl(Module): ) fsm.act("AWAIT_COMWAKE", trx.tx_idle.eq(1), - retry_timeout.dec.eq(1), + retry_timeout.ce.eq(1), If(trx.rx_comwake_stb, NextState("AWAIT_NO_COMWAKE") ).Else( @@ -118,7 +101,7 @@ class SATAPHYHostCtrl(Module): source.data.eq(0x4A4A4A4A), #D10.2 source.charisk.eq(0b0000), trx.rx_align.eq(1), - align_timeout.dec.eq(1), + align_timeout.ce.eq(1), If(align_detect & ~trx.rx_idle, NextState("SEND_ALIGN") ).Elif(align_timeout.reached, diff --git a/lib/sata/phy/datapath.py b/litesata/phy/datapath.py similarity index 89% rename from lib/sata/phy/datapath.py rename to litesata/phy/datapath.py index 8930955f..c47e7529 100644 --- a/lib/sata/phy/datapath.py +++ b/litesata/phy/datapath.py @@ -1,10 +1,6 @@ -from lib.sata.common import * +from litesata.common import * -from migen.genlib.misc import chooser -from migen.flow.plumbing import Multiplexer, Demultiplexer -from migen.actorlib.structuring import Converter - -class SATAPHYDatapathRX(Module): +class LiteSATAPHYDatapathRX(Module): def __init__(self): self.sink = Sink(phy_description(16)) self.source = Source(phy_description(32)) @@ -52,7 +48,7 @@ class SATAPHYDatapathRX(Module): Record.connect(fifo.source, self.source) ] -class SATAPHYDatapathTX(Module): +class LiteSATAPHYDatapathTX(Module): def __init__(self): self.sink = Sink(phy_description(32)) self.source = Source(phy_description(16)) @@ -77,7 +73,7 @@ class SATAPHYDatapathTX(Module): Record.connect(self.converter.source, self.source) ] -class SATAPHYAlignInserter(Module): +class LiteSATAPHYAlignInserter(Module): def __init__(self, ctrl): self.sink = sink = Sink(phy_description(32)) self.source = source = Source(phy_description(32)) @@ -110,7 +106,7 @@ class SATAPHYAlignInserter(Module): ) ] -class SATAPHYAlignRemover(Module): +class LiteSATAPHYAlignRemover(Module): def __init__(self): self.sink = sink = Sink(phy_description(32)) self.source = source = Source(phy_description(32)) @@ -127,7 +123,7 @@ class SATAPHYAlignRemover(Module): Record.connect(sink, source) ) -class SATAPHYDatapath(Module): +class LiteSATAPHYDatapath(Module): def __init__(self, trx, ctrl): self.sink = Sink(phy_description(32)) self.source = Source(phy_description(32)) @@ -135,9 +131,9 @@ class SATAPHYDatapath(Module): ### # TX path - self.align_inserter = SATAPHYAlignInserter(ctrl) + self.align_inserter = LiteSATAPHYAlignInserter(ctrl) self.mux = Multiplexer(phy_description(32), 2) - self.tx = SATAPHYDatapathTX() + self.tx = LiteSATAPHYDatapathTX() self.comb += [ self.mux.sel.eq(ctrl.ready), Record.connect(self.sink, self.align_inserter.sink), @@ -148,9 +144,9 @@ class SATAPHYDatapath(Module): ] # RX path - self.rx = SATAPHYDatapathRX() + self.rx = LiteSATAPHYDatapathRX() self.demux = Demultiplexer(phy_description(32), 2) - self.align_remover = SATAPHYAlignRemover() + self.align_remover = LiteSATAPHYAlignRemover() self.comb += [ self.demux.sel.eq(ctrl.ready), Record.connect(trx.source, self.rx.sink), diff --git a/lib/sata/phy/k7/crg.py b/litesata/phy/k7/crg.py similarity index 95% rename from lib/sata/phy/k7/crg.py rename to litesata/phy/k7/crg.py index 7e57e608..9bfc67eb 100644 --- a/lib/sata/phy/k7/crg.py +++ b/litesata/phy/k7/crg.py @@ -1,9 +1,7 @@ -from math import ceil +from litesata.common import * -from lib.sata.common import * - -class K7SATAPHYCRG(Module): - def __init__(self, pads, gtx, clk_freq, speed): +class K7LiteSATAPHYCRG(Module): + def __init__(self, pads, gtx, speed, clk_freq): self.reset = Signal() self.ready = Signal() @@ -78,7 +76,7 @@ class K7SATAPHYCRG(Module): # See AR43482 reset_en = Signal() clk_period_ns = 1000000000/clk_freq - reset_en_cnt_max = ceil(500/clk_period_ns) + reset_en_cnt_max = math.ceil(500/clk_period_ns) reset_en_cnt = Signal(max=reset_en_cnt_max, reset=reset_en_cnt_max-1) self.sync += \ If(self.reset, diff --git a/lib/sata/phy/k7/trx.py b/litesata/phy/k7/trx.py similarity index 99% rename from lib/sata/phy/k7/trx.py rename to litesata/phy/k7/trx.py index eba35f13..ad9a9c83 100644 --- a/lib/sata/phy/k7/trx.py +++ b/litesata/phy/k7/trx.py @@ -1,6 +1,4 @@ -from lib.sata.common import * - -from migen.genlib.cdc import * +from litesata.common import * def ones(width): return 2**width-1 @@ -19,7 +17,7 @@ class _RisingEdge(Module): self.sync += i_d.eq(i) self.comb += o.eq(i & ~i_d) -class K7SATAPHYTRX(Module): +class K7LiteSATAPHYTRX(Module): def __init__(self, pads, speed): # Common signals diff --git a/lib/sata/test/Makefile b/litesata/test/Makefile similarity index 95% rename from lib/sata/test/Makefile rename to litesata/test/Makefile index 02859182..6b2723bf 100644 --- a/lib/sata/test/Makefile +++ b/litesata/test/Makefile @@ -1,4 +1,4 @@ -MSCDIR = ../../../ +MSCDIR = ../../ PYTHON = python3 CMD = PYTHONPATH=$(MSCDIR) $(PYTHON) diff --git a/lib/sata/test/bist_tb.py b/litesata/test/bist_tb.py similarity index 70% rename from lib/sata/test/bist_tb.py rename to litesata/test/bist_tb.py index 72c99979..ed837504 100644 --- a/lib/sata/test/bist_tb.py +++ b/litesata/test/bist_tb.py @@ -1,9 +1,9 @@ -from lib.sata.common import * -from lib.sata import SATACON -from lib.sata.bist import SATABISTGenerator, SATABISTChecker +from litesata.common import * +from litesata import LiteSATA +from litesata.frontend.bist import LiteSATABISTGenerator, LiteSATABISTChecker -from lib.sata.test.hdd import * -from lib.sata.test.common import * +from litesata.test.hdd import * +from litesata.test.common import * class TB(Module): def __init__(self): @@ -11,9 +11,9 @@ class TB(Module): link_debug=False, link_random_level=0, transport_debug=False, transport_loopback=False, hdd_debug=True) - self.controller = SATACON(self.hdd.phy) - self.generator = SATABISTGenerator(self.controller.crossbar.get_port()) - self.checker = SATABISTChecker(self.controller.crossbar.get_port()) + self.controller = LiteSATA(self.hdd.phy, with_crossbar=True) + self.generator = LiteSATABISTGenerator(self.controller.crossbar.get_port()) + self.checker = LiteSATABISTChecker(self.controller.crossbar.get_port()) def gen_simulation(self, selfp): hdd = self.hdd diff --git a/lib/sata/test/command_tb.py b/litesata/test/command_tb.py similarity index 88% rename from lib/sata/test/command_tb.py rename to litesata/test/command_tb.py index 4470dd86..b5c9dc49 100644 --- a/lib/sata/test/command_tb.py +++ b/litesata/test/command_tb.py @@ -1,10 +1,8 @@ -from lib.sata.common import * -from lib.sata.link import SATALink -from lib.sata.transport import SATATransport -from lib.sata.command import SATACommand +from litesata.common import * +from litesata.core import LiteSATACore -from lib.sata.test.hdd import * -from lib.sata.test.common import * +from litesata.test.hdd import * +from litesata.test.common import * class CommandTXPacket(list): def __init__(self, write=0, read=0, sector=0, count=0, data=[]): @@ -61,9 +59,7 @@ class TB(Module): link_debug=False, link_random_level=50, transport_debug=False, transport_loopback=False, hdd_debug=True) - self.link = SATALink(self.hdd.phy) - self.transport = SATATransport(self.link) - self.command = SATACommand(self.transport) + self.core = LiteSATACore(self.hdd.phy) self.streamer = CommandStreamer() self.streamer_randomizer = Randomizer(command_tx_description(32), level=50) @@ -74,7 +70,7 @@ class TB(Module): self.pipeline = Pipeline( self.streamer, self.streamer_randomizer, - self.command, + self.core, self.logger_randomizer, self.logger ) diff --git a/lib/sata/test/common.py b/litesata/test/common.py similarity index 99% rename from lib/sata/test/common.py rename to litesata/test/common.py index e0ba6fe5..ec8da980 100644 --- a/lib/sata/test/common.py +++ b/litesata/test/common.py @@ -2,7 +2,7 @@ import random, copy from migen.sim.generic import run_simulation -from lib.sata.common import * +from litesata.common import * def seed_to_data(seed, random=True): if random: diff --git a/lib/sata/test/cont_tb.py b/litesata/test/cont_tb.py similarity index 89% rename from lib/sata/test/cont_tb.py rename to litesata/test/cont_tb.py index 61c800d2..bbd69011 100644 --- a/lib/sata/test/cont_tb.py +++ b/litesata/test/cont_tb.py @@ -1,7 +1,7 @@ -from lib.sata.common import * -from lib.sata.link.cont import SATACONTInserter, SATACONTRemover +from litesata.common import * +from litesata.core.link.cont import LiteSATACONTInserter, LiteSATACONTRemover -from lib.sata.test.common import * +from litesata.test.common import * class ContPacket(list): def __init__(self, data=[]): @@ -34,8 +34,8 @@ class TB(Module): def __init__(self): self.streamer = ContStreamer() self.streamer_randomizer = Randomizer(phy_description(32), level=50) - self.inserter = SATACONTInserter(phy_description(32)) - self.remover = SATACONTRemover(phy_description(32)) + self.inserter = LiteSATACONTInserter(phy_description(32)) + self.remover = LiteSATACONTRemover(phy_description(32)) self.logger_randomizer = Randomizer(phy_description(32), level=50) self.logger = ContLogger() diff --git a/lib/sata/test/crc.c b/litesata/test/crc.c similarity index 100% rename from lib/sata/test/crc.c rename to litesata/test/crc.c diff --git a/lib/sata/test/crc_tb.py b/litesata/test/crc_tb.py similarity index 90% rename from lib/sata/test/crc_tb.py rename to litesata/test/crc_tb.py index 2b974fbb..a36ec839 100644 --- a/lib/sata/test/crc_tb.py +++ b/litesata/test/crc_tb.py @@ -1,13 +1,13 @@ import subprocess -from lib.sata.common import * -from lib.sata.link.crc import * +from litesata.common import * +from litesata.core.link.crc import * -from lib.sata.test.common import * +from litesata.test.common import * class TB(Module): def __init__(self, length, random): - self.crc = SATACRC() + self.crc = LiteSATACRC() self.length = length self.random = random diff --git a/lib/sata/test/hdd.py b/litesata/test/hdd.py similarity index 99% rename from lib/sata/test/hdd.py rename to litesata/test/hdd.py index e390d81b..6e897f8e 100644 --- a/lib/sata/test/hdd.py +++ b/litesata/test/hdd.py @@ -1,8 +1,8 @@ import subprocess import math -from lib.sata.common import * -from lib.sata.test.common import * +from litesata.common import * +from litesata.test.common import * def print_with_prefix(s, prefix=""): if not isinstance(s, str): diff --git a/lib/sata/test/link_tb.py b/litesata/test/link_tb.py similarity index 85% rename from lib/sata/test/link_tb.py rename to litesata/test/link_tb.py index 4c8e689d..daca230d 100644 --- a/lib/sata/test/link_tb.py +++ b/litesata/test/link_tb.py @@ -1,8 +1,8 @@ -from lib.sata.common import * -from lib.sata.link import SATALink +from litesata.common import * +from litesata.core.link import LiteSATALink -from lib.sata.test.common import * -from lib.sata.test.hdd import * +from litesata.test.common import * +from litesata.test.hdd import * class LinkStreamer(PacketStreamer): def __init__(self): @@ -17,7 +17,7 @@ class TB(Module): self.hdd = HDD( link_debug=False, link_random_level=50, transport_debug=False, transport_loopback=True) - self.link = InsertReset(SATALink(self.hdd.phy)) + self.link = InsertReset(LiteSATALink(self.hdd.phy)) self.streamer = LinkStreamer() self.streamer_randomizer = Randomizer(link_description(32), level=50) diff --git a/lib/sata/test/phy_datapath_tb.py b/litesata/test/phy_datapath_tb.py similarity index 92% rename from lib/sata/test/phy_datapath_tb.py rename to litesata/test/phy_datapath_tb.py index d91092f1..71071035 100644 --- a/lib/sata/test/phy_datapath_tb.py +++ b/litesata/test/phy_datapath_tb.py @@ -1,7 +1,7 @@ -from lib.sata.common import * -from lib.sata.phy.datapath import SATAPHYDatapath +from litesata.common import * +from litesata.phy.datapath import liteSATAPHYDatapath -from lib.sata.test.common import * +from litesata.test.common import * class DataPacket(list): def __init__(self, data=[]): @@ -58,7 +58,7 @@ class TB(Module): self.streamer_randomizer = Randomizer(phy_description(32), level=10) self.trx = TRX() self.ctrl = CTRL() - self.datapath = SATAPHYDatapath(self.trx, self.ctrl) + self.datapath = LiteSATAPHYDatapath(self.trx, self.ctrl) self.logger_randomizer = Randomizer(phy_description(32), level=10) self.logger = DataLogger() diff --git a/lib/sata/test/scrambler.c b/litesata/test/scrambler.c similarity index 100% rename from lib/sata/test/scrambler.c rename to litesata/test/scrambler.c diff --git a/lib/sata/test/scrambler_tb.py b/litesata/test/scrambler_tb.py similarity index 91% rename from lib/sata/test/scrambler_tb.py rename to litesata/test/scrambler_tb.py index 69d7b63e..bf29e50c 100644 --- a/lib/sata/test/scrambler_tb.py +++ b/litesata/test/scrambler_tb.py @@ -1,9 +1,9 @@ import subprocess -from lib.sata.common import * -from lib.sata.link.scrambler import * +from litesata.common import * +from litesata.core.link.scrambler import * -from lib.sata.test.common import * +from litesata.test.common import * class TB(Module): def __init__(self, length): diff --git a/platforms/kc705.py b/platforms/kc705.py index 479f7347..14cd8915 100644 --- a/platforms/kc705.py +++ b/platforms/kc705.py @@ -73,7 +73,7 @@ _io = [ IOStandard("LVCMOS25") ), - ("sata_host", 0, + ("sata0", 0, Subsignal("refclk_p", Pins("C8")), Subsignal("refclk_n", Pins("C7")), Subsignal("txp", Pins("D2")), @@ -81,15 +81,6 @@ _io = [ Subsignal("rxp", Pins("E4")), Subsignal("rxn", Pins("E3")), ), - - ("sata_device", 0, - Subsignal("refclk_p", Pins("G8")), # 125MHz SGMII - Subsignal("refclk_n", Pins("G7")), # 125MHz SGMII - Subsignal("txp", Pins("H2")), # SFP - Subsignal("txn", Pins("H1")), # SFP - Subsignal("rxp", Pins("G4")), # SFP - Subsignal("rxn", Pins("G3")), # SFP - ), ] def Platform(*args, toolchain="vivado", programmer="xc3sprog", **kwargs): diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..ec8de134 --- /dev/null +++ b/setup.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + +import sys, os +from setuptools import setup +from setuptools import find_packages + +here = os.path.abspath(os.path.dirname(__file__)) +README = open(os.path.join(here, "README")).read() + +required_version = (3, 3) +if sys.version_info < required_version: + raise SystemExit("LiteSATA requires python {0} or greater".format( + ".".join(map(str, required_version)))) + +setup( + name="litesata", + version="unknown", + description="Generic open-source SATA1/2/3 controller", + long_description=README, + author="Florent Kermarrec", + author_email="florent@enjoy-digital.fr", + url="http://enjoy-digital.fr", + download_url="https://github.com/Florent-Kermarrec/litesata", + packages=find_packages(here), + license="GPL", + platforms=["Any"], + keywords="HDL ASIC FPGA hardware design", + classifiers=[ + "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)", + "Environment :: Console", + "Development Status :: Alpha", + "Intended Audience :: Developers", + "License :: OSI Approved :: GNU General Public License (GPL)", + "Operating System :: OS Independent", + "Programming Language :: Python", + ], +) diff --git a/targets/bist.py b/targets/bist_kc705.py similarity index 68% rename from targets/bist.py rename to targets/bist_kc705.py index d0ee9b6b..ff752d19 100644 --- a/targets/bist.py +++ b/targets/bist_kc705.py @@ -1,6 +1,6 @@ import os -from migen.fhdl.std import * +from litesata.common import * from migen.bank import csrgen from migen.bus import wishbone, csr from migen.bus import wishbone2csr @@ -8,18 +8,18 @@ from migen.genlib.cdc import * from migen.genlib.resetsync import AsyncResetSynchronizer from migen.bank.description import * +from misoclib import identifier + from miscope import MiLa, Term, UART2Wishbone -from misoclib import identifier -from lib.sata.common import * -from lib.sata.phy import SATAPHY -from lib.sata import SATACON -from lib.sata.bist import SATABIST +from litesata.common import * +from litesata.phy import LiteSATAPHY +from litesata import LiteSATA class _CRG(Module): def __init__(self, platform): self.cd_sys = ClockDomain() - self.sata_reset = Signal() + self.reset = Signal() clk200 = platform.request("clk200") clk200_se = Signal() @@ -49,7 +49,7 @@ class _CRG(Module): p_CLKOUT4_DIVIDE=2, p_CLKOUT4_PHASE=0.0, #o_CLKOUT4= ), Instance("BUFG", i_I=pll_sys, o_O=self.cd_sys.clk), - AsyncResetSynchronizer(self.cd_sys, ~pll_locked | platform.request("cpu_reset") | self.sata_reset), + AsyncResetSynchronizer(self.cd_sys, ~pll_locked | platform.request("cpu_reset") | self.reset), ] class GenSoC(Module): @@ -134,7 +134,7 @@ class BISTLeds(Module): class BISTSoC(GenSoC, AutoCSR): default_platform = "kc705" csr_map = { - "sata_bist": 10, + "sata": 10, } csr_map.update(GenSoC.csr_map) @@ -143,13 +143,10 @@ class BISTSoC(GenSoC, AutoCSR): GenSoC.__init__(self, platform, clk_freq) self.crg = _CRG(platform) - # SATA PHY and controller - self.sata_phy = SATAPHY(platform.request("sata_host"), clk_freq, speed="SATA2") - self.comb += self.crg.sata_reset.eq(self.sata_phy.ctrl.need_reset) - self.sata_con = SATACON(self.sata_phy) - - # SATA BIST generator and checker - self.sata_bist = SATABIST(self.sata_con.crossbar.get_ports(3), with_control=True) + # SATA PHY/Core/Frontend + self.sata_phy = LiteSATAPHY(platform.device, platform.request("sata0"), "SATA2", clk_freq) + self.comb += self.crg.reset.eq(self.sata_phy.ctrl.need_reset) # XXX FIXME + self.sata = LiteSATA(self.sata_phy, with_crossbar=True, with_bist=True, with_bist_csr=True) # Status Leds self.leds = BISTLeds(platform, self.sata_phy) @@ -162,12 +159,12 @@ class BISTSoCDevel(BISTSoC, AutoCSR): def __init__(self, platform, export_mila=False): BISTSoC.__init__(self, platform, export_mila) - self.sata_con_link_rx_fsm_state = Signal(4) - self.sata_con_link_tx_fsm_state = Signal(4) - self.sata_con_transport_rx_fsm_state = Signal(4) - self.sata_con_transport_tx_fsm_state = Signal(4) - self.sata_con_command_rx_fsm_state = Signal(4) - self.sata_con_command_tx_fsm_state = Signal(4) + self.sata_core_link_rx_fsm_state = Signal(4) + self.sata_core_link_tx_fsm_state = Signal(4) + self.sata_core_transport_rx_fsm_state = Signal(4) + self.sata_core_transport_tx_fsm_state = Signal(4) + self.sata_core_command_rx_fsm_state = Signal(4) + self.sata_core_command_tx_fsm_state = Signal(4) debug = ( self.sata_phy.ctrl.ready, @@ -180,31 +177,31 @@ class BISTSoCDevel(BISTSoC, AutoCSR): self.sata_phy.sink.data, self.sata_phy.sink.charisk, - self.sata_con.command.sink.stb, - self.sata_con.command.sink.sop, - self.sata_con.command.sink.eop, - self.sata_con.command.sink.ack, - self.sata_con.command.sink.write, - self.sata_con.command.sink.read, - self.sata_con.command.sink.identify, - - self.sata_con.command.source.stb, - self.sata_con.command.source.sop, - self.sata_con.command.source.eop, - self.sata_con.command.source.ack, - self.sata_con.command.source.write, - self.sata_con.command.source.read, - self.sata_con.command.source.identify, - self.sata_con.command.source.success, - self.sata_con.command.source.failed, - self.sata_con.command.source.data, - - self.sata_con_link_rx_fsm_state, - self.sata_con_link_tx_fsm_state, - self.sata_con_transport_rx_fsm_state, - self.sata_con_transport_tx_fsm_state, - self.sata_con_command_rx_fsm_state, - self.sata_con_command_tx_fsm_state, + self.sata.core.command.sink.stb, + self.sata.core.command.sink.sop, + self.sata.core.command.sink.eop, + self.sata.core.command.sink.ack, + self.sata.core.command.sink.write, + self.sata.core.command.sink.read, + self.sata.core.command.sink.identify, + + self.sata.core.command.source.stb, + self.sata.core.command.source.sop, + self.sata.core.command.source.eop, + self.sata.core.command.source.ack, + self.sata.core.command.source.write, + self.sata.core.command.source.read, + self.sata.core.command.source.identify, + self.sata.core.command.source.success, + self.sata.core.command.source.failed, + self.sata.core.command.source.data, + + self.sata_core_link_rx_fsm_state, + self.sata_core_link_tx_fsm_state, + self.sata_core_transport_rx_fsm_state, + self.sata_core_transport_tx_fsm_state, + self.sata_core_command_rx_fsm_state, + self.sata_core_command_tx_fsm_state, ) self.mila = MiLa(depth=2048, dat=Cat(*debug)) @@ -212,16 +209,17 @@ class BISTSoCDevel(BISTSoC, AutoCSR): if export_mila: mila_filename = os.path.join(platform.soc_ext_path, "test", "mila.csv") self.mila.export(self, debug, mila_filename) + def do_finalize(self): BISTSoC.do_finalize(self) self.comb += [ - self.sata_con_link_rx_fsm_state.eq(self.sata_con.link.rx.fsm.state), - self.sata_con_link_tx_fsm_state.eq(self.sata_con.link.tx.fsm.state), - self.sata_con_transport_rx_fsm_state.eq(self.sata_con.transport.rx.fsm.state), - self.sata_con_transport_tx_fsm_state.eq(self.sata_con.transport.tx.fsm.state), - self.sata_con_command_rx_fsm_state.eq(self.sata_con.command.rx.fsm.state), - self.sata_con_command_tx_fsm_state.eq(self.sata_con.command.tx.fsm.state) + self.sata_core_link_rx_fsm_state.eq(self.sata.core.link.rx.fsm.state), + self.sata_core_link_tx_fsm_state.eq(self.sata.core.link.tx.fsm.state), + self.sata_core_transport_rx_fsm_state.eq(self.sata.core.transport.rx.fsm.state), + self.sata_core_transport_tx_fsm_state.eq(self.sata.core.transport.tx.fsm.state), + self.sata_core_command_rx_fsm_state.eq(self.sata.core.command.rx.fsm.state), + self.sata_core_command_tx_fsm_state.eq(self.sata.core.command.tx.fsm.state) ] -default_subtarget = BISTSoC -#default_subtarget = BISTSoCDevel +#default_subtarget = BISTSoC +default_subtarget = BISTSoCDevel diff --git a/test/bist.py b/test/bist.py index c0c577fa..69272ffe 100644 --- a/test/bist.py +++ b/test/bist.py @@ -4,7 +4,7 @@ from config import * logical_sector_size = 512 -class SATABISTUnitDriver: +class LiteSATABISTUnitDriver: def __init__(self, regs, name): self.regs = regs self.name = name @@ -25,15 +25,15 @@ class SATABISTUnitDriver: errors = self.errors.read() return (speed, errors) -class SATABISTGeneratorDriver(SATABISTUnitDriver): +class LiteSATABISTGeneratorDriver(LiteSATABISTUnitDriver): def __init__(self, regs, name): - SATABISTUnitDriver.__init__(self, regs, name + "_generator") + LiteSATABISTUnitDriver.__init__(self, regs, name + "_generator") -class SATABISTCheckerDriver(SATABISTUnitDriver): +class LiteSATABISTCheckerDriver(LiteSATABISTUnitDriver): def __init__(self, regs, name): - SATABISTUnitDriver.__init__(self, regs, name + "_checker") + LiteSATABISTUnitDriver.__init__(self, regs, name + "_checker") -class SATABISTIdentifyDriver: +class LiteSATABISTIdentifyDriver: def __init__(self, regs, name): self.regs = regs self.name = name @@ -58,13 +58,16 @@ class SATABISTIdentifyDriver: def decode(self): self.serial_number = "" for i, dword in enumerate(self.data[10:20]): - s = dword.to_bytes(4, byteorder='big').decode("utf-8") - self.serial_number += s[2:] + s[:2] - - def __repr__(self): - r = "Serial Number: " + self.serial_number + try: + s = dword.to_bytes(4, byteorder='big').decode("utf-8") + self.serial_number += s[2:] + s[:2] + except: + self.serial_number += " " + + def hdd_info(self): + info = "Serial Number: " + self.serial_number # XXX: enhance decode function - return r + print(info) KB = 1024 MB = 1024*KB @@ -88,12 +91,12 @@ if __name__ == "__main__": args = _get_args() wb.open() ### - identify = SATABISTIdentifyDriver(wb.regs, "sata_bist") - generator = SATABISTGeneratorDriver(wb.regs, "sata_bist") - checker = SATABISTCheckerDriver(wb.regs, "sata_bist") + identify = LiteSATABISTIdentifyDriver(wb.regs, "sata_bist") + generator = LiteSATABISTGeneratorDriver(wb.regs, "sata_bist") + checker = LiteSATABISTCheckerDriver(wb.regs, "sata_bist") identify.run() - print(identify) + identify.hdd_info() sector = 0 count = int(args.transfer_size)*MB//logical_sector_size diff --git a/test/test_link.py b/test/test_link.py index 3849dc0a..46e41411 100644 --- a/test/test_link.py +++ b/test/test_link.py @@ -5,9 +5,9 @@ from bist import * from miscope.host.drivers import MiLaDriver mila = MiLaDriver(wb.regs, "mila") -identify = SATABISTIdentifyDriver(wb.regs, "sata_bist") -generator = SATABISTGeneratorDriver(wb.regs, "sata_bist") -checker = SATABISTCheckerDriver(wb.regs, "sata_bist") +identify = LiteSATABISTIdentifyDriver(wb.regs, "sata_bist") +generator = LiteSATABISTGeneratorDriver(wb.regs, "sata_bist") +checker = LiteSATABISTCheckerDriver(wb.regs, "sata_bist") wb.open() regs = wb.regs ### @@ -18,27 +18,27 @@ if len(sys.argv) < 2: conditions = {} conditions["wr_cmd"] = { - "bistsocdevel_sata_con_command_sink_stb" : 1, - "bistsocdevel_sata_con_command_sink_payload_write" : 1, + "bistsocdevel_core_sink_stb" : 1, + "bistsocdevel_core_sink_payload_write" : 1, } conditions["wr_dma_activate"] = { - "bistsocdevel_sata_con_command_source_source_stb" : 1, - "bistsocdevel_sata_con_command_source_source_payload_write" : 1, + "bistsocdevel_core_source_source_stb" : 1, + "bistsocdevel_core_source_source_payload_write" : 1, } conditions["rd_cmd"] = { - "bistsocdevel_sata_con_command_sink_stb" : 1, - "bistsocdevel_sata_con_command_sink_payload_read" : 1, + "bistsocdevel_core_sink_stb" : 1, + "bistsocdevel_core_sink_payload_read" : 1, } conditions["rd_data"] = { - "bistsocdevel_sata_con_command_source_source_stb" : 1, - "bistsocdevel_sata_con_command_source_source_payload_read" : 1, + "bistsocdevel_core_source_source_stb" : 1, + "bistsocdevel_core_source_source_payload_read" : 1, } conditions["id_cmd"] = { - "bistsocdevel_sata_con_command_sink_stb" : 1, - "bistsocdevel_sata_con_command_sink_payload_identify" : 1, + "bistsocdevel_core_sink_stb" : 1, + "bistsocdevel_core_sink_payload_identify" : 1, } conditions["id_pio_setup"] = { - "bistsocdevel_sata_phy_source_source_payload_data" : primitives["X_RDY"], + "bistsocdevel_source_source_payload_data" : primitives["X_RDY"], } mila.prog_term(port=0, cond=conditions[sys.argv[1]]) @@ -58,6 +58,6 @@ mila.export("dump.vcd") wb.close() print_link_trace(mila, - tx_data_name="bistsocdevel_sata_phy_sink_sink_payload_data", - rx_data_name="bistsocdevel_sata_phy_source_source_payload_data" + tx_data_name="bistsocdevel_sink_sink_payload_data", + rx_data_name="bistsocdevel_source_source_payload_data" ) -- 2.30.2