forked from M-Labs/artiq-zynq
Compare commits
35 Commits
drtio_port
...
master
Author | SHA1 | Date | |
---|---|---|---|
fdb658839b | |||
24747f09cd | |||
a4fbb96296 | |||
851ed095df | |||
dbc3f581e5 | |||
64fecf09b7 | |||
31fb2b388a | |||
e045837b67 | |||
ada3f2e704 | |||
8be5048cd3 | |||
e8db2a4b49 | |||
4218354e65 | |||
2376f9ab5e | |||
0b27349ec4 | |||
21eb1cab1a | |||
3096daaaee | |||
4fbfccf575 | |||
5c40115945 | |||
a5e3580d18 | |||
3582af564d | |||
742ce9fdde | |||
c4de1c261a | |||
219c075931 | |||
d04a7decfe | |||
0efa83e956 | |||
4fa824f42b | |||
ab0c205dd2 | |||
8d2bb09149 | |||
41295b0e01 | |||
aaec0abdf6 | |||
e241957419 | |||
50262b3f0c | |||
827c6c1306 | |||
e6863263b4 | |||
d7f45d473e |
14
README.md
14
README.md
@ -24,7 +24,7 @@ The following configuration keys are available:
|
|||||||
- ``ip``: IPv4 address.
|
- ``ip``: IPv4 address.
|
||||||
- ``ip6``: IPv6 address.
|
- ``ip6``: IPv6 address.
|
||||||
- ``startup``: startup kernel in ELF format (as produced by ``artiq_compile``).
|
- ``startup``: startup kernel in ELF format (as produced by ``artiq_compile``).
|
||||||
- ``rtioclk``: source of RTIO clock; valid values are ``external`` and ``internal``.
|
- ``rtio_clock``: source of RTIO clock; valid values are ``ext0_bypass`` and ``int_125``.
|
||||||
- ``boot``: SD card "boot.bin" file, for replacing the boot firmware/gateware. Write only.
|
- ``boot``: SD card "boot.bin" file, for replacing the boot firmware/gateware. Write only.
|
||||||
|
|
||||||
Configurations can be read/written/removed via ``artiq_coremgmt``. Config erase is
|
Configurations can be read/written/removed via ``artiq_coremgmt``. Config erase is
|
||||||
@ -45,7 +45,7 @@ Note: if you are using Nix channels the first time, you need to be aware of this
|
|||||||
Pure build with Nix and execution on a remote JTAG server:
|
Pure build with Nix and execution on a remote JTAG server:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
nix-build -A zc706-simple-jtag # or zc706-nist_qc2-jtag or zc706-nist_clock-jtag
|
nix-build -A zc706-nist_clock-jtag # or zc706-nist_qc2-jtag or zc706-nist_clock_satellite-jtag etc.
|
||||||
./remote_run.sh
|
./remote_run.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -54,19 +54,23 @@ Impure incremental build and execution on a remote JTAG server:
|
|||||||
```shell
|
```shell
|
||||||
nix-shell
|
nix-shell
|
||||||
cd src
|
cd src
|
||||||
gateware/zc706.py -g ../build/gateware # build gateware
|
gateware/zc706.py -g ../build/gateware -v <variant> # build gateware
|
||||||
make # build firmware
|
make GWARGS="-V <variant>" <runtime/satman> # build firmware
|
||||||
cd ..
|
cd ..
|
||||||
./remote_run.sh -i
|
./remote_run.sh -i
|
||||||
```
|
```
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
- This is developed with Nixpkgs 21.05, and the ``nixbld.m-labs.hk`` binary substituter can also be used here (see the ARTIQ manual for the public key and instructions).
|
- This is developed with Nixpkgs 21.05[^1], and the ``nixbld.m-labs.hk`` binary substituter can also be used here (see the ARTIQ manual for the public key and instructions).
|
||||||
- The impure build process is also compatible with non-Nix systems.
|
- The impure build process is also compatible with non-Nix systems.
|
||||||
|
- When calling make, you need to specify both the variant and firmware type.
|
||||||
|
- Firmware type must be either ``runtime`` for DRTIO-less or DRTIO master variants, or ``satman`` for DRTIO satellite.
|
||||||
- If the board is connected to the local machine, use the ``local_run.sh`` script.
|
- If the board is connected to the local machine, use the ``local_run.sh`` script.
|
||||||
- To update ``zynq-rs``, update the cargo files as per usual for Rust projects, but also keep ``zynq-rs.nix`` in sync.
|
- To update ``zynq-rs``, update the cargo files as per usual for Rust projects, but also keep ``zynq-rs.nix`` in sync.
|
||||||
|
|
||||||
|
[^1]: Thus, on newer version of NixOS, you should run `nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/21.05.tar.gz` instead
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
30
default.nix
30
default.nix
@ -8,7 +8,13 @@ let
|
|||||||
vivado = import <artiq-fast/vivado.nix> { inherit pkgs; };
|
vivado = import <artiq-fast/vivado.nix> { inherit pkgs; };
|
||||||
# FSBL configuration supplied by Vivado 2020.1 for these boards:
|
# FSBL configuration supplied by Vivado 2020.1 for these boards:
|
||||||
fsblTargets = ["zc702" "zc706" "zed"];
|
fsblTargets = ["zc702" "zc706" "zed"];
|
||||||
sat_variants = ["satellite" "acpki_satellite" "nist_clock_satellite" "nist_qc2_satellite"];
|
sat_variants = [
|
||||||
|
# kasli-soc satellite variants
|
||||||
|
"satellite"
|
||||||
|
# zc706 satellite variants
|
||||||
|
"nist_clock_satellite" "nist_qc2_satellite" "acpki_nist_clock_satellite" "acpki_nist_qc2_satellite"
|
||||||
|
"nist_clock_satellite_100mhz" "nist_qc2_satellite_100mhz" "acpki_nist_clock_satellite_100mhz" "acpki_nist_qc2_satellite_100mhz"
|
||||||
|
];
|
||||||
build = { target, variant, json ? null }: let
|
build = { target, variant, json ? null }: let
|
||||||
szl = (import zynq-rs)."${target}-szl";
|
szl = (import zynq-rs)."${target}-szl";
|
||||||
fsbl = import "${zynq-rs}/nix/fsbl.nix" {
|
fsbl = import "${zynq-rs}/nix/fsbl.nix" {
|
||||||
@ -22,7 +28,7 @@ let
|
|||||||
name = "firmware";
|
name = "firmware";
|
||||||
|
|
||||||
src = ./src;
|
src = ./src;
|
||||||
cargoSha256 = "0p9d2j7qp00wpxm48phl5rq26simzry6w0m673lyhrlbzqdz4frb";
|
cargoSha256 = "sha256-uiwESZNwPdVnDkA1n0v1DQHp3rTazDkgIYscVTpgNq0=";
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
pkgs.gnumake
|
pkgs.gnumake
|
||||||
@ -35,7 +41,7 @@ let
|
|||||||
export XARGO_RUST_SRC="${rustPlatform.rust.rustc}/lib/rustlib/src/rust/library"
|
export XARGO_RUST_SRC="${rustPlatform.rust.rustc}/lib/rustlib/src/rust/library"
|
||||||
export CLANG_EXTRA_INCLUDE_DIR="${pkgs.llvmPackages_9.clang-unwrapped.lib}/lib/clang/9.0.1/include"
|
export CLANG_EXTRA_INCLUDE_DIR="${pkgs.llvmPackages_9.clang-unwrapped.lib}/lib/clang/9.0.1/include"
|
||||||
export CARGO_HOME=$(mktemp -d cargo-home.XXX)
|
export CARGO_HOME=$(mktemp -d cargo-home.XXX)
|
||||||
make TARGET=${target} GWARGS="${if json == null then "-V ${variant}" else json}" ${fwtype}_target
|
make TARGET=${target} GWARGS="${if json == null then "-V ${variant}" else json}" ${fwtype}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
@ -81,14 +87,14 @@ let
|
|||||||
bifdir=`mktemp -d`
|
bifdir=`mktemp -d`
|
||||||
cd $bifdir
|
cd $bifdir
|
||||||
ln -s ${szl}/szl.elf szl.elf
|
ln -s ${szl}/szl.elf szl.elf
|
||||||
ln -s ${firmware}/runtime.elf runtime.elf
|
ln -s ${firmware}/${fwtype}.elf ${fwtype}.elf
|
||||||
ln -s ${gateware}/top.bit top.bit
|
ln -s ${gateware}/top.bit top.bit
|
||||||
cat > boot.bif << EOF
|
cat > boot.bif << EOF
|
||||||
the_ROM_image:
|
the_ROM_image:
|
||||||
{
|
{
|
||||||
[bootloader]szl.elf
|
[bootloader]szl.elf
|
||||||
top.bit
|
top.bit
|
||||||
runtime.elf
|
${fwtype}.elf
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
mkdir $out $out/nix-support
|
mkdir $out $out/nix-support
|
||||||
@ -106,13 +112,13 @@ let
|
|||||||
cd $bifdir
|
cd $bifdir
|
||||||
ln -s ${fsbl}/fsbl.elf fsbl.elf
|
ln -s ${fsbl}/fsbl.elf fsbl.elf
|
||||||
ln -s ${gateware}/top.bit top.bit
|
ln -s ${gateware}/top.bit top.bit
|
||||||
ln -s ${firmware}/runtime.elf runtime.elf
|
ln -s ${firmware}/${fwtype}.elf ${fwtype}.elf
|
||||||
cat > boot.bif << EOF
|
cat > boot.bif << EOF
|
||||||
the_ROM_image:
|
the_ROM_image:
|
||||||
{
|
{
|
||||||
[bootloader]fsbl.elf
|
[bootloader]fsbl.elf
|
||||||
top.bit
|
top.bit
|
||||||
runtime.elf
|
${fwtype}.elf
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
mkdir $out $out/nix-support
|
mkdir $out $out/nix-support
|
||||||
@ -133,24 +139,22 @@ let
|
|||||||
);
|
);
|
||||||
in
|
in
|
||||||
(
|
(
|
||||||
(build { target = "zc706"; variant = "simple"; }) //
|
|
||||||
(build { target = "zc706"; variant = "master"; }) //
|
|
||||||
(build { target = "zc706"; variant = "satellite"; }) //
|
|
||||||
(build { target = "zc706"; variant = "nist_clock"; }) //
|
(build { target = "zc706"; variant = "nist_clock"; }) //
|
||||||
(build { target = "zc706"; variant = "nist_clock_master"; }) //
|
(build { target = "zc706"; variant = "nist_clock_master"; }) //
|
||||||
(build { target = "zc706"; variant = "nist_clock_satellite"; }) //
|
(build { target = "zc706"; variant = "nist_clock_satellite"; }) //
|
||||||
|
(build { target = "zc706"; variant = "nist_clock_satellite_100mhz"; }) //
|
||||||
(build { target = "zc706"; variant = "nist_qc2"; }) //
|
(build { target = "zc706"; variant = "nist_qc2"; }) //
|
||||||
(build { target = "zc706"; variant = "nist_qc2_master"; }) //
|
(build { target = "zc706"; variant = "nist_qc2_master"; }) //
|
||||||
(build { target = "zc706"; variant = "nist_qc2_satellite"; }) //
|
(build { target = "zc706"; variant = "nist_qc2_satellite"; }) //
|
||||||
(build { target = "zc706"; variant = "acpki_simple"; }) //
|
(build { target = "zc706"; variant = "nist_qc2_satellite_100mhz"; }) //
|
||||||
(build { target = "zc706"; variant = "acpki_master"; }) //
|
|
||||||
(build { target = "zc706"; variant = "acpki_satellite"; }) //
|
|
||||||
(build { target = "zc706"; variant = "acpki_nist_clock"; }) //
|
(build { target = "zc706"; variant = "acpki_nist_clock"; }) //
|
||||||
(build { target = "zc706"; variant = "acpki_nist_clock_master"; }) //
|
(build { target = "zc706"; variant = "acpki_nist_clock_master"; }) //
|
||||||
(build { target = "zc706"; variant = "acpki_nist_clock_satellite"; }) //
|
(build { target = "zc706"; variant = "acpki_nist_clock_satellite"; }) //
|
||||||
|
(build { target = "zc706"; variant = "acpki_nist_clock_satellite_100mhz"; }) //
|
||||||
(build { target = "zc706"; variant = "acpki_nist_qc2"; }) //
|
(build { target = "zc706"; variant = "acpki_nist_qc2"; }) //
|
||||||
(build { target = "zc706"; variant = "acpki_nist_qc2_master"; }) //
|
(build { target = "zc706"; variant = "acpki_nist_qc2_master"; }) //
|
||||||
(build { target = "zc706"; variant = "acpki_nist_qc2_satellite"; }) //
|
(build { target = "zc706"; variant = "acpki_nist_qc2_satellite"; }) //
|
||||||
|
(build { target = "zc706"; variant = "acpki_nist_qc2_satellite_100mhz"; }) //
|
||||||
(build { target = "kasli_soc"; variant = "demo"; json = ./demo.json; }) //
|
(build { target = "kasli_soc"; variant = "demo"; json = ./demo.json; }) //
|
||||||
(build { target = "kasli_soc"; variant = "master"; json = ./kasli-soc-master.json; }) //
|
(build { target = "kasli_soc"; variant = "master"; json = ./kasli-soc-master.json; }) //
|
||||||
(build { target = "kasli_soc"; variant = "satellite"; json = ./kasli-soc-satellite.json; }) //
|
(build { target = "kasli_soc"; variant = "satellite"; json = ./kasli-soc-satellite.json; }) //
|
||||||
|
@ -29,30 +29,11 @@ device_db = {
|
|||||||
"class": "PCA9548"
|
"class": "PCA9548"
|
||||||
},
|
},
|
||||||
|
|
||||||
# led? are common to all variants
|
|
||||||
"led0": {
|
"led0": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
"module": "artiq.coredevice.ttl",
|
"module": "artiq.coredevice.ttl",
|
||||||
"class": "TTLOut",
|
"class": "TTLOut",
|
||||||
"arguments": {"channel": 0},
|
"arguments": {"channel": 41},
|
||||||
},
|
|
||||||
"led1": {
|
|
||||||
"type": "local",
|
|
||||||
"module": "artiq.coredevice.ttl",
|
|
||||||
"class": "TTLOut",
|
|
||||||
"arguments": {"channel": 1},
|
|
||||||
},
|
|
||||||
"led2": {
|
|
||||||
"type": "local",
|
|
||||||
"module": "artiq.coredevice.ttl",
|
|
||||||
"class": "TTLOut",
|
|
||||||
"arguments": {"channel": 2}
|
|
||||||
},
|
|
||||||
"led3": {
|
|
||||||
"type": "local",
|
|
||||||
"module": "artiq.coredevice.ttl",
|
|
||||||
"class": "TTLOut",
|
|
||||||
"arguments": {"channel": 3}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +43,7 @@ for i in range(40):
|
|||||||
"type": "local",
|
"type": "local",
|
||||||
"module": "artiq.coredevice.ttl",
|
"module": "artiq.coredevice.ttl",
|
||||||
"class": "TTLInOut",
|
"class": "TTLInOut",
|
||||||
"arguments": {"channel": 4+i}
|
"arguments": {"channel": i}
|
||||||
}
|
}
|
||||||
|
|
||||||
device_db["ad9914dds0"] = {
|
device_db["ad9914dds0"] = {
|
||||||
|
13
src/Makefile
13
src/Makefile
@ -1,20 +1,19 @@
|
|||||||
TARGET := zc706
|
TARGET := zc706
|
||||||
GWARGS := -V simple
|
GWARGS := -V nist_clock
|
||||||
|
|
||||||
all: runtime
|
all: runtime
|
||||||
|
|
||||||
runtime_target: ../build/runtime.bin
|
runtime: ../build/runtime.bin
|
||||||
|
|
||||||
satman_target: ../build/satman.bin
|
satman: ../build/satman.bin
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
|
|
||||||
|
.PHONY: all runtime_target satman_target
|
||||||
|
|
||||||
../build/pl.rs ../build/rustc-cfg ../build/mem.rs: gateware/*
|
../build/pl.rs ../build/rustc-cfg ../build/mem.rs: gateware/*
|
||||||
mkdir -p ../build
|
mkdir -p ../build
|
||||||
python gateware/$(TARGET).py -r ../build/pl.rs -c ../build/rustc-cfg -m ../build/mem.rs $(GWARGS)
|
python gateware/$(TARGET).py -r ../build/pl.rs -c ../build/rustc-cfg -m ../build/mem.rs $(GWARGS)
|
||||||
|
|
||||||
../build/firmware/armv7-none-eabihf/release/runtime: ../build/pl.rs ../build/rustc-cfg ../build/mem.rs $(shell find . -print)
|
../build/firmware/armv7-none-eabihf/release/runtime: ../build/pl.rs ../build/rustc-cfg ../build/mem.rs $(shell find . -type f -print)
|
||||||
cd runtime && \
|
cd runtime && \
|
||||||
XBUILD_SYSROOT_PATH=`pwd`/../../build/sysroot \
|
XBUILD_SYSROOT_PATH=`pwd`/../../build/sysroot \
|
||||||
cargo xbuild --release \
|
cargo xbuild --release \
|
||||||
@ -24,7 +23,7 @@ satman_target: ../build/satman.bin
|
|||||||
../build/runtime.bin: ../build/firmware/armv7-none-eabihf/release/runtime
|
../build/runtime.bin: ../build/firmware/armv7-none-eabihf/release/runtime
|
||||||
llvm-objcopy -O binary ../build/firmware/armv7-none-eabihf/release/runtime ../build/runtime.bin
|
llvm-objcopy -O binary ../build/firmware/armv7-none-eabihf/release/runtime ../build/runtime.bin
|
||||||
|
|
||||||
../build/firmware/armv7-none-eabihf/release/satman: ../build/pl.rs ../build/rustc-cfg ../build/mem.rs $(shell find . -print)
|
../build/firmware/armv7-none-eabihf/release/satman: ../build/pl.rs ../build/rustc-cfg ../build/mem.rs $(shell find . -type f -print)
|
||||||
cd satman && \
|
cd satman && \
|
||||||
XBUILD_SYSROOT_PATH=`pwd`/../../build/sysroot \
|
XBUILD_SYSROOT_PATH=`pwd`/../../build/sysroot \
|
||||||
cargo xbuild --release \
|
cargo xbuild --release \
|
||||||
|
@ -15,7 +15,7 @@ from misoc.integration import cpu_interface
|
|||||||
from artiq.coredevice import jsondesc
|
from artiq.coredevice import jsondesc
|
||||||
from artiq.gateware import rtio, eem_7series
|
from artiq.gateware import rtio, eem_7series
|
||||||
from artiq.gateware.rtio.phy import ttl_simple
|
from artiq.gateware.rtio.phy import ttl_simple
|
||||||
|
from artiq.gateware.rtio.xilinx_clocking import RTIOClockMultiplier
|
||||||
from artiq.gateware.drtio.transceiver import gtx_7series
|
from artiq.gateware.drtio.transceiver import gtx_7series
|
||||||
from artiq.gateware.drtio.siphaser import SiPhaser7Series
|
from artiq.gateware.drtio.siphaser import SiPhaser7Series
|
||||||
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
|
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
|
||||||
@ -24,7 +24,7 @@ from artiq.gateware.drtio import *
|
|||||||
import dma
|
import dma
|
||||||
import analyzer
|
import analyzer
|
||||||
import acpki
|
import acpki
|
||||||
import aux_controller
|
import drtio_aux_controller
|
||||||
|
|
||||||
class RTIOCRG(Module, AutoCSR):
|
class RTIOCRG(Module, AutoCSR):
|
||||||
def __init__(self, platform):
|
def __init__(self, platform):
|
||||||
@ -76,36 +76,6 @@ class RTIOCRG(Module, AutoCSR):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class _RTIOClockMultiplier(Module, AutoCSR):
|
|
||||||
def __init__(self, rtio_clk_freq):
|
|
||||||
self.pll_reset = CSRStorage(reset=1)
|
|
||||||
self.pll_locked = CSRStatus()
|
|
||||||
self.clock_domains.cd_rtiox4 = ClockDomain(reset_less=True)
|
|
||||||
|
|
||||||
# See "Global Clock Network Deskew Using Two BUFGs" in ug472.
|
|
||||||
clkfbout = Signal()
|
|
||||||
clkfbin = Signal()
|
|
||||||
rtiox4_clk = Signal()
|
|
||||||
pll_locked = Signal()
|
|
||||||
self.specials += [
|
|
||||||
Instance("MMCME2_BASE",
|
|
||||||
p_CLKIN1_PERIOD=1e9/rtio_clk_freq,
|
|
||||||
i_CLKIN1=ClockSignal("rtio"),
|
|
||||||
i_RST=self.pll_reset.storage,
|
|
||||||
o_LOCKED=pll_locked,
|
|
||||||
|
|
||||||
p_CLKFBOUT_MULT_F=8.0, p_DIVCLK_DIVIDE=1,
|
|
||||||
|
|
||||||
o_CLKFBOUT=clkfbout, i_CLKFBIN=clkfbin,
|
|
||||||
|
|
||||||
p_CLKOUT0_DIVIDE_F=2.0, o_CLKOUT0=rtiox4_clk,
|
|
||||||
),
|
|
||||||
Instance("BUFG", i_I=clkfbout, o_O=clkfbin),
|
|
||||||
Instance("BUFG", i_I=rtiox4_clk, o_O=self.cd_rtiox4.clk),
|
|
||||||
|
|
||||||
MultiReg(pll_locked, self.pll_locked.status)
|
|
||||||
]
|
|
||||||
|
|
||||||
eem_iostandard_dict = {
|
eem_iostandard_dict = {
|
||||||
0: "LVDS_25",
|
0: "LVDS_25",
|
||||||
1: "LVDS_25",
|
1: "LVDS_25",
|
||||||
@ -143,8 +113,8 @@ class GenericStandalone(SoCCore):
|
|||||||
platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]")
|
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")
|
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
||||||
|
|
||||||
self.rustc_cfg["HAS_SI5324"] = None
|
self.rustc_cfg["has_si5324"] = None
|
||||||
self.rustc_cfg["SI5324_SOFT_RESET"] = None
|
self.rustc_cfg["si5324_soft_reset"] = None
|
||||||
|
|
||||||
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
||||||
self.submodules.rtio_crg = RTIOCRG(self.platform)
|
self.submodules.rtio_crg = RTIOCRG(self.platform)
|
||||||
@ -210,6 +180,7 @@ class GenericStandalone(SoCCore):
|
|||||||
class GenericMaster(SoCCore):
|
class GenericMaster(SoCCore):
|
||||||
def __init__(self, description, acpki=False):
|
def __init__(self, description, acpki=False):
|
||||||
sys_clk_freq = 125e6
|
sys_clk_freq = 125e6
|
||||||
|
rtio_clk_freq = description["rtio_frequency"]
|
||||||
|
|
||||||
self.acpki = acpki
|
self.acpki = acpki
|
||||||
self.rustc_cfg = dict()
|
self.rustc_cfg = dict()
|
||||||
@ -226,8 +197,6 @@ class GenericMaster(SoCCore):
|
|||||||
platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]")
|
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")
|
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
||||||
|
|
||||||
# kasli_soc has no SATA, but it has 4x SFP
|
|
||||||
# not sure yet why sfp0 is omitted in MasterMode
|
|
||||||
data_pads = [platform.request("sfp", i) for i in range(4)]
|
data_pads = [platform.request("sfp", i) for i in range(4)]
|
||||||
|
|
||||||
self.submodules.drtio_transceiver = gtx_7series.GTX(
|
self.submodules.drtio_transceiver = gtx_7series.GTX(
|
||||||
@ -237,12 +206,8 @@ class GenericMaster(SoCCore):
|
|||||||
self.csr_devices.append("drtio_transceiver")
|
self.csr_devices.append("drtio_transceiver")
|
||||||
|
|
||||||
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
||||||
self.submodules.rtio_crg = RTIOCRG(self.platform)
|
self.submodules.rtio_crg = RTIOClockMultiplier(rtio_clk_freq)
|
||||||
self.csr_devices.append("rtio_crg")
|
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)
|
|
||||||
|
|
||||||
self.rtio_channels = []
|
self.rtio_channels = []
|
||||||
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
|
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
|
||||||
@ -279,7 +244,7 @@ class GenericMaster(SoCCore):
|
|||||||
self.drtio_cri.append(core.cri)
|
self.drtio_cri.append(core.cri)
|
||||||
self.csr_devices.append(core_name)
|
self.csr_devices.append(core_name)
|
||||||
|
|
||||||
coreaux = cdr(aux_controller.DRTIOAuxControllerBare(core.link_layer))
|
coreaux = cdr(drtio_aux_controller.DRTIOAuxControllerBare(core.link_layer))
|
||||||
setattr(self.submodules, coreaux_name, coreaux)
|
setattr(self.submodules, coreaux_name, coreaux)
|
||||||
self.csr_devices.append(coreaux_name)
|
self.csr_devices.append(coreaux_name)
|
||||||
|
|
||||||
@ -330,15 +295,12 @@ class GenericMaster(SoCCore):
|
|||||||
if has_grabber:
|
if has_grabber:
|
||||||
self.rustc_cfg["has_grabber"] = None
|
self.rustc_cfg["has_grabber"] = None
|
||||||
self.add_csr_group("grabber", self.grabber_csr_group)
|
self.add_csr_group("grabber", self.grabber_csr_group)
|
||||||
for grabber in self.grabber_csr_group:
|
|
||||||
self.platform.add_false_path_constraints(
|
|
||||||
self.rtio_crg.cd_rtio.clk, getattr(self, grabber).deserializer.cd_cl.clk)
|
|
||||||
|
|
||||||
|
|
||||||
class GenericSatellite(SoCCore):
|
class GenericSatellite(SoCCore):
|
||||||
def __init__(self, description, acpki=False):
|
def __init__(self, description, acpki=False):
|
||||||
sys_clk_freq = 125e6
|
sys_clk_freq = 125e6
|
||||||
rtio_clk_freq = 125e6
|
rtio_clk_freq = description["rtio_frequency"]
|
||||||
|
|
||||||
self.acpki = acpki
|
self.acpki = acpki
|
||||||
self.rustc_cfg = dict()
|
self.rustc_cfg = dict()
|
||||||
@ -356,7 +318,7 @@ class GenericSatellite(SoCCore):
|
|||||||
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
||||||
|
|
||||||
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
||||||
self.submodules.rtio_crg = _RTIOClockMultiplier(rtio_clk_freq)
|
self.submodules.rtio_crg = RTIOClockMultiplier(rtio_clk_freq)
|
||||||
self.csr_devices.append("rtio_crg")
|
self.csr_devices.append("rtio_crg")
|
||||||
|
|
||||||
data_pads = [platform.request("sfp", i) for i in range(4)]
|
data_pads = [platform.request("sfp", i) for i in range(4)]
|
||||||
@ -412,7 +374,7 @@ class GenericSatellite(SoCCore):
|
|||||||
self.drtio_cri.append(core.cri)
|
self.drtio_cri.append(core.cri)
|
||||||
self.csr_devices.append(corerep_name)
|
self.csr_devices.append(corerep_name)
|
||||||
|
|
||||||
coreaux = cdr(aux_controller.DRTIOAuxControllerBare(core.link_layer))
|
coreaux = cdr(drtio_aux_controller.DRTIOAuxControllerBare(core.link_layer))
|
||||||
setattr(self.submodules, coreaux_name, coreaux)
|
setattr(self.submodules, coreaux_name, coreaux)
|
||||||
self.csr_devices.append(coreaux_name)
|
self.csr_devices.append(coreaux_name)
|
||||||
|
|
||||||
@ -431,6 +393,9 @@ class GenericSatellite(SoCCore):
|
|||||||
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
|
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
|
||||||
self.add_csr_group("drtiorep", drtiorep_csr_group)
|
self.add_csr_group("drtiorep", drtiorep_csr_group)
|
||||||
|
|
||||||
|
self.rustc_cfg["has_si5324"] = None
|
||||||
|
self.rustc_cfg["si5324_soft_reset"] = None
|
||||||
|
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
self.rustc_cfg["ki_impl"] = "acp"
|
self.rustc_cfg["ki_impl"] = "acp"
|
||||||
self.submodules.rtio = acpki.KernelInitiator(self.rtio_tsc,
|
self.submodules.rtio = acpki.KernelInitiator(self.rtio_tsc,
|
||||||
|
@ -15,7 +15,7 @@ from misoc.cores import gpio
|
|||||||
|
|
||||||
from artiq.gateware import rtio, nist_clock, nist_qc2
|
from artiq.gateware import rtio, nist_clock, nist_qc2
|
||||||
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, dds, spi2
|
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, dds, spi2
|
||||||
|
from artiq.gateware.rtio.xilinx_clocking import RTIOClockMultiplier, fix_serdes_timing_path
|
||||||
from artiq.gateware.drtio.transceiver import gtx_7series
|
from artiq.gateware.drtio.transceiver import gtx_7series
|
||||||
from artiq.gateware.drtio.siphaser import SiPhaser7Series
|
from artiq.gateware.drtio.siphaser import SiPhaser7Series
|
||||||
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
|
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
|
||||||
@ -24,7 +24,8 @@ from artiq.gateware.drtio import *
|
|||||||
import dma
|
import dma
|
||||||
import analyzer
|
import analyzer
|
||||||
import acpki
|
import acpki
|
||||||
import aux_controller
|
import drtio_aux_controller
|
||||||
|
|
||||||
|
|
||||||
class RTIOCRG(Module, AutoCSR):
|
class RTIOCRG(Module, AutoCSR):
|
||||||
def __init__(self, platform, rtio_internal_clk):
|
def __init__(self, platform, rtio_internal_clk):
|
||||||
@ -70,48 +71,6 @@ class RTIOCRG(Module, AutoCSR):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class _RTIOClockMultiplier(Module, AutoCSR):
|
|
||||||
def __init__(self, rtio_clk_freq):
|
|
||||||
self.pll_reset = CSRStorage(reset=1)
|
|
||||||
self.pll_locked = CSRStatus()
|
|
||||||
self.clock_domains.cd_rtiox4 = ClockDomain(reset_less=True)
|
|
||||||
|
|
||||||
# See "Global Clock Network Deskew Using Two BUFGs" in ug472.
|
|
||||||
clkfbout = Signal()
|
|
||||||
clkfbin = Signal()
|
|
||||||
rtiox4_clk = Signal()
|
|
||||||
pll_locked = Signal()
|
|
||||||
self.specials += [
|
|
||||||
Instance("MMCME2_BASE",
|
|
||||||
p_CLKIN1_PERIOD=1e9/rtio_clk_freq,
|
|
||||||
i_CLKIN1=ClockSignal("rtio"),
|
|
||||||
i_RST=self.pll_reset.storage,
|
|
||||||
o_LOCKED=pll_locked,
|
|
||||||
|
|
||||||
p_CLKFBOUT_MULT_F=8.0, p_DIVCLK_DIVIDE=1,
|
|
||||||
|
|
||||||
o_CLKFBOUT=clkfbout, i_CLKFBIN=clkfbin,
|
|
||||||
|
|
||||||
p_CLKOUT0_DIVIDE_F=2.0, o_CLKOUT0=rtiox4_clk,
|
|
||||||
),
|
|
||||||
Instance("BUFG", i_I=clkfbout, o_O=clkfbin),
|
|
||||||
Instance("BUFG", i_I=rtiox4_clk, o_O=self.cd_rtiox4.clk),
|
|
||||||
|
|
||||||
MultiReg(pll_locked, self.pll_locked.status)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def fix_serdes_timing_path(platform):
|
|
||||||
# ignore timing of path from OSERDESE2 through the pad to ISERDESE2
|
|
||||||
platform.add_platform_command(
|
|
||||||
"set_false_path -quiet "
|
|
||||||
"-through [get_pins -filter {{REF_PIN_NAME == OQ || REF_PIN_NAME == TQ}} "
|
|
||||||
"-of [get_cells -filter {{REF_NAME == OSERDESE2}}]] "
|
|
||||||
"-to [get_pins -filter {{REF_PIN_NAME == D}} "
|
|
||||||
"-of [get_cells -filter {{REF_NAME == ISERDESE2}}]]"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# The NIST backplanes require setting VADJ to 3.3V by reprogramming the power supply.
|
# The NIST backplanes require setting VADJ to 3.3V by reprogramming the power supply.
|
||||||
# This also changes the I/O standard for some on-board LEDs.
|
# This also changes the I/O standard for some on-board LEDs.
|
||||||
leds_fmc33 = [
|
leds_fmc33 = [
|
||||||
@ -129,6 +88,35 @@ si5324_fmc33 = [
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
pmod1_33 = [
|
||||||
|
("pmod1_33", 0, Pins("AJ21"), IOStandard("LVCMOS33")),
|
||||||
|
("pmod1_33", 1, Pins("AK21"), IOStandard("LVCMOS33")),
|
||||||
|
("pmod1_33", 2, Pins("AB21"), IOStandard("LVCMOS33")),
|
||||||
|
("pmod1_33", 3, Pins("AB16"), IOStandard("LVCMOS33")),
|
||||||
|
# rest removed for use with dummy spi
|
||||||
|
]
|
||||||
|
|
||||||
|
_ams101_dac = [
|
||||||
|
("ams101_dac", 0,
|
||||||
|
Subsignal("ldac", Pins("XADC:GPIO0")),
|
||||||
|
Subsignal("clk", Pins("XADC:GPIO1")),
|
||||||
|
Subsignal("mosi", Pins("XADC:GPIO2")),
|
||||||
|
Subsignal("cs_n", Pins("XADC:GPIO3")),
|
||||||
|
IOStandard("LVCMOS15")
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
_pmod_spi = [
|
||||||
|
("pmod_spi", 0,
|
||||||
|
# PMOD_1 4-7 pins, same bank as sfp_tx_disable or user_sma_clock
|
||||||
|
Subsignal("miso", Pins("Y20"), IOStandard("LVCMOS25")),
|
||||||
|
Subsignal("clk", Pins("AA20"), IOStandard("LVCMOS25")),
|
||||||
|
Subsignal("mosi", Pins("AC18"), IOStandard("LVCMOS25")),
|
||||||
|
Subsignal("cs_n", Pins("AC19"), IOStandard("LVCMOS25")),
|
||||||
|
IOStandard("LVCMOS25")
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def prepare_zc706_platform(platform):
|
def prepare_zc706_platform(platform):
|
||||||
platform.toolchain.bitstream_commands.extend([
|
platform.toolchain.bitstream_commands.extend([
|
||||||
@ -136,7 +124,6 @@ def prepare_zc706_platform(platform):
|
|||||||
])
|
])
|
||||||
platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]")
|
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")
|
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
||||||
return platform
|
|
||||||
|
|
||||||
|
|
||||||
class ZC706(SoCCore):
|
class ZC706(SoCCore):
|
||||||
@ -145,7 +132,7 @@ class ZC706(SoCCore):
|
|||||||
self.rustc_cfg = dict()
|
self.rustc_cfg = dict()
|
||||||
|
|
||||||
platform = zc706.Platform()
|
platform = zc706.Platform()
|
||||||
platform = prepare_zc706_platform(platform)
|
prepare_zc706_platform(platform)
|
||||||
|
|
||||||
ident = self.__class__.__name__
|
ident = self.__class__.__name__
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
@ -194,37 +181,36 @@ class ZC706(SoCCore):
|
|||||||
|
|
||||||
|
|
||||||
class _MasterBase(SoCCore):
|
class _MasterBase(SoCCore):
|
||||||
def __init__(self, acpki=False, use_si5324_33=False):
|
def __init__(self, acpki=False, drtio100mhz=False):
|
||||||
self.acpki = acpki
|
self.acpki = acpki
|
||||||
self.rustc_cfg = dict()
|
self.rustc_cfg = dict()
|
||||||
|
|
||||||
platform = zc706.Platform()
|
platform = zc706.Platform()
|
||||||
platform = prepare_zc706_platform(platform)
|
prepare_zc706_platform(platform)
|
||||||
ident = self.__class__.__name__
|
ident = self.__class__.__name__
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
ident = "acpki_" + ident
|
ident = "acpki_" + ident
|
||||||
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=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")
|
|
||||||
|
|
||||||
if use_si5324_33:
|
|
||||||
platform.add_extension(si5324_fmc33)
|
platform.add_extension(si5324_fmc33)
|
||||||
|
|
||||||
self.sys_clk_freq = 125e6
|
self.sys_clk_freq = 125e6
|
||||||
|
rtio_clk_freq = 100e6 if drtio100mhz else self.sys_clk_freq
|
||||||
|
|
||||||
platform = self.platform
|
platform = self.platform
|
||||||
|
|
||||||
self.comb += platform.request("sfp_tx_disable_n").eq(1)
|
self.comb += platform.request("sfp_tx_disable_n").eq(1)
|
||||||
data_pads = [
|
data_pads = [
|
||||||
platform.request("sfp")
|
platform.request("sfp"),
|
||||||
|
platform.request("user_sma_mgt")
|
||||||
]
|
]
|
||||||
|
|
||||||
# 1000BASE_BX10 Ethernet compatible, 125MHz RTIO clock
|
# 1000BASE_BX10 Ethernet compatible, 125MHz RTIO clock
|
||||||
self.submodules.drtio_transceiver = gtx_7series.GTX(
|
self.submodules.drtio_transceiver = gtx_7series.GTX(
|
||||||
clock_pads=platform.request("si5324_clkout"),
|
clock_pads=platform.request("si5324_clkout"),
|
||||||
pads=data_pads,
|
pads=data_pads,
|
||||||
sys_clk_freq=self.sys_clk_freq)
|
sys_clk_freq=self.sys_clk_freq,
|
||||||
|
rtio_clk_freq=rtio_clk_freq)
|
||||||
self.csr_devices.append("drtio_transceiver")
|
self.csr_devices.append("drtio_transceiver")
|
||||||
|
|
||||||
self.submodules.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3)
|
self.submodules.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3)
|
||||||
@ -249,7 +235,7 @@ class _MasterBase(SoCCore):
|
|||||||
self.drtio_cri.append(core.cri)
|
self.drtio_cri.append(core.cri)
|
||||||
self.csr_devices.append(core_name)
|
self.csr_devices.append(core_name)
|
||||||
|
|
||||||
coreaux = cdr(aux_controller.DRTIOAuxControllerBare(core.link_layer))
|
coreaux = cdr(drtio_aux_controller.DRTIOAuxControllerBare(core.link_layer))
|
||||||
setattr(self.submodules, coreaux_name, coreaux)
|
setattr(self.submodules, coreaux_name, coreaux)
|
||||||
self.csr_devices.append(coreaux_name)
|
self.csr_devices.append(coreaux_name)
|
||||||
|
|
||||||
@ -263,12 +249,9 @@ class _MasterBase(SoCCore):
|
|||||||
self.add_csr_group("drtioaux", drtioaux_csr_group)
|
self.add_csr_group("drtioaux", drtioaux_csr_group)
|
||||||
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
|
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
|
||||||
|
|
||||||
self.rustc_cfg["RTIO_FREQUENCY"] = str(self.drtio_transceiver.rtio_clk_freq/1e6)
|
self.rustc_cfg["rtio_frequency"] = str(self.drtio_transceiver.rtio_clk_freq/1e6)
|
||||||
|
|
||||||
if use_si5324_33:
|
|
||||||
self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324_33").rst_n)
|
self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324_33").rst_n)
|
||||||
else:
|
|
||||||
self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324").rst_n)
|
|
||||||
self.csr_devices.append("si5324_rst_n")
|
self.csr_devices.append("si5324_rst_n")
|
||||||
self.rustc_cfg["has_si5324"] = None
|
self.rustc_cfg["has_si5324"] = None
|
||||||
self.rustc_cfg["si5324_as_synthesizer"] = None
|
self.rustc_cfg["si5324_as_synthesizer"] = None
|
||||||
@ -289,7 +272,7 @@ class _MasterBase(SoCCore):
|
|||||||
platform.add_false_path_constraints(
|
platform.add_false_path_constraints(
|
||||||
self.ps7.cd_sys.clk, gtx0.txoutclk, gtx.rxoutclk)
|
self.ps7.cd_sys.clk, gtx0.txoutclk, gtx.rxoutclk)
|
||||||
|
|
||||||
self.submodules.rtio_crg = _RTIOClockMultiplier(self.sys_clk_freq)
|
self.submodules.rtio_crg = RTIOClockMultiplier(self.sys_clk_freq)
|
||||||
self.csr_devices.append("rtio_crg")
|
self.csr_devices.append("rtio_crg")
|
||||||
fix_serdes_timing_path(self.platform)
|
fix_serdes_timing_path(self.platform)
|
||||||
|
|
||||||
@ -332,27 +315,28 @@ class _MasterBase(SoCCore):
|
|||||||
|
|
||||||
|
|
||||||
class _SatelliteBase(SoCCore):
|
class _SatelliteBase(SoCCore):
|
||||||
def __init__(self, acpki=False, use_si5324_33=False):
|
def __init__(self, acpki=False, drtio100mhz=False):
|
||||||
self.acpki = acpki
|
self.acpki = acpki
|
||||||
self.rustc_cfg = dict()
|
self.rustc_cfg = dict()
|
||||||
|
|
||||||
platform = zc706.Platform()
|
platform = zc706.Platform()
|
||||||
platform = prepare_zc706_platform(platform)
|
prepare_zc706_platform(platform)
|
||||||
ident = self.__class__.__name__
|
ident = self.__class__.__name__
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
ident = "acpki_" + ident
|
ident = "acpki_" + ident
|
||||||
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
||||||
|
|
||||||
if use_si5324_33:
|
|
||||||
platform.add_extension(si5324_fmc33)
|
platform.add_extension(si5324_fmc33)
|
||||||
|
|
||||||
self.sys_clk_freq = 125e6
|
self.sys_clk_freq = 125e6
|
||||||
|
rtio_clk_freq = 100e6 if drtio100mhz else self.sys_clk_freq
|
||||||
platform = self.platform
|
platform = self.platform
|
||||||
|
|
||||||
# SFP
|
# SFP
|
||||||
self.comb += platform.request("sfp_tx_disable_n").eq(0)
|
self.comb += platform.request("sfp_tx_disable_n").eq(0)
|
||||||
data_pads = [
|
data_pads = [
|
||||||
platform.request("sfp")
|
platform.request("sfp"),
|
||||||
|
platform.request("user_sma_mgt")
|
||||||
]
|
]
|
||||||
|
|
||||||
self.submodules.rtio_tsc = rtio.TSC("sync", glbl_fine_ts_width=3)
|
self.submodules.rtio_tsc = rtio.TSC("sync", glbl_fine_ts_width=3)
|
||||||
@ -361,11 +345,13 @@ class _SatelliteBase(SoCCore):
|
|||||||
self.submodules.drtio_transceiver = gtx_7series.GTX(
|
self.submodules.drtio_transceiver = gtx_7series.GTX(
|
||||||
clock_pads=platform.request("si5324_clkout"),
|
clock_pads=platform.request("si5324_clkout"),
|
||||||
pads=data_pads,
|
pads=data_pads,
|
||||||
sys_clk_freq=self.sys_clk_freq)
|
sys_clk_freq=self.sys_clk_freq,
|
||||||
|
rtio_clk_freq=rtio_clk_freq)
|
||||||
self.csr_devices.append("drtio_transceiver")
|
self.csr_devices.append("drtio_transceiver")
|
||||||
|
|
||||||
drtioaux_csr_group = []
|
drtioaux_csr_group = []
|
||||||
drtioaux_memory_group = []
|
drtioaux_memory_group = []
|
||||||
|
drtiorep_csr_group = []
|
||||||
self.drtio_cri = []
|
self.drtio_cri = []
|
||||||
for i in range(len(self.drtio_transceiver.channels)):
|
for i in range(len(self.drtio_transceiver.channels)):
|
||||||
coreaux_name = "drtioaux" + str(i)
|
coreaux_name = "drtioaux" + str(i)
|
||||||
@ -382,10 +368,17 @@ class _SatelliteBase(SoCCore):
|
|||||||
self.rtio_tsc, self.drtio_transceiver.channels[0], self.rx_synchronizer))
|
self.rtio_tsc, self.drtio_transceiver.channels[0], self.rx_synchronizer))
|
||||||
self.submodules.drtiosat = core
|
self.submodules.drtiosat = core
|
||||||
self.csr_devices.append("drtiosat")
|
self.csr_devices.append("drtiosat")
|
||||||
# Repeaters - there would be for i != 0 - however zc706 only has one SFP
|
# Repeaters
|
||||||
# and no other means to connect to
|
else:
|
||||||
|
corerep_name = "drtiorep" + str(i-1)
|
||||||
|
drtiorep_csr_group.append(corerep_name)
|
||||||
|
core = cdr(DRTIORepeater(
|
||||||
|
self.rtio_tsc, self.drtio_transceiver.channels[i]))
|
||||||
|
setattr(self.submodules, corerep_name, core)
|
||||||
|
self.drtio_cri.append(core.cri)
|
||||||
|
self.csr_devices.append(corerep_name)
|
||||||
|
|
||||||
coreaux = cdr(aux_controller.DRTIOAuxControllerBare(core.link_layer))
|
coreaux = cdr(drtio_aux_controller.DRTIOAuxControllerBare(core.link_layer))
|
||||||
setattr(self.submodules, coreaux_name, coreaux)
|
setattr(self.submodules, coreaux_name, coreaux)
|
||||||
self.csr_devices.append(coreaux_name)
|
self.csr_devices.append(coreaux_name)
|
||||||
|
|
||||||
@ -399,8 +392,9 @@ class _SatelliteBase(SoCCore):
|
|||||||
# manually, because software refers to rx/tx by halves of entire memory block, not names
|
# manually, because software refers to rx/tx by halves of entire memory block, not names
|
||||||
self.add_memory_region(memory_name, self.mem_map["csr"] + memory_address, mem_size * 2)
|
self.add_memory_region(memory_name, self.mem_map["csr"] + memory_address, mem_size * 2)
|
||||||
self.rustc_cfg["has_drtio"] = None
|
self.rustc_cfg["has_drtio"] = None
|
||||||
# no repeaters - it does not have drtio routing support
|
self.rustc_cfg["has_drtio_routing"] = None
|
||||||
self.add_csr_group("drtioaux", drtioaux_csr_group)
|
self.add_csr_group("drtioaux", drtioaux_csr_group)
|
||||||
|
self.add_csr_group("drtiorep", drtiorep_csr_group)
|
||||||
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
|
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
|
||||||
|
|
||||||
self.rustc_cfg["rtio_frequency"] = str(self.drtio_transceiver.rtio_clk_freq/1e6)
|
self.rustc_cfg["rtio_frequency"] = str(self.drtio_transceiver.rtio_clk_freq/1e6)
|
||||||
@ -414,10 +408,7 @@ class _SatelliteBase(SoCCore):
|
|||||||
platform.add_false_path_constraints(
|
platform.add_false_path_constraints(
|
||||||
self.ps7.cd_sys.clk, self.siphaser.mmcm_freerun_output)
|
self.ps7.cd_sys.clk, self.siphaser.mmcm_freerun_output)
|
||||||
self.csr_devices.append("siphaser")
|
self.csr_devices.append("siphaser")
|
||||||
if use_si5324_33:
|
|
||||||
self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324_33").rst_n)
|
self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324_33").rst_n)
|
||||||
else:
|
|
||||||
self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324").rst_n)
|
|
||||||
self.csr_devices.append("si5324_rst_n")
|
self.csr_devices.append("si5324_rst_n")
|
||||||
self.rustc_cfg["has_si5324"] = None
|
self.rustc_cfg["has_si5324"] = None
|
||||||
self.rustc_cfg["has_siphaser"] = None
|
self.rustc_cfg["has_siphaser"] = None
|
||||||
@ -438,7 +429,7 @@ class _SatelliteBase(SoCCore):
|
|||||||
platform.add_false_path_constraints(
|
platform.add_false_path_constraints(
|
||||||
self.ps7.cd_sys.clk, gtx.rxoutclk)
|
self.ps7.cd_sys.clk, gtx.rxoutclk)
|
||||||
|
|
||||||
self.submodules.rtio_crg = _RTIOClockMultiplier(self.sys_clk_freq)
|
self.submodules.rtio_crg = RTIOClockMultiplier(self.sys_clk_freq)
|
||||||
self.csr_devices.append("rtio_crg")
|
self.csr_devices.append("rtio_crg")
|
||||||
fix_serdes_timing_path(self.platform)
|
fix_serdes_timing_path(self.platform)
|
||||||
|
|
||||||
@ -469,21 +460,6 @@ class _SatelliteBase(SoCCore):
|
|||||||
self.csr_devices.append("routing_table")
|
self.csr_devices.append("routing_table")
|
||||||
|
|
||||||
|
|
||||||
class _Simple_RTIO:
|
|
||||||
def __init__(self):
|
|
||||||
platform = self.platform
|
|
||||||
|
|
||||||
rtio_channels = []
|
|
||||||
for i in range(4):
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
class _NIST_CLOCK_RTIO:
|
class _NIST_CLOCK_RTIO:
|
||||||
"""
|
"""
|
||||||
@ -493,14 +469,12 @@ class _NIST_CLOCK_RTIO:
|
|||||||
platform = self.platform
|
platform = self.platform
|
||||||
platform.add_extension(nist_clock.fmc_adapter_io)
|
platform.add_extension(nist_clock.fmc_adapter_io)
|
||||||
platform.add_extension(leds_fmc33)
|
platform.add_extension(leds_fmc33)
|
||||||
|
platform.add_extension(pmod1_33)
|
||||||
|
platform.add_extension(_ams101_dac)
|
||||||
|
platform.add_extension(_pmod_spi)
|
||||||
|
|
||||||
rtio_channels = []
|
rtio_channels = []
|
||||||
|
|
||||||
for i in range(4):
|
|
||||||
phy = ttl_simple.Output(platform.request("user_led_33", i))
|
|
||||||
self.submodules += phy
|
|
||||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
|
||||||
|
|
||||||
for i in range(16):
|
for i in range(16):
|
||||||
if i % 4 == 3:
|
if i % 4 == 3:
|
||||||
phy = ttl_serdes_7series.InOut_8X(platform.request("ttl", i))
|
phy = ttl_serdes_7series.InOut_8X(platform.request("ttl", i))
|
||||||
@ -516,16 +490,40 @@ class _NIST_CLOCK_RTIO:
|
|||||||
self.submodules += phy
|
self.submodules += phy
|
||||||
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=512))
|
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=512))
|
||||||
|
|
||||||
|
# no SMA GPIO, replaced with PMOD1_0
|
||||||
|
phy = ttl_serdes_7series.InOut_8X(platform.request("pmod1_33", 0))
|
||||||
|
self.submodules += phy
|
||||||
|
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=512))
|
||||||
|
|
||||||
|
phy = ttl_simple.Output(platform.request("user_led_33", 0))
|
||||||
|
self.submodules += phy
|
||||||
|
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||||
|
|
||||||
|
ams101_dac = self.platform.request("ams101_dac", 0)
|
||||||
|
phy = ttl_simple.Output(ams101_dac.ldac)
|
||||||
|
self.submodules += phy
|
||||||
|
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||||
|
|
||||||
phy = ttl_simple.ClockGen(platform.request("la32_p"))
|
phy = ttl_simple.ClockGen(platform.request("la32_p"))
|
||||||
self.submodules += phy
|
self.submodules += phy
|
||||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||||
|
|
||||||
|
phy = spi2.SPIMaster(ams101_dac)
|
||||||
|
self.submodules += phy
|
||||||
|
rtio_channels.append(rtio.Channel.from_phy(
|
||||||
|
phy, ififo_depth=4))
|
||||||
|
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
phy = spi2.SPIMaster(self.platform.request("spi", i))
|
phy = spi2.SPIMaster(self.platform.request("spi", i))
|
||||||
self.submodules += phy
|
self.submodules += phy
|
||||||
rtio_channels.append(rtio.Channel.from_phy(
|
rtio_channels.append(rtio.Channel.from_phy(
|
||||||
phy, ififo_depth=128))
|
phy, ififo_depth=128))
|
||||||
|
|
||||||
|
# no SDIO on PL side, dummy SPI placeholder instead
|
||||||
|
phy = spi2.SPIMaster(platform.request("pmod_spi"))
|
||||||
|
self.submodules += phy
|
||||||
|
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=4))
|
||||||
|
|
||||||
phy = dds.AD9914(platform.request("dds"), 11, onehot=True)
|
phy = dds.AD9914(platform.request("dds"), 11, onehot=True)
|
||||||
self.submodules += phy
|
self.submodules += phy
|
||||||
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=4))
|
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=4))
|
||||||
@ -545,20 +543,31 @@ class _NIST_QC2_RTIO:
|
|||||||
platform = self.platform
|
platform = self.platform
|
||||||
platform.add_extension(nist_qc2.fmc_adapter_io)
|
platform.add_extension(nist_qc2.fmc_adapter_io)
|
||||||
platform.add_extension(leds_fmc33)
|
platform.add_extension(leds_fmc33)
|
||||||
|
platform.add_extension(_ams101_dac)
|
||||||
|
platform.add_extension(pmod1_33)
|
||||||
|
|
||||||
rtio_channels = []
|
rtio_channels = []
|
||||||
|
|
||||||
for i in range(4):
|
|
||||||
phy = ttl_simple.Output(platform.request("user_led_33", i))
|
|
||||||
self.submodules += phy
|
|
||||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
|
||||||
|
|
||||||
# All TTL channels are In+Out capable
|
# All TTL channels are In+Out capable
|
||||||
for i in range(40):
|
for i in range(40):
|
||||||
phy = ttl_serdes_7series.InOut_8X(platform.request("ttl", i))
|
phy = ttl_serdes_7series.InOut_8X(platform.request("ttl", i))
|
||||||
self.submodules += phy
|
self.submodules += phy
|
||||||
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=512))
|
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=512))
|
||||||
|
|
||||||
|
# no SMA GPIO, replaced with PMOD1_0
|
||||||
|
phy = ttl_serdes_7series.InOut_8X(platform.request("pmod1_33", 0))
|
||||||
|
self.submodules += phy
|
||||||
|
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=512))
|
||||||
|
|
||||||
|
phy = ttl_simple.Output(platform.request("user_led_33", 0))
|
||||||
|
self.submodules += phy
|
||||||
|
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||||
|
|
||||||
|
ams101_dac = self.platform.request("ams101_dac", 0)
|
||||||
|
phy = ttl_simple.Output(ams101_dac.ldac)
|
||||||
|
self.submodules += phy
|
||||||
|
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||||
|
|
||||||
# CLK0, CLK1 are for clock generators, on backplane SMP connectors
|
# CLK0, CLK1 are for clock generators, on backplane SMP connectors
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
phy = ttl_simple.ClockGen(
|
phy = ttl_simple.ClockGen(
|
||||||
@ -566,6 +575,11 @@ class _NIST_QC2_RTIO:
|
|||||||
self.submodules += phy
|
self.submodules += phy
|
||||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||||
|
|
||||||
|
phy = spi2.SPIMaster(ams101_dac)
|
||||||
|
self.submodules += phy
|
||||||
|
rtio_channels.append(rtio.Channel.from_phy(
|
||||||
|
phy, ififo_depth=4))
|
||||||
|
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
phy = spi2.SPIMaster(self.platform.request("spi", i))
|
phy = spi2.SPIMaster(self.platform.request("spi", i))
|
||||||
self.submodules += phy
|
self.submodules += phy
|
||||||
@ -584,55 +598,37 @@ class _NIST_QC2_RTIO:
|
|||||||
self.add_rtio(rtio_channels)
|
self.add_rtio(rtio_channels)
|
||||||
|
|
||||||
|
|
||||||
class Simple(ZC706, _Simple_RTIO):
|
|
||||||
def __init__(self, acpki):
|
|
||||||
ZC706.__init__(self, acpki)
|
|
||||||
_Simple_RTIO.__init__(self)
|
|
||||||
|
|
||||||
class Master(_MasterBase, _Simple_RTIO):
|
|
||||||
def __init__(self, acpki):
|
|
||||||
_MasterBase.__init__(self, acpki, use_si5324_33=False)
|
|
||||||
_Simple_RTIO.__init__(self)
|
|
||||||
|
|
||||||
class Satellite(_SatelliteBase, _Simple_RTIO):
|
|
||||||
def __init__(self, acpki):
|
|
||||||
_SatelliteBase.__init__(self, acpki, use_si5324_33=False)
|
|
||||||
_Simple_RTIO.__init__(self)
|
|
||||||
|
|
||||||
class NIST_CLOCK(ZC706, _NIST_CLOCK_RTIO):
|
class NIST_CLOCK(ZC706, _NIST_CLOCK_RTIO):
|
||||||
def __init__(self, acpki):
|
def __init__(self, acpki, drtio100mhz):
|
||||||
ZC706.__init__(self, acpki)
|
ZC706.__init__(self, acpki)
|
||||||
_NIST_CLOCK_RTIO.__init__(self)
|
_NIST_CLOCK_RTIO.__init__(self)
|
||||||
|
|
||||||
class NIST_CLOCK_Master(_MasterBase, _NIST_CLOCK_RTIO):
|
class NIST_CLOCK_Master(_MasterBase, _NIST_CLOCK_RTIO):
|
||||||
def __init__(self, acpki):
|
def __init__(self, acpki, drtio100mhz):
|
||||||
_MasterBase.__init__(self, acpki, use_si5324_33=True)
|
_MasterBase.__init__(self, acpki, drtio100mhz)
|
||||||
|
|
||||||
_NIST_CLOCK_RTIO.__init__(self)
|
_NIST_CLOCK_RTIO.__init__(self)
|
||||||
|
|
||||||
class NIST_CLOCK_Satellite(_SatelliteBase, _NIST_CLOCK_RTIO):
|
class NIST_CLOCK_Satellite(_SatelliteBase, _NIST_CLOCK_RTIO):
|
||||||
def __init__(self, acpki):
|
def __init__(self, acpki, drtio100mhz):
|
||||||
_SatelliteBase.__init__(self, acpki, use_si5324_33=True)
|
_SatelliteBase.__init__(self, acpki, drtio100mhz)
|
||||||
_NIST_CLOCK_RTIO.__init__(self)
|
_NIST_CLOCK_RTIO.__init__(self)
|
||||||
|
|
||||||
class NIST_QC2(ZC706, _NIST_QC2_RTIO):
|
class NIST_QC2(ZC706, _NIST_QC2_RTIO):
|
||||||
def __init__(self, acpki):
|
def __init__(self, acpki, drtio100mhz):
|
||||||
ZC706.__init__(self, acpki)
|
ZC706.__init__(self, acpki)
|
||||||
_NIST_QC2_RTIO.__init__(self)
|
_NIST_QC2_RTIO.__init__(self)
|
||||||
|
|
||||||
class NIST_QC2_Master(_MasterBase, _NIST_QC2_RTIO):
|
class NIST_QC2_Master(_MasterBase, _NIST_QC2_RTIO):
|
||||||
def __init__(self, acpki):
|
def __init__(self, acpki, drtio100mhz):
|
||||||
_MasterBase.__init__(self, acpki, use_si5324_33=True)
|
_MasterBase.__init__(self, acpki, drtio100mhz)
|
||||||
_NIST_QC2_RTIO.__init__(self)
|
_NIST_QC2_RTIO.__init__(self)
|
||||||
|
|
||||||
class NIST_QC2_Satellite(_SatelliteBase, _NIST_QC2_RTIO):
|
class NIST_QC2_Satellite(_SatelliteBase, _NIST_QC2_RTIO):
|
||||||
def __init__(self, acpki):
|
def __init__(self, acpki, drtio100mhz):
|
||||||
_SatelliteBase.__init__(self, acpki, use_si5324_33=True)
|
_SatelliteBase.__init__(self, acpki, drtio100mhz)
|
||||||
_NIST_QC2_RTIO.__init__(self)
|
_NIST_QC2_RTIO.__init__(self)
|
||||||
|
|
||||||
|
VARIANTS = {cls.__name__.lower(): cls for cls in [NIST_CLOCK, NIST_CLOCK_Master, NIST_CLOCK_Satellite,
|
||||||
VARIANTS = {cls.__name__.lower(): cls for cls in [Simple, Master, Satellite,
|
|
||||||
NIST_CLOCK, NIST_CLOCK_Master, NIST_CLOCK_Satellite,
|
|
||||||
NIST_QC2, NIST_QC2_Master, NIST_QC2_Satellite]}
|
NIST_QC2, NIST_QC2_Master, NIST_QC2_Satellite]}
|
||||||
|
|
||||||
|
|
||||||
@ -667,9 +663,9 @@ def main():
|
|||||||
help="build Rust compiler configuration into the specified file")
|
help="build Rust compiler configuration into the specified file")
|
||||||
parser.add_argument("-g", default=None,
|
parser.add_argument("-g", default=None,
|
||||||
help="build gateware into the specified directory")
|
help="build gateware into the specified directory")
|
||||||
parser.add_argument("-V", "--variant", default="simple",
|
parser.add_argument("-V", "--variant", default="nist_clock",
|
||||||
help="variant: "
|
help="variant: "
|
||||||
"[acpki_]simple/nist_clock/nist_qc2 "
|
"[acpki_]nist_clock/nist_qc2[_master/_satellite][_100mhz]"
|
||||||
"(default: %(default)s)")
|
"(default: %(default)s)")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@ -677,12 +673,15 @@ def main():
|
|||||||
acpki = variant.startswith("acpki_")
|
acpki = variant.startswith("acpki_")
|
||||||
if acpki:
|
if acpki:
|
||||||
variant = variant[6:]
|
variant = variant[6:]
|
||||||
|
drtio100mhz = variant.endswith("_100mhz")
|
||||||
|
if drtio100mhz:
|
||||||
|
variant = variant[:-7]
|
||||||
try:
|
try:
|
||||||
cls = VARIANTS[variant]
|
cls = VARIANTS[variant]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise SystemExit("Invalid variant (-V/--variant)")
|
raise SystemExit("Invalid variant (-V/--variant)")
|
||||||
|
|
||||||
soc = cls(acpki=acpki)
|
soc = cls(acpki=acpki, drtio100mhz=drtio100mhz)
|
||||||
soc.finalize()
|
soc.finalize()
|
||||||
|
|
||||||
if args.r is not None:
|
if args.r is not None:
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use crc;
|
use crc;
|
||||||
|
|
||||||
use core_io::{ErrorKind as IoErrorKind, Error as IoError};
|
use core_io::{ErrorKind as IoErrorKind, Error as IoError};
|
||||||
|
|
||||||
use io::{proto::ProtoRead, proto::ProtoWrite, Cursor};
|
use io::{proto::ProtoRead, proto::ProtoWrite, Cursor};
|
||||||
use libboard_zynq::{timer::GlobalTimer, time::Milliseconds};
|
use libboard_zynq::{timer::GlobalTimer, time::Milliseconds};
|
||||||
use crate::mem::mem::DRTIOAUX_MEM;
|
use crate::mem::mem::DRTIOAUX_MEM;
|
||||||
@ -58,22 +57,15 @@ pub fn has_rx_error(linkno: u8) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_with_swap(src: *mut u8, dst: *mut u8, len: isize) {
|
pub fn copy_work_buffer(src: *mut u16, dst: *mut u16, len: isize) {
|
||||||
// for some reason, everything except checksum arrives
|
// AXI writes must be 4-byte aligned (drtio proto doesn't care for that),
|
||||||
// with byte order swapped. and it must be sent as such too.
|
// and AXI burst reads/writes are not implemented yet in gateware
|
||||||
|
// thus the need for a work buffer for transmitting and copying it over
|
||||||
unsafe {
|
unsafe {
|
||||||
for i in (0..(len-4)).step_by(4) {
|
for i in (0..(len/2)).step_by(2) {
|
||||||
*dst.offset(i) = *src.offset(i+3);
|
*dst.offset(i) = *src.offset(i);
|
||||||
*dst.offset(i+1) = *src.offset(i+2);
|
*dst.offset(i+1) = *src.offset(i+1);
|
||||||
*dst.offset(i+2) = *src.offset(i+1);
|
|
||||||
*dst.offset(i+3) = *src.offset(i);
|
|
||||||
}
|
}
|
||||||
// checksum untouched
|
|
||||||
// unrolled for performance
|
|
||||||
*dst.offset(len-4) = *src.offset(len-4);
|
|
||||||
*dst.offset(len-3) = *src.offset(len-3);
|
|
||||||
*dst.offset(len-2) = *src.offset(len-2);
|
|
||||||
*dst.offset(len-1) = *src.offset(len-1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,11 +75,11 @@ fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, Error>
|
|||||||
let linkidx = linkno as usize;
|
let linkidx = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
|
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
|
||||||
let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2) as *mut u8;
|
let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2) as *mut u16;
|
||||||
let len = (DRTIOAUX[linkidx].aux_rx_length_read)() as usize;
|
let len = (DRTIOAUX[linkidx].aux_rx_length_read)() as usize;
|
||||||
// work buffer, as byte order will need to be swapped, cannot be in place
|
// work buffer to accomodate axi burst reads
|
||||||
let mut buf: [u8; 1024] = [0; 1024];
|
let mut buf: [u8; 1024] = [0; 1024];
|
||||||
copy_with_swap(ptr, buf.as_mut_ptr(), len as isize);
|
copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u16, len as isize);
|
||||||
let result = f(&buf[0..len]);
|
let result = f(&buf[0..len]);
|
||||||
(DRTIOAUX[linkidx].aux_rx_present_write)(1);
|
(DRTIOAUX[linkidx].aux_rx_present_write)(1);
|
||||||
Ok(Some(result?))
|
Ok(Some(result?))
|
||||||
@ -141,12 +133,12 @@ fn transmit<F>(linkno: u8, f: F) -> Result<(), Error>
|
|||||||
let linkno = linkno as usize;
|
let linkno = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
while (DRTIOAUX[linkno].aux_tx_read)() != 0 {}
|
while (DRTIOAUX[linkno].aux_tx_read)() != 0 {}
|
||||||
let ptr = DRTIOAUX_MEM[linkno].base as *mut u8;
|
let ptr = DRTIOAUX_MEM[linkno].base as *mut u16;
|
||||||
let len = DRTIOAUX_MEM[linkno].size / 2;
|
let len = DRTIOAUX_MEM[linkno].size / 2;
|
||||||
// work buffer, works with unaligned mem access
|
// work buffer, works with unaligned mem access
|
||||||
let mut buf: [u8; 1024] = [0; 1024];
|
let mut buf: [u8; 1024] = [0; 1024];
|
||||||
let len = f(&mut buf[0..len])?;
|
let len = f(&mut buf[0..len])?;
|
||||||
copy_with_swap(buf.as_mut_ptr(), ptr, len as isize);
|
copy_work_buffer(buf.as_mut_ptr() as *mut u16, ptr, len as isize);
|
||||||
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
|
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
|
||||||
(DRTIOAUX[linkno].aux_tx_write)(1);
|
(DRTIOAUX[linkno].aux_tx_write)(1);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -10,7 +10,7 @@ use libasync::{task, block_async};
|
|||||||
use io::{proto::ProtoRead, proto::ProtoWrite, Cursor};
|
use io::{proto::ProtoRead, proto::ProtoWrite, Cursor};
|
||||||
use crate::mem::mem::DRTIOAUX_MEM;
|
use crate::mem::mem::DRTIOAUX_MEM;
|
||||||
use crate::pl::csr::DRTIOAUX;
|
use crate::pl::csr::DRTIOAUX;
|
||||||
use crate::drtioaux::{Error, has_rx_error, copy_with_swap};
|
use crate::drtioaux::{Error, has_rx_error, copy_work_buffer};
|
||||||
|
|
||||||
pub use crate::drtioaux_proto::Packet;
|
pub use crate::drtioaux_proto::Packet;
|
||||||
|
|
||||||
@ -42,11 +42,11 @@ async fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, Error>
|
|||||||
let linkidx = linkno as usize;
|
let linkidx = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
|
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
|
||||||
let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2) as *mut u8;
|
let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2) as *mut u16;
|
||||||
let len = (DRTIOAUX[linkidx].aux_rx_length_read)() as usize;
|
let len = (DRTIOAUX[linkidx].aux_rx_length_read)() as usize;
|
||||||
// work buffer, as byte order will need to be swapped, cannot be in place
|
// work buffer to accomodate axi burst reads
|
||||||
let mut buf: [u8; 1024] = [0; 1024];
|
let mut buf: [u8; 1024] = [0; 1024];
|
||||||
copy_with_swap(ptr, buf.as_mut_ptr(), len as isize);
|
copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u16, len as isize);
|
||||||
let result = f(&buf[0..len]);
|
let result = f(&buf[0..len]);
|
||||||
(DRTIOAUX[linkidx].aux_rx_present_write)(1);
|
(DRTIOAUX[linkidx].aux_rx_present_write)(1);
|
||||||
Ok(Some(result?))
|
Ok(Some(result?))
|
||||||
@ -106,12 +106,12 @@ async fn transmit<F>(linkno: u8, f: F) -> Result<(), Error>
|
|||||||
let linkno = linkno as usize;
|
let linkno = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
let _ = block_async!(tx_ready(linkno)).await;
|
let _ = block_async!(tx_ready(linkno)).await;
|
||||||
let ptr = DRTIOAUX_MEM[linkno].base as *mut u8;
|
let ptr = DRTIOAUX_MEM[linkno].base as *mut u16;
|
||||||
let len = DRTIOAUX_MEM[linkno].size / 2;
|
let len = DRTIOAUX_MEM[linkno].size / 2;
|
||||||
// work buffer, works with unaligned mem access
|
// work buffer, works with unaligned mem access
|
||||||
let mut buf: [u8; 1024] = [0; 1024];
|
let mut buf: [u8; 1024] = [0; 1024];
|
||||||
let len = f(&mut buf[0..len])?;
|
let len = f(&mut buf[0..len])?;
|
||||||
copy_with_swap(buf.as_mut_ptr(), ptr, len as isize);
|
copy_work_buffer(buf.as_mut_ptr() as *mut u16, ptr, len as isize);
|
||||||
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
|
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
|
||||||
(DRTIOAUX[linkno].aux_tx_write)(1);
|
(DRTIOAUX[linkno].aux_tx_write)(1);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -54,8 +54,6 @@ pub enum Packet {
|
|||||||
SpiReadReply { succeeded: bool, data: u32 },
|
SpiReadReply { succeeded: bool, data: u32 },
|
||||||
SpiBasicReply { succeeded: bool },
|
SpiBasicReply { succeeded: bool },
|
||||||
|
|
||||||
JdacBasicRequest { destination: u8, dacno: u8, reqno: u8, param: u8 },
|
|
||||||
JdacBasicReply { succeeded: bool, retval: u8 },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Packet {
|
impl Packet {
|
||||||
@ -181,17 +179,6 @@ impl Packet {
|
|||||||
succeeded: reader.read_bool()?
|
succeeded: reader.read_bool()?
|
||||||
},
|
},
|
||||||
|
|
||||||
0xa0 => Packet::JdacBasicRequest {
|
|
||||||
destination: reader.read_u8()?,
|
|
||||||
dacno: reader.read_u8()?,
|
|
||||||
reqno: reader.read_u8()?,
|
|
||||||
param: reader.read_u8()?,
|
|
||||||
},
|
|
||||||
0xa1 => Packet::JdacBasicReply {
|
|
||||||
succeeded: reader.read_bool()?,
|
|
||||||
retval: reader.read_u8()?
|
|
||||||
},
|
|
||||||
|
|
||||||
ty => return Err(Error::UnknownPacket(ty))
|
ty => return Err(Error::UnknownPacket(ty))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -345,18 +332,6 @@ impl Packet {
|
|||||||
writer.write_bool(succeeded)?;
|
writer.write_bool(succeeded)?;
|
||||||
},
|
},
|
||||||
|
|
||||||
Packet::JdacBasicRequest { destination, dacno, reqno, param } => {
|
|
||||||
writer.write_u8(0xa0)?;
|
|
||||||
writer.write_u8(destination)?;
|
|
||||||
writer.write_u8(dacno)?;
|
|
||||||
writer.write_u8(reqno)?;
|
|
||||||
writer.write_u8(param)?;
|
|
||||||
}
|
|
||||||
Packet::JdacBasicReply { succeeded, retval } => {
|
|
||||||
writer.write_u8(0xa1)?;
|
|
||||||
writer.write_bool(succeeded)?;
|
|
||||||
writer.write_u8(retval)?;
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ pub mod si5324;
|
|||||||
pub mod drtioaux;
|
pub mod drtioaux;
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
pub mod drtioaux_async;
|
pub mod drtioaux_async;
|
||||||
|
#[cfg(has_drtio)]
|
||||||
#[path = "../../../build/mem.rs"]
|
#[path = "../../../build/mem.rs"]
|
||||||
pub mod mem;
|
pub mod mem;
|
||||||
|
|
||||||
|
@ -1,5 +1,22 @@
|
|||||||
|
use std::env;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader, Write};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
|
||||||
|
pub fn add_linker_script() {
|
||||||
|
// Put the linker script somewhere the linker can find it
|
||||||
|
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
|
File::create(out.join("link.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("link.x"))
|
||||||
|
.unwrap();
|
||||||
|
println!("cargo:rustc-link-search={}", out.display());
|
||||||
|
|
||||||
|
// Only re-run the build script when link.x is changed,
|
||||||
|
// instead of when any part of the source code changes.
|
||||||
|
println!("cargo:rerun-if-changed=link.x");
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cfg() {
|
pub fn cfg() {
|
||||||
// Handle rustc-cfg file
|
// Handle rustc-cfg file
|
||||||
|
@ -1,21 +1,6 @@
|
|||||||
use std::env;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Write;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
extern crate build_zynq;
|
extern crate build_zynq;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Put the linker script somewhere the linker can find it
|
build_zynq::add_linker_script();
|
||||||
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
|
||||||
File::create(out.join("link.x"))
|
|
||||||
.unwrap()
|
|
||||||
.write_all(include_bytes!("link.x"))
|
|
||||||
.unwrap();
|
|
||||||
println!("cargo:rustc-link-search={}", out.display());
|
|
||||||
|
|
||||||
// Only re-run the build script when link.x is changed,
|
|
||||||
// instead of when any part of the source code changes.
|
|
||||||
println!("cargo:rerun-if-changed=link.x");
|
|
||||||
build_zynq::cfg();
|
build_zynq::cfg();
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ use crate::moninj;
|
|||||||
use crate::mgmt;
|
use crate::mgmt;
|
||||||
use crate::analyzer;
|
use crate::analyzer;
|
||||||
use crate::rtio_mgt;
|
use crate::rtio_mgt;
|
||||||
|
#[cfg(has_drtio)]
|
||||||
use crate::pl;
|
use crate::pl;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
@ -223,13 +224,14 @@ async fn handle_run_kernel(stream: Option<&TcpStream>, control: &Rc<RefCell<kern
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
kernel::Message::KernelFinished => {
|
kernel::Message::KernelFinished(async_errors) => {
|
||||||
if let Some(stream) = stream {
|
if let Some(stream) = stream {
|
||||||
write_header(stream, Reply::KernelFinished).await?;
|
write_header(stream, Reply::KernelFinished).await?;
|
||||||
|
write_i8(stream, async_errors as i8).await?;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
kernel::Message::KernelException(exception, backtrace) => {
|
kernel::Message::KernelException(exception, backtrace, async_errors) => {
|
||||||
match stream {
|
match stream {
|
||||||
Some(stream) => {
|
Some(stream) => {
|
||||||
// only send the exception data to host if there is host,
|
// only send the exception data to host if there is host,
|
||||||
@ -248,6 +250,7 @@ async fn handle_run_kernel(stream: Option<&TcpStream>, control: &Rc<RefCell<kern
|
|||||||
for &addr in backtrace {
|
for &addr in backtrace {
|
||||||
write_i32(stream, addr as i32).await?;
|
write_i32(stream, addr as i32).await?;
|
||||||
}
|
}
|
||||||
|
write_i8(stream, async_errors as i8).await?;
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
error!("Uncaught kernel exception: {:?}", exception);
|
error!("Uncaught kernel exception: {:?}", exception);
|
||||||
|
@ -14,7 +14,7 @@ use libcortex_a9::{
|
|||||||
use libboard_zynq::{mpcore, gic};
|
use libboard_zynq::{mpcore, gic};
|
||||||
use libsupport_zynq::ram;
|
use libsupport_zynq::ram;
|
||||||
use dyld::{self, Library};
|
use dyld::{self, Library};
|
||||||
use crate::{eh_artiq, rtio};
|
use crate::{eh_artiq, get_async_errors, rtio};
|
||||||
use super::{
|
use super::{
|
||||||
api::resolve,
|
api::resolve,
|
||||||
rpc::rpc_send_async,
|
rpc::rpc_send_async,
|
||||||
@ -192,7 +192,8 @@ pub extern "C" fn main_core1() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
info!("kernel finished");
|
info!("kernel finished");
|
||||||
core1_tx.send(Message::KernelFinished);
|
let async_errors = unsafe { get_async_errors() };
|
||||||
|
core1_tx.send(Message::KernelFinished(async_errors));
|
||||||
}
|
}
|
||||||
_ => error!("Core1 received unexpected message: {:?}", message),
|
_ => error!("Core1 received unexpected message: {:?}", message),
|
||||||
}
|
}
|
||||||
@ -216,7 +217,8 @@ pub fn terminate(exception: &'static eh_artiq::Exception<'static>, backtrace: &'
|
|||||||
|
|
||||||
{
|
{
|
||||||
let core1_tx = unsafe { KERNEL_CHANNEL_1TO0.as_mut().unwrap() };
|
let core1_tx = unsafe { KERNEL_CHANNEL_1TO0.as_mut().unwrap() };
|
||||||
core1_tx.send(Message::KernelException(exception, &backtrace[..cursor]));
|
let errors = unsafe { get_async_errors() };
|
||||||
|
core1_tx.send(Message::KernelException(exception, &backtrace[..cursor], errors));
|
||||||
}
|
}
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,8 @@ pub enum Message {
|
|||||||
LoadCompleted,
|
LoadCompleted,
|
||||||
LoadFailed,
|
LoadFailed,
|
||||||
StartRequest,
|
StartRequest,
|
||||||
KernelFinished,
|
KernelFinished(u8),
|
||||||
KernelException(&'static eh_artiq::Exception<'static>, &'static [usize]),
|
KernelException(&'static eh_artiq::Exception<'static>, &'static [usize], u8),
|
||||||
RpcSend { is_async: bool, data: Vec<u8> },
|
RpcSend { is_async: bool, data: Vec<u8> },
|
||||||
RpcRecvRequest(*mut ()),
|
RpcRecvRequest(*mut ()),
|
||||||
RpcRecvReply(Result<usize, RPCException>),
|
RpcRecvReply(Result<usize, RPCException>),
|
||||||
|
@ -18,12 +18,9 @@ use libasync::{task, block_async};
|
|||||||
use libsupport_zynq::ram;
|
use libsupport_zynq::ram;
|
||||||
use nb;
|
use nb;
|
||||||
use void::Void;
|
use void::Void;
|
||||||
use embedded_hal::blocking::delay::DelayMs;
|
|
||||||
use libconfig::Config;
|
use libconfig::Config;
|
||||||
use libcortex_a9::l2c::enable_l2_cache;
|
use libcortex_a9::l2c::enable_l2_cache;
|
||||||
use libboard_artiq::{logger, identifier_read, init_gateware, pl};
|
use libboard_artiq::{logger, identifier_read, init_gateware, pl};
|
||||||
#[cfg(has_si5324)]
|
|
||||||
use libboard_artiq::si5324;
|
|
||||||
|
|
||||||
mod proto_async;
|
mod proto_async;
|
||||||
mod comms;
|
mod comms;
|
||||||
@ -35,6 +32,7 @@ mod rtio;
|
|||||||
#[path = "rtio_acp.rs"]
|
#[path = "rtio_acp.rs"]
|
||||||
mod rtio;
|
mod rtio;
|
||||||
mod rtio_mgt;
|
mod rtio_mgt;
|
||||||
|
mod rtio_clocking;
|
||||||
mod kernel;
|
mod kernel;
|
||||||
mod moninj;
|
mod moninj;
|
||||||
mod eh_artiq;
|
mod eh_artiq;
|
||||||
@ -44,66 +42,14 @@ mod analyzer;
|
|||||||
mod irq;
|
mod irq;
|
||||||
mod i2c;
|
mod i2c;
|
||||||
|
|
||||||
fn init_rtio(timer: &mut GlobalTimer, _cfg: &Config) {
|
static mut SEEN_ASYNC_ERRORS: u8 = 0;
|
||||||
#[cfg(has_rtio_crg_clock_sel)]
|
|
||||||
let clock_sel =
|
|
||||||
if let Ok(rtioclk) = _cfg.read_str("rtioclk") {
|
|
||||||
match rtioclk.as_ref() {
|
|
||||||
"internal" => {
|
|
||||||
info!("using internal RTIO clock");
|
|
||||||
0
|
|
||||||
},
|
|
||||||
"external" => {
|
|
||||||
info!("using external RTIO clock");
|
|
||||||
1
|
|
||||||
},
|
|
||||||
other => {
|
|
||||||
warn!("RTIO clock specification '{}' not recognized", other);
|
|
||||||
info!("using internal RTIO clock");
|
|
||||||
0
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
info!("using internal RTIO clock (default)");
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
loop {
|
pub unsafe fn get_async_errors() -> u8 {
|
||||||
unsafe {
|
let errors = SEEN_ASYNC_ERRORS;
|
||||||
pl::csr::rtio_crg::pll_reset_write(1);
|
SEEN_ASYNC_ERRORS = 0;
|
||||||
#[cfg(has_rtio_crg_clock_sel)]
|
errors
|
||||||
pl::csr::rtio_crg::clock_sel_write(clock_sel);
|
|
||||||
pl::csr::rtio_crg::pll_reset_write(0);
|
|
||||||
}
|
|
||||||
timer.delay_ms(1);
|
|
||||||
let locked = unsafe { pl::csr::rtio_crg::pll_locked_read() != 0 };
|
|
||||||
if locked {
|
|
||||||
info!("RTIO PLL locked");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
warn!("RTIO PLL failed to lock, retrying...");
|
|
||||||
timer.delay_ms(500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
pl::csr::rtio_core::reset_phy_write(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
|
||||||
fn init_drtio(timer: &mut GlobalTimer)
|
|
||||||
{
|
|
||||||
unsafe {
|
|
||||||
pl::csr::drtio_transceiver::stable_clkin_write(1);
|
|
||||||
}
|
|
||||||
timer.delay_ms(2); // wait for CPLL/QPLL lock
|
|
||||||
unsafe {
|
|
||||||
pl::csr::drtio_transceiver::txenable_write(0xffffffffu32 as _);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn wait_for_async_rtio_error() -> nb::Result<(), Void> {
|
fn wait_for_async_rtio_error() -> nb::Result<(), Void> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if pl::csr::rtio_core::async_error_read() != 0 {
|
if pl::csr::rtio_core::async_error_read() != 0 {
|
||||||
@ -131,24 +77,13 @@ async fn report_async_rtio_errors() {
|
|||||||
error!("RTIO sequence error involving channel {}",
|
error!("RTIO sequence error involving channel {}",
|
||||||
pl::csr::rtio_core::sequence_error_channel_read());
|
pl::csr::rtio_core::sequence_error_channel_read());
|
||||||
}
|
}
|
||||||
|
SEEN_ASYNC_ERRORS = errors;
|
||||||
pl::csr::rtio_core::async_error_write(errors);
|
pl::csr::rtio_core::async_error_write(errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_si5324)]
|
|
||||||
// 125MHz output, from crystal, 7 Hz
|
|
||||||
const SI5324_SETTINGS: si5324::FrequencySettings
|
|
||||||
= si5324::FrequencySettings {
|
|
||||||
n1_hs : 10,
|
|
||||||
nc1_ls : 4,
|
|
||||||
n2_hs : 10,
|
|
||||||
n2_ls : 19972,
|
|
||||||
n31 : 4565,
|
|
||||||
n32 : 4565,
|
|
||||||
bwsel : 4,
|
|
||||||
crystal_ref: true
|
|
||||||
};
|
|
||||||
|
|
||||||
static mut LOG_BUFFER: [u8; 1<<17] = [0; 1<<17];
|
static mut LOG_BUFFER: [u8; 1<<17] = [0; 1<<17];
|
||||||
|
|
||||||
@ -173,9 +108,6 @@ pub fn main_core0() {
|
|||||||
info!("detected gateware: {}", identifier_read(&mut [0; 64]));
|
info!("detected gateware: {}", identifier_read(&mut [0; 64]));
|
||||||
|
|
||||||
i2c::init();
|
i2c::init();
|
||||||
#[cfg(has_si5324)]
|
|
||||||
si5324::setup(unsafe { (&mut i2c::I2C_BUS).as_mut().unwrap() },
|
|
||||||
&SI5324_SETTINGS, si5324::Input::Ckin2, &mut timer).expect("cannot initialize Si5324");
|
|
||||||
|
|
||||||
let cfg = match Config::new() {
|
let cfg = match Config::new() {
|
||||||
Ok(cfg) => cfg,
|
Ok(cfg) => cfg,
|
||||||
@ -185,10 +117,8 @@ pub fn main_core0() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
rtio_clocking::init(&mut timer, &cfg);
|
||||||
init_drtio(&mut timer);
|
|
||||||
|
|
||||||
init_rtio(&mut timer, &cfg);
|
|
||||||
task::spawn(report_async_rtio_errors());
|
task::spawn(report_async_rtio_errors());
|
||||||
|
|
||||||
comms::main(timer, cfg);
|
comms::main(timer, cfg);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use core::{fmt, cell::RefCell};
|
use core::{fmt, cell::RefCell};
|
||||||
use alloc::{collections::BTreeMap, rc::Rc};
|
use alloc::{collections::BTreeMap, rc::Rc};
|
||||||
use log::{debug, info, warn, error};
|
use log::{debug, info, warn};
|
||||||
use void::Void;
|
use void::Void;
|
||||||
|
|
||||||
use libboard_artiq::drtio_routing;
|
use libboard_artiq::drtio_routing;
|
||||||
@ -60,6 +60,7 @@ mod remote_moninj {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use libboard_artiq::drtioaux;
|
use libboard_artiq::drtioaux;
|
||||||
use crate::rtio_mgt::drtio;
|
use crate::rtio_mgt::drtio;
|
||||||
|
use log::error;
|
||||||
|
|
||||||
pub fn read_probe(aux_mutex: &Rc<Mutex<bool>>, timer: GlobalTimer, linkno: u8, destination: u8, channel: i32, probe: i8) -> i32 {
|
pub fn read_probe(aux_mutex: &Rc<Mutex<bool>>, timer: GlobalTimer, linkno: u8, destination: u8, channel: i32, probe: i8) -> i32 {
|
||||||
let reply = task::block_on(drtio::aux_transact(aux_mutex, linkno, &drtioaux::Packet::MonitorRequest {
|
let reply = task::block_on(drtio::aux_transact(aux_mutex, linkno, &drtioaux::Packet::MonitorRequest {
|
||||||
@ -151,7 +152,7 @@ macro_rules! dispatch {
|
|||||||
macro_rules! dispatch {
|
macro_rules! dispatch {
|
||||||
($timer:ident, $aux_mutex:ident, $routing_table:ident, $channel:expr, $func:ident $(, $param:expr)*) => {{
|
($timer:ident, $aux_mutex:ident, $routing_table:ident, $channel:expr, $func:ident $(, $param:expr)*) => {{
|
||||||
let channel = $channel as u16;
|
let channel = $channel as u16;
|
||||||
local_moninj::$func(channel, $($param, )*)
|
local_moninj::$func(channel.into(), $($param, )*)
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
238
src/runtime/src/rtio_clocking.rs
Normal file
238
src/runtime/src/rtio_clocking.rs
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
use log::{info, warn};
|
||||||
|
use libboard_zynq::timer::GlobalTimer;
|
||||||
|
use embedded_hal::blocking::delay::DelayMs;
|
||||||
|
use libconfig::Config;
|
||||||
|
use libboard_artiq::pl;
|
||||||
|
#[cfg(has_si5324)]
|
||||||
|
use libboard_zynq::i2c::I2c;
|
||||||
|
#[cfg(has_si5324)]
|
||||||
|
use crate::i2c;
|
||||||
|
#[cfg(has_si5324)]
|
||||||
|
use libboard_artiq::si5324;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub enum RtioClock {
|
||||||
|
Default,
|
||||||
|
Int_125,
|
||||||
|
Int_100,
|
||||||
|
Int_150,
|
||||||
|
Ext0_Bypass,
|
||||||
|
Ext0_Synth0_10to125,
|
||||||
|
Ext0_Synth0_100to125,
|
||||||
|
Ext0_Synth0_125to125,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unreachable_code)]
|
||||||
|
fn get_rtio_clock_cfg(cfg: &Config) -> RtioClock {
|
||||||
|
let mut res = RtioClock::Default;
|
||||||
|
if let Ok(clk) = cfg.read_str("rtio_clock") {
|
||||||
|
res = match clk.as_ref() {
|
||||||
|
"int_125" => RtioClock::Int_125,
|
||||||
|
"int_100" => RtioClock::Int_100,
|
||||||
|
"int_150" => RtioClock::Int_150,
|
||||||
|
"ext0_bypass" => RtioClock::Ext0_Bypass,
|
||||||
|
"ext0_bypass_125" => RtioClock::Ext0_Bypass,
|
||||||
|
"ext0_bypass_100" => RtioClock::Ext0_Bypass,
|
||||||
|
"ext0_synth0_10to125" => RtioClock::Ext0_Synth0_10to125,
|
||||||
|
"ext0_synth0_100to125" => RtioClock::Ext0_Synth0_100to125,
|
||||||
|
"ext0_synth0_125to125" => RtioClock::Ext0_Synth0_125to125,
|
||||||
|
_ => {
|
||||||
|
warn!("Unrecognised rtio_clock setting. Falling back to default.");
|
||||||
|
RtioClock::Default
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
warn!("error reading configuration. Falling back to default.");
|
||||||
|
}
|
||||||
|
if res == RtioClock::Default {
|
||||||
|
#[cfg(rtio_frequency="100.0")]
|
||||||
|
{
|
||||||
|
warn!("Using default configuration - internal 100MHz RTIO clock.");
|
||||||
|
return RtioClock::Int_100;
|
||||||
|
}
|
||||||
|
#[cfg(rtio_frequency="125.0")]
|
||||||
|
{
|
||||||
|
warn!("Using default configuration - internal 125MHz RTIO clock.");
|
||||||
|
return RtioClock::Int_125;
|
||||||
|
}
|
||||||
|
// anything else
|
||||||
|
{
|
||||||
|
warn!("Using default configuration - internal 125MHz RTIO clock.");
|
||||||
|
return RtioClock::Int_125;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn init_rtio(timer: &mut GlobalTimer, _clk: RtioClock) {
|
||||||
|
#[cfg(has_rtio_crg_clock_sel)]
|
||||||
|
let clock_sel = match _clk {
|
||||||
|
RtioClock::Ext0_Bypass => {
|
||||||
|
info!("Using bypassed external clock");
|
||||||
|
1
|
||||||
|
},
|
||||||
|
RtioClock::Int_125 => {
|
||||||
|
info!("Using internal RTIO clock");
|
||||||
|
0
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
warn!("rtio_clock setting '{:?}' is not supported. Using default internal RTIO clock instead", _clk);
|
||||||
|
0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
loop {
|
||||||
|
unsafe {
|
||||||
|
pl::csr::rtio_crg::pll_reset_write(1);
|
||||||
|
#[cfg(has_rtio_crg_clock_sel)]
|
||||||
|
pl::csr::rtio_crg::clock_sel_write(clock_sel);
|
||||||
|
pl::csr::rtio_crg::pll_reset_write(0);
|
||||||
|
}
|
||||||
|
timer.delay_ms(1);
|
||||||
|
let locked = unsafe { pl::csr::rtio_crg::pll_locked_read() != 0 };
|
||||||
|
if locked {
|
||||||
|
info!("RTIO PLL locked");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
warn!("RTIO PLL failed to lock, retrying...");
|
||||||
|
timer.delay_ms(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
pl::csr::rtio_core::reset_phy_write(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
fn init_drtio(timer: &mut GlobalTimer)
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
pl::csr::drtio_transceiver::stable_clkin_write(1);
|
||||||
|
}
|
||||||
|
timer.delay_ms(2); // wait for CPLL/QPLL lock
|
||||||
|
unsafe {
|
||||||
|
pl::csr::drtio_transceiver::txenable_write(0xffffffffu32 as _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(has_si5324)]
|
||||||
|
fn setup_si5324(i2c: &mut I2c, timer: &mut GlobalTimer, clk: RtioClock) {
|
||||||
|
let si5324_settings = match clk {
|
||||||
|
RtioClock::Ext0_Synth0_10to125 => { // 125 MHz output from 10 MHz CLKINx reference, 504 Hz BW
|
||||||
|
info!("using 10MHz reference to make 125MHz RTIO clock with PLL");
|
||||||
|
si5324::FrequencySettings {
|
||||||
|
n1_hs : 10,
|
||||||
|
nc1_ls : 4,
|
||||||
|
n2_hs : 10,
|
||||||
|
n2_ls : 300,
|
||||||
|
n31 : 6,
|
||||||
|
n32 : 6,
|
||||||
|
bwsel : 4,
|
||||||
|
crystal_ref: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RtioClock::Ext0_Synth0_100to125 => { // 125MHz output, from 100MHz CLKINx reference, 586 Hz loop bandwidth
|
||||||
|
info!("using 10MHz reference to make 125MHz RTIO clock with PLL");
|
||||||
|
si5324::FrequencySettings {
|
||||||
|
n1_hs : 10,
|
||||||
|
nc1_ls : 4,
|
||||||
|
n2_hs : 10,
|
||||||
|
n2_ls : 260,
|
||||||
|
n31 : 52,
|
||||||
|
n32 : 52,
|
||||||
|
bwsel : 4,
|
||||||
|
crystal_ref: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RtioClock::Ext0_Synth0_125to125 => { // 125MHz output, from 125MHz CLKINx reference, 606 Hz loop bandwidth
|
||||||
|
info!("using 10MHz reference to make 125MHz RTIO clock with PLL");
|
||||||
|
si5324::FrequencySettings {
|
||||||
|
n1_hs : 5,
|
||||||
|
nc1_ls : 8,
|
||||||
|
n2_hs : 7,
|
||||||
|
n2_ls : 360,
|
||||||
|
n31 : 63,
|
||||||
|
n32 : 63,
|
||||||
|
bwsel : 4,
|
||||||
|
crystal_ref: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RtioClock::Int_150 => { // 150MHz output, from crystal
|
||||||
|
info!("using internal 150MHz RTIO clock");
|
||||||
|
si5324::FrequencySettings {
|
||||||
|
n1_hs : 9,
|
||||||
|
nc1_ls : 4,
|
||||||
|
n2_hs : 10,
|
||||||
|
n2_ls : 33732,
|
||||||
|
n31 : 7139,
|
||||||
|
n32 : 7139,
|
||||||
|
bwsel : 3,
|
||||||
|
crystal_ref: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RtioClock::Int_100 => { // 100MHz output, from crystal.
|
||||||
|
info!("using internal 100MHz RTIO clock");
|
||||||
|
si5324::FrequencySettings {
|
||||||
|
n1_hs : 9,
|
||||||
|
nc1_ls : 6,
|
||||||
|
n2_hs : 10,
|
||||||
|
n2_ls : 33732,
|
||||||
|
n31 : 7139,
|
||||||
|
n32 : 7139,
|
||||||
|
bwsel : 3,
|
||||||
|
crystal_ref: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RtioClock::Int_125 => { // 125MHz output, from crystal, 7 Hz
|
||||||
|
info!("using internal 125MHz RTIO clock");
|
||||||
|
si5324::FrequencySettings {
|
||||||
|
n1_hs : 10,
|
||||||
|
nc1_ls : 4,
|
||||||
|
n2_hs : 10,
|
||||||
|
n2_ls : 19972,
|
||||||
|
n31 : 4565,
|
||||||
|
n32 : 4565,
|
||||||
|
bwsel : 4,
|
||||||
|
crystal_ref: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => { // same setting as Int_125, but fallback to default
|
||||||
|
warn!("rtio_clock setting '{:?}' is unsupported. Falling back to default internal 125MHz RTIO clock.", clk);
|
||||||
|
si5324::FrequencySettings {
|
||||||
|
n1_hs : 10,
|
||||||
|
nc1_ls : 4,
|
||||||
|
n2_hs : 10,
|
||||||
|
n2_ls : 19972,
|
||||||
|
n31 : 4565,
|
||||||
|
n32 : 4565,
|
||||||
|
bwsel : 4,
|
||||||
|
crystal_ref: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let si5324_ref_input = si5324::Input::Ckin2;
|
||||||
|
si5324::setup(i2c, &si5324_settings, si5324_ref_input, timer).expect("cannot initialize Si5324");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(timer: &mut GlobalTimer, cfg: &Config) {
|
||||||
|
|
||||||
|
let clk = get_rtio_clock_cfg(cfg);
|
||||||
|
#[cfg(has_si5324)]
|
||||||
|
{
|
||||||
|
let i2c = unsafe { (&mut i2c::I2C_BUS).as_mut().unwrap() };
|
||||||
|
let si5324_ext_input = si5324::Input::Ckin2;
|
||||||
|
match clk {
|
||||||
|
RtioClock::Ext0_Bypass => si5324::bypass(i2c, si5324_ext_input, timer).expect("cannot bypass Si5324"),
|
||||||
|
_ => setup_si5324(i2c, timer, clk),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
init_drtio(timer);
|
||||||
|
|
||||||
|
init_rtio(timer, clk);
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
use libboard_zynq::{timer::GlobalTimer, time::Milliseconds};
|
use libboard_zynq::timer::GlobalTimer;
|
||||||
use libboard_artiq::{pl::csr, drtio_routing};
|
use libboard_artiq::{pl::csr, drtio_routing};
|
||||||
use libcortex_a9::mutex::Mutex;
|
use libcortex_a9::mutex::Mutex;
|
||||||
|
|
||||||
@ -14,6 +14,7 @@ pub mod drtio {
|
|||||||
use log::{warn, error, info};
|
use log::{warn, error, info};
|
||||||
use embedded_hal::blocking::delay::DelayMs;
|
use embedded_hal::blocking::delay::DelayMs;
|
||||||
use libasync::{task, delay};
|
use libasync::{task, delay};
|
||||||
|
use libboard_zynq::time::Milliseconds;
|
||||||
|
|
||||||
pub fn startup(aux_mutex: &Rc<Mutex<bool>>,
|
pub fn startup(aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &Rc<RefCell<drtio_routing::RoutingTable>>,
|
routing_table: &Rc<RefCell<drtio_routing::RoutingTable>>,
|
||||||
@ -24,7 +25,7 @@ pub mod drtio {
|
|||||||
let up_destinations = up_destinations.clone();
|
let up_destinations = up_destinations.clone();
|
||||||
task::spawn(async move {
|
task::spawn(async move {
|
||||||
let routing_table = routing_table.borrow();
|
let routing_table = routing_table.borrow();
|
||||||
link_thread(&aux_mutex, &routing_table, &up_destinations, timer).await;
|
link_task(&aux_mutex, &routing_table, &up_destinations, timer).await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +246,7 @@ pub mod drtio {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn link_thread(aux_mutex: &Rc<Mutex<bool>>,
|
pub async fn link_task(aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &drtio_routing::RoutingTable,
|
||||||
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
timer: GlobalTimer) {
|
timer: GlobalTimer) {
|
||||||
|
@ -1,21 +1,6 @@
|
|||||||
use std::env;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Write;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
extern crate build_zynq;
|
extern crate build_zynq;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Put the linker script somewhere the linker can find it
|
build_zynq::add_linker_script();
|
||||||
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
|
||||||
File::create(out.join("link.x"))
|
|
||||||
.unwrap()
|
|
||||||
.write_all(include_bytes!("link.x"))
|
|
||||||
.unwrap();
|
|
||||||
println!("cargo:rustc-link-search={}", out.display());
|
|
||||||
|
|
||||||
// Only re-run the build script when link.x is changed,
|
|
||||||
// instead of when any part of the source code changes.
|
|
||||||
println!("cargo:rerun-if-changed=link.x");
|
|
||||||
build_zynq::cfg();
|
build_zynq::cfg();
|
||||||
}
|
}
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
ENTRY(Reset);
|
|
||||||
|
|
||||||
MEMORY
|
|
||||||
{
|
|
||||||
SDRAM : ORIGIN = 0x00100000, LENGTH = 0x1FF00000
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
__text_start = .;
|
|
||||||
.text :
|
|
||||||
{
|
|
||||||
KEEP(*(.text.exceptions));
|
|
||||||
*(.text.boot);
|
|
||||||
*(.text .text.*);
|
|
||||||
} > SDRAM
|
|
||||||
__text_end = .;
|
|
||||||
|
|
||||||
__exidx_start = .;
|
|
||||||
.ARM.exidx :
|
|
||||||
{
|
|
||||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
|
||||||
} > SDRAM
|
|
||||||
__exidx_end = .;
|
|
||||||
|
|
||||||
.ARM.extab :
|
|
||||||
{
|
|
||||||
* (.ARM.extab*)
|
|
||||||
} > SDRAM
|
|
||||||
|
|
||||||
.rodata : ALIGN(4)
|
|
||||||
{
|
|
||||||
*(.rodata .rodata.*);
|
|
||||||
} > SDRAM
|
|
||||||
|
|
||||||
.data : ALIGN(4)
|
|
||||||
{
|
|
||||||
*(.data .data.*);
|
|
||||||
} > SDRAM
|
|
||||||
|
|
||||||
.bss (NOLOAD) : ALIGN(4)
|
|
||||||
{
|
|
||||||
__bss_start = .;
|
|
||||||
*(.bss .bss.*);
|
|
||||||
. = ALIGN(4);
|
|
||||||
__bss_end = .;
|
|
||||||
} > SDRAM
|
|
||||||
|
|
||||||
.heap (NOLOAD) : ALIGN(8)
|
|
||||||
{
|
|
||||||
__heap0_start = .;
|
|
||||||
. += 0x8000000;
|
|
||||||
__heap0_end = .;
|
|
||||||
__heap1_start = .;
|
|
||||||
. += 0x8000000;
|
|
||||||
__heap1_end = .;
|
|
||||||
} > SDRAM
|
|
||||||
|
|
||||||
.stack1 (NOLOAD) : ALIGN(8)
|
|
||||||
{
|
|
||||||
__stack1_end = .;
|
|
||||||
. += 0x1000000;
|
|
||||||
__stack1_start = .;
|
|
||||||
} > SDRAM
|
|
||||||
|
|
||||||
.stack0 (NOLOAD) : ALIGN(8)
|
|
||||||
{
|
|
||||||
__stack0_end = .;
|
|
||||||
. += 0x20000;
|
|
||||||
__stack0_start = .;
|
|
||||||
} > SDRAM
|
|
||||||
|
|
||||||
.irq_stack1 (NOLOAD) : ALIGN(8)
|
|
||||||
{
|
|
||||||
__irq_stack1_end = .;
|
|
||||||
. += 0x100;
|
|
||||||
__irq_stack1_start = .;
|
|
||||||
} > SDRAM
|
|
||||||
|
|
||||||
.irq_stack0 (NOLOAD) : ALIGN(8)
|
|
||||||
{
|
|
||||||
__irq_stack0_end = .;
|
|
||||||
. += 0x100;
|
|
||||||
__irq_stack0_start = .;
|
|
||||||
} > SDRAM
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
INCLUDE generated/output_format.ld
|
|
||||||
INCLUDE generated/regions.ld
|
|
||||||
ENTRY(_reset_handler)
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
.vectors :
|
|
||||||
{
|
|
||||||
*(.vectors)
|
|
||||||
} > main_ram
|
|
||||||
|
|
||||||
.text :
|
|
||||||
{
|
|
||||||
*(.text .text.*)
|
|
||||||
} > main_ram
|
|
||||||
|
|
||||||
/* https://sourceware.org/bugzilla/show_bug.cgi?id=20475 */
|
|
||||||
.got :
|
|
||||||
{
|
|
||||||
PROVIDE(_GLOBAL_OFFSET_TABLE_ = .);
|
|
||||||
*(.got)
|
|
||||||
} > main_ram
|
|
||||||
|
|
||||||
.got.plt :
|
|
||||||
{
|
|
||||||
*(.got.plt)
|
|
||||||
} > main_ram
|
|
||||||
|
|
||||||
.rodata :
|
|
||||||
{
|
|
||||||
_frodata = .;
|
|
||||||
*(.rodata .rodata.*)
|
|
||||||
_erodata = .;
|
|
||||||
} > main_ram
|
|
||||||
|
|
||||||
.data :
|
|
||||||
{
|
|
||||||
*(.data .data.*)
|
|
||||||
} > main_ram
|
|
||||||
|
|
||||||
.bss ALIGN(4) :
|
|
||||||
{
|
|
||||||
_fbss = .;
|
|
||||||
*(.bss .bss.*)
|
|
||||||
. = ALIGN(4);
|
|
||||||
_ebss = .;
|
|
||||||
} > main_ram
|
|
||||||
|
|
||||||
.stack :
|
|
||||||
{
|
|
||||||
_estack = .;
|
|
||||||
. += 0x10000;
|
|
||||||
_fstack = . - 4;
|
|
||||||
} > main_ram
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
pub const INIT: u8 = 0x00;
|
|
||||||
pub const PRINT_STATUS: u8 = 0x01;
|
|
||||||
pub const PRBS: u8 = 0x02;
|
|
||||||
pub const STPL: u8 = 0x03;
|
|
||||||
|
|
||||||
pub const SYSREF_DELAY_DAC: u8 = 0x10;
|
|
||||||
pub const SYSREF_SLIP: u8 = 0x11;
|
|
||||||
pub const SYNC: u8 = 0x12;
|
|
||||||
|
|
||||||
pub const DDMTD_SYSREF_RAW: u8 = 0x20;
|
|
||||||
pub const DDMTD_SYSREF: u8 = 0x21;
|
|
||||||
|
|
||||||
|
|
||||||
fn average_2phases(a: i32, b: i32, modulo: i32) -> i32 {
|
|
||||||
let diff = ((a - b + modulo/2 + modulo) % modulo) - modulo/2;
|
|
||||||
return (modulo + b + diff/2) % modulo;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn average_phases(phases: &[i32], modulo: i32) -> i32 {
|
|
||||||
if phases.len() == 1 {
|
|
||||||
panic!("input array length must be a power of 2");
|
|
||||||
} else if phases.len() == 2 {
|
|
||||||
average_2phases(phases[0], phases[1], modulo)
|
|
||||||
} else {
|
|
||||||
let cut = phases.len()/2;
|
|
||||||
average_2phases(
|
|
||||||
average_phases(&phases[..cut], modulo),
|
|
||||||
average_phases(&phases[cut..], modulo),
|
|
||||||
modulo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const RAW_DDMTD_N_SHIFT: i32 = 6;
|
|
||||||
pub const RAW_DDMTD_N: i32 = 1 << RAW_DDMTD_N_SHIFT;
|
|
||||||
pub const DDMTD_DITHER_BITS: i32 = 1;
|
|
||||||
pub const DDMTD_N_SHIFT: i32 = RAW_DDMTD_N_SHIFT + DDMTD_DITHER_BITS;
|
|
||||||
pub const DDMTD_N: i32 = 1 << DDMTD_N_SHIFT;
|
|
@ -311,14 +311,6 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
|||||||
&drtioaux::Packet::SpiReadReply { succeeded: false, data: 0 })
|
&drtioaux::Packet::SpiReadReply { succeeded: false, data: 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
drtioaux::Packet::JdacBasicRequest { destination: _destination, dacno: _dacno,
|
|
||||||
reqno: _reqno, param: _param } => {
|
|
||||||
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
|
||||||
let (succeeded, retval) = (false, 0);
|
|
||||||
drtioaux::send(0,
|
|
||||||
&drtioaux::Packet::JdacBasicReply { succeeded: succeeded, retval: retval })
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
warn!("received unexpected aux packet");
|
warn!("received unexpected aux packet");
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -406,7 +398,7 @@ fn hardware_tick(ts: &mut u64, timer: &mut GlobalTimer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_si5324)]
|
#[cfg(all(has_si5324, rtio_frequency = "125.0"))]
|
||||||
const SI5324_SETTINGS: si5324::FrequencySettings
|
const SI5324_SETTINGS: si5324::FrequencySettings
|
||||||
= si5324::FrequencySettings {
|
= si5324::FrequencySettings {
|
||||||
n1_hs : 5,
|
n1_hs : 5,
|
||||||
@ -419,6 +411,19 @@ const SI5324_SETTINGS: si5324::FrequencySettings
|
|||||||
crystal_ref: true
|
crystal_ref: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(all(has_si5324, rtio_frequency = "100.0"))]
|
||||||
|
const SI5324_SETTINGS: si5324::FrequencySettings
|
||||||
|
= si5324::FrequencySettings {
|
||||||
|
n1_hs : 5,
|
||||||
|
nc1_ls : 10,
|
||||||
|
n2_hs : 10,
|
||||||
|
n2_ls : 250,
|
||||||
|
n31 : 50,
|
||||||
|
n32 : 50,
|
||||||
|
bwsel : 4,
|
||||||
|
crystal_ref: true
|
||||||
|
};
|
||||||
|
|
||||||
static mut LOG_BUFFER: [u8; 1<<17] = [0; 1<<17];
|
static mut LOG_BUFFER: [u8; 1<<17] = [0; 1<<17];
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
Loading…
Reference in New Issue
Block a user