diff --git a/artiq/gateware/rtio/phy/phaser.py b/artiq/gateware/rtio/phy/phaser.py index bb299ab0c..038f8b2c5 100644 --- a/artiq/gateware/rtio/phy/phaser.py +++ b/artiq/gateware/rtio/phy/phaser.py @@ -1,5 +1,6 @@ from migen import * from misoc.cores.duc import MultiDDS +from misoc.interconnect.stream import Endpoint from artiq.gateware.rtio import rtlink from .fastlink import SerDes, SerInterface @@ -87,3 +88,83 @@ class Phaser(Module): self.rtlink.i.stb.eq(re_dly[0] & self.serializer.stb), self.rtlink.i.data.eq(self.serializer.readback), ] + + +class MiqroChannel(Module): + def __init__(self, regs): + self.rtlink = rtlink.Interface( + rtlink.OInterface(data_width=30, address_width=2, fine_ts_width=1, + enable_replace=False)) + self.pulse = Signal(128) + self.ack = Signal() + regs = [Signal(30, reset_less=True) for _ in range(3)] + dt = Signal(7, reset_less=True) + stb = Signal() + self.comb += self.pulase.payload.data.eq(Cat(stb, dt, regs)) + self.sync.rtio += [ + dt.eq(dt + 2), + If(self.ack, + dt.eq(0), + stb.eq(0), + ), + If(self.rtlink.o.stb, + Array(regs)[self.rtlink.o.address].eq(self.rtlink.o.data), + If(self.rtlink.o.address == 0, + dt[0].eq(self.rtlink.o.fine_ts), + stb.eq(1), + ), + ), + ] + + +class Miqro(Module): + def __init__(self, pins, pins_n): + self.rtlink = rtlink.Interface( + rtlink.OInterface(data_width=8, address_width=8, + enable_replace=False), + rtlink.IInterface(data_width=10)) + + self.submodules.ch0 = MiqroChannel() + self.submodules.ch1 = MiqroChannel() + + self.submodules.serializer = SerDes( + n_data=8, t_clk=8, d_clk=0b00001111, + n_frame=10, n_crc=6, poly=0x2f) + self.submodules.intf = SerInterface(pins, pins_n) + self.comb += [ + Cat(self.intf.data[:-1]).eq(Cat(self.serializer.data[:-1])), + self.serializer.data[-1].eq(self.intf.data[-1]), + ] + + header = Record([ + ("we", 1), + ("addr", 7), + ("data", 8), + ("type", 4) + ]) + self.comb += [ + self.serializer.payload.eq(Cat( + header.raw_bits(), + self.ch0.pulse.payload, + self.ch1.pulse.payload, + )), + self.ch0.ack.eq(self.serializer.stb), + self.ch1.ack.eq(self.serializer.stb), + ] + + re_dly = Signal(3) # stage, send, respond + self.sync.rtio += [ + header.type.eq(1), # body type is miqro pulse data + If(self.serializer.stb, + header.we.eq(0), + re_dly.eq(re_dly[1:]), + ), + If(self.rtlink.o.stb, + re_dly[-1].eq(~self.rtlink.o.address[-1]), + header.we.eq(self.rtlink.o.address[-1]), + header.addr.eq(self.rtlink.o.address), + header.data.eq(self.rtlink.o.data), + ), + self.rtlink.i.stb.eq(re_dly[0] & self.serializer.stb), + self.rtlink.i.data.eq(self.serializer.readback), + ]