forked from M-Labs/artiq
drtio: split kernel/system CSRs
This commit is contained in:
parent
9aa94e1a2d
commit
07ad00c1ca
|
@ -56,5 +56,8 @@ class DRTIOMaster(Module):
|
||||||
self.submodules.rt_controller = rt_controller.RTController(
|
self.submodules.rt_controller = rt_controller.RTController(
|
||||||
self.rt_packets, channel_count, fine_ts_width)
|
self.rt_packets, channel_count, fine_ts_width)
|
||||||
|
|
||||||
|
def get_kernel_csrs(self):
|
||||||
|
return self.rt_controller.get_kernel_csrs()
|
||||||
|
|
||||||
def get_csrs(self):
|
def get_csrs(self):
|
||||||
return self.rt_controller.get_csrs()
|
return self.rt_controller.get_csrs()
|
||||||
|
|
|
@ -23,6 +23,12 @@ class _KernelCSRs(AutoCSR):
|
||||||
self.counter = CSRStatus(64)
|
self.counter = CSRStatus(64)
|
||||||
self.counter_update = CSR()
|
self.counter_update = CSR()
|
||||||
|
|
||||||
|
|
||||||
|
class _CSRs(AutoCSR):
|
||||||
|
def __init__(self):
|
||||||
|
self.chan_sel_override = CSRStorage(16)
|
||||||
|
self.chan_sel_override_en = CSRStorage()
|
||||||
|
|
||||||
self.tsc_correction = CSRStorage(64)
|
self.tsc_correction = CSRStorage(64)
|
||||||
self.set_time = CSR()
|
self.set_time = CSR()
|
||||||
self.underflow_margin = CSRStorage(16, reset=200)
|
self.underflow_margin = CSRStorage(16, reset=200)
|
||||||
|
@ -31,6 +37,7 @@ class _KernelCSRs(AutoCSR):
|
||||||
self.o_dbg_fifo_space = CSRStatus(16)
|
self.o_dbg_fifo_space = CSRStatus(16)
|
||||||
self.o_dbg_last_timestamp = CSRStatus(64)
|
self.o_dbg_last_timestamp = CSRStatus(64)
|
||||||
self.o_reset_channel_status = CSR()
|
self.o_reset_channel_status = CSR()
|
||||||
|
self.o_wait = CSRStatus()
|
||||||
|
|
||||||
self.err_present = CSR()
|
self.err_present = CSR()
|
||||||
self.err_code = CSRStatus(8)
|
self.err_code = CSRStatus(8)
|
||||||
|
@ -39,21 +46,28 @@ class _KernelCSRs(AutoCSR):
|
||||||
class RTController(Module):
|
class RTController(Module):
|
||||||
def __init__(self, rt_packets, channel_count, fine_ts_width):
|
def __init__(self, rt_packets, channel_count, fine_ts_width):
|
||||||
self.kcsrs = _KernelCSRs()
|
self.kcsrs = _KernelCSRs()
|
||||||
|
self.csrs = _CSRs()
|
||||||
|
|
||||||
|
chan_sel = Signal(16)
|
||||||
|
self.comb += chan_sel.eq(
|
||||||
|
Mux(self.csrs.chan_sel_override_en.storage,
|
||||||
|
self.csrs.chan_sel_override.storage,
|
||||||
|
self.kcsrs.chan_sel.storage))
|
||||||
|
|
||||||
self.submodules.counter = RTIOCounter(64-fine_ts_width)
|
self.submodules.counter = RTIOCounter(64-fine_ts_width)
|
||||||
self.sync += If(self.kcsrs.counter_update.re,
|
self.sync += If(self.kcsrs.counter_update.re,
|
||||||
self.kcsrs.counter.status.eq(self.counter.value_sys))
|
self.kcsrs.counter.status.eq(self.counter.value_sys))
|
||||||
tsc_correction = Signal(64)
|
tsc_correction = Signal(64)
|
||||||
self.kcsrs.tsc_correction.storage.attr.add("no_retiming")
|
self.csrs.tsc_correction.storage.attr.add("no_retiming")
|
||||||
self.specials += MultiReg(self.kcsrs.tsc_correction.storage, tsc_correction)
|
self.specials += MultiReg(self.csrs.tsc_correction.storage, tsc_correction)
|
||||||
self.comb += [
|
self.comb += [
|
||||||
rt_packets.tsc_value.eq(
|
rt_packets.tsc_value.eq(
|
||||||
self.counter.value_rtio + tsc_correction),
|
self.counter.value_rtio + tsc_correction),
|
||||||
self.kcsrs.set_time.w.eq(rt_packets.set_time_stb)
|
self.csrs.set_time.w.eq(rt_packets.set_time_stb)
|
||||||
]
|
]
|
||||||
self.sync += [
|
self.sync += [
|
||||||
If(rt_packets.set_time_ack, rt_packets.set_time_stb.eq(0)),
|
If(rt_packets.set_time_ack, rt_packets.set_time_stb.eq(0)),
|
||||||
If(self.kcsrs.set_time.re, rt_packets.set_time_stb.eq(1))
|
If(self.csrs.set_time.re, rt_packets.set_time_stb.eq(1))
|
||||||
]
|
]
|
||||||
|
|
||||||
fifo_spaces_mem = Memory(16, channel_count)
|
fifo_spaces_mem = Memory(16, channel_count)
|
||||||
|
@ -65,10 +79,10 @@ class RTController(Module):
|
||||||
|
|
||||||
rt_packets_fifo_request = Signal()
|
rt_packets_fifo_request = Signal()
|
||||||
self.comb += [
|
self.comb += [
|
||||||
fifo_spaces.adr.eq(self.kcsrs.chan_sel.storage),
|
fifo_spaces.adr.eq(chan_sel),
|
||||||
last_timestamps.adr.eq(self.kcsrs.chan_sel.storage),
|
last_timestamps.adr.eq(chan_sel),
|
||||||
last_timestamps.dat_w.eq(self.kcsrs.o_timestamp.storage),
|
last_timestamps.dat_w.eq(self.kcsrs.o_timestamp.storage),
|
||||||
rt_packets.write_channel.eq(self.kcsrs.chan_sel.storage),
|
rt_packets.write_channel.eq(chan_sel),
|
||||||
rt_packets.write_address.eq(self.kcsrs.o_address.storage),
|
rt_packets.write_address.eq(self.kcsrs.o_address.storage),
|
||||||
rt_packets.write_data.eq(self.kcsrs.o_data.storage),
|
rt_packets.write_data.eq(self.kcsrs.o_data.storage),
|
||||||
If(rt_packets_fifo_request,
|
If(rt_packets_fifo_request,
|
||||||
|
@ -84,8 +98,11 @@ class RTController(Module):
|
||||||
status_wait = Signal()
|
status_wait = Signal()
|
||||||
status_underflow = Signal()
|
status_underflow = Signal()
|
||||||
status_sequence_error = Signal()
|
status_sequence_error = Signal()
|
||||||
self.comb += self.kcsrs.o_status.status.eq(Cat(
|
self.comb += [
|
||||||
status_wait, status_underflow, status_sequence_error))
|
self.kcsrs.o_status.status.eq(Cat(
|
||||||
|
status_wait, status_underflow, status_sequence_error)),
|
||||||
|
self.csrs.o_wait.status.eq(status_wait)
|
||||||
|
]
|
||||||
sequence_error_set = Signal()
|
sequence_error_set = Signal()
|
||||||
underflow_set = Signal()
|
underflow_set = Signal()
|
||||||
self.sync += [
|
self.sync += [
|
||||||
|
@ -98,7 +115,7 @@ class RTController(Module):
|
||||||
# TODO: collision, replace, busy
|
# TODO: collision, replace, busy
|
||||||
cond_sequence_error = self.kcsrs.o_timestamp.storage < last_timestamps.dat_r
|
cond_sequence_error = self.kcsrs.o_timestamp.storage < last_timestamps.dat_r
|
||||||
cond_underflow = ((self.kcsrs.o_timestamp.storage[fine_ts_width:]
|
cond_underflow = ((self.kcsrs.o_timestamp.storage[fine_ts_width:]
|
||||||
- self.kcsrs.underflow_margin.storage[fine_ts_width:]) < self.counter.value_sys)
|
- self.csrs.underflow_margin.storage[fine_ts_width:]) < self.counter.value_sys)
|
||||||
cond_fifo_emptied = ((last_timestamps.dat_r[fine_ts_width:] < self.counter.value_sys)
|
cond_fifo_emptied = ((last_timestamps.dat_r[fine_ts_width:] < self.counter.value_sys)
|
||||||
& (last_timestamps.dat_r != 0))
|
& (last_timestamps.dat_r != 0))
|
||||||
|
|
||||||
|
@ -112,7 +129,7 @@ class RTController(Module):
|
||||||
NextState("WRITE")
|
NextState("WRITE")
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
If(self.kcsrs.o_get_fifo_space.re,
|
If(self.csrs.o_get_fifo_space.re,
|
||||||
NextState("GET_FIFO_SPACE")
|
NextState("GET_FIFO_SPACE")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -157,9 +174,9 @@ class RTController(Module):
|
||||||
)
|
)
|
||||||
|
|
||||||
self.comb += [
|
self.comb += [
|
||||||
self.kcsrs.o_dbg_fifo_space.status.eq(fifo_spaces.dat_r),
|
self.csrs.o_dbg_fifo_space.status.eq(fifo_spaces.dat_r),
|
||||||
self.kcsrs.o_dbg_last_timestamp.status.eq(last_timestamps.dat_r),
|
self.csrs.o_dbg_last_timestamp.status.eq(last_timestamps.dat_r),
|
||||||
If(self.kcsrs.o_reset_channel_status.re,
|
If(self.csrs.o_reset_channel_status.re,
|
||||||
fifo_spaces.dat_w.eq(0),
|
fifo_spaces.dat_w.eq(0),
|
||||||
fifo_spaces.we.eq(1),
|
fifo_spaces.we.eq(1),
|
||||||
last_timestamps.dat_w.eq(0),
|
last_timestamps.dat_w.eq(0),
|
||||||
|
@ -168,10 +185,13 @@ class RTController(Module):
|
||||||
]
|
]
|
||||||
|
|
||||||
self.comb += [
|
self.comb += [
|
||||||
self.kcsrs.err_present.w.eq(rt_packets.error_not),
|
self.csrs.err_present.w.eq(rt_packets.error_not),
|
||||||
rt_packets.error_not_ack.eq(self.kcsrs.err_present.re),
|
rt_packets.error_not_ack.eq(self.csrs.err_present.re),
|
||||||
self.kcsrs.err_code.status.eq(rt_packets.error_code)
|
self.csrs.err_code.status.eq(rt_packets.error_code)
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_csrs(self):
|
def get_kernel_csrs(self):
|
||||||
return self.kcsrs.get_csrs()
|
return self.kcsrs.get_csrs()
|
||||||
|
|
||||||
|
def get_csrs(self):
|
||||||
|
return self.csrs.get_csrs()
|
||||||
|
|
|
@ -39,8 +39,9 @@ class AMPSoC:
|
||||||
self.submodules.timer_kernel = timer.Timer()
|
self.submodules.timer_kernel = timer.Timer()
|
||||||
self.register_kernel_cpu_csrdevice("timer_kernel")
|
self.register_kernel_cpu_csrdevice("timer_kernel")
|
||||||
|
|
||||||
def register_kernel_cpu_csrdevice(self, name):
|
def register_kernel_cpu_csrdevice(self, name, csrs=None):
|
||||||
csrs = getattr(self, name).get_csrs()
|
if csrs is None:
|
||||||
|
csrs = getattr(self, name).get_csrs()
|
||||||
bank = wishbone.CSRBank(csrs)
|
bank = wishbone.CSRBank(csrs)
|
||||||
self.submodules += bank
|
self.submodules += bank
|
||||||
self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map[name]),
|
self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map[name]),
|
||||||
|
|
|
@ -16,7 +16,7 @@ from artiq import __version__ as artiq_version
|
||||||
class Master(MiniSoC, AMPSoC):
|
class Master(MiniSoC, AMPSoC):
|
||||||
mem_map = {
|
mem_map = {
|
||||||
"timer_kernel": 0x10000000, # (shadow @0x90000000)
|
"timer_kernel": 0x10000000, # (shadow @0x90000000)
|
||||||
"drtio": 0x20000000, # (shadow @0xa0000000)
|
"kdrtio": 0x20000000, # (shadow @0xa0000000)
|
||||||
"mailbox": 0x70000000 # (shadow @0xf0000000)
|
"mailbox": 0x70000000 # (shadow @0xf0000000)
|
||||||
}
|
}
|
||||||
mem_map.update(MiniSoC.mem_map)
|
mem_map.update(MiniSoC.mem_map)
|
||||||
|
@ -41,7 +41,8 @@ class Master(MiniSoC, AMPSoC):
|
||||||
sys_clk_freq=self.clk_freq,
|
sys_clk_freq=self.clk_freq,
|
||||||
clock_div2=True)
|
clock_div2=True)
|
||||||
self.submodules.drtio = DRTIOMaster(self.transceiver)
|
self.submodules.drtio = DRTIOMaster(self.transceiver)
|
||||||
self.register_kernel_cpu_csrdevice("drtio")
|
self.register_kernel_cpu_csrdevice("kdrtio", self.drtio.get_kernel_csrs())
|
||||||
|
self.csr_devices.append("drtio")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -58,6 +58,7 @@ class TestFullStack(unittest.TestCase):
|
||||||
def test_full_stack(self):
|
def test_full_stack(self):
|
||||||
dut = DUT(2)
|
dut = DUT(2)
|
||||||
kcsrs = dut.master.rt_controller.kcsrs
|
kcsrs = dut.master.rt_controller.kcsrs
|
||||||
|
csrs = dut.master.rt_controller.csrs
|
||||||
|
|
||||||
ttl_changes = []
|
ttl_changes = []
|
||||||
correct_ttl_changes = [
|
correct_ttl_changes = [
|
||||||
|
@ -80,12 +81,15 @@ class TestFullStack(unittest.TestCase):
|
||||||
now += dt
|
now += dt
|
||||||
|
|
||||||
def get_fifo_space(channel):
|
def get_fifo_space(channel):
|
||||||
yield from kcsrs.chan_sel.write(channel)
|
yield from csrs.chan_sel_override_en.write(1)
|
||||||
yield from kcsrs.o_get_fifo_space.write(1)
|
yield from csrs.chan_sel_override.write(channel)
|
||||||
|
yield from csrs.o_get_fifo_space.write(1)
|
||||||
yield
|
yield
|
||||||
while (yield from kcsrs.o_status.read()) & 1:
|
while (yield from csrs.o_wait.read()):
|
||||||
yield
|
yield
|
||||||
return (yield from kcsrs.o_dbg_fifo_space.read())
|
r = (yield from csrs.o_dbg_fifo_space.read())
|
||||||
|
yield from csrs.chan_sel_override_en.write(0)
|
||||||
|
return r
|
||||||
|
|
||||||
def write(channel, data):
|
def write(channel, data):
|
||||||
yield from kcsrs.chan_sel.write(channel)
|
yield from kcsrs.chan_sel.write(channel)
|
||||||
|
@ -153,23 +157,23 @@ class TestFullStack(unittest.TestCase):
|
||||||
self.assertEqual(wlen, 2)
|
self.assertEqual(wlen, 2)
|
||||||
|
|
||||||
def test_tsc_error():
|
def test_tsc_error():
|
||||||
err_present = yield from kcsrs.err_present.read()
|
err_present = yield from csrs.err_present.read()
|
||||||
self.assertEqual(err_present, 0)
|
self.assertEqual(err_present, 0)
|
||||||
yield from kcsrs.tsc_correction.write(10000000)
|
yield from csrs.tsc_correction.write(10000000)
|
||||||
yield from kcsrs.set_time.write(1)
|
yield from csrs.set_time.write(1)
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
yield
|
yield
|
||||||
delay(10000)
|
delay(10000)
|
||||||
yield from write(0, 1)
|
yield from write(0, 1)
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
yield
|
yield
|
||||||
err_present = yield from kcsrs.err_present.read()
|
err_present = yield from csrs.err_present.read()
|
||||||
err_code = yield from kcsrs.err_code.read()
|
err_code = yield from csrs.err_code.read()
|
||||||
self.assertEqual(err_present, 1)
|
self.assertEqual(err_present, 1)
|
||||||
self.assertEqual(err_code, 2)
|
self.assertEqual(err_code, 2)
|
||||||
yield from kcsrs.err_present.write(1)
|
yield from csrs.err_present.write(1)
|
||||||
yield
|
yield
|
||||||
err_present = yield from kcsrs.err_present.read()
|
err_present = yield from csrs.err_present.read()
|
||||||
self.assertEqual(err_present, 0)
|
self.assertEqual(err_present, 0)
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
|
|
Loading…
Reference in New Issue