Skip to content

Commit

Permalink
Added support for Digilent Genesys 2
Browse files Browse the repository at this point in the history
  • Loading branch information
kaolpr committed Mar 24, 2023
1 parent e9a153b commit 7ed6984
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 4 deletions.
1 change: 1 addition & 0 deletions RELEASE_NOTES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Highlights:
For earlier hardware versions, specify the hardware version in the device
database file (e.g. ``"hw_rev": "v2.1"``) to use the correct conversion factor.
- Metlino and Sayma support has been dropped due to complications with synchronous RTIO clocking.
- Digilent Genesys 2, Xilinx Kintex 7 development board with single FMC HPC connector.
* CPU (on softcore platforms) and AXI bus (on Zynq) are now clocked synchronously with the RTIO
clock, to facilitate implementation of local processing on DRTIO satellites, and to slightly
reduce RTIO latency.
Expand Down
2 changes: 2 additions & 0 deletions artiq/firmware/libboard_misoc/net_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ pub fn get_adresses() -> NetAddresses {
}
#[cfg(soc_platform = "kc705")]
{ hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]); }
#[cfg(soc_platform = "digilent_genesys2")]
{ hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x03]); }
}
}

Expand Down
2 changes: 1 addition & 1 deletion artiq/firmware/libboard_misoc/spiflash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub unsafe fn write(mut addr: usize, mut data: &[u8]) {
}
}

#[cfg(any(soc_platform = "kasli", soc_platform = "kc705"))]
#[cfg(any(soc_platform = "kasli", soc_platform = "kc705", soc_platform = "digilent_genesys2"))]
pub unsafe fn reload () -> ! {
csr::icap::iprog_write(1);
loop {}
Expand Down
14 changes: 12 additions & 2 deletions artiq/firmware/runtime/rtio_clocking.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@

#[cfg(has_si5324)]
use board_misoc::config;
#[cfg(has_si5324)]
use board_artiq::si5324;
#[cfg(has_si5324)]
use board_misoc::{csr, clock};

#[derive(Debug, PartialEq)]
#[allow(non_camel_case_types)]
#[cfg(has_si5324)]
pub enum RtioClock {
Default,
Int_125,
Expand All @@ -15,6 +20,7 @@ pub enum RtioClock {
}

#[allow(unreachable_code)]
#[cfg(has_si5324)]
fn get_rtio_clock_cfg() -> RtioClock {
config::read_str("rtio_clock", |result| {
let res = match result {
Expand Down Expand Up @@ -92,6 +98,7 @@ const SI5324_EXT_INPUT: si5324::Input = si5324::Input::Ckin2;
#[cfg(all(soc_platform = "kc705"))]
const SI5324_EXT_INPUT: si5324::Input = si5324::Input::Ckin2;

#[cfg(has_si5324)]
fn setup_si5324_pll(cfg: RtioClock) {
let (si5324_settings, si5324_ref_input) = match cfg {
RtioClock::Ext0_Synth0_10to125 => { // 125 MHz output from 10 MHz CLKINx reference, 504 Hz BW
Expand Down Expand Up @@ -194,6 +201,7 @@ fn setup_si5324_pll(cfg: RtioClock) {
si5324::setup(&si5324_settings, si5324_ref_input).expect("cannot initialize Si5324");
}

#[cfg(has_si5324)]
fn setup_si5324(clock_cfg: RtioClock) {
let switched = unsafe {
csr::crg::switch_done_read()
Expand Down Expand Up @@ -225,8 +233,10 @@ fn setup_si5324(clock_cfg: RtioClock) {


pub fn init() {
let clock_cfg = get_rtio_clock_cfg();
setup_si5324(clock_cfg);
#[cfg(has_si5324)] {
let clock_cfg = get_rtio_clock_cfg();
setup_si5324(clock_cfg);
}

#[cfg(has_drtio)]
{
Expand Down
37 changes: 36 additions & 1 deletion artiq/frontend/artiq_flash.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def get_argparser():
help="SSH host to jump through")
parser.add_argument("-t", "--target", default="kasli",
help="target board, default: %(default)s, one of: "
"kasli kc705")
"kasli kc705 genesys2")
parser.add_argument("-I", "--preinit-command", default=[], action="append",
help="add a pre-initialization OpenOCD command. "
"Useful for selecting a board when several are connected.")
Expand Down Expand Up @@ -230,6 +230,34 @@ def start(self):
"xc7_program xc7.tap")


class ProgrammerGenesys2(Programmer):
_sector_size = 0x10000

def __init__(self, client, preinit_script):
Programmer.__init__(self, client, preinit_script)

add_commands(self._board_script,
"adapter driver ftdi",
"ftdi vid_pid 0x0403 0x6010",
"ftdi channel 1",
"ftdi layout_init 0x00e8 0x60eb",
"reset_config none",
"adapter speed 25000",
"transport select jtag",
"source {}".format(self._transfer_script("cpld/xilinx-xc7.cfg")),
"source {}".format(self._transfer_script("fpga/xilinx-xadc.cfg")),
"source {}".format(self._transfer_script("cpld/jtagspi.cfg")))
self.add_flash_bank("spi0", "xc7", index=0)

add_commands(self._script, "xadc_report xc7.tap")

def load_proxy(self):
self.load(find_proxy_bitfile("bscan_spi_xc7k325t.bit"), pld=0)

def start(self):
add_commands(self._script, "xc7_program xc7.tap")


def main():
args = get_argparser().parse_args()
common_args.init_logger_from_args(args)
Expand All @@ -249,6 +277,13 @@ def main():
"storage": ("spi0", 0xb30000),
"firmware": ("spi0", 0xb40000),
},
"genesys2": {
"programmer": ProgrammerGenesys2,
"gateware": ("spi0", 0x000000),
"bootloader": ("spi0", 0xaf0000),
"storage": ("spi0", 0xb30000),
"firmware": ("spi0", 0xb40000),
},
}[args.target]

if not args.action:
Expand Down
113 changes: 113 additions & 0 deletions artiq/gateware/targets/digilent_genesys2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env python3

import argparse

from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.genlib.cdc import MultiReg
from migen.build.generic_platform import *

from misoc.interconnect.csr import *
from misoc.cores import gpio, timer
from misoc.targets.digilent_genesys2 import MiniSoC
from misoc.integration.builder import builder_args, builder_argdict
from misoc.integration.soc_sdram import *

from artiq.gateware.amp import AMPSoC
from artiq.gateware import rtio
from artiq.gateware.rtio.phy import ttl_simple
from artiq.build_soc import *


class _StandaloneBase(MiniSoC, AMPSoC):
mem_map = {
"cri_con": 0x10000000,
"rtio": 0x20000000,
"rtio_dma": 0x30000000,
"mailbox": 0x70000000
}
mem_map.update(MiniSoC.mem_map)

def __init__(self, gateware_identifier_str=None, **kwargs):
MiniSoC.__init__(self,
cpu_type="vexriscv",
cpu_bus_width=64,
sdram_controller_type="minicon",
l2_size=128*1024,
integrated_sram_size=8192,
ethmac_nrxslots=4,
ethmac_ntxslots=4,
**kwargs)
AMPSoC.__init__(self)
add_identifier(self, gateware_identifier_str=gateware_identifier_str)

self.submodules.timer1 = timer.Timer()
self.csr_devices.append("timer1")
self.interrupt_devices.append("timer1")

self.submodules.leds = gpio.GPIOOut(Cat(
self.platform.request("user_led", 0),
self.platform.request("user_led", 1)))
self.csr_devices.append("leds")

def add_rtio(self, rtio_channels):
self.submodules.rtio_tsc = rtio.TSC(glbl_fine_ts_width=3)
self.submodules.rtio_core = rtio.Core(self.rtio_tsc, rtio_channels)
self.csr_devices.append("rtio_core")
self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc)
self.submodules.rtio_dma = ClockDomainsRenamer("sys_kernel")(
rtio.DMA(self.get_native_sdram_if(), self.cpu_dw))
self.register_kernel_cpu_csrdevice("rtio")
self.register_kernel_cpu_csrdevice("rtio_dma")
self.submodules.cri_con = rtio.CRIInterconnectShared(
[self.rtio.cri, self.rtio_dma.cri],
[self.rtio_core.cri])
self.register_kernel_cpu_csrdevice("cri_con")

# Only add MonInj core if there is anything to monitor
if any([len(c.probes) for c in rtio_channels]):
self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)
self.csr_devices.append("rtio_moninj")

self.submodules.rtio_analyzer = rtio.Analyzer(self.rtio_tsc, self.rtio_core.cri,
self.get_native_sdram_if(), cpu_dw=self.cpu_dw)
self.csr_devices.append("rtio_analyzer")


class TestVariant(_StandaloneBase):
def __init__(self, gateware_identifier_str=None, **kwargs):
_StandaloneBase.__init__(self, gateware_identifier_str, **kwargs)

rtio_channels = []
for i in range(2, 7):
phy = ttl_simple.Output(self.platform.request("user_led", i))
self.submodules += phy
rtio_channels.append(rtio.Channel.from_phy(phy))
for i in range(8):
phy = ttl_simple.InOut(self.platform.request("user_sw", i))
self.submodules += phy
rtio_channels.append(rtio.Channel.from_phy(phy))

self.config["HAS_RTIO_LOG"] = None
self.config["RTIO_LOG_CHANNEL"] = len(rtio_channels)
rtio_channels.append(rtio.LogChannel())

self.add_rtio(rtio_channels)


def main():
parser = argparse.ArgumentParser(
description="ARTIQ device binary builder for Digilent Genesys2 systems")
builder_args(parser)
soc_sdram_args(parser)
parser.set_defaults(output_dir="artiq_genesys2")
parser.add_argument("--gateware-identifier-str", default=None,
help="Override ROM identifier")
args = parser.parse_args()

soc = TestVariant(gateware_identifier_str=args.gateware_identifier_str, **soc_sdram_argdict(args))
build_artiq_soc(soc, builder_argdict(args))


if __name__ == "__main__":
main()

0 comments on commit 7ed6984

Please sign in to comment.