Skip to content

Commit

Permalink
Added support for Digilent Genesys 2
Browse files Browse the repository at this point in the history
Based on:
- m-labs/misoc#130
- m-labs/migen#264

Signed-off-by: Mikołaj Sowiński <msowinski@technosystem.com.pl>
  • Loading branch information
kaolpr committed Sep 1, 2022
1 parent 7c306d5 commit e171225
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 2 deletions.
3 changes: 2 additions & 1 deletion RELEASE_NOTES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Unreleased
Highlights:

* Implemented Phaser-servo. This requires recent gateware on Phaser.

* New hardware support:
- Digilent Genesys 2, Xilinx Kintex 7 development board with single FMC HPC connector.

ARTIQ-7
-------
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 @@ -73,6 +73,8 @@ pub fn get_adresses() -> NetAddresses {
{ hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x19]); }
#[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 = "metlino", soc_platform = "kc705"))]
#[cfg(any(soc_platform = "kasli", soc_platform = "metlino", soc_platform = "kc705", soc_platform = "digilent_genesys2"))]
pub unsafe fn reload () -> ! {
csr::icap::iprog_write(1);
loop {}
Expand Down
35 changes: 35 additions & 0 deletions artiq/frontend/artiq_flash.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,34 @@ def start(self):
add_commands(self._script, "xcu_program xcu.tap")


class ProgrammerGenesys2(Programmer):
_sector_size = 0x10000

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

add_commands(self._board_script,
"interface ftdi",
"ftdi_vid_pid 0x0403 0x6010",
"ftdi_channel 1",
"ftdi_layout_init 0x00e8 0x60eb",
"reset_config none",
"adapter_khz 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 Down Expand Up @@ -338,6 +366,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
156 changes: 156 additions & 0 deletions artiq/gateware/targets/digilent_genesys2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
#!/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 _RTIOCRG(Module, AutoCSR):
def __init__(self, platform, rtio_internal_clk):
# TODO: See if we can get rid of it?
self._clock_sel = CSRStorage()
self._pll_reset = CSRStorage(reset=1)
self._pll_locked = CSRStatus()
self.clock_domains.cd_rtio = ClockDomain()
self.clock_domains.cd_rtiox4 = ClockDomain(reset_less=True)

pll_locked = Signal()
rtio_clk = Signal()
rtiox4_clk = Signal()
self.specials += [
Instance("PLLE2_ADV",
p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,

p_REF_JITTER1=0.01,
p_CLKIN1_PERIOD=8.0, p_CLKIN2_PERIOD=8.0,
i_CLKIN1=rtio_internal_clk, i_CLKIN2=0,
# Warning: CLKINSEL=0 means CLKIN2 is selected
i_CLKINSEL=1,

# VCO @ 1GHz when using 125MHz input
p_CLKFBOUT_MULT=8, p_DIVCLK_DIVIDE=1,
i_CLKFBIN=self.cd_rtio.clk,
i_RST=self._pll_reset.storage,

o_CLKFBOUT=rtio_clk,

p_CLKOUT0_DIVIDE=2, p_CLKOUT0_PHASE=0.0,
o_CLKOUT0=rtiox4_clk),
Instance("BUFG", i_I=rtio_clk, o_O=self.cd_rtio.clk),
Instance("BUFG", i_I=rtiox4_clk, o_O=self.cd_rtiox4.clk),

AsyncResetSynchronizer(self.cd_rtio, ~pll_locked),
MultiReg(pll_locked, self._pll_locked.status)
]


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_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk)
self.csr_devices.append("rtio_crg")
self.submodules.rtio_tsc = rtio.TSC("async", 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")
self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)
self.csr_devices.append("rtio_moninj")

self.platform.add_period_constraint(self.rtio_crg.cd_rtio.clk, 8.)
self.platform.add_false_path_constraints(
self.crg.cd_sys.clk,
self.rtio_crg.cd_rtio.clk)

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 e171225

Please sign in to comment.