From 113c8eb0b86fa7ea49385e264e788e0d902d137f Mon Sep 17 00:00:00 2001 From: Astro Date: Fri, 13 Nov 2020 20:17:18 +0100 Subject: [PATCH] add coraz7 + redpitaya targets --- default.nix | 69 +++++++++----- src/Cargo.lock | 50 +++++----- src/Makefile | 9 +- src/gateware/coraz7.py | 194 ++++++++++++++++++++++++++++++++++++++ src/gateware/redpitaya.py | 191 +++++++++++++++++++++++++++++++++++++ src/runtime/Cargo.toml | 2 + zynq-rs.nix | 4 +- 7 files changed, 464 insertions(+), 55 deletions(-) create mode 100755 src/gateware/coraz7.py create mode 100755 src/gateware/redpitaya.py diff --git a/default.nix b/default.nix index e7a290cd..191790a7 100644 --- a/default.nix +++ b/default.nix @@ -3,18 +3,24 @@ let pkgs = import { overlays = [ (import "${zynq-rs}/nix/mozilla-overlay.nix") ]; }; rustPlatform = (import "${zynq-rs}/nix/rust-platform.nix" { inherit pkgs; }); cargo-xbuild = (import zynq-rs).cargo-xbuild; - zc706-szl = (import zynq-rs).zc706-szl; - zc706-fsbl = import "${zynq-rs}/nix/fsbl.nix" { inherit pkgs; }; mkbootimage = import "${zynq-rs}/nix/mkbootimage.nix" { inherit pkgs; }; artiqpkgs = import { inherit pkgs; }; vivado = import { inherit pkgs; }; - build-zc706 = { variant }: let + # FSBL configuration supplied by Vivado 2020.1 for these boards: + fsblTargets = ["zc702" "zc706" "zed"]; + build = { target, variant }: let + szl = (import zynq-rs)."${target}-szl"; + fsbl = import "${zynq-rs}/nix/fsbl.nix" { + inherit pkgs; + board = target; + }; + firmware = rustPlatform.buildRustPackage rec { # note: due to fetchCargoTarball, cargoSha256 depends on package name - name = "zc706-firmware"; + name = "firmware"; src = ./src; - cargoSha256 = "1nibi7xhdx7qg0vi93n981fmc23flhvx67japn48kcmwsq3g46dm"; + cargoSha256 = "17313zy3vjna0pri4jpikcfbpydngxxpq48n3j5mwyw8d6jwhs3q"; nativeBuildInputs = [ pkgs.gnumake @@ -26,7 +32,7 @@ let buildPhase = '' export XARGO_RUST_SRC="${rustPlatform.rust.rustc.src}/library" export CARGO_HOME=$(mktemp -d cargo-home.XXX) - make VARIANT=${variant} + make TARGET=${target} VARIANT=${variant} ''; installPhase = '' @@ -40,7 +46,7 @@ let doCheck = false; dontFixup = true; }; - gateware = pkgs.runCommand "zc706-${variant}-gateware" + gateware = pkgs.runCommand "${target}-${variant}-gateware" { nativeBuildInputs = [ (pkgs.python3.withPackages(ps: (with artiqpkgs; [ migen migen-axi misoc artiq ]))) @@ -48,21 +54,21 @@ let ]; } '' - python ${./src/gateware}/zc706.py -g build -V ${variant} + python ${./src/gateware}/${target}.py -g build -V ${variant} mkdir -p $out $out/nix-support cp build/top.bit $out echo file binary-dist $out/top.bit >> $out/nix-support/hydra-build-products ''; # SZL startup - jtag = pkgs.runCommand "zc706-${variant}-jtag" {} + jtag = pkgs.runCommand "${target}-${variant}-jtag" {} '' mkdir $out - ln -s ${zc706-szl}/szl.elf $out + ln -s ${szl}/szl.elf $out ln -s ${firmware}/runtime.bin $out ln -s ${gateware}/top.bit $out ''; - sd = pkgs.runCommand "zc706-${variant}-sd" + sd = pkgs.runCommand "${target}-${variant}-sd" { buildInputs = [ mkbootimage ]; } @@ -71,7 +77,7 @@ let # can't write software (mkbootimage will segfault). bifdir=`mktemp -d` cd $bifdir - ln -s ${zc706-szl}/szl.elf szl.elf + ln -s ${szl}/szl.elf szl.elf ln -s ${firmware}/runtime.elf runtime.elf ln -s ${gateware}/top.bit top.bit cat > boot.bif << EOF @@ -88,14 +94,14 @@ let ''; # FSBL startup - fsbl-sd = pkgs.runCommand "zc706-${variant}-fsbl-sd" + fsbl-sd = pkgs.runCommand "${target}-${variant}-fsbl-sd" { buildInputs = [ mkbootimage ]; } '' bifdir=`mktemp -d` cd $bifdir - ln -s ${zc706-fsbl}/fsbl.elf fsbl.elf + ln -s ${fsbl}/fsbl.elf fsbl.elf ln -s ${gateware}/top.bit top.bit ln -s ${firmware}/runtime.elf runtime.elf cat > boot.bif << EOF @@ -111,19 +117,30 @@ let echo file binary-dist $out/boot.bin >> $out/nix-support/hydra-build-products ''; in { - "zc706-${variant}-firmware" = firmware; - "zc706-${variant}-gateware" = gateware; - "zc706-${variant}-jtag" = jtag; - "zc706-${variant}-sd" = sd; - "zc706-${variant}-fsbl-sd" = fsbl-sd; - }; + "${target}-${variant}-firmware" = firmware; + "${target}-${variant}-gateware" = gateware; + "${target}-${variant}-jtag" = jtag; + "${target}-${variant}-sd" = sd; + } // ( + if builtins.elem target fsblTargets + then { + "${target}-${variant}-fsbl-sd" = fsbl-sd; + } + else {} + ); in ( - (build-zc706 { variant = "simple"; }) // - (build-zc706 { variant = "nist_clock"; }) // - (build-zc706 { variant = "nist_qc2"; }) // - (build-zc706 { variant = "acpki_simple"; }) // - (build-zc706 { variant = "acpki_nist_clock"; }) // - (build-zc706 { variant = "acpki_nist_qc2"; }) // + (build { target = "zc706"; variant = "simple"; }) // + (build { target = "zc706"; variant = "nist_clock"; }) // + (build { target = "zc706"; variant = "nist_qc2"; }) // + (build { target = "zc706"; variant = "acpki_simple"; }) // + (build { target = "zc706"; variant = "acpki_nist_clock"; }) // + (build { target = "zc706"; variant = "acpki_nist_qc2"; }) // + (build { target = "coraz7"; variant = "10"; }) // + (build { target = "coraz7"; variant = "07s"; }) // + (build { target = "coraz7"; variant = "acpki_10"; }) // + (build { target = "coraz7"; variant = "acpki_07s"; }) // + (build { target = "redpitaya"; variant = "simple"; }) // + (build { target = "redpitaya"; variant = "acpki_simple"; }) // { inherit zynq-rs; } ) diff --git a/src/Cargo.lock b/src/Cargo.lock index 4f573238..174cbf8f 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -37,9 +37,9 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] name = "cc" -version = "1.0.61" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d" +checksum = "f1770ced377336a88a67c473594ccc14eca6f4559217c34f64aac8f83d641b40" [[package]] name = "cfg-if" @@ -56,7 +56,7 @@ checksum = "e3fcd8aba10d17504c87ef12d4f62ef404c6a4703d16682a9eb5543e6cf24455" [[package]] name = "core_io" version = "0.1.20200410" -source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#d623913535906739c31dc9838cdf1db4b975fb46" +source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#cb50c8d61b9ffbb4c88b5f2e96fa9f4394266c43" dependencies = [ "memchr", ] @@ -109,9 +109,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95314d38584ffbfda215621d723e0a3906f032e03ae5551e650058dac83d4797" +checksum = "9b3b0c040a1fe6529d30b3c5944b280c7f0dcb2930d2c3062bca967b602583d0" dependencies = [ "futures-channel", "futures-core", @@ -123,9 +123,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0448174b01148032eed37ac4aed28963aaaa8cfa93569a08e5b479bbc6c2c151" +checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64" dependencies = [ "futures-core", "futures-sink", @@ -133,21 +133,21 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18eaa56102984bed2c88ea39026cff3ce3b4c7f508ca970cedf2450ea10d4e46" +checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748" [[package]] name = "futures-io" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1798854a4727ff944a7b12aa999f58ce7aa81db80d2dfaaf2ba06f065ddd2b" +checksum = "611834ce18aaa1bd13c4b374f5d653e1027cf99b6b502584ff8c9a64413b30bb" [[package]] name = "futures-macro" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36fccf3fc58563b4a14d265027c627c3b665d7fed489427e88e7cc929559efe" +checksum = "77408a692f1f97bcc61dc001d752e00643408fbc922e4d634c655df50d595556" dependencies = [ "proc-macro-hack", "proc-macro2", @@ -157,21 +157,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3ca3f17d6e8804ae5d3df7a7d35b2b3a6fe89dac84b31872720fc3060a0b11" +checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d" [[package]] name = "futures-task" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d502af37186c4fef99453df03e374683f8a1eec9dcc1e66b3b82dc8278ce3c" +checksum = "7c554eb5bf48b2426c4771ab68c6b14468b6e76cc90996f528c3338d761a4d0d" [[package]] name = "futures-util" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abcb44342f62e6f3e8ac427b8aa815f724fd705dfad060b18ac7866c15bb8e34" +checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2" dependencies = [ "futures-core", "futures-macro", @@ -186,7 +186,7 @@ dependencies = [ [[package]] name = "libasync" version = "0.0.0" -source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#d623913535906739c31dc9838cdf1db4b975fb46" +source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#cb50c8d61b9ffbb4c88b5f2e96fa9f4394266c43" dependencies = [ "embedded-hal", "libcortex_a9", @@ -198,7 +198,7 @@ dependencies = [ [[package]] name = "libboard_zynq" version = "0.0.0" -source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#d623913535906739c31dc9838cdf1db4b975fb46" +source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#cb50c8d61b9ffbb4c88b5f2e96fa9f4394266c43" dependencies = [ "bit_field", "embedded-hal", @@ -222,7 +222,7 @@ dependencies = [ [[package]] name = "libconfig" version = "0.1.0" -source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#d623913535906739c31dc9838cdf1db4b975fb46" +source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#cb50c8d61b9ffbb4c88b5f2e96fa9f4394266c43" dependencies = [ "core_io", "fatfs", @@ -233,7 +233,7 @@ dependencies = [ [[package]] name = "libcortex_a9" version = "0.0.0" -source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#d623913535906739c31dc9838cdf1db4b975fb46" +source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#cb50c8d61b9ffbb4c88b5f2e96fa9f4394266c43" dependencies = [ "bit_field", "libregister", @@ -249,7 +249,7 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libregister" version = "0.0.0" -source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#d623913535906739c31dc9838cdf1db4b975fb46" +source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#cb50c8d61b9ffbb4c88b5f2e96fa9f4394266c43" dependencies = [ "bit_field", "vcell", @@ -259,7 +259,7 @@ dependencies = [ [[package]] name = "libsupport_zynq" version = "0.0.0" -source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#d623913535906739c31dc9838cdf1db4b975fb46" +source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#cb50c8d61b9ffbb4c88b5f2e96fa9f4394266c43" dependencies = [ "compiler_builtins", "libboard_zynq", diff --git a/src/Makefile b/src/Makefile index ab00d1d0..da0d6563 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,4 @@ +TARGET := zc706 VARIANT := simple all: ../build/firmware/armv7-none-eabihf/release/runtime ../build/runtime.bin @@ -7,10 +8,14 @@ all: ../build/firmware/armv7-none-eabihf/release/runtime ../build/runtime.bin ../build/pl.rs ../build/rustc-cfg: gateware/* mkdir -p ../build - python gateware/zc706.py -r ../build/pl.rs -c ../build/rustc-cfg -V $(VARIANT) + python gateware/$(TARGET).py -r ../build/pl.rs -c ../build/rustc-cfg -V $(VARIANT) ../build/firmware/armv7-none-eabihf/release/runtime: ../build/pl.rs ../build/rustc-cfg $(shell find . -print) - XBUILD_SYSROOT_PATH=`pwd`/../build/sysroot cargo xbuild --release -p runtime --target-dir ../build/firmware + cd runtime && \ + XBUILD_SYSROOT_PATH=`pwd`/../../build/sysroot \ + cargo xbuild --release \ + --target-dir ../../build/firmware \ + --no-default-features --features=target_$(TARGET) ../build/runtime.bin: ../build/firmware/armv7-none-eabihf/release/runtime llvm-objcopy -O binary ../build/firmware/armv7-none-eabihf/release/runtime ../build/runtime.bin diff --git a/src/gateware/coraz7.py b/src/gateware/coraz7.py new file mode 100755 index 00000000..b8ec94d4 --- /dev/null +++ b/src/gateware/coraz7.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python + +import argparse +from operator import itemgetter + +from migen import * +from migen.build.generic_platform import * +from migen.genlib.resetsync import AsyncResetSynchronizer +from migen.genlib.cdc import MultiReg +from migen_axi.integration.soc_core import SoCCore +from migen_axi.platforms import coraz7 +from misoc.interconnect.csr import * +from misoc.integration import cpu_interface + +from artiq.gateware import rtio +from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, dds, spi2 + +import dma +import analyzer +import acpki + + +class RTIOCRG(Module, AutoCSR): + def __init__(self, platform, rtio_internal_clk): + 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) + + rtio_external_clk = Signal() + # user_sma_clock = platform.request("user_sma_clock") + # platform.add_period_constraint(user_sma_clock.p, 8.0) + # self.specials += Instance("IBUFDS", + # i_I=user_sma_clock.p, i_IB=user_sma_clock.n, + # o_O=rtio_external_clk) + + 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=rtio_external_clk, + # Warning: CLKINSEL=0 means CLKIN2 is selected + i_CLKINSEL=~self.clock_sel.storage, + + # 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 CoraZ7(SoCCore): + def __init__(self, device_variant="10", acpki=False): + self.acpki = acpki + self.rustc_cfg = dict() + + platform = coraz7.Platform(device_variant=device_variant) + platform.toolchain.bitstream_commands.extend([ + "set_property BITSTREAM.GENERAL.COMPRESS True [current_design]", + ]) + ident = self.__class__.__name__ + if self.acpki: + ident = "acpki_" + ident + SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident) + + platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]") + platform.add_platform_command("set_input_jitter clk_fpga_0 0.24") + + self.submodules.rtio_crg = RTIOCRG(self.platform, self.ps7.cd_sys.clk) + self.csr_devices.append("rtio_crg") + self.platform.add_period_constraint(self.rtio_crg.cd_rtio.clk, 8.) + self.platform.add_false_path_constraints( + self.ps7.cd_sys.clk, + self.rtio_crg.cd_rtio.clk) + + def add_rtio(self, rtio_channels): + 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") + + if self.acpki: + self.rustc_cfg["ki_impl"] = "acp" + self.submodules.rtio = acpki.KernelInitiator(self.rtio_tsc, + bus=self.ps7.s_axi_acp, + user=self.ps7.s_axi_acp_user, + evento=self.ps7.event.o) + self.csr_devices.append("rtio") + else: + self.rustc_cfg["ki_impl"] = "csr" + self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc, now64=True) + self.csr_devices.append("rtio") + + self.submodules.rtio_dma = dma.DMA(self.ps7.s_axi_hp0) + self.csr_devices.append("rtio_dma") + + self.submodules.cri_con = rtio.CRIInterconnectShared( + [self.rtio.cri, self.rtio_dma.cri], + [self.rtio_core.cri]) + self.csr_devices.append("cri_con") + + self.submodules.rtio_moninj = rtio.MonInj(rtio_channels) + self.csr_devices.append("rtio_moninj") + + self.submodules.rtio_analyzer = analyzer.Analyzer(self.rtio_tsc, self.rtio_core.cri, + self.ps7.s_axi_hp1) + self.csr_devices.append("rtio_analyzer") + + +class Simple(CoraZ7): + def __init__(self, **kwargs): + CoraZ7.__init__(self, **kwargs) + + platform = self.platform + + rtio_channels = [] + for i in range(2): + phy = ttl_simple.Output(platform.request("user_led", i)) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy)) + + self.config["RTIO_LOG_CHANNEL"] = len(rtio_channels) + rtio_channels.append(rtio.LogChannel()) + + self.add_rtio(rtio_channels) + + +VARIANTS = {cls.__name__.lower(): cls for cls in [Simple]} + + +def write_csr_file(soc, filename): + with open(filename, "w") as f: + f.write(cpu_interface.get_csr_rust( + soc.get_csr_regions(), soc.get_csr_groups(), soc.get_constants())) + + +def write_rustc_cfg_file(soc, filename): + with open(filename, "w") as f: + for k, v in sorted(soc.rustc_cfg.items(), key=itemgetter(0)): + if v is None: + f.write("{}\n".format(k)) + else: + f.write("{}=\"{}\"\n".format(k, v)) + + +def main(): + parser = argparse.ArgumentParser( + description="ARTIQ port to the Cora Z7 Zynq development kit") + parser.add_argument("-r", default=None, + help="build Rust interface into the specified file") + parser.add_argument("-c", default=None, + help="build Rust compiler configuration into the specified file") + parser.add_argument("-g", default=None, + help="build gateware into the specified directory") + parser.add_argument("-V", "--variant", default="10", + help="variant: " + "[acpki_]10/07s " + "(default: %(default)s)") + args = parser.parse_args() + + variant = args.variant.lower() + acpki = variant.startswith("acpki_") + if acpki: + variant = variant[6:] + try: + soc = Simple(device_variant=variant, acpki=acpki) + except KeyError: + raise SystemExit("Invalid variant (-V/--variant)") + soc.finalize() + + if args.r is not None: + write_csr_file(soc, args.r) + if args.c is not None: + write_rustc_cfg_file(soc, args.c) + if args.g is not None: + soc.build(build_dir=args.g) + + +if __name__ == "__main__": + main() diff --git a/src/gateware/redpitaya.py b/src/gateware/redpitaya.py new file mode 100755 index 00000000..5095894f --- /dev/null +++ b/src/gateware/redpitaya.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python + +import argparse +from operator import itemgetter + +from migen import * +from migen.build.generic_platform import * +from migen.genlib.resetsync import AsyncResetSynchronizer +from migen.genlib.cdc import MultiReg +from migen_axi.integration.soc_core import SoCCore +from migen_axi.platforms import redpitaya +from misoc.interconnect.csr import * +from misoc.integration import cpu_interface + +from artiq.gateware import rtio +from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, dds, spi2 + +import dma +import analyzer +import acpki + + +class RTIOCRG(Module, AutoCSR): + def __init__(self, platform, rtio_internal_clk): + 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) + + rtio_external_clk = Signal() + # user_sma_clock = platform.request("user_sma_clock") + # platform.add_period_constraint(user_sma_clock.p, 8.0) + # self.specials += Instance("IBUFDS", + # i_I=user_sma_clock.p, i_IB=user_sma_clock.n, + # o_O=rtio_external_clk) + + 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=rtio_external_clk, + # Warning: CLKINSEL=0 means CLKIN2 is selected + i_CLKINSEL=~self.clock_sel.storage, + + # 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 Redpitaya(SoCCore): + def __init__(self, acpki=False): + self.acpki = acpki + self.rustc_cfg = dict() + + platform = redpitaya.Platform() + platform.toolchain.bitstream_commands.extend([ + "set_property BITSTREAM.GENERAL.COMPRESS True [current_design]", + ]) + ident = self.__class__.__name__ + if self.acpki: + ident = "acpki_" + ident + SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident) + + platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]") + platform.add_platform_command("set_input_jitter clk_fpga_0 0.24") + + self.submodules.rtio_crg = RTIOCRG(self.platform, self.ps7.cd_sys.clk) + self.csr_devices.append("rtio_crg") + self.platform.add_period_constraint(self.rtio_crg.cd_rtio.clk, 8.) + self.platform.add_false_path_constraints( + self.ps7.cd_sys.clk, + self.rtio_crg.cd_rtio.clk) + + def add_rtio(self, rtio_channels): + 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") + + if self.acpki: + self.rustc_cfg["ki_impl"] = "acp" + self.submodules.rtio = acpki.KernelInitiator(self.rtio_tsc, + bus=self.ps7.s_axi_acp, + user=self.ps7.s_axi_acp_user, + evento=self.ps7.event.o) + self.csr_devices.append("rtio") + else: + self.rustc_cfg["ki_impl"] = "csr" + self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc, now64=True) + self.csr_devices.append("rtio") + + self.submodules.rtio_dma = dma.DMA(self.ps7.s_axi_hp0) + self.csr_devices.append("rtio_dma") + + self.submodules.cri_con = rtio.CRIInterconnectShared( + [self.rtio.cri, self.rtio_dma.cri], + [self.rtio_core.cri]) + self.csr_devices.append("cri_con") + + self.submodules.rtio_moninj = rtio.MonInj(rtio_channels) + self.csr_devices.append("rtio_moninj") + + self.submodules.rtio_analyzer = analyzer.Analyzer(self.rtio_tsc, self.rtio_core.cri, + self.ps7.s_axi_hp1) + self.csr_devices.append("rtio_analyzer") + + +class Simple(Redpitaya): + def __init__(self, **kwargs): + Redpitaya.__init__(self, **kwargs) + + platform = self.platform + + rtio_channels = [] + for i in range(2): + phy = ttl_simple.Output(platform.request("user_led", i)) + self.submodules += phy + rtio_channels.append(rtio.Channel.from_phy(phy)) + + self.config["RTIO_LOG_CHANNEL"] = len(rtio_channels) + rtio_channels.append(rtio.LogChannel()) + + self.add_rtio(rtio_channels) + + +VARIANTS = {cls.__name__.lower(): cls for cls in [Simple]} + + +def write_csr_file(soc, filename): + with open(filename, "w") as f: + f.write(cpu_interface.get_csr_rust( + soc.get_csr_regions(), soc.get_csr_groups(), soc.get_constants())) + + +def write_rustc_cfg_file(soc, filename): + with open(filename, "w") as f: + for k, v in sorted(soc.rustc_cfg.items(), key=itemgetter(0)): + if v is None: + f.write("{}\n".format(k)) + else: + f.write("{}=\"{}\"\n".format(k, v)) + + +def main(): + parser = argparse.ArgumentParser( + description="ARTIQ port to the Redpitaya Zynq development kit") + parser.add_argument("-r", default=None, + help="build Rust interface into the specified file") + parser.add_argument("-c", default=None, + help="build Rust compiler configuration into the specified file") + parser.add_argument("-g", default=None, + help="build gateware into the specified directory") + parser.add_argument("-V", "--variant", default="10", + help="variant: " + "[acpki_]simple " + "(default: %(default)s)") + args = parser.parse_args() + + variant = args.variant.lower() + acpki = variant.startswith("acpki_") + if acpki: + variant = variant[6:] + soc = Simple(acpki=acpki) + soc.finalize() + + if args.r is not None: + write_csr_file(soc, args.r) + if args.c is not None: + write_rustc_cfg_file(soc, args.c) + if args.g is not None: + soc.build(build_dir=args.g) + + +if __name__ == "__main__": + main() diff --git a/src/runtime/Cargo.toml b/src/runtime/Cargo.toml index 9b7af9c6..bff589f1 100644 --- a/src/runtime/Cargo.toml +++ b/src/runtime/Cargo.toml @@ -7,6 +7,8 @@ edition = "2018" [features] target_zc706 = ["libboard_zynq/target_zc706", "libsupport_zynq/target_zc706", "libconfig/target_zc706"] +target_coraz7 = ["libboard_zynq/target_coraz7", "libsupport_zynq/target_coraz7", "libconfig/target_coraz7"] +target_redpitaya = ["libboard_zynq/target_redpitaya", "libsupport_zynq/target_redpitaya", "libconfig/target_redpitaya"] default = ["target_zc706"] [dependencies] diff --git a/zynq-rs.nix b/zynq-rs.nix index 023db8f1..f41de7df 100644 --- a/zynq-rs.nix +++ b/zynq-rs.nix @@ -3,6 +3,6 @@ let in pkgs.fetchgit { url = "https://git.m-labs.hk/M-Labs/zynq-rs.git"; - rev = "d623913535906739c31dc9838cdf1db4b975fb46"; - sha256 = "1bbxv1pgqkz9x5awshqh02r0ha0zc6yjabr5iwfbci8dpc63msv1"; + rev = "cb50c8d61b9ffbb4c88b5f2e96fa9f4394266c43"; + sha256 = "1wp81fm689l5ghh2bzlanqx7g066166ki39mlzhly48xczky6np2"; }