drtio: separate aux controller

This helps with managing CSR groups and heterogeneous (satellite/repeaters) DRTIO cores.
pull/1212/head
Sebastien Bourdeauducq 2018-09-05 17:56:56 +08:00
parent 92be9324df
commit 87e0384e97
8 changed files with 123 additions and 101 deletions

View File

@ -2,7 +2,7 @@ use core::slice;
use crc;
use io::{ProtoRead, ProtoWrite, Cursor, Error as IoError};
use board_misoc::{csr::DRTIO, mem::DRTIO_AUX, clock};
use board_misoc::{csr::DRTIOAUX, mem::DRTIOAUX_MEM, clock};
use proto_artiq::drtioaux_proto::Error as ProtocolError;
pub use proto_artiq::drtioaux_proto::Packet;
@ -40,17 +40,17 @@ pub fn reset(linkno: u8) {
// clear buffer first to limit race window with buffer overflow
// error. We assume the CPU is fast enough so that no two packets
// will be received between the buffer and the error flag are cleared.
(DRTIO[linkno].aux_rx_present_write)(1);
(DRTIO[linkno].aux_rx_error_write)(1);
(DRTIOAUX[linkno].aux_rx_present_write)(1);
(DRTIOAUX[linkno].aux_rx_error_write)(1);
}
}
fn has_rx_error(linkno: u8) -> bool {
let linkno = linkno as usize;
unsafe {
let error = (DRTIO[linkno].aux_rx_error_read)() != 0;
let error = (DRTIOAUX[linkno].aux_rx_error_read)() != 0;
if error {
(DRTIO[linkno].aux_rx_error_write)(1)
(DRTIOAUX[linkno].aux_rx_error_write)(1)
}
error
}
@ -61,11 +61,11 @@ fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, Error<!>>
{
let linkidx = linkno as usize;
unsafe {
if (DRTIO[linkidx].aux_rx_present_read)() == 1 {
let ptr = DRTIO_AUX[linkidx].base + DRTIO_AUX[linkidx].size / 2;
let len = (DRTIO[linkidx].aux_rx_length_read)();
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
let ptr = DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2;
let len = (DRTIOAUX[linkidx].aux_rx_length_read)();
let result = f(slice::from_raw_parts(ptr as *mut u8, len as usize));
(DRTIO[linkidx].aux_rx_present_write)(1);
(DRTIOAUX[linkidx].aux_rx_present_write)(1);
Ok(Some(result?))
} else {
Ok(None)
@ -114,12 +114,12 @@ fn transmit<F>(linkno: u8, f: F) -> Result<(), Error<!>>
{
let linkno = linkno as usize;
unsafe {
while (DRTIO[linkno].aux_tx_read)() != 0 {}
let ptr = DRTIO_AUX[linkno].base;
let len = DRTIO_AUX[linkno].size / 2;
while (DRTIOAUX[linkno].aux_tx_read)() != 0 {}
let ptr = DRTIOAUX_MEM[linkno].base;
let len = DRTIOAUX_MEM[linkno].size / 2;
let len = f(slice::from_raw_parts_mut(ptr as *mut u8, len))?;
(DRTIO[linkno].aux_tx_length_write)(len as u16);
(DRTIO[linkno].aux_tx_write)(1);
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
(DRTIOAUX[linkno].aux_tx_write)(1);
Ok(())
}
}
@ -146,7 +146,7 @@ pub fn send_link(linkno: u8, packet: &Packet) -> Result<(), Error<!>> {
// TODO: routing
fn get_linkno(nodeno: u8) -> Result<u8, Error<!>> {
if nodeno == 0 || nodeno as usize > DRTIO.len() {
if nodeno == 0 || nodeno as usize > DRTIOAUX.len() {
return Err(Error::NoRoute)
}
Ok(nodeno - 1)

View File

@ -16,21 +16,21 @@ use board_artiq::hmc830_7043;
fn drtio_reset(reset: bool) {
unsafe {
(csr::DRTIO[0].reset_write)(if reset { 1 } else { 0 });
csr::drtiosat::reset_write(if reset { 1 } else { 0 });
}
}
fn drtio_reset_phy(reset: bool) {
unsafe {
(csr::DRTIO[0].reset_phy_write)(if reset { 1 } else { 0 });
csr::drtiosat::reset_phy_write(if reset { 1 } else { 0 });
}
}
fn drtio_tsc_loaded() -> bool {
unsafe {
let tsc_loaded = (csr::DRTIO[0].tsc_loaded_read)() == 1;
let tsc_loaded = csr::drtiosat::tsc_loaded_read() == 1;
if tsc_loaded {
(csr::DRTIO[0].tsc_loaded_write)(1);
csr::drtiosat::tsc_loaded_write(1);
}
tsc_loaded
}
@ -56,29 +56,29 @@ fn process_aux_packet(packet: drtioaux::Packet) -> Result<(), drtioaux::Error<!>
drtioaux::Packet::RtioErrorRequest => {
let errors;
unsafe {
errors = (csr::DRTIO[0].rtio_error_read)();
errors = csr::drtiosat::rtio_error_read();
}
if errors & 1 != 0 {
let channel;
unsafe {
channel = (csr::DRTIO[0].sequence_error_channel_read)();
(csr::DRTIO[0].rtio_error_write)(1);
channel = csr::drtiosat::sequence_error_channel_read();
csr::drtiosat::rtio_error_write(1);
}
drtioaux::send_link(0,
&drtioaux::Packet::RtioErrorSequenceErrorReply { channel })
} else if errors & 2 != 0 {
let channel;
unsafe {
channel = (csr::DRTIO[0].collision_channel_read)();
(csr::DRTIO[0].rtio_error_write)(2);
channel = csr::drtiosat::collision_channel_read();
csr::drtiosat::rtio_error_write(2);
}
drtioaux::send_link(0,
&drtioaux::Packet::RtioErrorCollisionReply { channel })
} else if errors & 4 != 0 {
let channel;
unsafe {
channel = (csr::DRTIO[0].busy_channel_read)();
(csr::DRTIO[0].rtio_error_write)(4);
channel = csr::drtiosat::busy_channel_read();
csr::drtiosat::rtio_error_write(4);
}
drtioaux::send_link(0,
&drtioaux::Packet::RtioErrorBusyReply { channel })
@ -201,7 +201,7 @@ fn process_aux_packets() {
fn process_errors() {
let errors;
unsafe {
errors = (csr::DRTIO[0].protocol_error_read)();
errors = csr::drtiosat::protocol_error_read();
}
if errors & 1 != 0 {
error!("received packet of an unknown type");
@ -217,9 +217,9 @@ fn process_errors() {
let timestamp_event;
let timestamp_counter;
unsafe {
channel = (csr::DRTIO[0].underflow_channel_read)();
timestamp_event = (csr::DRTIO[0].underflow_timestamp_event_read)() as i64;
timestamp_counter = (csr::DRTIO[0].underflow_timestamp_counter_read)() as i64;
channel = csr::drtiosat::underflow_channel_read();
timestamp_event = csr::drtiosat::underflow_timestamp_event_read() as i64;
timestamp_counter = csr::drtiosat::underflow_timestamp_counter_read() as i64;
}
error!("write underflow, channel={}, timestamp={}, counter={}, slack={}",
channel, timestamp_event, timestamp_counter, timestamp_event-timestamp_counter);
@ -228,7 +228,7 @@ fn process_errors() {
error!("write overflow");
}
unsafe {
(csr::DRTIO[0].protocol_error_write)(errors);
csr::drtiosat::protocol_error_write(errors);
}
}
@ -247,7 +247,7 @@ const SI5324_SETTINGS: si5324::FrequencySettings
fn drtio_link_rx_up() -> bool {
unsafe {
(csr::DRTIO[0].rx_up_read)() == 1
csr::drtiosat::rx_up_read() == 1
}
}

View File

@ -1,2 +1,2 @@
from artiq.gateware.drtio.core import SyncRTIO, DRTIOSatellite, DRTIOMaster, DRTIORepeater
from artiq.gateware.drtio.aux_controller import DRTIOAuxController

View File

@ -211,7 +211,7 @@ class Receiver(Module, AutoCSR):
# TODO: FullMemoryWE should be applied by migen.build
@FullMemoryWE()
class AuxController(Module):
class DRTIOAuxController(Module):
def __init__(self, link_layer):
self.bus = wishbone.Interface()
self.submodules.transmitter = Transmitter(link_layer, len(self.bus.dat_w))

View File

@ -8,7 +8,7 @@ from misoc.interconnect.csr import *
from artiq.gateware.rtio import cri, rtlink
from artiq.gateware.rtio.sed.core import *
from artiq.gateware.rtio.input_collector import *
from artiq.gateware.drtio import (link_layer, aux_controller,
from artiq.gateware.drtio import (link_layer,
rt_packet_satellite, rt_errors_satellite,
rt_packet_master, rt_controller_master,
rt_controller_repeater)
@ -145,13 +145,10 @@ class DRTIOSatellite(Module):
self.submodules.rt_errors = rt_errors_satellite.RTErrorsSatellite(
self.rt_packet, tsc, self.cri, self.async_errors)
self.submodules.aux_controller = aux_controller.AuxController(
self.link_layer)
def get_csrs(self):
return ([self.reset, self.reset_phy, self.tsc_loaded] +
self.link_layer.get_csrs() + self.link_stats.get_csrs() +
self.rt_errors.get_csrs() + self.aux_controller.get_csrs())
self.rt_errors.get_csrs())
class DRTIOMaster(Module):
@ -166,15 +163,11 @@ class DRTIOMaster(Module):
tsc, self.rt_packet)
self.submodules.rt_manager = rt_controller_master.RTManager(self.rt_packet)
self.submodules.aux_controller = aux_controller.AuxController(
self.link_layer)
def get_csrs(self):
return (self.link_layer.get_csrs() +
self.link_stats.get_csrs() +
self.rt_controller.get_csrs() +
self.rt_manager.get_csrs() +
self.aux_controller.get_csrs())
self.rt_manager.get_csrs())
@property
def cri(self):
@ -191,14 +184,10 @@ class DRTIORepeater(Module):
self.submodules.rt_packet = rt_packet_repeater.RTPacketRepeater(tsc, self.link_layer)
self.submodules.rt_controller = rt_controller_repeater.RTController(self.rt_packet)
self.submodules.aux_controller = aux_controller.AuxController(
self.link_layer)
def get_csrs(self):
return (self.link_layer.get_csrs() +
self.link_stats.get_csrs() +
self.rt_controller.get_csrs() +
self.aux_controller.get_csrs())
self.rt_controller.get_csrs())
@property
def cri(self):

View File

@ -21,7 +21,7 @@ from artiq.gateware import eem
from artiq.gateware.drtio.transceiver import gtp_7series
from artiq.gateware.drtio.siphaser import SiPhaser7Series
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
from artiq.gateware.drtio import DRTIOMaster, DRTIOSatellite, SyncRTIO
from artiq.gateware.drtio import *
from artiq.build_soc import *
@ -622,7 +622,7 @@ class _MasterBase(MiniSoC, AMPSoC):
"cri_con": 0x10000000,
"rtio": 0x20000000,
"rtio_dma": 0x30000000,
"drtio_aux": 0x50000000,
"drtioaux": 0x50000000,
"mailbox": 0x70000000
}
mem_map.update(MiniSoC.mem_map)
@ -666,27 +666,36 @@ class _MasterBase(MiniSoC, AMPSoC):
self.submodules.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3)
drtio_csr_group = []
drtio_memory_group = []
drtioaux_csr_group = []
drtioaux_memory_group = []
self.drtio_cri = []
for i in range(2):
core_name = "drtio" + str(i)
memory_name = "drtio" + str(i) + "_aux"
coreaux_name = "drtioaux" + str(i)
memory_name = "drtioaux" + str(i) + "_mem"
drtio_csr_group.append(core_name)
drtio_memory_group.append(memory_name)
drtioaux_csr_group.append(coreaux_name)
drtioaux_memory_group.append(memory_name)
core = ClockDomainsRenamer({"rtio_rx": "rtio_rx" + str(i)})(
DRTIOMaster(self.rtio_tsc, self.drtio_transceiver.channels[i]))
cdr = ClockDomainsRenamer({"rtio_rx": "rtio_rx" + str(i)})
core = cdr(DRTIOMaster(self.rtio_tsc, self.drtio_transceiver.channels[i]))
setattr(self.submodules, core_name, core)
self.drtio_cri.append(core.cri)
self.csr_devices.append(core_name)
memory_address = self.mem_map["drtio_aux"] + 0x800*i
coreaux = cdr(DRTIOAuxController(core.link_layer))
setattr(self.submodules, coreaux_name, coreaux)
self.csr_devices.append(coreaux_name)
memory_address = self.mem_map["drtioaux"] + 0x800*i
self.add_wb_slave(memory_address, 0x800,
core.aux_controller.bus)
coreaux.bus)
self.add_memory_region(memory_name, memory_address | self.shadow_base, 0x800)
self.config["HAS_DRTIO"] = None
self.add_csr_group("drtio", drtio_csr_group)
self.add_memory_group("drtio_aux", drtio_memory_group)
self.add_csr_group("drtioaux", drtioaux_csr_group)
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
rtio_clk_period = 1e9/rtio_clk_freq
gtp = self.drtio_transceiver.gtps[0]
@ -759,7 +768,7 @@ class _MasterBase(MiniSoC, AMPSoC):
class _SatelliteBase(BaseSoC):
mem_map = {
"drtio_aux": 0x50000000,
"drtioaux": 0x50000000,
}
mem_map.update(BaseSoC.mem_map)
@ -806,16 +815,19 @@ class _SatelliteBase(BaseSoC):
rx0 = ClockDomainsRenamer({"rtio_rx": "rtio_rx0"})
self.submodules.rx_synchronizer = rx0(XilinxRXSynchronizer())
self.submodules.drtio0 = rx0(DRTIOSatellite(
self.submodules.drtiosat = rx0(DRTIOSatellite(
self.rtio_tsc, self.drtio_transceiver.channels[0],
self.rx_synchronizer))
self.csr_devices.append("drtio0")
self.add_wb_slave(self.mem_map["drtio_aux"], 0x800,
self.drtio0.aux_controller.bus)
self.add_memory_region("drtio0_aux", self.mem_map["drtio_aux"] | self.shadow_base, 0x800)
self.csr_devices.append("drtiosat")
self.submodules.drtioaux0 = rx0(DRTIOAuxController(
self.drtiosat.link_layer))
self.csr_devices.append("drtioaux0")
self.add_wb_slave(self.mem_map["drtioaux"], 0x800,
self.drtioaux0.bus)
self.add_memory_region("drtioaux0_mem", self.mem_map["drtioaux"] | self.shadow_base, 0x800)
self.config["HAS_DRTIO"] = None
self.add_csr_group("drtio", ["drtio0"])
self.add_memory_group("drtio_aux", ["drtio0_aux"])
self.add_csr_group("drtioaux", ["drtioaux0"])
self.add_memory_group("drtioaux_mem", ["drtioaux0_mem"])
self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6)
self.submodules.siphaser = SiPhaser7Series(
@ -847,10 +859,10 @@ class _SatelliteBase(BaseSoC):
self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)
self.csr_devices.append("rtio_moninj")
self.submodules.drtio0_io = SyncRTIO(self.rtio_tsc, rtio_channels)
self.submodules.local_io = SyncRTIO(self.rtio_tsc, rtio_channels)
self.comb += [
self.drtio0.cri.connect(self.drtio0_io.cri),
self.drtio0.async_errors.eq(self.drtio0_io.async_errors),
self.drtiosat.cri.connect(self.local_io.cri),
self.drtiosat.async_errors.eq(self.local_io.async_errors)
]

View File

@ -22,7 +22,7 @@ from artiq.gateware.rtio.phy import ttl_simple, sawg
from artiq.gateware.drtio.transceiver import gth_ultrascale
from artiq.gateware.drtio.siphaser import SiPhaser7Series
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
from artiq.gateware.drtio import DRTIOMaster, DRTIOSatellite, SyncRTIO
from artiq.gateware.drtio import *
from artiq.build_soc import *
@ -234,7 +234,7 @@ class MasterDAC(MiniSoC, AMPSoC, RTMCommon):
"rtio": 0x11000000,
"rtio_dma": 0x12000000,
"serwb": 0x13000000,
"drtio_aux": 0x14000000,
"drtioaux": 0x14000000,
"mailbox": 0x70000000
}
mem_map.update(MiniSoC.mem_map)
@ -287,27 +287,36 @@ class MasterDAC(MiniSoC, AMPSoC, RTMCommon):
self.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3)
drtio_csr_group = []
drtio_memory_group = []
drtioaux_csr_group = []
drtioaux_memory_group = []
drtio_cri = []
for i in range(2):
core_name = "drtio" + str(i)
memory_name = "drtio" + str(i) + "_aux"
coreaux_name = "drtioaux" + str(i)
memory_name = "drtioaux" + str(i) + "_mem"
drtio_csr_group.append(core_name)
drtio_memory_group.append(memory_name)
drtioaux_csr_group.append(coreaux_name)
drtioaux_memory_group.append(memory_name)
core = ClockDomainsRenamer({"rtio_rx": "rtio_rx"+str(i)})(
DRTIOMaster(self.rtio_tsc, self.drtio_transceiver.channels[i]))
cdr = ClockDomainsRenamer({"rtio_rx": "rtio_rx" + str(i)})
core = cdr(DRTIOMaster(self.rtio_tsc, self.drtio_transceiver.channels[i]))
setattr(self.submodules, core_name, core)
drtio_cri.append(core.cri)
self.csr_devices.append(core_name)
memory_address = self.mem_map["drtio_aux"] + 0x800*i
coreaux = cdr(DRTIOAuxController(core.link_layer))
setattr(self.submodules, coreaux_name, coreaux)
self.csr_devices.append(coreaux_name)
memory_address = self.mem_map["drtioaux"] + 0x800*i
self.add_wb_slave(memory_address, 0x800,
core.aux_controller.bus)
coreaux.bus)
self.add_memory_region(memory_name, memory_address | self.shadow_base, 0x800)
self.config["HAS_DRTIO"] = None
self.add_csr_group("drtio", drtio_csr_group)
self.add_memory_group("drtio_aux", drtio_memory_group)
self.add_csr_group("drtioaux", drtioaux_csr_group)
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
rtio_clk_period = 1e9/rtio_clk_freq
gth = self.drtio_transceiver.gths[0]
@ -389,7 +398,7 @@ class Master(MiniSoC, AMPSoC):
"cri_con": 0x10000000,
"rtio": 0x11000000,
"rtio_dma": 0x12000000,
"drtio_aux": 0x14000000,
"drtioaux": 0x14000000,
"mailbox": 0x70000000
}
mem_map.update(MiniSoC.mem_map)
@ -433,27 +442,36 @@ class Master(MiniSoC, AMPSoC):
self.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3)
drtio_csr_group = []
drtio_memory_group = []
drtioaux_csr_group = []
drtioaux_memory_group = []
drtio_cri = []
for i in range(10):
core_name = "drtio" + str(i)
memory_name = "drtio" + str(i) + "_aux"
coreaux_name = "drtioaux" + str(i)
memory_name = "drtioaux" + str(i) + "_mem"
drtio_csr_group.append(core_name)
drtio_memory_group.append(memory_name)
drtioaux_csr_group.append(coreaux_name)
drtioaux_memory_group.append(memory_name)
core = ClockDomainsRenamer({"rtio_rx": "rtio_rx"+str(i)})(
DRTIOMaster(self.rtio_tsc, self.drtio_transceiver.channels[i]))
cdr = ClockDomainsRenamer({"rtio_rx": "rtio_rx" + str(i)})
core = cdr(DRTIOMaster(self.rtio_tsc, self.drtio_transceiver.channels[i]))
setattr(self.submodules, core_name, core)
drtio_cri.append(core.cri)
self.csr_devices.append(core_name)
memory_address = self.mem_map["drtio_aux"] + 0x800*i
coreaux = cdr(DRTIOAuxController(core.link_layer))
setattr(self.submodules, coreaux_name, coreaux)
self.csr_devices.append(coreaux_name)
memory_address = self.mem_map["drtioaux"] + 0x800*i
self.add_wb_slave(memory_address, 0x800,
core.aux_controller.bus)
coreaux.bus)
self.add_memory_region(memory_name, memory_address | self.shadow_base, 0x800)
self.config["HAS_DRTIO"] = None
self.add_csr_group("drtio", drtio_csr_group)
self.add_memory_group("drtio_aux", drtio_memory_group)
self.add_csr_group("drtioaux", drtioaux_csr_group)
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
rtio_clk_period = 1e9/rtio_clk_freq
gth = self.drtio_transceiver.gths[0]
@ -525,7 +543,7 @@ class Satellite(BaseSoC, RTMCommon):
"""
mem_map = {
"serwb": 0x13000000,
"drtio_aux": 0x14000000,
"drtioaux": 0x14000000,
}
mem_map.update(BaseSoC.mem_map)
@ -592,21 +610,24 @@ class Satellite(BaseSoC, RTMCommon):
rx0 = ClockDomainsRenamer({"rtio_rx": "rtio_rx0"})
self.submodules.rx_synchronizer = rx0(XilinxRXSynchronizer())
self.submodules.drtio0 = rx0(DRTIOSatellite(
self.submodules.drtiosat = rx0(DRTIOSatellite(
self.rtio_tsc, self.drtio_transceiver.channels[0],
self.rx_synchronizer))
self.csr_devices.append("drtio0")
self.add_wb_slave(self.mem_map["drtio_aux"], 0x800,
self.drtio0.aux_controller.bus)
self.add_memory_region("drtio0_aux", self.mem_map["drtio_aux"] | self.shadow_base, 0x800)
self.csr_devices.append("drtiosat")
self.submodules.drtioaux0 = rx0(DRTIOAuxController(
self.drtiosat.link_layer))
self.csr_devices.append("drtioaux0")
self.add_wb_slave(self.mem_map["drtioaux"], 0x800,
self.drtioaux0.bus)
self.add_memory_region("drtioaux0_mem", self.mem_map["drtioaux"] | self.shadow_base, 0x800)
self.config["HAS_DRTIO"] = None
self.add_csr_group("drtio", ["drtio0"])
self.add_memory_group("drtio_aux", ["drtio0_aux"])
self.add_csr_group("drtioaux", ["drtioaux0"])
self.add_memory_group("drtioaux_mem", ["drtioaux0_mem"])
self.submodules.drtio0_io = SyncRTIO(self.rtio_tsc, rtio_channels)
self.submodules.local_io = SyncRTIO(self.rtio_tsc, rtio_channels)
self.comb += [
self.drtio0.cri.connect(self.drtio0_io.cri),
self.drtio0.async_errors.eq(self.drtio0_io.async_errors),
self.drtiosat.cri.connect(self.local_io.cri),
self.drtiosat.async_errors.eq(self.local_io.async_errors),
]
self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6)

View File

@ -36,7 +36,7 @@ class TB(Module):
def __init__(self, nwords):
self.submodules.link_layer = Loopback(nwords)
self.submodules.aux_controller = ClockDomainsRenamer(
{"rtio": "sys", "rtio_rx": "sys"})(AuxController(self.link_layer))
{"rtio": "sys", "rtio_rx": "sys"})(DRTIOAuxController(self.link_layer))
class TestAuxController(unittest.TestCase):