From cb473ddb6ecfc136df55317dc1b978a0ee42943b Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 13 Apr 2015 14:09:58 +0200 Subject: [PATCH] liteusb: pep8 (replace tabs with spaces) --- misoclib/com/liteusb/common.py | 70 +-- misoclib/com/liteusb/core/com.py | 30 +- misoclib/com/liteusb/core/crc.py | 538 ++++++++++----------- misoclib/com/liteusb/core/depacketizer.py | 242 +++++----- misoclib/com/liteusb/core/packetizer.py | 244 +++++----- misoclib/com/liteusb/frontend/crossbar.py | 50 +- misoclib/com/liteusb/frontend/dma.py | 164 +++---- misoclib/com/liteusb/frontend/uart.py | 98 ++-- misoclib/com/liteusb/phy/ft2232h.py | 556 +++++++++++----------- 9 files changed, 996 insertions(+), 996 deletions(-) diff --git a/misoclib/com/liteusb/common.py b/misoclib/com/liteusb/common.py index e660137f..bb357df1 100644 --- a/misoclib/com/liteusb/common.py +++ b/misoclib/com/liteusb/common.py @@ -4,39 +4,39 @@ from migen.actorlib.fifo import * from migen.flow.actor import EndpointDescription user_layout = EndpointDescription( - [ ("dst", 8), - ("length", 4*8), - ("error", 1), - ("d", 8) - ], - packetized=True + [ ("dst", 8), + ("length", 4*8), + ("error", 1), + ("d", 8) + ], + packetized=True ) phy_layout = [ - ("d", 8) + ("d", 8) ] class LiteUSBPipe: - def __init__(self, layout): - self.sink = Sink(layout) - self.source = Source(layout) + def __init__(self, layout): + self.sink = Sink(layout) + self.source = Source(layout) class LiteUSBTimeout(Module): - def __init__(self, clk_freq, length): - cnt_max = int(clk_freq*length) - width = bits_for(cnt_max) - - self.clear = Signal() - self.done = Signal() - - cnt = Signal(width) - self.sync += \ - If(self.clear, - cnt.eq(0) - ).Elif(~self.done, - cnt.eq(cnt+1) - ) - self.comb += self.done.eq(cnt == cnt_max) + def __init__(self, clk_freq, length): + cnt_max = int(clk_freq*length) + width = bits_for(cnt_max) + + self.clear = Signal() + self.done = Signal() + + cnt = Signal(width) + self.sync += \ + If(self.clear, + cnt.eq(0) + ).Elif(~self.done, + cnt.eq(cnt+1) + ) + self.comb += self.done.eq(cnt == cnt_max) # # TB @@ -44,15 +44,15 @@ class LiteUSBTimeout(Module): import random def randn(max_n): - return random.randint(0, max_n-1) + return random.randint(0, max_n-1) class RandRun: - def __init__(self, level=0): - self.run = True - self.level = level - - def do_simulation(self, selfp): - self.run = True - n = randn(100) - if n < self.level: - self.run = False + def __init__(self, level=0): + self.run = True + self.level = level + + def do_simulation(self, selfp): + self.run = True + n = randn(100) + if n < self.level: + self.run = False diff --git a/misoclib/com/liteusb/core/com.py b/misoclib/com/liteusb/core/com.py index 826cf5d5..22d8beb5 100644 --- a/misoclib/com/liteusb/core/com.py +++ b/misoclib/com/liteusb/core/com.py @@ -7,20 +7,20 @@ from misoclib.com.liteusb.core.packetizer import LiteUSBPacketizer from misoclib.com.liteusb.core.depacketizer import LiteUSBDepacketizer class LiteUSBCom(Module): - def __init__(self, phy, *ports): - # crossbar - self.submodules.crossbar = LiteUSBCrossbar(list(ports)) + def __init__(self, phy, *ports): + # crossbar + self.submodules.crossbar = LiteUSBCrossbar(list(ports)) - # packetizer / depacketizer - self.submodules.packetizer = LiteUSBPacketizer() - self.submodules.depacketizer = LiteUSBDepacketizer() - self.comb += [ - self.crossbar.slave.source.connect(self.packetizer.sink), - self.depacketizer.source.connect(self.crossbar.slave.sink) - ] + # packetizer / depacketizer + self.submodules.packetizer = LiteUSBPacketizer() + self.submodules.depacketizer = LiteUSBDepacketizer() + self.comb += [ + self.crossbar.slave.source.connect(self.packetizer.sink), + self.depacketizer.source.connect(self.crossbar.slave.sink) + ] - # phy - self.comb += [ - self.packetizer.source.connect(phy.sink), - phy.source.connect(self.depacketizer.sink) - ] + # phy + self.comb += [ + self.packetizer.source.connect(phy.sink), + phy.source.connect(self.depacketizer.sink) + ] diff --git a/misoclib/com/liteusb/core/crc.py b/misoclib/com/liteusb/core/crc.py index dfbb5c31..4c60d474 100644 --- a/misoclib/com/liteusb/core/crc.py +++ b/misoclib/com/liteusb/core/crc.py @@ -9,289 +9,289 @@ from migen.actorlib.fifo import SyncFIFO from misoclib.com.liteusb.common import * class CRCEngine(Module): - """Cyclic Redundancy Check Engine - - Compute next CRC value from last CRC value and data input using - an optimized asynchronous LFSR. - - Parameters - ---------- - dat_width : int - Width of the data bus. - width : int - Width of the CRC. - polynom : int - Polynom of the CRC (ex: 0x04C11DB7 for IEEE 802.3 CRC) - - Attributes - ---------- - d : in - Data input. - last : in - last CRC value. - next : - next CRC value. - """ - def __init__(self, dat_width, width, polynom): - self.d = Signal(dat_width) - self.last = Signal(width) - self.next = Signal(width) - - ### - - def _optimize_eq(l): - """ - Replace even numbers of XORs in the equation - with an equivalent XOR - """ - d = OrderedDict() - for e in l: - if e in d: - d[e] += 1 - else: - d[e] = 1 - r = [] - for key, value in d.items(): - if value%2 != 0: - r.append(key) - return r - - # compute and optimize CRC's LFSR - curval = [[("state", i)] for i in range(width)] - for i in range(dat_width): - feedback = curval.pop() + [("din", i)] - for j in range(width-1): - if (polynom & (1<<(j+1))): - curval[j] += feedback - curval[j] = _optimize_eq(curval[j]) - curval.insert(0, feedback) - - # implement logic - for i in range(width): - xors = [] - for t, n in curval[i]: - if t == "state": - xors += [self.last[n]] - elif t == "din": - xors += [self.d[n]] - self.comb += self.next[i].eq(optree("^", xors)) + """Cyclic Redundancy Check Engine + + Compute next CRC value from last CRC value and data input using + an optimized asynchronous LFSR. + + Parameters + ---------- + dat_width : int + Width of the data bus. + width : int + Width of the CRC. + polynom : int + Polynom of the CRC (ex: 0x04C11DB7 for IEEE 802.3 CRC) + + Attributes + ---------- + d : in + Data input. + last : in + last CRC value. + next : + next CRC value. + """ + def __init__(self, dat_width, width, polynom): + self.d = Signal(dat_width) + self.last = Signal(width) + self.next = Signal(width) + + ### + + def _optimize_eq(l): + """ + Replace even numbers of XORs in the equation + with an equivalent XOR + """ + d = OrderedDict() + for e in l: + if e in d: + d[e] += 1 + else: + d[e] = 1 + r = [] + for key, value in d.items(): + if value%2 != 0: + r.append(key) + return r + + # compute and optimize CRC's LFSR + curval = [[("state", i)] for i in range(width)] + for i in range(dat_width): + feedback = curval.pop() + [("din", i)] + for j in range(width-1): + if (polynom & (1<<(j+1))): + curval[j] += feedback + curval[j] = _optimize_eq(curval[j]) + curval.insert(0, feedback) + + # implement logic + for i in range(width): + xors = [] + for t, n in curval[i]: + if t == "state": + xors += [self.last[n]] + elif t == "din": + xors += [self.d[n]] + self.comb += self.next[i].eq(optree("^", xors)) @DecorateModule(InsertReset) @DecorateModule(InsertCE) class CRC32(Module): - """IEEE 802.3 CRC - - Implement an IEEE 802.3 CRC generator/checker. - - Parameters - ---------- - dat_width : int - Width of the data bus. - - Attributes - ---------- - d : in - Data input. - value : out - CRC value (used for generator). - error : out - CRC error (used for checker). - """ - width = 32 - polynom = 0x04C11DB7 - init = 2**width-1 - check = 0xC704DD7B - def __init__(self, dat_width): - self.d = Signal(dat_width) - self.value = Signal(self.width) - self.error = Signal() - - ### - - self.submodules.engine = CRCEngine(dat_width, self.width, self.polynom) - reg = Signal(self.width, reset=self.init) - self.sync += reg.eq(self.engine.next) - self.comb += [ - self.engine.d.eq(self.d), - self.engine.last.eq(reg), - - self.value.eq(~reg[::-1]), - self.error.eq(self.engine.next != self.check) - ] + """IEEE 802.3 CRC + + Implement an IEEE 802.3 CRC generator/checker. + + Parameters + ---------- + dat_width : int + Width of the data bus. + + Attributes + ---------- + d : in + Data input. + value : out + CRC value (used for generator). + error : out + CRC error (used for checker). + """ + width = 32 + polynom = 0x04C11DB7 + init = 2**width-1 + check = 0xC704DD7B + def __init__(self, dat_width): + self.d = Signal(dat_width) + self.value = Signal(self.width) + self.error = Signal() + + ### + + self.submodules.engine = CRCEngine(dat_width, self.width, self.polynom) + reg = Signal(self.width, reset=self.init) + self.sync += reg.eq(self.engine.next) + self.comb += [ + self.engine.d.eq(self.d), + self.engine.last.eq(reg), + + self.value.eq(~reg[::-1]), + self.error.eq(self.engine.next != self.check) + ] class CRCInserter(Module): - """CRC Inserter - - Append a CRC at the end of each packet. - - Parameters - ---------- - layout : layout - Layout of the dataflow. - - Attributes - ---------- - sink : in - Packets input without CRC. - source : out - Packets output with CRC. - """ - def __init__(self, crc_class, layout): - self.sink = sink = Sink(layout) - self.source = source = Source(layout) - self.busy = Signal() - - ### - - dw = flen(sink.d) - crc = crc_class(dw) - fsm = FSM(reset_state="IDLE") - self.submodules += crc, fsm - - fsm.act("IDLE", - crc.reset.eq(1), - sink.ack.eq(1), - If(sink.stb & sink.sop, - sink.ack.eq(0), - NextState("COPY"), - ) - ) - fsm.act("COPY", - crc.ce.eq(sink.stb & source.ack), - crc.d.eq(sink.d), - Record.connect(sink, source), - source.eop.eq(0), - If(sink.stb & sink.eop & source.ack, - NextState("INSERT"), - ) - ) - ratio = crc.width//dw - if ratio > 1: - cnt = Signal(max=ratio, reset=ratio-1) - cnt_done = Signal() - fsm.act("INSERT", - source.stb.eq(1), - chooser(crc.value, cnt, source.d, reverse=True), - If(cnt_done, - source.eop.eq(1), - If(source.ack, NextState("IDLE")) - ) - ) - self.comb += cnt_done.eq(cnt == 0) - self.sync += \ - If(fsm.ongoing("IDLE"), - cnt.eq(cnt.reset) - ).Elif(fsm.ongoing("INSERT") & ~cnt_done, - cnt.eq(cnt - source.ack) - ) - else: - fsm.act("INSERT", - source.stb.eq(1), - source.eop.eq(1), - source.d.eq(crc.value), - If(source.ack, NextState("IDLE")) - ) - self.comb += self.busy.eq(~fsm.ongoing("IDLE")) + """CRC Inserter + + Append a CRC at the end of each packet. + + Parameters + ---------- + layout : layout + Layout of the dataflow. + + Attributes + ---------- + sink : in + Packets input without CRC. + source : out + Packets output with CRC. + """ + def __init__(self, crc_class, layout): + self.sink = sink = Sink(layout) + self.source = source = Source(layout) + self.busy = Signal() + + ### + + dw = flen(sink.d) + crc = crc_class(dw) + fsm = FSM(reset_state="IDLE") + self.submodules += crc, fsm + + fsm.act("IDLE", + crc.reset.eq(1), + sink.ack.eq(1), + If(sink.stb & sink.sop, + sink.ack.eq(0), + NextState("COPY"), + ) + ) + fsm.act("COPY", + crc.ce.eq(sink.stb & source.ack), + crc.d.eq(sink.d), + Record.connect(sink, source), + source.eop.eq(0), + If(sink.stb & sink.eop & source.ack, + NextState("INSERT"), + ) + ) + ratio = crc.width//dw + if ratio > 1: + cnt = Signal(max=ratio, reset=ratio-1) + cnt_done = Signal() + fsm.act("INSERT", + source.stb.eq(1), + chooser(crc.value, cnt, source.d, reverse=True), + If(cnt_done, + source.eop.eq(1), + If(source.ack, NextState("IDLE")) + ) + ) + self.comb += cnt_done.eq(cnt == 0) + self.sync += \ + If(fsm.ongoing("IDLE"), + cnt.eq(cnt.reset) + ).Elif(fsm.ongoing("INSERT") & ~cnt_done, + cnt.eq(cnt - source.ack) + ) + else: + fsm.act("INSERT", + source.stb.eq(1), + source.eop.eq(1), + source.d.eq(crc.value), + If(source.ack, NextState("IDLE")) + ) + self.comb += self.busy.eq(~fsm.ongoing("IDLE")) class CRC32Inserter(CRCInserter): - def __init__(self, layout): - CRCInserter.__init__(self, CRC32, layout) + def __init__(self, layout): + CRCInserter.__init__(self, CRC32, layout) class CRCChecker(Module): - """CRC Checker - - Check CRC at the end of each packet. - - Parameters - ---------- - layout : layout - Layout of the dataflow. - - Attributes - ---------- - sink : in - Packets input with CRC. - source : out - Packets output without CRC and "error" set to 0 - on eop when CRC OK / set to 1 when CRC KO. - """ - def __init__(self, crc_class, layout): - self.sink = sink = Sink(layout) - self.source = source = Source(layout) - self.busy = Signal() - - ### - - dw = flen(sink.d) - crc = crc_class(dw) - self.submodules += crc - ratio = crc.width//dw - - error = Signal() - fifo = InsertReset(SyncFIFO(layout, ratio + 1)) - self.submodules += fifo - - fsm = FSM(reset_state="RESET") - self.submodules += fsm - - fifo_in = Signal() - fifo_out = Signal() - fifo_full = Signal() - - self.comb += [ - fifo_full.eq(fifo.fifo.level == ratio), - fifo_in.eq(sink.stb & (~fifo_full | fifo_out)), - fifo_out.eq(source.stb & source.ack), - - Record.connect(sink, fifo.sink), - fifo.sink.stb.eq(fifo_in), - self.sink.ack.eq(fifo_in), - - source.stb.eq(sink.stb & fifo_full), - source.sop.eq(fifo.source.sop), - source.eop.eq(sink.eop), - fifo.source.ack.eq(fifo_out), - source.payload.eq(fifo.source.payload), - - source.error.eq(sink.error | crc.error), - ] - - fsm.act("RESET", - crc.reset.eq(1), - fifo.reset.eq(1), - NextState("IDLE"), - ) - fsm.act("IDLE", - crc.d.eq(sink.d), - If(sink.stb & sink.sop & sink.ack, - crc.ce.eq(1), - NextState("COPY") - ) - ) - fsm.act("COPY", - crc.d.eq(sink.d), - If(sink.stb & sink.ack, - crc.ce.eq(1), - If(sink.eop, - NextState("RESET") - ) - ) - ) - self.comb += self.busy.eq(~fsm.ongoing("IDLE")) + """CRC Checker + + Check CRC at the end of each packet. + + Parameters + ---------- + layout : layout + Layout of the dataflow. + + Attributes + ---------- + sink : in + Packets input with CRC. + source : out + Packets output without CRC and "error" set to 0 + on eop when CRC OK / set to 1 when CRC KO. + """ + def __init__(self, crc_class, layout): + self.sink = sink = Sink(layout) + self.source = source = Source(layout) + self.busy = Signal() + + ### + + dw = flen(sink.d) + crc = crc_class(dw) + self.submodules += crc + ratio = crc.width//dw + + error = Signal() + fifo = InsertReset(SyncFIFO(layout, ratio + 1)) + self.submodules += fifo + + fsm = FSM(reset_state="RESET") + self.submodules += fsm + + fifo_in = Signal() + fifo_out = Signal() + fifo_full = Signal() + + self.comb += [ + fifo_full.eq(fifo.fifo.level == ratio), + fifo_in.eq(sink.stb & (~fifo_full | fifo_out)), + fifo_out.eq(source.stb & source.ack), + + Record.connect(sink, fifo.sink), + fifo.sink.stb.eq(fifo_in), + self.sink.ack.eq(fifo_in), + + source.stb.eq(sink.stb & fifo_full), + source.sop.eq(fifo.source.sop), + source.eop.eq(sink.eop), + fifo.source.ack.eq(fifo_out), + source.payload.eq(fifo.source.payload), + + source.error.eq(sink.error | crc.error), + ] + + fsm.act("RESET", + crc.reset.eq(1), + fifo.reset.eq(1), + NextState("IDLE"), + ) + fsm.act("IDLE", + crc.d.eq(sink.d), + If(sink.stb & sink.sop & sink.ack, + crc.ce.eq(1), + NextState("COPY") + ) + ) + fsm.act("COPY", + crc.d.eq(sink.d), + If(sink.stb & sink.ack, + crc.ce.eq(1), + If(sink.eop, + NextState("RESET") + ) + ) + ) + self.comb += self.busy.eq(~fsm.ongoing("IDLE")) class CRC32Checker(CRCChecker): - def __init__(self, layout): - CRCChecker.__init__(self, CRC32, layout) + def __init__(self, layout): + CRCChecker.__init__(self, CRC32, layout) class LiteUSBCRC32(Module): - def __init__(self, tag): - self.tag = tag + def __init__(self, tag): + self.tag = tag - self.submodules.inserter = CRC32Inserter(user_layout) - self.submodules.checker = CRC32Checker(user_layout) + self.submodules.inserter = CRC32Inserter(user_layout) + self.submodules.checker = CRC32Checker(user_layout) - self.dma_sink = self.inserter.sink - self.dma_source = self.checker.source + self.dma_sink = self.inserter.sink + self.dma_source = self.checker.source - self.sink = self.checker.sink - self.source = self.inserter.source + self.sink = self.checker.sink + self.source = self.inserter.source diff --git a/misoclib/com/liteusb/core/depacketizer.py b/misoclib/com/liteusb/core/depacketizer.py index a6b0e18a..469f0011 100644 --- a/misoclib/com/liteusb/core/depacketizer.py +++ b/misoclib/com/liteusb/core/depacketizer.py @@ -5,149 +5,149 @@ from migen.genlib.fsm import FSM, NextState from misoclib.com.liteusb.common import * class LiteUSBDepacketizer(Module): - def __init__(self, timeout=10): - self.sink = sink = Sink(phy_layout) - self.source = source = Source(user_layout) - - # Packet description - # - preamble : 4 bytes - # - dst : 1 byte - # - length : 4 bytes - # - payload - preamble = Array(Signal(8) for i in range(4)) - - header = [ - # dst - source.dst, - # length - source.length[24:32], - source.length[16:24], - source.length[8:16], - source.length[0:8], - ] - - header_pack = InsertReset(Pack(phy_layout, len(header))) - self.submodules += header_pack - - for i, byte in enumerate(header): - chunk = getattr(header_pack.source.payload, "chunk" + str(i)) - self.comb += byte.eq(chunk.d) - - fsm = FSM() - self.submodules += fsm - - self.comb += preamble[0].eq(sink.d) - for i in range(1, 4): - self.sync += If(sink.stb & sink.ack, - preamble[i].eq(preamble[i-1]) - ) - fsm.act("WAIT_SOP", - If( (preamble[3] == 0x5A) & - (preamble[2] == 0xA5) & - (preamble[1] == 0x5A) & - (preamble[0] == 0xA5) & - sink.stb, - NextState("RECEIVE_HEADER") - ), - sink.ack.eq(1), - header_pack.source.ack.eq(1), - ) - - self.submodules.timeout = LiteUSBTimeout(60000000, timeout) - self.comb += self.timeout.clear.eq(fsm.ongoing("WAIT_SOP")) - - fsm.act("RECEIVE_HEADER", - header_pack.sink.stb.eq(sink.stb), - header_pack.sink.payload.eq(sink.payload), - If(self.timeout.done, NextState("WAIT_SOP")) - .Elif(header_pack.source.stb, NextState("RECEIVE_PAYLOAD")) - .Else(sink.ack.eq(1)) - ) - - self.comb += header_pack.reset.eq(self.timeout.done) - - sop = Signal() - eop = Signal() - cnt = Signal(32) - - fsm.act("RECEIVE_PAYLOAD", - source.stb.eq(sink.stb), - source.sop.eq(sop), - source.eop.eq(eop), - source.d.eq(sink.d), - sink.ack.eq(source.ack), - If((eop & sink.stb & source.ack) | self.timeout.done, NextState("WAIT_SOP")) - ) - - self.sync += \ - If(fsm.ongoing("WAIT_SOP"), - cnt.eq(0) - ).Elif(source.stb & source.ack, - cnt.eq(cnt + 1) - ) - self.comb += sop.eq(cnt == 0) - self.comb += eop.eq(cnt == source.length - 1) + def __init__(self, timeout=10): + self.sink = sink = Sink(phy_layout) + self.source = source = Source(user_layout) + + # Packet description + # - preamble : 4 bytes + # - dst : 1 byte + # - length : 4 bytes + # - payload + preamble = Array(Signal(8) for i in range(4)) + + header = [ + # dst + source.dst, + # length + source.length[24:32], + source.length[16:24], + source.length[8:16], + source.length[0:8], + ] + + header_pack = InsertReset(Pack(phy_layout, len(header))) + self.submodules += header_pack + + for i, byte in enumerate(header): + chunk = getattr(header_pack.source.payload, "chunk" + str(i)) + self.comb += byte.eq(chunk.d) + + fsm = FSM() + self.submodules += fsm + + self.comb += preamble[0].eq(sink.d) + for i in range(1, 4): + self.sync += If(sink.stb & sink.ack, + preamble[i].eq(preamble[i-1]) + ) + fsm.act("WAIT_SOP", + If( (preamble[3] == 0x5A) & + (preamble[2] == 0xA5) & + (preamble[1] == 0x5A) & + (preamble[0] == 0xA5) & + sink.stb, + NextState("RECEIVE_HEADER") + ), + sink.ack.eq(1), + header_pack.source.ack.eq(1), + ) + + self.submodules.timeout = LiteUSBTimeout(60000000, timeout) + self.comb += self.timeout.clear.eq(fsm.ongoing("WAIT_SOP")) + + fsm.act("RECEIVE_HEADER", + header_pack.sink.stb.eq(sink.stb), + header_pack.sink.payload.eq(sink.payload), + If(self.timeout.done, NextState("WAIT_SOP")) + .Elif(header_pack.source.stb, NextState("RECEIVE_PAYLOAD")) + .Else(sink.ack.eq(1)) + ) + + self.comb += header_pack.reset.eq(self.timeout.done) + + sop = Signal() + eop = Signal() + cnt = Signal(32) + + fsm.act("RECEIVE_PAYLOAD", + source.stb.eq(sink.stb), + source.sop.eq(sop), + source.eop.eq(eop), + source.d.eq(sink.d), + sink.ack.eq(source.ack), + If((eop & sink.stb & source.ack) | self.timeout.done, NextState("WAIT_SOP")) + ) + + self.sync += \ + If(fsm.ongoing("WAIT_SOP"), + cnt.eq(0) + ).Elif(source.stb & source.ack, + cnt.eq(cnt + 1) + ) + self.comb += sop.eq(cnt == 0) + self.comb += eop.eq(cnt == source.length - 1) # # TB # -src_data = [ - 0x5A, 0xA5, 0x5A, 0xA5, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03, - 0x5A, 0xA5, 0x5A, 0xA5, 0x12, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, +src_data = [ + 0x5A, 0xA5, 0x5A, 0xA5, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03, + 0x5A, 0xA5, 0x5A, 0xA5, 0x12, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ]*4 class DepacketizerSourceModel(Module, Source, RandRun): - def __init__(self, data): - Source.__init__(self, phy_layout) - RandRun.__init__(self, 50) - self.data = data + def __init__(self, data): + Source.__init__(self, phy_layout) + RandRun.__init__(self, 50) + self.data = data - self._stb = 0 - self._cnt = 0 + self._stb = 0 + self._cnt = 0 - def do_simulation(self, selfp): - RandRun.do_simulation(self, selfp) + def do_simulation(self, selfp): + RandRun.do_simulation(self, selfp) - if self.run and not self._stb: - self._stb = 1 + if self.run and not self._stb: + self._stb = 1 - if selfp.stb and selfp.ack: - self._cnt +=1 + if selfp.stb and selfp.ack: + self._cnt +=1 - selfp.stb = self._stb - selfp.d = self.data[self._cnt] + selfp.stb = self._stb + selfp.d = self.data[self._cnt] - if self._cnt == len(self.data)-1: - raise StopSimulation + if self._cnt == len(self.data)-1: + raise StopSimulation class DepacketizerSinkModel(Module, Sink, RandRun): - def __init__(self): - Sink.__init__(self, user_layout, True) - RandRun.__init__(self, 50) + def __init__(self): + Sink.__init__(self, user_layout, True) + RandRun.__init__(self, 50) - def do_simulation(self, selfp): - RandRun.do_simulation(self, selfp) - if self.run: - selfp.ack = 1 - else: - selfp.ack = 0 + def do_simulation(self, selfp): + RandRun.do_simulation(self, selfp) + if self.run: + selfp.ack = 1 + else: + selfp.ack = 0 class TB(Module): - def __init__(self): - self.submodules.source = DepacketizerSourceModel(src_data) - self.submodules.dut = LiteUSBDepacketizer() - self.submodules.sink = DepacketizerSinkModel() + def __init__(self): + self.submodules.source = DepacketizerSourceModel(src_data) + self.submodules.dut = LiteUSBDepacketizer() + self.submodules.sink = DepacketizerSinkModel() - self.comb += [ - self.source.connect(self.dut.sink), - self.dut.source.connect(self.sink), - ] + self.comb += [ + self.source.connect(self.dut.sink), + self.dut.source.connect(self.sink), + ] def main(): - from migen.sim.generic import run_simulation - run_simulation(TB(), ncycles=400, vcd_name="tb_depacketizer.vcd") + from migen.sim.generic import run_simulation + run_simulation(TB(), ncycles=400, vcd_name="tb_depacketizer.vcd") if __name__ == "__main__": - main() + main() diff --git a/misoclib/com/liteusb/core/packetizer.py b/misoclib/com/liteusb/core/packetizer.py index 6926aa69..7ede9db4 100644 --- a/misoclib/com/liteusb/core/packetizer.py +++ b/misoclib/com/liteusb/core/packetizer.py @@ -5,144 +5,144 @@ from migen.genlib.fsm import FSM, NextState from misoclib.com.liteusb.common import * class LiteUSBPacketizer(Module): - def __init__(self): - self.sink = sink = Sink(user_layout) - self.source = source = Source(phy_layout) - - # Packet description - # - preamble : 4 bytes - # - dst : 1 byte - # - length : 4 bytes - # - payload - header = [ - # preamble - 0x5A, - 0xA5, - 0x5A, - 0xA5, - # dst - sink.dst, - # length - sink.length[24:32], - sink.length[16:24], - sink.length[8:16], - sink.length[0:8], - ] - - header_unpack = Unpack(len(header), phy_layout) - self.submodules += header_unpack - - for i, byte in enumerate(header): - chunk = getattr(header_unpack.sink.payload, "chunk" + str(i)) - self.comb += chunk.d.eq(byte) - - fsm = FSM() - self.submodules += fsm - - fsm.act("WAIT_SOP", - If(sink.stb & sink.sop, NextState("SEND_HEADER")) - ) - - fsm.act("SEND_HEADER", - header_unpack.sink.stb.eq(1), - source.stb.eq(1), - source.d.eq(header_unpack.source.d), - header_unpack.source.ack.eq(source.ack), - If(header_unpack.sink.ack, NextState("SEND_DATA")) - ) - - fsm.act("SEND_DATA", - source.stb.eq(sink.stb), - source.d.eq(sink.d), - sink.ack.eq(source.ack), - If(source.ack & sink.eop, NextState("WAIT_SOP")) - ) + def __init__(self): + self.sink = sink = Sink(user_layout) + self.source = source = Source(phy_layout) + + # Packet description + # - preamble : 4 bytes + # - dst : 1 byte + # - length : 4 bytes + # - payload + header = [ + # preamble + 0x5A, + 0xA5, + 0x5A, + 0xA5, + # dst + sink.dst, + # length + sink.length[24:32], + sink.length[16:24], + sink.length[8:16], + sink.length[0:8], + ] + + header_unpack = Unpack(len(header), phy_layout) + self.submodules += header_unpack + + for i, byte in enumerate(header): + chunk = getattr(header_unpack.sink.payload, "chunk" + str(i)) + self.comb += chunk.d.eq(byte) + + fsm = FSM() + self.submodules += fsm + + fsm.act("WAIT_SOP", + If(sink.stb & sink.sop, NextState("SEND_HEADER")) + ) + + fsm.act("SEND_HEADER", + header_unpack.sink.stb.eq(1), + source.stb.eq(1), + source.d.eq(header_unpack.source.d), + header_unpack.source.ack.eq(source.ack), + If(header_unpack.sink.ack, NextState("SEND_DATA")) + ) + + fsm.act("SEND_DATA", + source.stb.eq(sink.stb), + source.d.eq(sink.d), + sink.ack.eq(source.ack), + If(source.ack & sink.eop, NextState("WAIT_SOP")) + ) # # TB # src_data = [ - (0x01, 4, - [0x0, 0x1, 0x2, 0x3] - ), - (0x16, 8, - [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7] - ), - (0x22, 16, - [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF] - ), + (0x01, 4, + [0x0, 0x1, 0x2, 0x3] + ), + (0x16, 8, + [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7] + ), + (0x22, 16, + [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF] + ), ] class PacketizerSourceModel(Module, Source, RandRun): - def __init__(self, data): - Source.__init__(self, user_layout, True) - RandRun.__init__(self, 25) - self.data = data - - self._stb = 0 - self._sop = 0 - self._eop = 0 - self._frame_cnt = 0 - self._payload_cnt = 0 - - def do_simulation(self, selfp): - RandRun.do_simulation(self, selfp) - dst, length, payload = self.data[self._frame_cnt] - - if selfp.stb and selfp.ack: - if self._payload_cnt == length-1: - self._frame_cnt += 1 - self._payload_cnt = 0 - else: - self._payload_cnt += 1 - if self.run: - self._stb = 1 - else: - self._stb = 0 - - if self.run and not self._stb: - self._stb = 1 - - self._sop = int((self._payload_cnt == 0)) - self._eop = int((self._payload_cnt == length-1)) - - selfp.stb = self._stb - selfp.sop = self._sop & self._stb - selfp.eop = self._eop & self._stb - selfp.dst = dst - selfp.length = length - selfp.d = payload[self._payload_cnt] - - if self._frame_cnt == len(self.data): - raise StopSimulation + def __init__(self, data): + Source.__init__(self, user_layout, True) + RandRun.__init__(self, 25) + self.data = data + + self._stb = 0 + self._sop = 0 + self._eop = 0 + self._frame_cnt = 0 + self._payload_cnt = 0 + + def do_simulation(self, selfp): + RandRun.do_simulation(self, selfp) + dst, length, payload = self.data[self._frame_cnt] + + if selfp.stb and selfp.ack: + if self._payload_cnt == length-1: + self._frame_cnt += 1 + self._payload_cnt = 0 + else: + self._payload_cnt += 1 + if self.run: + self._stb = 1 + else: + self._stb = 0 + + if self.run and not self._stb: + self._stb = 1 + + self._sop = int((self._payload_cnt == 0)) + self._eop = int((self._payload_cnt == length-1)) + + selfp.stb = self._stb + selfp.sop = self._sop & self._stb + selfp.eop = self._eop & self._stb + selfp.dst = dst + selfp.length = length + selfp.d = payload[self._payload_cnt] + + if self._frame_cnt == len(self.data): + raise StopSimulation class PacketizerSinkModel(Module, Sink, RandRun): - def __init__(self): - Sink.__init__(self, phy_layout) - RandRun.__init__(self, 25) + def __init__(self): + Sink.__init__(self, phy_layout) + RandRun.__init__(self, 25) - def do_simulation(self, selfp): - RandRun.do_simulation(self, selfp) - if self.run: - selfp.ack = 1 - else: - selfp.ack = 0 + def do_simulation(self, selfp): + RandRun.do_simulation(self, selfp) + if self.run: + selfp.ack = 1 + else: + selfp.ack = 0 class TB(Module): - def __init__(self): - self.submodules.source = PacketizerSourceModel(src_data) - self.submodules.dut = LiteUSBPacketizer() - self.submodules.sink = PacketizerSinkModel() + def __init__(self): + self.submodules.source = PacketizerSourceModel(src_data) + self.submodules.dut = LiteUSBPacketizer() + self.submodules.sink = PacketizerSinkModel() - self.comb +=[ - self.source.connect(self.dut.sink), - self.dut.source.connect(self.sink), - ] + self.comb +=[ + self.source.connect(self.dut.sink), + self.dut.source.connect(self.sink), + ] def main(): - from migen.sim.generic import run_simulation - run_simulation(TB(), ncycles=400, vcd_name="tb_packetizer.vcd") + from migen.sim.generic import run_simulation + run_simulation(TB(), ncycles=400, vcd_name="tb_packetizer.vcd") if __name__ == "__main__": - main() + main() diff --git a/misoclib/com/liteusb/frontend/crossbar.py b/misoclib/com/liteusb/frontend/crossbar.py index 5f57abae..e76937a4 100644 --- a/misoclib/com/liteusb/frontend/crossbar.py +++ b/misoclib/com/liteusb/frontend/crossbar.py @@ -5,31 +5,31 @@ from migen.genlib.record import Record from misoclib.com.liteusb.common import * class LiteUSBCrossbar(Module): - def __init__(self, masters, slave=None): - if slave is None: - slave = LiteUSBPipe(user_layout) - self.slave = slave + def __init__(self, masters, slave=None): + if slave is None: + slave = LiteUSBPipe(user_layout) + self.slave = slave - # masters --> slave arbitration - self.submodules.rr = RoundRobin(len(masters)) - cases = {} - for i, m in enumerate(masters): - sop = Signal() - eop = Signal() - ongoing = Signal() - self.comb += [ - sop.eq(m.source.stb & m.source.sop), - eop.eq(m.source.stb & m.source.eop & m.source.ack), - ] - self.sync += ongoing.eq((sop | ongoing) & ~eop) - self.comb += self.rr.request[i].eq(sop | ongoing) + # masters --> slave arbitration + self.submodules.rr = RoundRobin(len(masters)) + cases = {} + for i, m in enumerate(masters): + sop = Signal() + eop = Signal() + ongoing = Signal() + self.comb += [ + sop.eq(m.source.stb & m.source.sop), + eop.eq(m.source.stb & m.source.eop & m.source.ack), + ] + self.sync += ongoing.eq((sop | ongoing) & ~eop) + self.comb += self.rr.request[i].eq(sop | ongoing) - cases[i] = [Record.connect(masters[i].source, slave.source)] - self.comb += Case(self.rr.grant, cases) + cases[i] = [Record.connect(masters[i].source, slave.source)] + self.comb += Case(self.rr.grant, cases) - # slave --> master demux - cases = {} - for i, m in enumerate(masters): - cases[m.tag] = [Record.connect(slave.sink, masters[i].sink)] - cases["default"] = [slave.sink.ack.eq(1)] - self.comb += Case(slave.sink.dst, cases) + # slave --> master demux + cases = {} + for i, m in enumerate(masters): + cases[m.tag] = [Record.connect(slave.sink, masters[i].sink)] + cases["default"] = [slave.sink.ack.eq(1)] + self.comb += Case(slave.sink.dst, cases) diff --git a/misoclib/com/liteusb/frontend/dma.py b/misoclib/com/liteusb/frontend/dma.py index 4768d5b5..4e26004e 100644 --- a/misoclib/com/liteusb/frontend/dma.py +++ b/misoclib/com/liteusb/frontend/dma.py @@ -11,91 +11,91 @@ from misoclib.mem.sdram.frontend import dma_lasmi from misoclib.com.liteusb.common import * class LiteUSBDMAWriter(Module, AutoCSR): - def __init__(self, lasmim): - self.sink = sink = Sink(user_layout) - - # Pack data - pack_factor = lasmim.dw//8 - pack = structuring.Pack(phy_layout, pack_factor, reverse=True) - cast = structuring.Cast(pack.source.payload.layout, lasmim.dw) - - # DMA - writer = dma_lasmi.Writer(lasmim) - self._reset = CSR() - self.dma = InsertReset(spi.DMAWriteController(writer, mode=spi.MODE_SINGLE_SHOT)) - self.comb += self.dma.reset.eq(self._reset.r & self._reset.re) - - # Remove sop/eop/length/dst fields from payload - self.comb += [ - pack.sink.stb.eq(sink.stb), - pack.sink.payload.eq(sink.payload), - sink.ack.eq(pack.sink.ack) - ] - - # Graph - g = DataFlowGraph() - g.add_pipeline(pack, cast, self.dma) - self.submodules += CompositeActor(g) - - # IRQ - self.submodules.ev = EventManager() - self.ev.done = EventSourcePulse() - self.ev.finalize() - self.comb += self.ev.done.trigger.eq(sink.stb & sink.eop) - - # CRC - self._crc_failed = CSRStatus() - self.sync += \ - If(sink.stb & sink.eop, - self._crc_failed.status.eq(sink.error) - ) + def __init__(self, lasmim): + self.sink = sink = Sink(user_layout) + + # Pack data + pack_factor = lasmim.dw//8 + pack = structuring.Pack(phy_layout, pack_factor, reverse=True) + cast = structuring.Cast(pack.source.payload.layout, lasmim.dw) + + # DMA + writer = dma_lasmi.Writer(lasmim) + self._reset = CSR() + self.dma = InsertReset(spi.DMAWriteController(writer, mode=spi.MODE_SINGLE_SHOT)) + self.comb += self.dma.reset.eq(self._reset.r & self._reset.re) + + # Remove sop/eop/length/dst fields from payload + self.comb += [ + pack.sink.stb.eq(sink.stb), + pack.sink.payload.eq(sink.payload), + sink.ack.eq(pack.sink.ack) + ] + + # Graph + g = DataFlowGraph() + g.add_pipeline(pack, cast, self.dma) + self.submodules += CompositeActor(g) + + # IRQ + self.submodules.ev = EventManager() + self.ev.done = EventSourcePulse() + self.ev.finalize() + self.comb += self.ev.done.trigger.eq(sink.stb & sink.eop) + + # CRC + self._crc_failed = CSRStatus() + self.sync += \ + If(sink.stb & sink.eop, + self._crc_failed.status.eq(sink.error) + ) class LiteUSBDMAReader(Module, AutoCSR): - def __init__(self, lasmim, tag): - self.source = source = Source(user_layout) - - reader = dma_lasmi.Reader(lasmim) - self.dma = spi.DMAReadController(reader, mode=spi.MODE_SINGLE_SHOT) - - pack_factor = lasmim.dw//8 - packed_dat = structuring.pack_layout(8, pack_factor) - cast = structuring.Cast(lasmim.dw, packed_dat) - unpack = structuring.Unpack(pack_factor, phy_layout, reverse=True) - - # Graph - cnt = Signal(32) - self.sync += \ - If(self.dma.generator._r_shoot.re, - cnt.eq(0) - ).Elif(source.stb & source.ack, - cnt.eq(cnt + 1) - ) - g = DataFlowGraph() - g.add_pipeline(self.dma, cast, unpack) - self.submodules += CompositeActor(g) - self.comb += [ - source.stb.eq(unpack.source.stb), - source.sop.eq(cnt == 0), - source.eop.eq(cnt == (self.dma.length*pack_factor-1)), - source.length.eq(self.dma.length*pack_factor+4), - source.d.eq(unpack.source.d), - source.dst.eq(tag), - unpack.source.ack.eq(source.ack) - ] - - # IRQ - self.submodules.ev = EventManager() - self.ev.done = EventSourcePulse() - self.ev.finalize() - self.comb += self.ev.done.trigger.eq(source.stb & source.eop) + def __init__(self, lasmim, tag): + self.source = source = Source(user_layout) + + reader = dma_lasmi.Reader(lasmim) + self.dma = spi.DMAReadController(reader, mode=spi.MODE_SINGLE_SHOT) + + pack_factor = lasmim.dw//8 + packed_dat = structuring.pack_layout(8, pack_factor) + cast = structuring.Cast(lasmim.dw, packed_dat) + unpack = structuring.Unpack(pack_factor, phy_layout, reverse=True) + + # Graph + cnt = Signal(32) + self.sync += \ + If(self.dma.generator._r_shoot.re, + cnt.eq(0) + ).Elif(source.stb & source.ack, + cnt.eq(cnt + 1) + ) + g = DataFlowGraph() + g.add_pipeline(self.dma, cast, unpack) + self.submodules += CompositeActor(g) + self.comb += [ + source.stb.eq(unpack.source.stb), + source.sop.eq(cnt == 0), + source.eop.eq(cnt == (self.dma.length*pack_factor-1)), + source.length.eq(self.dma.length*pack_factor+4), + source.d.eq(unpack.source.d), + source.dst.eq(tag), + unpack.source.ack.eq(source.ack) + ] + + # IRQ + self.submodules.ev = EventManager() + self.ev.done = EventSourcePulse() + self.ev.finalize() + self.comb += self.ev.done.trigger.eq(source.stb & source.eop) class LiteUSBDMA(Module, AutoCSR): - def __init__(self, lasmim_ftdi_dma_wr, lasmim_ftdi_dma_rd, tag): - self.tag = tag + def __init__(self, lasmim_ftdi_dma_wr, lasmim_ftdi_dma_rd, tag): + self.tag = tag - self.submodules.writer = LiteUSBDMAWriter(lasmim_ftdi_dma_wr) - self.submodules.reader = LiteUSBDMAReader(lasmim_ftdi_dma_rd, self.tag) - self.submodules.ev = SharedIRQ(self.writer.ev, self.reader.ev) + self.submodules.writer = LiteUSBDMAWriter(lasmim_ftdi_dma_wr) + self.submodules.reader = LiteUSBDMAReader(lasmim_ftdi_dma_rd, self.tag) + self.submodules.ev = SharedIRQ(self.writer.ev, self.reader.ev) - self.sink = self.writer.sink - self.source = self.reader.source + self.sink = self.writer.sink + self.source = self.reader.source diff --git a/misoclib/com/liteusb/frontend/uart.py b/misoclib/com/liteusb/frontend/uart.py index a490dbc0..ea56a6b5 100644 --- a/misoclib/com/liteusb/frontend/uart.py +++ b/misoclib/com/liteusb/frontend/uart.py @@ -6,52 +6,52 @@ from migen.genlib.fifo import SyncFIFOBuffered from misoclib.com.liteusb.common import * class LiteUSBUART(Module, AutoCSR): - def __init__(self, tag, fifo_depth=64): - self.tag = tag - - self._rxtx = CSR(8) - - self.submodules.ev = EventManager() - self.ev.tx = EventSourcePulse() - self.ev.rx = EventSourceLevel() - self.ev.finalize() - - self.source = source = Source(user_layout) - self.sink = sink = Sink(user_layout) - - ### - - # TX - tx_start = self._rxtx.re - tx_done = self.ev.tx.trigger - - self.sync += \ - If(tx_start, - source.stb.eq(1), - source.d.eq(self._rxtx.r), - ).Elif(tx_done, - source.stb.eq(0) - ) - - self.comb += [ - source.sop.eq(1), - source.eop.eq(1), - source.length.eq(1), - source.dst.eq(self.tag), - tx_done.eq(source.stb & source.ack), - ] - - # RX - rx_available = self.ev.rx.trigger - - rx_fifo = SyncFIFOBuffered(8, fifo_depth) - self.submodules += rx_fifo - self.comb += [ - rx_fifo.we.eq(sink.stb), - sink.ack.eq(sink.stb & rx_fifo.writable), - rx_fifo.din.eq(sink.d), - - rx_available.eq(rx_fifo.readable), - rx_fifo.re.eq(self.ev.rx.clear), - self._rxtx.w.eq(rx_fifo.dout) - ] + def __init__(self, tag, fifo_depth=64): + self.tag = tag + + self._rxtx = CSR(8) + + self.submodules.ev = EventManager() + self.ev.tx = EventSourcePulse() + self.ev.rx = EventSourceLevel() + self.ev.finalize() + + self.source = source = Source(user_layout) + self.sink = sink = Sink(user_layout) + + ### + + # TX + tx_start = self._rxtx.re + tx_done = self.ev.tx.trigger + + self.sync += \ + If(tx_start, + source.stb.eq(1), + source.d.eq(self._rxtx.r), + ).Elif(tx_done, + source.stb.eq(0) + ) + + self.comb += [ + source.sop.eq(1), + source.eop.eq(1), + source.length.eq(1), + source.dst.eq(self.tag), + tx_done.eq(source.stb & source.ack), + ] + + # RX + rx_available = self.ev.rx.trigger + + rx_fifo = SyncFIFOBuffered(8, fifo_depth) + self.submodules += rx_fifo + self.comb += [ + rx_fifo.we.eq(sink.stb), + sink.ack.eq(sink.stb & rx_fifo.writable), + rx_fifo.din.eq(sink.d), + + rx_available.eq(rx_fifo.readable), + rx_fifo.re.eq(self.ev.rx.clear), + self._rxtx.w.eq(rx_fifo.dout) + ] diff --git a/misoclib/com/liteusb/phy/ft2232h.py b/misoclib/com/liteusb/phy/ft2232h.py index 9ae35ba5..9f2a0d5a 100644 --- a/misoclib/com/liteusb/phy/ft2232h.py +++ b/misoclib/com/liteusb/phy/ft2232h.py @@ -6,250 +6,250 @@ from migen.fhdl.specials import * from misoclib.com.liteusb.common import * class FT2232HPHY(Module): - def __init__(self, pads, fifo_depth=32, read_time=16, write_time=16): - dw = flen(pads.data) - - # - # Read / Write Fifos - # - - # Read Fifo (Ftdi --> SoC) - read_fifo = RenameClockDomains(AsyncFIFO(phy_layout, fifo_depth), - {"write":"ftdi", "read":"sys"}) - read_buffer = RenameClockDomains(SyncFIFO(phy_layout, 4), - {"sys":"ftdi"}) - self.comb += read_buffer.source.connect(read_fifo.sink) - - # Write Fifo (SoC --> Ftdi) - write_fifo = RenameClockDomains(AsyncFIFO(phy_layout, fifo_depth), - {"write":"sys", "read":"ftdi"}) - - self.submodules += read_fifo, read_buffer, write_fifo - - # - # Sink / Source interfaces - # - self.sink = write_fifo.sink - self.source = read_fifo.source - - # - # Read / Write Arbitration - # - wants_write = Signal() - wants_read = Signal() - - txe_n = Signal() - rxf_n = Signal() - - self.comb += [ - txe_n.eq(pads.txe_n), - rxf_n.eq(pads.rxf_n), - wants_write.eq(~txe_n & write_fifo.source.stb), - wants_read.eq(~rxf_n & read_fifo.sink.ack), - ] - - def anti_starvation(timeout): - en = Signal() - max_time = Signal() - if timeout: - t = timeout - 1 - time = Signal(max=t+1) - self.comb += max_time.eq(time == 0) - self.sync += If(~en, - time.eq(t) - ).Elif(~max_time, - time.eq(time - 1) - ) - else: - self.comb += max_time.eq(0) - return en, max_time - - read_time_en, max_read_time = anti_starvation(read_time) - write_time_en, max_write_time = anti_starvation(write_time) - - data_w_accepted = Signal(reset=1) - - fsm = FSM() - self.submodules += RenameClockDomains(fsm, {"sys": "ftdi"}) - - fsm.act("READ", - read_time_en.eq(1), - If(wants_write, - If(~wants_read | max_read_time, NextState("RTW")) - ) - ) - fsm.act("RTW", - NextState("WRITE") - ) - fsm.act("WRITE", - write_time_en.eq(1), - If(wants_read, - If(~wants_write | max_write_time, NextState("WTR")) - ), - write_fifo.source.ack.eq(wants_write & data_w_accepted) - ) - fsm.act("WTR", - NextState("READ") - ) - - # - # Read / Write Actions - # - - data_w = Signal(dw) - data_r = Signal(dw) - data_oe = Signal() - - if hasattr(pads, "oe_n"): - pads_oe_n = pads.oe_n - else: - pads_oe_n = Signal() - - pads_oe_n.reset = 1 - pads.rd_n.reset = 1 - pads.wr_n.reset = 1 - - self.sync.ftdi += [ - If(fsm.ongoing("READ"), - data_oe.eq(0), - - pads_oe_n.eq(0), - pads.rd_n.eq(~wants_read), - pads.wr_n.eq(1) - - ).Elif(fsm.ongoing("WRITE"), - data_oe.eq(1), - - pads_oe_n.eq(1), - pads.rd_n.eq(1), - pads.wr_n.eq(~wants_write), - - data_w_accepted.eq(~txe_n) - - ).Else( - data_oe.eq(1), - - pads_oe_n.eq(~fsm.ongoing("WTR")), - pads.rd_n.eq(1), - pads.wr_n.eq(1) - ), - read_buffer.sink.stb.eq(~pads.rd_n & ~rxf_n), - read_buffer.sink.d.eq(data_r), - If(~txe_n & data_w_accepted, - data_w.eq(write_fifo.source.d) - ) - ] - - # - # Databus Tristate - # - self.specials += Tristate(pads.data, data_w, data_oe, data_r) - - self.debug = Signal(8) - self.comb += self.debug.eq(data_r) + def __init__(self, pads, fifo_depth=32, read_time=16, write_time=16): + dw = flen(pads.data) + + # + # Read / Write Fifos + # + + # Read Fifo (Ftdi --> SoC) + read_fifo = RenameClockDomains(AsyncFIFO(phy_layout, fifo_depth), + {"write":"ftdi", "read":"sys"}) + read_buffer = RenameClockDomains(SyncFIFO(phy_layout, 4), + {"sys":"ftdi"}) + self.comb += read_buffer.source.connect(read_fifo.sink) + + # Write Fifo (SoC --> Ftdi) + write_fifo = RenameClockDomains(AsyncFIFO(phy_layout, fifo_depth), + {"write":"sys", "read":"ftdi"}) + + self.submodules += read_fifo, read_buffer, write_fifo + + # + # Sink / Source interfaces + # + self.sink = write_fifo.sink + self.source = read_fifo.source + + # + # Read / Write Arbitration + # + wants_write = Signal() + wants_read = Signal() + + txe_n = Signal() + rxf_n = Signal() + + self.comb += [ + txe_n.eq(pads.txe_n), + rxf_n.eq(pads.rxf_n), + wants_write.eq(~txe_n & write_fifo.source.stb), + wants_read.eq(~rxf_n & read_fifo.sink.ack), + ] + + def anti_starvation(timeout): + en = Signal() + max_time = Signal() + if timeout: + t = timeout - 1 + time = Signal(max=t+1) + self.comb += max_time.eq(time == 0) + self.sync += If(~en, + time.eq(t) + ).Elif(~max_time, + time.eq(time - 1) + ) + else: + self.comb += max_time.eq(0) + return en, max_time + + read_time_en, max_read_time = anti_starvation(read_time) + write_time_en, max_write_time = anti_starvation(write_time) + + data_w_accepted = Signal(reset=1) + + fsm = FSM() + self.submodules += RenameClockDomains(fsm, {"sys": "ftdi"}) + + fsm.act("READ", + read_time_en.eq(1), + If(wants_write, + If(~wants_read | max_read_time, NextState("RTW")) + ) + ) + fsm.act("RTW", + NextState("WRITE") + ) + fsm.act("WRITE", + write_time_en.eq(1), + If(wants_read, + If(~wants_write | max_write_time, NextState("WTR")) + ), + write_fifo.source.ack.eq(wants_write & data_w_accepted) + ) + fsm.act("WTR", + NextState("READ") + ) + + # + # Read / Write Actions + # + + data_w = Signal(dw) + data_r = Signal(dw) + data_oe = Signal() + + if hasattr(pads, "oe_n"): + pads_oe_n = pads.oe_n + else: + pads_oe_n = Signal() + + pads_oe_n.reset = 1 + pads.rd_n.reset = 1 + pads.wr_n.reset = 1 + + self.sync.ftdi += [ + If(fsm.ongoing("READ"), + data_oe.eq(0), + + pads_oe_n.eq(0), + pads.rd_n.eq(~wants_read), + pads.wr_n.eq(1) + + ).Elif(fsm.ongoing("WRITE"), + data_oe.eq(1), + + pads_oe_n.eq(1), + pads.rd_n.eq(1), + pads.wr_n.eq(~wants_write), + + data_w_accepted.eq(~txe_n) + + ).Else( + data_oe.eq(1), + + pads_oe_n.eq(~fsm.ongoing("WTR")), + pads.rd_n.eq(1), + pads.wr_n.eq(1) + ), + read_buffer.sink.stb.eq(~pads.rd_n & ~rxf_n), + read_buffer.sink.d.eq(data_r), + If(~txe_n & data_w_accepted, + data_w.eq(write_fifo.source.d) + ) + ] + + # + # Databus Tristate + # + self.specials += Tristate(pads.data, data_w, data_oe, data_r) + + self.debug = Signal(8) + self.comb += self.debug.eq(data_r) # # TB # class FT2232HModel(Module, RandRun): - def __init__(self, rd_data): - RandRun.__init__(self, 50) - self.rd_data = [0] + rd_data - self.rd_idx = 0 - - # pads - self.data = Signal(8) - self.rxf_n = Signal(reset=1) - self.txe_n = Signal(reset=1) - self.rd_n = Signal(reset=1) - self.wr_n = Signal(reset=1) - self.oe_n = Signal(reset=1) - self.siwua = Signal() - self.pwren_n = Signal(reset=1) - - self.init = True - self.wr_data = [] - self.wait_wr_n = False - self.rd_done = 0 - - def wr_sim(self, selfp): - if not selfp.wr_n and not selfp.txe_n: - self.wr_data.append(selfp.data) - self.wait_wr_n = False - - if not self.wait_wr_n: - if self.run: - selfp.txe_n = 1 - else: - if selfp.txe_n: - self.wait_wr_n = True - selfp.txe_n = 0 - - def rd_sim(self, selfp): - rxf_n = selfp.rxf_n - if self.run: - if self.rd_idx < len(self.rd_data)-1: - self.rd_done = selfp.rxf_n - selfp.rxf_n = 0 - else: - selfp.rxf_n = self.rd_done - else: - selfp.rxf_n = self.rd_done - - if not selfp.rd_n and not selfp.oe_n: - if self.rd_idx < len(self.rd_data)-1: - self.rd_idx += not rxf_n - selfp.data = self.rd_data[self.rd_idx] - self.rd_done = 1 - - def do_simulation(self, selfp): - RandRun.do_simulation(self, selfp) - if self.init: - selfp.rxf_n = 0 - self.wr_data = [] - self.init = False - self.wr_sim(selfp) - self.rd_sim(selfp) + def __init__(self, rd_data): + RandRun.__init__(self, 50) + self.rd_data = [0] + rd_data + self.rd_idx = 0 + + # pads + self.data = Signal(8) + self.rxf_n = Signal(reset=1) + self.txe_n = Signal(reset=1) + self.rd_n = Signal(reset=1) + self.wr_n = Signal(reset=1) + self.oe_n = Signal(reset=1) + self.siwua = Signal() + self.pwren_n = Signal(reset=1) + + self.init = True + self.wr_data = [] + self.wait_wr_n = False + self.rd_done = 0 + + def wr_sim(self, selfp): + if not selfp.wr_n and not selfp.txe_n: + self.wr_data.append(selfp.data) + self.wait_wr_n = False + + if not self.wait_wr_n: + if self.run: + selfp.txe_n = 1 + else: + if selfp.txe_n: + self.wait_wr_n = True + selfp.txe_n = 0 + + def rd_sim(self, selfp): + rxf_n = selfp.rxf_n + if self.run: + if self.rd_idx < len(self.rd_data)-1: + self.rd_done = selfp.rxf_n + selfp.rxf_n = 0 + else: + selfp.rxf_n = self.rd_done + else: + selfp.rxf_n = self.rd_done + + if not selfp.rd_n and not selfp.oe_n: + if self.rd_idx < len(self.rd_data)-1: + self.rd_idx += not rxf_n + selfp.data = self.rd_data[self.rd_idx] + self.rd_done = 1 + + def do_simulation(self, selfp): + RandRun.do_simulation(self, selfp) + if self.init: + selfp.rxf_n = 0 + self.wr_data = [] + self.init = False + self.wr_sim(selfp) + self.rd_sim(selfp) class UserModel(Module, RandRun): - def __init__(self, wr_data): - RandRun.__init__(self, 50) - self.wr_data = wr_data - self.wr_data_idx = 0 - - self.sink = Sink(phy_layout) - self.source = Source(phy_layout) - - self.rd_data = [] - - def wr_sim(self, selfp): - auth = True - if selfp.source.stb and not selfp.source.ack: - auth = False - if auth: - if self.wr_data_idx < len(self.wr_data): - if self.run: - selfp.source.d = self.wr_data[self.wr_data_idx] - selfp.source.stb = 1 - self.wr_data_idx += 1 - else: - selfp.source.stb = 0 - else: - self.source.stb = 0 - - def rd_sim(self, selfp): - if self.run: - selfp.sink.ack = 1 - else: - selfp.sink.ack = 0 - if selfp.sink.stb & selfp.sink.ack: - self.rd_data.append(selfp.sink.d) - - def do_simulation(self, selfp): - RandRun.do_simulation(self, selfp) - self.wr_sim(selfp) - self.rd_sim(selfp) + def __init__(self, wr_data): + RandRun.__init__(self, 50) + self.wr_data = wr_data + self.wr_data_idx = 0 + + self.sink = Sink(phy_layout) + self.source = Source(phy_layout) + + self.rd_data = [] + + def wr_sim(self, selfp): + auth = True + if selfp.source.stb and not selfp.source.ack: + auth = False + if auth: + if self.wr_data_idx < len(self.wr_data): + if self.run: + selfp.source.d = self.wr_data[self.wr_data_idx] + selfp.source.stb = 1 + self.wr_data_idx += 1 + else: + selfp.source.stb = 0 + else: + self.source.stb = 0 + + def rd_sim(self, selfp): + if self.run: + selfp.sink.ack = 1 + else: + selfp.sink.ack = 0 + if selfp.sink.stb & selfp.sink.ack: + self.rd_data.append(selfp.sink.d) + + def do_simulation(self, selfp): + RandRun.do_simulation(self, selfp) + self.wr_sim(selfp) + self.rd_sim(selfp) LENGTH = 512 @@ -257,56 +257,56 @@ model_rd_data = [i%256 for i in range(LENGTH)][::-1] user_wr_data = [i%256 for i in range(LENGTH)] class TB(Module): - def __init__(self): - self.submodules.model = FT2232HModel(model_rd_data) - self.submodules.phy = FT2232HPHY(self.model) + def __init__(self): + self.submodules.model = FT2232HModel(model_rd_data) + self.submodules.phy = FT2232HPHY(self.model) - self.submodules.user = UserModel(user_wr_data) + self.submodules.user = UserModel(user_wr_data) - self.comb += [ - self.user.source.connect(self.phy.sink), - self.phy.source.connect(self.user.sink) - ] + self.comb += [ + self.user.source.connect(self.phy.sink), + self.phy.source.connect(self.user.sink) + ] - # Use sys_clk as ftdi_clk in simulation - self.comb += [ - ClockSignal("ftdi").eq(ClockSignal()), - ResetSignal("ftdi").eq(ResetSignal()) - ] + # Use sys_clk as ftdi_clk in simulation + self.comb += [ + ClockSignal("ftdi").eq(ClockSignal()), + ResetSignal("ftdi").eq(ResetSignal()) + ] def print_results(s, l1, l2): - def comp(l1, l2): - r = True - try: - for i, val in enumerate(l1): - if val != l2[i]: - print(s + " : val : %02X, exp : %02X" %(val, l2[i])) - r = False - except: - return r - return r - - c = comp(l1, l2) - r = s + " " - if c: - r += "[OK]" - else: - r += "[KO]" - print(r) + def comp(l1, l2): + r = True + try: + for i, val in enumerate(l1): + if val != l2[i]: + print(s + " : val : %02X, exp : %02X" %(val, l2[i])) + r = False + except: + return r + return r + + c = comp(l1, l2) + r = s + " " + if c: + r += "[OK]" + else: + r += "[KO]" + print(r) def main(): - from migen.sim.generic import run_simulation - tb = TB() - run_simulation(tb, ncycles=8000, vcd_name="tb_phy.vcd") + from migen.sim.generic import run_simulation + tb = TB() + run_simulation(tb, ncycles=8000, vcd_name="tb_phy.vcd") - ### - #print(tb.user.rd_data) - #print(tb.model.wr_data) - #print(len(tb.user.rd_data)) - #print(len(tb.model.wr_data)) + ### + #print(tb.user.rd_data) + #print(tb.model.wr_data) + #print(len(tb.user.rd_data)) + #print(len(tb.model.wr_data)) - print_results("F2232HModel --> UserModel", model_rd_data, tb.user.rd_data) - print_results("UserModel --> FT2232HModel", user_wr_data, tb.model.wr_data) + print_results("F2232HModel --> UserModel", model_rd_data, tb.user.rd_data) + print_results("UserModel --> FT2232HModel", user_wr_data, tb.model.wr_data) if __name__ == "__main__": - main() + main() -- 2.30.2