[[Glasgow Notes]] ## Using in-fifo/out-fifo to stream data to/from Glasgow ### Build The in-fifo is requested using `iface.get_in_fifo()` Its class is: `glasgow.access.direct.multiplexer._FIFOWritePort` (see [[glasgow Multiplexer]]) Options: - `auto_flush`. Default = True. We found that using `auto_flush = False` better optimized our usage of USB bandwidth because partial USB packets were not transmitted. The out-fifo is requested using `iface.get_out_fifo()` ```python def build(self, target, args): self.mux_interface = iface = target.multiplexer.claim_interface(self, args) iface.add_subtarget(Subtarget( pads=iface.get_pads(args, pins=self.__pins), in_fifo=iface.get_in_fifo(), out_fifo=iface.get_out_fifo(), )) ``` ### Amaranth The Amaranth `Elaboratable` is initialized with `self.in_fifo = in_fifo` and `self.out_fifo = out_fifo`. To write data to the in_fifo (from Glasgow to PC): - `w_rdy` must be True if anything is to be written - `w_data` is set to the value or signal to write - `w_en` is set True to allow the write Example: ```python with m.If(self.in_fifo.w_rdy): m.d.comb += [ self.in_fifo.w_data.eq(data), self.in_fifo.w_en.eq(1), ] ``` To read data from the out_fifo (from PC to Glasgow): - `r_en` must be set True - `r_rdy` must be True if anything is to be written - `r_data` is the value read from the out-fifo Example: ```python m.d.comb += [self.out_fifo.r_en.eq(1)] with m.If(self.out_fifo.r_rdy): m.d.sync += [ data.eq(self.out_fifo.r_data), ] ``` ### Run/Interact To read the data continuously when the applet runs: ```python async def run(self, device, args): iface = await device.demultiplexer.claim_interface(self, self.mux_interface, args) while True: raw_data = await iface.read() data = raw_data.tolist() print(data) ``` The raw data is a [memview](https://docs.python.org/3/library/stdtypes.html#memoryview) To write data while the applet runs: ```python await iface.write(data) ``` `data` can be a single value or a list of values, it will be converted to bytes ### iface.read Options: - flush: default = True. If True, run `iface.flush()` as the first step of `iface.read()` ### iface.flush Options: - wait: default = False. If False, `iface.flush()` will not block other tasks