-
Notifications
You must be signed in to change notification settings - Fork 201
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into new-py2llvm
Showing
24 changed files
with
857 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
from migen.fhdl.std import * | ||
|
||
from artiq.gateware.rtio.phy import ttl_serdes_generic | ||
|
||
|
||
class _OSERDESE2_8X(Module): | ||
def __init__(self, pad): | ||
self.o = Signal(8) | ||
self.t_in = Signal() | ||
self.t_out = Signal() | ||
|
||
# # # | ||
|
||
o = self.o | ||
self.specials += Instance("OSERDESE2", | ||
p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF", | ||
p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1, | ||
o_OQ=pad, o_TQ=self.t_out, | ||
i_CLK=ClockSignal("rtiox4"), | ||
i_CLKDIV=ClockSignal("rio_phy"), | ||
i_D1=o[0], i_D2=o[1], i_D3=o[2], i_D4=o[3], | ||
i_D5=o[4], i_D6=o[5], i_D7=o[6], i_D8=o[7], | ||
i_TCE=1, i_OCE=1, i_RST=0, | ||
i_T1=self.t_in) | ||
|
||
|
||
class _IOSERDESE2_8X(Module): | ||
def __init__(self, pad): | ||
self.o = Signal(8) | ||
self.i = Signal(8) | ||
self.oe = Signal() | ||
|
||
# # # | ||
|
||
pad_i = Signal() | ||
pad_o = Signal() | ||
i = self.i | ||
self.specials += Instance("ISERDESE2", p_DATA_RATE="DDR", | ||
p_DATA_WIDTH=8, | ||
p_INTERFACE_TYPE="NETWORKING", p_NUM_CE=1, | ||
o_Q1=i[7], o_Q2=i[6], o_Q3=i[5], o_Q4=i[4], | ||
o_Q5=i[3], o_Q6=i[2], o_Q7=i[1], o_Q8=i[0], | ||
i_D=pad_i, | ||
i_CLK=ClockSignal("rtiox4"), | ||
i_CLKB=~ClockSignal("rtiox4"), | ||
i_CE1=1, i_RST=0, | ||
i_CLKDIV=ClockSignal("rio_phy")) | ||
oserdes = _OSERDESE2_8X(pad_o) | ||
self.submodules += oserdes | ||
self.specials += Instance("IOBUF", | ||
i_I=pad_o, o_O=pad_i, i_T=oserdes.t_out, | ||
io_IO=pad) | ||
self.comb += [ | ||
oserdes.t_in.eq(~self.oe), | ||
oserdes.o.eq(self.o) | ||
] | ||
|
||
|
||
class Output_8X(ttl_serdes_generic.Output): | ||
def __init__(self, pad): | ||
serdes = _OSERDESE2_8X(pad) | ||
self.submodules += serdes | ||
ttl_serdes_generic.Output.__init__(self, serdes) | ||
|
||
|
||
class Inout_8X(ttl_serdes_generic.Inout): | ||
def __init__(self, pad): | ||
serdes = _IOSERDESE2_8X(pad) | ||
self.submodules += serdes | ||
ttl_serdes_generic.Inout.__init__(self, serdes) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,273 @@ | ||
from migen.fhdl.std import * | ||
from migen.genlib.coding import PriorityEncoder | ||
|
||
from artiq.gateware.rtio import rtlink | ||
|
||
|
||
def _mk_edges(w, direction): | ||
l = [(1 << i) - 1 for i in range(w)] | ||
if direction == "rising": | ||
l = [2**w - 1 ^ x for x in l] | ||
elif direction == "falling": | ||
pass | ||
else: | ||
raise ValueError | ||
return l | ||
|
||
|
||
class _SerdesDriver(Module): | ||
def __init__(self, serdes_o, stb, data, fine_ts, override_en, override_o): | ||
previous_data = Signal() | ||
serdes_width = flen(serdes_o) | ||
edges = Array(_mk_edges(serdes_width, "rising")) | ||
edges_n = Array(_mk_edges(serdes_width, "falling")) | ||
self.sync.rio_phy += [ | ||
If(stb, previous_data.eq(data)), | ||
If(override_en, | ||
serdes_o.eq(Replicate(override_o, serdes_width)) | ||
).Else( | ||
If(stb & ~previous_data & data, | ||
serdes_o.eq(edges[fine_ts]), | ||
).Elif(stb & previous_data & ~data, | ||
serdes_o.eq(edges_n[fine_ts]), | ||
).Else( | ||
serdes_o.eq(Replicate(previous_data, serdes_width)), | ||
) | ||
) | ||
] | ||
|
||
|
||
class Output(Module): | ||
def __init__(self, serdes): | ||
self.rtlink = rtlink.Interface( | ||
rtlink.OInterface(1, fine_ts_width=log2_int(flen(serdes.o)))) | ||
self.probes = [serdes.o[-1]] | ||
override_en = Signal() | ||
override_o = Signal() | ||
self.overrides = [override_en, override_o] | ||
|
||
# # # | ||
|
||
self.submodules += _SerdesDriver( | ||
serdes.o, | ||
self.rtlink.o.stb, self.rtlink.o.data, self.rtlink.o.fine_ts, | ||
override_en, override_o) | ||
|
||
|
||
class Inout(Module): | ||
def __init__(self, serdes): | ||
serdes_width = flen(serdes.o) | ||
assert flen(serdes.i) == serdes_width | ||
self.rtlink = rtlink.Interface( | ||
rtlink.OInterface(2, 2, fine_ts_width=log2_int(serdes_width)), | ||
rtlink.IInterface(1, fine_ts_width=log2_int(serdes_width))) | ||
self.probes = [serdes.i[-1], serdes.oe] | ||
override_en = Signal() | ||
override_o = Signal() | ||
override_oe = Signal() | ||
self.overrides = [override_en, override_o, override_oe] | ||
|
||
# # # | ||
|
||
# Output | ||
self.submodules += _SerdesDriver( | ||
serdes_o=serdes.o, | ||
stb=self.rtlink.o.stb & (self.rtlink.o.address == 0), | ||
data=self.rtlink.o.data[0], | ||
fine_ts=self.rtlink.o.fine_ts, | ||
override_en=override_en, override_o=override_o) | ||
|
||
oe_k = Signal() | ||
self.sync.rio_phy += [ | ||
If(self.rtlink.o.stb & (self.rtlink.o.address == 1), | ||
oe_k.eq(self.rtlink.o.data[0])), | ||
If(override_en, | ||
serdes.oe.eq(override_oe) | ||
).Else( | ||
serdes.oe.eq(oe_k) | ||
) | ||
] | ||
|
||
# Input | ||
sensitivity = Signal(2) | ||
self.sync.rio += If(self.rtlink.o.stb & (self.rtlink.o.address == 2), | ||
sensitivity.eq(self.rtlink.o.data)) | ||
|
||
i = serdes.i[-1] | ||
i_d = Signal() | ||
self.sync.rio_phy += [ | ||
i_d.eq(i), | ||
self.rtlink.i.stb.eq( | ||
(sensitivity[0] & ( i & ~i_d)) | | ||
(sensitivity[1] & (~i & i_d)) | ||
), | ||
self.rtlink.i.data.eq(i), | ||
] | ||
|
||
pe = PriorityEncoder(serdes_width) | ||
self.submodules += pe | ||
self.comb += pe.i.eq(serdes.i ^ Replicate(i_d, serdes_width)) | ||
self.sync.rio_phy += self.rtlink.i.fine_ts.eq(pe.o) | ||
|
||
|
||
class _FakeSerdes(Module): | ||
def __init__(self): | ||
self.o = Signal(8) | ||
self.i = Signal(8) | ||
self.oe = Signal() | ||
|
||
|
||
class _OutputTB(Module): | ||
def __init__(self): | ||
serdes = _FakeSerdes() | ||
self.submodules.dut = RenameClockDomains(Output(serdes), | ||
{"rio_phy": "sys"}) | ||
|
||
def gen_simulation(self, selfp): | ||
selfp.dut.rtlink.o.data = 1 | ||
selfp.dut.rtlink.o.fine_ts = 1 | ||
selfp.dut.rtlink.o.stb = 1 | ||
yield | ||
selfp.dut.rtlink.o.stb = 0 | ||
yield | ||
selfp.dut.rtlink.o.data = 0 | ||
selfp.dut.rtlink.o.fine_ts = 2 | ||
selfp.dut.rtlink.o.stb = 1 | ||
yield | ||
yield | ||
selfp.dut.rtlink.o.data = 1 | ||
selfp.dut.rtlink.o.fine_ts = 7 | ||
selfp.dut.rtlink.o.stb = 1 | ||
for _ in range(6): | ||
# note that stb stays active; output should not change | ||
yield | ||
|
||
|
||
class _InoutTB(Module): | ||
def __init__(self): | ||
self.serdes = _FakeSerdes() | ||
self.submodules.dut = RenameClockDomains(Inout(self.serdes), | ||
{"rio_phy": "sys", | ||
"rio": "sys"}) | ||
|
||
def check_input(self, selfp, stb, fine_ts=None): | ||
if stb != selfp.dut.rtlink.i.stb: | ||
print("KO rtlink.i.stb should be {} but is {}" | ||
.format(stb, selfp.dut.rtlink.i.stb)) | ||
elif fine_ts is not None and fine_ts != selfp.dut.rtlink.i.fine_ts: | ||
print("KO rtlink.i.fine_ts should be {} but is {}" | ||
.format(fine_ts, selfp.dut.rtlink.i.fine_ts)) | ||
else: | ||
print("OK") | ||
|
||
def check_output(self, selfp, data): | ||
if selfp.serdes.o != data: | ||
print("KO io.o should be {} but is {}".format(data, selfp.serdes.o)) | ||
else: | ||
print("OK") | ||
|
||
def check_output_enable(self, selfp, oe): | ||
if selfp.serdes.oe != oe: | ||
print("KO io.oe should be {} but is {}".format(oe, selfp.serdes.oe)) | ||
else: | ||
print("OK") | ||
|
||
def gen_simulation(self, selfp): | ||
selfp.dut.rtlink.o.address = 2 | ||
selfp.dut.rtlink.o.data = 0b11 | ||
selfp.dut.rtlink.o.stb = 1 # set sensitivity to rising + falling | ||
yield | ||
selfp.dut.rtlink.o.stb = 0 | ||
|
||
self.check_output_enable(selfp, 0) | ||
yield | ||
|
||
selfp.serdes.i = 0b11111110 # rising edge at fine_ts = 1 | ||
yield | ||
selfp.serdes.i = 0b11111111 | ||
yield | ||
self.check_input(selfp, stb=1, fine_ts=1) | ||
|
||
selfp.serdes.i = 0b01111111 # falling edge at fine_ts = 7 | ||
yield | ||
selfp.serdes.i = 0b00000000 | ||
yield | ||
self.check_input(selfp, stb=1, fine_ts=7) | ||
|
||
selfp.serdes.i = 0b11000000 # rising edge at fine_ts = 6 | ||
yield | ||
selfp.serdes.i = 0b11111111 | ||
yield | ||
self.check_input(selfp, stb=1, fine_ts=6) | ||
|
||
selfp.dut.rtlink.o.address = 2 | ||
selfp.dut.rtlink.o.data = 0b11 | ||
selfp.dut.rtlink.o.stb = 1 # set sensitivity to rising only | ||
yield | ||
selfp.dut.rtlink.o.stb = 0 | ||
yield | ||
|
||
selfp.serdes.i = 0b00001111 # falling edge at fine_ts = 4 | ||
yield | ||
self.check_input(selfp, stb=0) # no strobe, sensitivity is rising edge | ||
|
||
selfp.serdes.i = 0b11110000 # rising edge at fine_ts = 4 | ||
yield | ||
self.check_input(selfp, stb=1, fine_ts=4) | ||
|
||
selfp.dut.rtlink.o.address = 1 | ||
selfp.dut.rtlink.o.data = 1 | ||
selfp.dut.rtlink.o.stb = 1 # set Output Enable to 1 | ||
yield | ||
selfp.dut.rtlink.o.stb = 0 | ||
yield | ||
yield | ||
self.check_output_enable(selfp, 1) | ||
|
||
selfp.dut.rtlink.o.address = 0 | ||
selfp.dut.rtlink.o.data = 1 | ||
selfp.dut.rtlink.o.fine_ts = 3 | ||
selfp.dut.rtlink.o.stb = 1 # rising edge at fine_ts = 3 | ||
yield | ||
selfp.dut.rtlink.o.stb = 0 | ||
yield | ||
self.check_output(selfp, data=0b11111000) | ||
|
||
yield | ||
self.check_output(selfp, data=0xFF) # stays at 1 | ||
|
||
selfp.dut.rtlink.o.data = 0 | ||
selfp.dut.rtlink.o.fine_ts = 0 | ||
selfp.dut.rtlink.o.stb = 1 # falling edge at fine_ts = 0 | ||
yield | ||
selfp.dut.rtlink.o.stb = 0 | ||
yield | ||
self.check_output(selfp, data=0) | ||
|
||
yield | ||
self.check_output(selfp, data=0) | ||
|
||
selfp.dut.rtlink.o.data = 1 | ||
selfp.dut.rtlink.o.fine_ts = 7 | ||
selfp.dut.rtlink.o.stb = 1 # rising edge at fine_ts = 7 | ||
yield | ||
selfp.dut.rtlink.o.stb = 0 | ||
yield | ||
self.check_output(selfp, data=0b10000000) | ||
|
||
|
||
if __name__ == "__main__": | ||
import sys | ||
from migen.sim.generic import Simulator, TopLevel | ||
|
||
if len(sys.argv) != 2: | ||
print("Incorrect command line") | ||
sys.exit(1) | ||
|
||
cls = { | ||
"output": _OutputTB, | ||
"inout": _InoutTB | ||
}[sys.argv[1]] | ||
|
||
with Simulator(cls(), TopLevel("top.vcd", clk_period=int(1/0.125))) as s: | ||
s.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
from migen.fhdl.std import * | ||
|
||
from artiq.gateware.rtio.phy import ttl_serdes_generic | ||
|
||
|
||
class _OSERDES2_8X(Module): | ||
def __init__(self, pad, stb): | ||
self.o = Signal(8) | ||
self.t_in = Signal() | ||
self.t_out = Signal() | ||
|
||
# # # | ||
|
||
cascade = Signal(4) | ||
o = self.o | ||
common = dict(p_DATA_RATE_OQ="SDR", p_DATA_RATE_OT="SDR", | ||
p_DATA_WIDTH=8, p_OUTPUT_MODE="SINGLE_ENDED", i_TRAIN=0, | ||
i_CLK0=ClockSignal("rtiox8"), i_CLK1=0, | ||
i_CLKDIV=ClockSignal("rio_phy"), | ||
i_IOCE=stb, i_OCE=1, i_TCE=1, i_RST=0, | ||
i_T4=self.t_in, i_T3=self.t_in, | ||
i_T2=self.t_in, i_T1=self.t_in) | ||
|
||
self.specials += [ | ||
Instance("OSERDES2", p_SERDES_MODE="MASTER", | ||
i_D4=o[7], i_D3=o[6], i_D2=o[5], i_D1=o[4], | ||
i_SHIFTIN1=1, i_SHIFTIN2=1, | ||
i_SHIFTIN3=cascade[2], i_SHIFTIN4=cascade[3], | ||
o_SHIFTOUT1=cascade[0], o_SHIFTOUT2=cascade[1], | ||
o_OQ=pad, o_TQ=self.t_out, **common), | ||
Instance("OSERDES2", p_SERDES_MODE="SLAVE", | ||
i_D4=o[3], i_D3=o[2], i_D2=o[1], i_D1=o[0], | ||
i_SHIFTIN1=cascade[0], i_SHIFTIN2=cascade[1], | ||
i_SHIFTIN3=1, i_SHIFTIN4=1, | ||
o_SHIFTOUT3=cascade[2], o_SHIFTOUT4=cascade[3], | ||
**common), | ||
] | ||
|
||
|
||
class _IOSERDES2_8X(Module): | ||
def __init__(self, pad, stb): | ||
self.o = Signal(8) | ||
self.i = Signal(8) | ||
self.oe = Signal() | ||
|
||
# # # | ||
|
||
pad_i = Signal() | ||
pad_o = Signal() | ||
cascade = Signal() | ||
i = self.i | ||
common = dict(p_BITSLIP_ENABLE="FALSE", p_DATA_RATE="SDR", | ||
p_DATA_WIDTH=8, p_INTERFACE_TYPE="RETIMED", | ||
i_BITSLIP=0, i_CE0=1, i_IOCE=stb, | ||
i_RST=0, i_CLK0=ClockSignal("rtiox8"), i_CLK1=0, | ||
i_CLKDIV=ClockSignal("rio_phy")) | ||
self.specials += [ | ||
Instance("ISERDES2", p_SERDES_MODE="MASTER", | ||
o_Q4=i[7], o_Q3=i[6], o_Q2=i[5], o_Q1=i[4], | ||
o_SHIFTOUT=cascade, i_D=pad_i, i_SHIFTIN=0, | ||
**common), | ||
Instance("ISERDES2", p_SERDES_MODE="SLAVE", | ||
o_Q4=i[3], o_Q3=i[2], o_Q2=i[1], o_Q1=i[0], | ||
i_D=0, i_SHIFTIN=cascade, **common), | ||
] | ||
|
||
oserdes = _OSERDES2_8X(pad_o, stb) | ||
self.submodules += oserdes | ||
self.specials += Instance("IOBUF", | ||
i_I=pad_o, o_O=pad_i, i_T=oserdes.t_out, | ||
io_IO=pad) | ||
self.comb += [ | ||
oserdes.t_in.eq(~self.oe), | ||
oserdes.o.eq(self.o), | ||
] | ||
|
||
|
||
class Output_8X(ttl_serdes_generic.Output): | ||
def __init__(self, pad, stb): | ||
serdes = _OSERDES2_8X(pad, stb) | ||
self.submodules += serdes | ||
ttl_serdes_generic.Output.__init__(self, serdes) | ||
|
||
|
||
class Inout_8X(ttl_serdes_generic.Inout): | ||
def __init__(self, pad, stb): | ||
serdes = _IOSERDES2_8X(pad, stb) | ||
self.submodules += serdes | ||
ttl_serdes_generic.Inout.__init__(self, serdes) | ||
|
||
|
||
class _OSERDES2_4X(Module): | ||
def __init__(self, pad, stb): | ||
self.o = Signal(4) | ||
self.t_in = Signal() | ||
self.t_out = Signal() | ||
|
||
# # # | ||
|
||
o = self.o | ||
self.specials += Instance("OSERDES2", p_SERDES_MODE="NONE", | ||
p_DATA_RATE_OQ="SDR", p_DATA_RATE_OT="SDR", | ||
p_DATA_WIDTH=4, p_OUTPUT_MODE="SINGLE_ENDED", | ||
i_TRAIN=0, i_CLK0=ClockSignal("rtiox4"), | ||
i_CLK1=0, i_CLKDIV=ClockSignal("rio_phy"), | ||
i_IOCE=stb, i_OCE=1, i_TCE=1, i_RST=0, | ||
i_T4=self.t_in, i_T3=self.t_in, | ||
i_T2=self.t_in, i_T1=self.t_in, | ||
i_D4=o[3], i_D3=o[2], i_D2=o[1], i_D1=o[0], | ||
o_OQ=pad, o_TQ=self.t_out) | ||
|
||
|
||
class _IOSERDES2_4X(Module): | ||
def __init__(self, pad, stb): | ||
self.o = Signal(4) | ||
self.i = Signal(4) | ||
self.oe = Signal() | ||
|
||
# # # | ||
|
||
pad_i = Signal() | ||
pad_o = Signal() | ||
i = self.i | ||
self.specials += Instance("ISERDES2", p_SERDES_MODE="NONE", | ||
p_BITSLIP_ENABLE="FALSE", p_DATA_RATE="SDR", | ||
p_DATA_WIDTH=4, p_INTERFACE_TYPE="RETIMED", | ||
i_BITSLIP=0, i_CE0=1, i_IOCE=stb, | ||
i_RST=0, i_CLK0=ClockSignal("rtiox4"), | ||
i_CLK1=0, i_CLKDIV=ClockSignal("rio_phy"), | ||
o_Q4=i[3], o_Q3=i[2], o_Q2=i[1], o_Q1=i[0], | ||
i_D=pad_i, i_SHIFTIN=0) | ||
oserdes = _OSERDES2_4X(pad_o, stb) | ||
self.submodules += oserdes | ||
self.specials += Instance("IOBUF", | ||
i_I=pad_o, o_O=pad_i, i_T=oserdes.t_out, | ||
io_IO=pad) | ||
self.comb += [ | ||
oserdes.t_in.eq(~self.oe), | ||
oserdes.o.eq(self.o), | ||
] | ||
|
||
|
||
class Output_4X(ttl_serdes_generic.Output): | ||
def __init__(self, pad, stb): | ||
serdes = _OSERDES2_4X(pad, stb) | ||
self.submodules += serdes | ||
ttl_serdes_generic.Output.__init__(self, serdes) | ||
|
||
|
||
class Inout_4X(ttl_serdes_generic.Inout): | ||
def __init__(self, pad, stb): | ||
serdes = _IOSERDES2_4X(pad, stb) | ||
self.submodules += serdes | ||
ttl_serdes_generic.Inout.__init__(self, serdes) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
from artiq import * | ||
|
||
|
||
class PulseNotReceivedError(Exception): | ||
pass | ||
|
||
|
||
class TDR(EnvExperiment): | ||
"""Time domain reflectometer. | ||
From ttl2 an impedance matched pulse is send onto a coax | ||
cable with an open end. pmt0 (very short stub, high impedance) also | ||
listens on the transmission line near ttl2. | ||
When the forward propagating pulse passes pmt0, the voltage is half of the | ||
logic voltage and does not register as a rising edge. Once the | ||
rising edge is reflected at an open end (same sign) and passes by pmt0 on | ||
its way back to ttl2, it is detected. Analogously, hysteresis leads to | ||
detection of the falling edge once the reflection reaches pmt0 after | ||
one round trip time. | ||
This works marginally and is just a proof of principle: it relies on | ||
hysteresis at FPGA inputs around half voltage and good impedance steps, | ||
as well as reasonably low loss cable. It does not work well for longer | ||
cables (>100 ns RTT). The default drive strength of 12 mA and 3.3 V would | ||
be ~300 Ω but it seems 40 Ω series impedance at the output matches | ||
the hysteresis of the input. | ||
This is also equivalent to a loopback tester or a delay measurement. | ||
""" | ||
def build(self): | ||
self.attr_device("core") | ||
self.attr_device("pmt0") | ||
self.attr_device("ttl2") | ||
|
||
def run(self): | ||
n = 1000 # repetitions | ||
latency = 50e-9 # calibrated latency without a transmission line | ||
pulse = 1e-6 # pulse length, larger than rtt | ||
try: | ||
self.many(n, seconds_to_mu(pulse, self.core)) | ||
except PulseNotReceivedError: | ||
print("to few edges: cable too long or wiring bad") | ||
else: | ||
print(self.t) | ||
t_rise = mu_to_seconds(self.t[0], self.core)/n - latency | ||
t_fall = mu_to_seconds(self.t[1], self.core)/n - latency - pulse | ||
print("round trip times:") | ||
print("rising: {:5g} ns, falling {:5g} ns".format( | ||
t_rise/1e-9, t_fall/1e-9)) | ||
|
||
@kernel | ||
def many(self, n, p): | ||
t = [0 for i in range(2)] | ||
self.core.break_realtime() | ||
for i in range(n): | ||
self.one(t, p) | ||
self.t = t | ||
|
||
@kernel | ||
def one(self, t, p): | ||
t0 = now_mu() | ||
with parallel: | ||
self.pmt0.gate_both_mu(2*p) | ||
self.ttl2.pulse_mu(p) | ||
for i in range(len(t)): | ||
ti = self.pmt0.timestamp_mu() | ||
if ti <= 0: | ||
raise PulseNotReceivedError | ||
t[i] += ti - t0 | ||
self.pmt0.count() # flush |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,4 +53,3 @@ clean: | |
|
||
liblwip.a: $(LWIPOBJS) | ||
$(AR) clr liblwip.a $(LWIPOBJS) | ||
$(RANLIB) liblwip.a |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#include <stdio.h> | ||
#include <generated/csr.h> | ||
|
||
#include "clock.h" | ||
#include "flash_storage.h" | ||
#include "rtiocrg.h" | ||
|
||
void rtiocrg_init(void) | ||
{ | ||
char b; | ||
int clk; | ||
|
||
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR | ||
rtio_crg_pll_reset_write(0); | ||
#endif | ||
b = 'i'; | ||
clk = 0; | ||
fs_read("startup_clock", &b, 1, NULL); | ||
if(b == 'i') | ||
printf("Startup RTIO clock: internal\n"); | ||
else if(b == 'e') { | ||
printf("Startup RTIO clock: external\n"); | ||
clk = 1; | ||
} else | ||
printf("WARNING: unknown startup_clock entry in flash storage\n"); | ||
|
||
if(!rtiocrg_switch_clock(clk)) { | ||
printf("WARNING: startup RTIO clock failed\n"); | ||
printf("WARNING: this may cause the system initialization to fail\n"); | ||
printf("WARNING: fix clocking and reset the device\n"); | ||
} | ||
} | ||
|
||
int rtiocrg_check(void) | ||
{ | ||
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR | ||
return rtio_crg_pll_locked_read(); | ||
#else | ||
return 1; | ||
#endif | ||
} | ||
|
||
int rtiocrg_switch_clock(int clk) | ||
{ | ||
int current_clk; | ||
|
||
current_clk = rtio_crg_clock_sel_read(); | ||
if(clk == current_clk) { | ||
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR | ||
busywait_us(150); | ||
if(!rtio_crg_pll_locked_read()) | ||
return 0; | ||
#endif | ||
return 1; | ||
} | ||
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR | ||
rtio_crg_pll_reset_write(1); | ||
#endif | ||
rtio_crg_clock_sel_write(clk); | ||
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR | ||
rtio_crg_pll_reset_write(0); | ||
busywait_us(150); | ||
if(!rtio_crg_pll_locked_read()) | ||
return 0; | ||
#endif | ||
return 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#ifndef __RTIOCRG_H | ||
#define __RTIOCRG_H | ||
|
||
void rtiocrg_init(void); | ||
int rtiocrg_check(void); | ||
int rtiocrg_switch_clock(int clk); | ||
|
||
#endif /* __RTIOCRG_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters