noptica-rs/glasgow-applet.diff

136 lines
4.7 KiB
Diff
Raw Permalink Normal View History

2019-11-21 11:03:28 +08:00
Written by whitequark, 2019.
2019-10-09 23:44:19 +08:00
diff --git a/software/glasgow/access/direct/demultiplexer.py b/software/glasgow/access/direct/demultiplexer.py
2019-10-10 00:14:35 +08:00
index 3df8c2e..068b40e 100644
2019-10-09 23:44:19 +08:00
--- a/software/glasgow/access/direct/demultiplexer.py
+++ b/software/glasgow/access/direct/demultiplexer.py
2019-10-10 00:14:35 +08:00
@@ -30,7 +30,7 @@ from .. import AccessDemultiplexer, AccessDemultiplexerInterface
#
# To deal with this, use requests of at most 1024 EP buffer sizes (512 KiB with the FX2) as
# an arbitrary cutoff, and hope for the best.
-_max_packets_per_ep = 1024
+_max_packets_per_ep = 2048
# USB has the limitation that all transactions are host-initiated. Therefore, if we do not queue
# reads for the IN endpoints quickly enough, the HC will not even poll the device, and the buffer
2019-10-09 23:44:19 +08:00
@@ -52,7 +52,7 @@ _max_packets_per_ep = 1024
# To try and balance these effects, we choose a medium buffer size that should work well with most
# applications. It's possible that this will need to become customizable later, but for now
# a single fixed value works.
-_packets_per_xfer = 32
2019-10-10 00:14:35 +08:00
+_packets_per_xfer = 512
2019-10-09 23:44:19 +08:00
# Queue as many transfers as we can, but no more than 10, as the returns beyond that point
# are diminishing.
diff --git a/software/glasgow/applet/all.py b/software/glasgow/applet/all.py
2019-10-08 20:08:25 +08:00
index 35b8960..3f37b9f 100644
--- a/software/glasgow/applet/all.py
+++ b/software/glasgow/applet/all.py
2019-10-08 20:08:25 +08:00
@@ -44,3 +44,5 @@ from .video.rgb_input import VideoRGBInputApplet
from .video.vga_output import VGAOutputApplet
from .video.vga_terminal import VGATerminalApplet
from .video.ws2812_output import VideoWS2812OutputApplet
+
+from .logic import LogicApplet
diff --git a/software/glasgow/applet/logic.py b/software/glasgow/applet/logic.py
new file mode 100644
2019-10-24 16:05:49 +08:00
index 0000000..483e99e
--- /dev/null
+++ b/software/glasgow/applet/logic.py
2019-10-24 16:05:49 +08:00
@@ -0,0 +1,95 @@
+import sys
+import logging
+import os
+import asyncio
+from nmigen.compat import *
2019-10-08 20:08:25 +08:00
+from nmigen.compat.genlib.cdc import MultiReg
+
+from . import *
+
+
+class LogicSubtarget(Module):
+ def __init__(self, pads, in_fifo):
2019-10-08 20:08:25 +08:00
+ input = Signal.like(pads.d_t.i)
+ latch = Signal.like(pads.d_t.i)
+ self.submodules += MultiReg(pads.d_t.i, input)
+
+ self.comb += [
2019-10-08 20:08:25 +08:00
+ in_fifo.din[0:4].eq(input[0:4]),
+ in_fifo.din[4:8].eq(latch[0:4]),
+ ]
+
+ self.submodules.fsm = FSM()
+ self.fsm.act("CAPTURE-1",
2019-10-08 20:08:25 +08:00
+ NextValue(latch, input),
+ NextState("CAPTURE-2")
+ )
+ self.fsm.act("CAPTURE-2",
+ in_fifo.we.eq(1),
2019-10-08 20:08:25 +08:00
+ If(in_fifo.writable,
+ NextState("CAPTURE-1")
+ ).Else(
+ NextState("OVERFLOW")
+ )
+ )
+ self.fsm.act("OVERFLOW",
+ NextState("OVERFLOW")
+ )
+
+
+async def async_stdout(limit=asyncio.streams._DEFAULT_LIMIT, loop=None):
+ if loop is None:
+ loop = asyncio.get_event_loop()
+
+ writer_transport, writer_protocol = await loop.connect_write_pipe(
+ lambda: asyncio.streams.FlowControlMixin(loop=loop),
+ os.fdopen(sys.stdout.fileno(), "wb"))
+ writer = asyncio.streams.StreamWriter(
+ writer_transport, writer_protocol, None, loop)
+
+ return writer
+
+
+class LogicApplet(GlasgowApplet, name="logic"):
+ logger = logging.getLogger(__name__)
+ preview = True
+
+ @classmethod
+ def add_build_arguments(cls, parser, access):
+ super().add_build_arguments(parser, access)
+
+ access.add_pin_set_argument(parser, "d", required=True, width=range(5))
+
+ def build(self, target, args):
+ self.mux_interface = iface = target.multiplexer.claim_interface(self, args)
+ iface.add_subtarget(LogicSubtarget(
+ pads=iface.get_pads(args, pin_sets=("d",)),
2019-10-10 00:14:35 +08:00
+ in_fifo=iface.get_in_fifo(auto_flush=False, depth=16384),
+ ))
+
+ @classmethod
+ def add_run_arguments(cls, parser, access):
+ super().add_run_arguments(parser, access)
+
+ async def run(self, device, args):
+ return await device.demultiplexer.claim_interface(self, self.mux_interface, args)
+
+ @classmethod
+ def add_interact_arguments(cls, parser):
+ pass
+
+ async def interact(self, device, args, iface):
+ output_stream = await async_stdout()
+ while True:
+ data = await iface.read(65536)
+ output_stream.write(data)
+ if output_stream.is_closing():
2019-10-24 16:05:49 +08:00
+ print("glasgow: stdout closed, terminating", file=sys.stderr)
+ return
+
2019-10-08 20:08:25 +08:00
+# ------------------------------------------------------------------------------------------------
+
+class LogicAppletTestCase(GlasgowAppletTestCase, applet=LogicApplet):
+ @synthesis_test
+ def test_build(self):
+ self.assertBuilds()